From 82bd0bb4519a72c4583d94965dbec0c85486ea3a Mon Sep 17 00:00:00 2001 From: "Kevin P. Fleming" Date: Wed, 8 Mar 2023 09:28:38 -0500 Subject: [PATCH 001/909] builder-support: Prepare to make Debian-style source artifacts Debian requires an 'orig' tarball to be part of the source artifact set (along with the .dsc and .debian.tar.xz files), so the debbuild-prepare Dockerfile will now make a copy of the sdist-provided tarball with the proper name. --- builder-support/dockerfiles/Dockerfile.debbuild-prepare | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/builder-support/dockerfiles/Dockerfile.debbuild-prepare b/builder-support/dockerfiles/Dockerfile.debbuild-prepare index 2c8626e1e4b5..7f03177fe684 100644 --- a/builder-support/dockerfiles/Dockerfile.debbuild-prepare +++ b/builder-support/dockerfiles/Dockerfile.debbuild-prepare @@ -17,12 +17,18 @@ COPY --from=sdist /sdist /sdist @IF [ -n "$M_authoritative$M_all" ] RUN tar xvf /sdist/pdns-${BUILDER_VERSION}.tar.bz2 +# create copy of source tarball with name that dpkg-source requires +RUN cp /sdist/pdns-${BUILDER_VERSION}.tar.bz2 pdns_${BUILDER_VERSION}.orig.tar.bz2 @ENDIF @IF [ -n "$M_recursor$M_all" ] RUN tar xvf /sdist/pdns-recursor-${BUILDER_VERSION}.tar.bz2 +# create copy of source tarball with name that dpkg-source requires +RUN cp /sdist/pdns-recursor-${BUILDER_VERSION}.tar.bz2 pdns-recursor_${BUILDER_VERSION}.orig.tar.bz2 @ENDIF @IF [ -n "$M_dnsdist$M_all" ] RUN tar xvf /sdist/dnsdist-${BUILDER_VERSION}.tar.bz2 +# create copy of source tarball with name that dpkg-source requires +RUN cp /sdist/dnsdist-${BUILDER_VERSION}.tar.bz2 dnsdist_${BUILDER_VERSION}.orig.tar.bz2 @ENDIF From c6ca0aa8058271301ccbd2a63061fa0d5c3d2397 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Fri, 17 Feb 2023 16:42:30 -0500 Subject: [PATCH 002/909] auth: harmonize *xfr log messages --- pdns/tcpreceiver.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 7d9a4f54b517..473d4095b9e7 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -584,7 +584,7 @@ namespace { /** do the actual zone transfer. Return 0 in case of error, 1 in case of success */ int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr& q, int outsock) { - string logPrefix="AXFR-out zone '"+target.toLogString()+"', client '"+q->getRemoteString()+"', "; + string logPrefix="AXFR-out zone '"+target.toLogString()+"', client '"+q->getRemoteStringWithPort()+"', "; std::unique_ptr outpacket= getFreshAXFRPacket(q); if(q->d_dnssecOk) @@ -1160,7 +1160,7 @@ int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr& q, int TCPNameserver::doIXFR(std::unique_ptr& q, int outsock) { - string logPrefix="IXFR-out zone '"+q->qdomain.toLogString()+"', client '"+q->getRemoteString()+"', "; + string logPrefix="IXFR-out zone '"+q->qdomain.toLogString()+"', client '"+q->getRemoteStringWithPort()+"', "; std::unique_ptr outpacket=getFreshAXFRPacket(q); if(q->d_dnssecOk) From 9273c94d88794368a8dd0c9742d00e7bf7d1e729 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Tue, 31 Jan 2023 10:48:06 -0500 Subject: [PATCH 003/909] Replace `msec` with `ms` --- pdns/dnsbulktest.cc | 8 ++++---- pdns/dnsdist-lua-actions.cc | 4 ++-- pdns/dnsdist-lua-inspection.cc | 4 ++-- pdns/dnsreplay.cc | 4 ++-- pdns/dnsscope.cc | 4 ++-- pdns/dnstcpbench.cc | 2 +- pdns/recursordist/syncres.cc | 6 +++--- pdns/tools/rrd/makegraphs | 4 ++-- 8 files changed, 18 insertions(+), 18 deletions(-) diff --git a/pdns/dnsbulktest.cc b/pdns/dnsbulktest.cc index 1a4d20f78ee3..df221c06f0f3 100644 --- a/pdns/dnsbulktest.cc +++ b/pdns/dnsbulktest.cc @@ -188,9 +188,9 @@ struct SendReceive { (*d_acc)(usec/1000.0); // if(usec > 1000000) - // cerr<<"Slow: "<second*1.0); } boost::format fmt("%7.2f\t%s\n"); - g_outputBuffer += (fmt % "msec" % "").str(); + g_outputBuffer += (fmt % "ms" % "").str(); for(auto iter = histo.cbegin(); iter != histo.cend(); ++iter) { int stars = (70.0 * iter->second/highest); diff --git a/pdns/dnsreplay.cc b/pdns/dnsreplay.cc index 8d3a529b8e25..8db158c642dd 100644 --- a/pdns/dnsreplay.cc +++ b/pdns/dnsreplay.cc @@ -306,9 +306,9 @@ static void emitFlightTimes() cout.precision(2); for(unsigned int i =0 ; i < sizeof(limits)/sizeof(limits[0]); ++i) { if(limits[i]!=flightTimes.size()) - cout<<"Within "<first < 1024) cout<< perc <<"% of questions answered within " << j->first << " usec ("; else - cout<< perc <<"% of questions answered within " << j->first/1000.0 << " msec ("; + cout<< perc <<"% of questions answered within " << j->first/1000.0 << " ms ("; cout<first < 1024) cout<< perc <<"% of questions answered within " << j->first << " usec ("; else - cout<< perc <<"% of questions answered within " << j->first/1000.0 << " msec ("; + cout<< perc <<"% of questions answered within " << j->first/1000.0 << " ms ("; cout<(EDNSExtendedError::code::NoReachableAuthority), "Timeout waiting for answer(s)"}; } - throw ImmediateServFailException("Too much time waiting for " + qname.toLogString() + "|" + qtype.toString() + ", timeouts: " + std::to_string(d_timeouts) + ", throttles: " + std::to_string(d_throttledqueries) + ", queries: " + std::to_string(d_outqueries) + ", " + std::to_string(d_totUsec / 1000) + "msec"); + throw ImmediateServFailException("Too much time waiting for " + qname.toLogString() + "|" + qtype.toString() + ", timeouts: " + std::to_string(d_timeouts) + ", throttles: " + std::to_string(d_throttledqueries) + ", queries: " + std::to_string(d_outqueries) + ", " + std::to_string(d_totUsec / 1000) + " ms"); } if (doTCP) { @@ -5172,7 +5172,7 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, if (resolveret == LWResult::Result::Timeout) { /* Time out */ - LOG(prefix << qname << ": Timeout resolving after " << lwr.d_usec / 1000.0 << "msec " << (doTCP ? "over TCP" : "") << endl); + LOG(prefix << qname << ": Timeout resolving after " << lwr.d_usec / 1000.0 << " ms " << (doTCP ? "over TCP" : "") << endl); d_timeouts++; t_Counters.at(rec::Counter::outgoingtimeouts)++; @@ -5661,7 +5661,7 @@ int SyncRes::doResolveAt(NsSet& nameservers, DNSName auth, bool flawedNSSet, con if(remoteIP->sin4.sin_family==AF_INET6) lwr.d_usec/=3; */ - // cout<<"msec: "<find_or_enter(tns->first.empty() ? DNSName(remoteIP->toStringWithPort()) : tns->first, d_now).submit(*remoteIP, lwr.d_usec, d_now); diff --git a/pdns/tools/rrd/makegraphs b/pdns/tools/rrd/makegraphs index a0f66998c2e1..62dfbf6787a3 100755 --- a/pdns/tools/rrd/makegraphs +++ b/pdns/tools/rrd/makegraphs @@ -78,8 +78,8 @@ function makeGraphs() LINE1:alloutqueries#00ff00:"outqueries/s" rrdtool graph $GRAPHOPTS --start -$1 $WWWPREFIX/qa-latency-$2.png -w $WSIZE -h $HSIZE -l 0 \ - -t "Questions/answer latency in milliseconds" \ - -v "msec" \ + -t "Questions/answer latency in ms" \ + -v "ms" \ DEF:qalatency=pdns_recursor.rrd:qa-latency:AVERAGE \ CDEF:mqalatency=qalatency,1000,/ \ LINE1:mqalatency#ff0000:"questions/s" From 35f4f57433255aa364acbdfb60b36f2776bb741a Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Tue, 31 Jan 2023 11:07:50 -0500 Subject: [PATCH 004/909] Replace `usec` with `us` - Swap `total [unit]` to `[unit] total` - Mostly remove leading space before `us` - `took` lines excluded - lines with other units that still had leading spaces excluded --- modules/gmysqlbackend/smysql.cc | 4 ++-- modules/gpgsqlbackend/spgsql.cc | 4 ++-- modules/lmdbbackend/lmdbbackend.cc | 4 ++-- pdns/dnsdist-carbon.cc | 2 +- pdns/dnsdist-lua-rules.cc | 2 +- pdns/dnsdist-tcp.cc | 2 +- pdns/dnsdist.cc | 4 ++-- pdns/dnsdistdist/doh.cc | 4 ++-- pdns/dnsscope.cc | 6 +++--- pdns/dnssecinfra.cc | 2 +- pdns/dnstcpbench.cc | 4 ++-- pdns/speedtest.cc | 2 +- pdns/ssqlite3.cc | 4 ++-- 13 files changed, 22 insertions(+), 22 deletions(-) diff --git a/modules/gmysqlbackend/smysql.cc b/modules/gmysqlbackend/smysql.cc index db8e6c2f3215..04518bb5ce34 100644 --- a/modules/gmysqlbackend/smysql.cc +++ b/modules/gmysqlbackend/smysql.cc @@ -262,7 +262,7 @@ class SMySQLStatement : public SSqlStatement } if (d_dolog) - g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " usec to execute" << endl; + g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us to execute" << endl; return this; } @@ -270,7 +270,7 @@ class SMySQLStatement : public SSqlStatement bool hasNextRow() { if (d_dolog && d_residx == d_resnum) { - g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " total usec to last row" << endl; + g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us total to last row" << endl; } return d_residx < d_resnum; } diff --git a/modules/gpgsqlbackend/spgsql.cc b/modules/gpgsqlbackend/spgsql.cc index 9b19b0ce2a7e..f373c8adf75e 100644 --- a/modules/gpgsqlbackend/spgsql.cc +++ b/modules/gpgsqlbackend/spgsql.cc @@ -112,7 +112,7 @@ class SPgSQLStatement : public SSqlStatement d_cur_set = 0; if (d_dolog) { auto diff = d_dtime.udiffNoReset(); - g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << diff << " usec to execute" << endl; + g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << diff << " us to execute" << endl; } nextResult(); @@ -143,7 +143,7 @@ class SPgSQLStatement : public SSqlStatement bool hasNextRow() { if (d_dolog && d_residx == d_resnum) { - g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiff() << " total usec to last row" << endl; + g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiff() << " us total to last row" << endl; } return d_residx < d_resnum; diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 086200f50b05..2518f2bdf028 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -813,13 +813,13 @@ void LMDBBackend::lookup(const QType& type, const DNSName& qdomain, int zoneId, if (d_getcursor->lower_bound(d_matchkey, key, val) || key.get().rfind(d_matchkey, 0) != 0) { d_getcursor.reset(); if (d_dolog) { - g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " usec to execute (found nothing)" << endl; + g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us to execute (found nothing)" << endl; } return; } if (d_dolog) { - g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " usec to execute" << endl; + g_log << Logger::Warning << "Query " << ((long)(void*)this) << ": " << d_dtime.udiffNoReset() << " us to execute" << endl; } d_lookupdomain = hunt; diff --git a/pdns/dnsdist-carbon.cc b/pdns/dnsdist-carbon.cc index b953180180e8..0fc8674839b9 100644 --- a/pdns/dnsdist-carbon.cc +++ b/pdns/dnsdist-carbon.cc @@ -281,7 +281,7 @@ static void carbonHandler(Carbon::Endpoint&& endpoint) usleep(toSleepUSec); } else { - vinfolog("Carbon export for %s took longer (%s usec) than the configured interval (%d usec)", endpoint.server.toStringWithPort(), elapsedUSec, intervalUSec); + vinfolog("Carbon export for %s took longer (%s us) than the configured interval (%d us)", endpoint.server.toStringWithPort(), elapsedUSec, intervalUSec); } consecutiveFailures = 0; } diff --git a/pdns/dnsdist-lua-rules.cc b/pdns/dnsdist-lua-rules.cc index 7100cf72bebd..347b617072cf 100644 --- a/pdns/dnsdist-lua-rules.cc +++ b/pdns/dnsdist-lua-rules.cc @@ -468,7 +468,7 @@ void setupLuaRules(LuaContext& luaCtx) } } double udiff = sw.udiff(); - g_outputBuffer=(boost::format("Had %d matches out of %d, %.1f qps, in %.1f usec\n") % matches % times % (1000000*(1.0*times/udiff)) % udiff).str(); + g_outputBuffer=(boost::format("Had %d matches out of %d, %.1f qps, in %.1f us\n") % matches % times % (1000000*(1.0*times/udiff)) % udiff).str(); }); diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 11da401daf2b..7c714c1e20db 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -241,7 +241,7 @@ static void handleResponseSent(std::shared_ptr& stat if (currentResponse.d_idstate.selfGenerated == false && ds) { const auto& ids = currentResponse.d_idstate; double udiff = ids.queryRealTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (%s, %d bytes), took %f usec", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), currentResponse.d_buffer.size(), udiff); + vinfolog("Got answer from %s, relayed to %s (%s, %d bytes), took %f us", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), currentResponse.d_buffer.size(), udiff); auto backendProtocol = ds->getProtocol(); if (backendProtocol == dnsdist::Protocol::DoUDP) { diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 6dddd4fd5057..b443ff1f0c36 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -696,10 +696,10 @@ static void handleResponseForUDPClient(InternalQueryState& ids, PacketBuffer& re if (!selfGenerated) { double udiff = ids.queryRealTime.udiff(); if (!muted) { - vinfolog("Got answer from %s, relayed to %s (UDP), took %f usec", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff); + vinfolog("Got answer from %s, relayed to %s (UDP), took %f us", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff); } else { - vinfolog("Got answer from %s, NOT relayed to %s (UDP) since that frontend is muted, took %f usec", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff); + vinfolog("Got answer from %s, NOT relayed to %s (UDP) since that frontend is muted, took %f us", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), udiff); } handleResponseSent(ids, udiff, dr.ids.origRemote, ds->d_config.remote, response.size(), cleartextDH, ds->getProtocol(), true); diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 8481193d877b..021eec32d2d0 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -486,7 +486,7 @@ class DoHTCPCrossQuerySender : public TCPQuerySender if (!du->ids.selfGenerated) { double udiff = du->ids.queryRealTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (https), took %f usec", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); + vinfolog("Got answer from %s, relayed to %s (https), took %f us", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); auto backendProtocol = du->downstream->getProtocol(); if (backendProtocol == dnsdist::Protocol::DoUDP && du->tcp) { @@ -1735,7 +1735,7 @@ void handleUDPResponseForDoH(DOHUnitUniquePtr&& du, PacketBuffer&& udpResponse, du = std::move(dr.ids.du); double udiff = du->ids.queryRealTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (https), took %f usec", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); + vinfolog("Got answer from %s, relayed to %s (https), took %f us", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); handleResponseSent(du->ids, udiff, dr.ids.origRemote, du->downstream->d_config.remote, du->response.size(), cleartextDH, du->downstream->getProtocol(), true); diff --git a/pdns/dnsscope.cc b/pdns/dnsscope.cc index 62181dabfb10..8c0c32c2c05d 100644 --- a/pdns/dnsscope.cc +++ b/pdns/dnsscope.cc @@ -478,7 +478,7 @@ try perc=sum*100.0/totpairs; if(j->first < 1024) - cout<< perc <<"% of questions answered within " << j->first << " usec ("; + cout<< perc <<"% of questions answered within " << j->first << " us ("; else cout<< perc <<"% of questions answered within " << j->first/1000.0 << " ms ("; @@ -494,7 +494,7 @@ try if(!j->second) { perc=sum*100.0/totpairs; if(j->first < 1024) - cout<< perc <<"% of questions answered within " << j->first << " usec ("; + cout<< perc <<"% of questions answered within " << j->first << " us ("; else cout<< perc <<"% of questions answered within " << j->first/1000.0 << " ms ("; @@ -507,7 +507,7 @@ try cout<< (totpairs-lastsum)<<" responses ("<<((totpairs-lastsum)*100.0/answers) <<"%) older than "<< (done.rbegin()->first/1000000.0) <<" seconds"<().empty()) { ofstream load(g_vm["load-stats"].as().c_str()); diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index 50479d5ee788..49b8c9a880dc 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -375,7 +375,7 @@ void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t if(verified) { udiffVerify = dt.udiff() / 100; - cout<<"Signature & verify ok, create "<getName()+" with signer "+dckeSign->getName()+" and verifier "+dckeVerify->getName()+" failed"); diff --git a/pdns/dnstcpbench.cc b/pdns/dnstcpbench.cc index d092a6a9d1e3..b35ebc7a9607 100644 --- a/pdns/dnstcpbench.cc +++ b/pdns/dnstcpbench.cc @@ -305,8 +305,8 @@ try } cout<<"Average qps: "< void doRun(const C& cmd, int mseconds=100) cmd(); } double delta=dt.ndiff()/1000000000.0; - boost::format fmt("'%s' %.02f seconds: %.1f runs/s, %.02f usec/run"); + boost::format fmt("'%s' %.02f seconds: %.1f runs/s, %.02f us/run"); cerr<< (fmt % cmd.getName() % delta % (runs/delta) % (delta* 1000000.0/runs)) << endl; g_totalRuns += runs; diff --git a/pdns/ssqlite3.cc b/pdns/ssqlite3.cc index c2c96ebea7b8..85efc190659e 100644 --- a/pdns/ssqlite3.cc +++ b/pdns/ssqlite3.cc @@ -97,12 +97,12 @@ class SSQLite3Statement: public SSqlStatement throw SSqlException(string("Error while retrieving SQLite query results: ")+SSQLite3ErrorString(d_db->db())); } if(d_dolog) - g_log< Date: Thu, 9 Mar 2023 17:11:49 +0100 Subject: [PATCH 005/909] auth: make feedComment return bool, have callers check it --- pdns/backends/gsql/gsqlbackend.cc | 4 +++- pdns/backends/gsql/gsqlbackend.hh | 2 +- pdns/dnsbackend.hh | 3 ++- pdns/pdnsutil.cc | 4 +++- pdns/ws-auth.cc | 4 +++- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/pdns/backends/gsql/gsqlbackend.cc b/pdns/backends/gsql/gsqlbackend.cc index ead6243d68fa..5a231e115bd8 100644 --- a/pdns/backends/gsql/gsqlbackend.cc +++ b/pdns/backends/gsql/gsqlbackend.cc @@ -1989,7 +1989,7 @@ bool GSQLBackend::getComment(Comment& comment) } } -void GSQLBackend::feedComment(const Comment& comment) +bool GSQLBackend::feedComment(const Comment& comment) { try { reconnectIfNeeded(); @@ -2007,6 +2007,8 @@ void GSQLBackend::feedComment(const Comment& comment) catch (SSqlException &e) { throw PDNSException("GSQLBackend unable to feed comment for RRSet '" + comment.qname.toLogString() + "|" + comment.qtype.toString() + "': "+e.txtReason()); } + + return true; } bool GSQLBackend::replaceComments(const uint32_t domain_id, const DNSName& qname, const QType& qt, const vector& comments) diff --git a/pdns/backends/gsql/gsqlbackend.hh b/pdns/backends/gsql/gsqlbackend.hh index a7afbd13fe6d..9ba76db92d0b 100644 --- a/pdns/backends/gsql/gsqlbackend.hh +++ b/pdns/backends/gsql/gsqlbackend.hh @@ -251,7 +251,7 @@ public: bool listComments(const uint32_t domain_id) override; bool getComment(Comment& comment) override; - void feedComment(const Comment& comment) override; + bool feedComment(const Comment& comment) override; bool replaceComments(const uint32_t domain_id, const DNSName& qname, const QType& qt, const vector& comments) override; string directBackendCmd(const string &query) override; bool searchRecords(const string &pattern, int maxResults, vector& result) override; diff --git a/pdns/dnsbackend.hh b/pdns/dnsbackend.hh index 244782da6cce..5859c77dceb1 100644 --- a/pdns/dnsbackend.hh +++ b/pdns/dnsbackend.hh @@ -268,8 +268,9 @@ public: return false; } - virtual void feedComment(const Comment& /* comment */) + virtual bool feedComment(const Comment& /* comment */) { + return false; } virtual bool replaceComments(const uint32_t /* domain_id */, const DNSName& /* qname */, const QType& /* qt */, const vector& /* comments */) diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 03da0ac20843..eb30fbec3b0a 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -4126,7 +4126,9 @@ try Comment c; while(src->getComment(c)) { c.domain_id = di_new.id; - tgt->feedComment(c); + if (!tgt->feedComment(c)) { + throw PDNSException("Target backend does not support comments - remove them first"); + } nc++; } } diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index c0827d1b6667..20d79875f682 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1829,7 +1829,9 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { } for(Comment& c : new_comments) { c.domain_id = di.id; - di.backend->feedComment(c); + if (!di.backend->feedComment(c)) { + throw ApiException("Hosting backend does not support editing comments."); + } } updateDomainSettingsFromDocument(B, di, zonename, document, !new_records.empty()); From f626cc48fdf88204a77284493882f1ff0ecb1e88 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 9 Mar 2023 19:55:45 +0100 Subject: [PATCH 006/909] auth lmdb: support replaceComments, but only accept the empty vector --- modules/lmdbbackend/lmdbbackend.cc | 7 +++++++ modules/lmdbbackend/lmdbbackend.hh | 1 + regression-tests.api/test_Zones.py | 16 ++++++++++++---- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 086200f50b05..0927649ec24f 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -568,6 +568,13 @@ bool LMDBBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const Q return true; } +bool LMDBBackend::replaceComments(const uint32_t domain_id, const DNSName& qname, const QType& qt, const vector& comments) +{ + // if the vector is empty, good, that's what we do here (LMDB does not store comments) + // if it's not, report failure + return comments.empty(); +} + // tempting to templatize these two functions but the pain is not worth it std::shared_ptr LMDBBackend::getRecordsRWTransaction(uint32_t id) { diff --git a/modules/lmdbbackend/lmdbbackend.hh b/modules/lmdbbackend/lmdbbackend.hh index c1d29a864f88..4b55184748b3 100644 --- a/modules/lmdbbackend/lmdbbackend.hh +++ b/modules/lmdbbackend/lmdbbackend.hh @@ -74,6 +74,7 @@ public: bool feedEnts(int domain_id, map& nonterm) override; bool feedEnts3(int domain_id, const DNSName& domain, map& nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow) override; bool replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector& rrset) override; + bool replaceComments(uint32_t domain_id, const DNSName& qname, const QType& qt, const vector& comments) override; void getAllDomains(vector* domains, bool doSerial, bool include_disabled) override; void lookup(const QType& type, const DNSName& qdomain, int zoneId, DNSPacket* p = nullptr) override; diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 0c26db393b8b..46d92f552075 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -3,6 +3,7 @@ import operator import time import unittest +import requests.exceptions from copy import deepcopy from parameterized import parameterized from pprint import pprint @@ -242,7 +243,6 @@ def test_create_zone_with_wildcard_records(self): # check our record has appeared self.assertEqual(get_rrset(data, rrset['name'], 'A')['records'], rrset['records']) - @unittest.skipIf(is_auth_lmdb(), "No comments in LMDB") def test_create_zone_with_comments(self): name = unique_zone_name() rrsets = [ @@ -288,6 +288,12 @@ def test_create_zone_with_comments(self): }], }, ] + + if is_auth_lmdb(): + with self.assertRaises(requests.exceptions.HTTPError): # No comments in LMDB + self.create_zone(name=name, rrsets=rrsets) + return + name, payload, data = self.create_zone(name=name, rrsets=rrsets) # NS records have been created self.assertEqual(len(data['rrsets']), len(rrsets) + 1) @@ -1848,7 +1854,6 @@ def test_zone_delete(self): self.assertEqual(r.status_code, 204) self.assertNotIn('Content-Type', r.headers) - @unittest.skipIf(is_auth_lmdb(), "No comments in LMDB") def test_zone_comment_create(self): name, payload, zone = self.create_zone() rrset = { @@ -1872,7 +1877,11 @@ def test_zone_comment_create(self): self.url("/api/v1/servers/localhost/zones/" + name), data=json.dumps(payload), headers={'content-type': 'application/json'}) - self.assert_success(r) + if is_auth_lmdb(): + self.assert_error_json(r) # No comments in LMDB + return + else: + self.assert_success(r) # make sure the comments have been set, and that the NS # records are still present data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() @@ -1885,7 +1894,6 @@ def test_zone_comment_create(self): # verify that TTL is correct (regression test) self.assertEqual(serverset['ttl'], 3600) - @unittest.skipIf(is_auth_lmdb(), "No comments in LMDB") def test_zone_comment_delete(self): # Test: Delete ONLY comments. name, payload, zone = self.create_zone() From f1766172de104560fc4676ace93682dd1af1dabd Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 31 Mar 2021 16:10:56 +0200 Subject: [PATCH 007/909] Update Debian packaging for Recursor debhelper compat handling is different from Debian sid, because we try to support older distributions. --- .../recursor/debian-buster/README.source | 1 - .../configure-helpers/net-snmp-config | 21 +++ .../debian/recursor/debian-buster/control | 27 ++- .../debian/recursor/debian-buster/copyright | 5 +- .../debian-buster/pdns-recursor.default | 7 - .../recursor/debian-buster/pdns-recursor.init | 175 ------------------ .../pdns-recursor.lintian-overrides | 2 - .../debian-buster/pdns-recursor.postinst | 18 +- .../debian-buster/pdns-recursor.preinst | 30 +++ .../debian-buster/pdns-recursor.prerm | 11 -- .../debian/recursor/debian-buster/rules | 85 ++++----- .../debian-buster/source.lintian-overrides | 2 - .../recursor/debian-buster/tests/control | 3 +- .../debian/recursor/debian-buster/tests/smoke | 10 +- 14 files changed, 115 insertions(+), 282 deletions(-) delete mode 100644 builder-support/debian/recursor/debian-buster/README.source create mode 100755 builder-support/debian/recursor/debian-buster/configure-helpers/net-snmp-config delete mode 100644 builder-support/debian/recursor/debian-buster/pdns-recursor.default delete mode 100644 builder-support/debian/recursor/debian-buster/pdns-recursor.init create mode 100644 builder-support/debian/recursor/debian-buster/pdns-recursor.preinst delete mode 100644 builder-support/debian/recursor/debian-buster/pdns-recursor.prerm delete mode 100644 builder-support/debian/recursor/debian-buster/source.lintian-overrides diff --git a/builder-support/debian/recursor/debian-buster/README.source b/builder-support/debian/recursor/debian-buster/README.source deleted file mode 100644 index cf42723cec9d..000000000000 --- a/builder-support/debian/recursor/debian-buster/README.source +++ /dev/null @@ -1 +0,0 @@ -See /usr/share/doc/quilt/README.source diff --git a/builder-support/debian/recursor/debian-buster/configure-helpers/net-snmp-config b/builder-support/debian/recursor/debian-buster/configure-helpers/net-snmp-config new file mode 100755 index 000000000000..6d8d6e7d3e64 --- /dev/null +++ b/builder-support/debian/recursor/debian-buster/configure-helpers/net-snmp-config @@ -0,0 +1,21 @@ +#!/bin/bash + +if [ "$1" = "--cflags" ]; then + FLAGS=$(/usr/bin/net-snmp-config --cflags) + MYFLAGS="" + for flag in $FLAGS; do + if [[ "$flag" =~ -DNETSNMP* ]]; then + MYFLAGS="$MYFLAGS $flag" + fi + done + echo "$MYFLAGS" + exit 0 + +elif [ "$1" = "--netsnmp-agent-libs" ]; then + /usr/bin/net-snmp-config "$@" + exit $? + +else + echo "E: debian/configure-helpers/net-snmp-config: unknown flag $1" >&2 + exit 1 +fi diff --git a/builder-support/debian/recursor/debian-buster/control b/builder-support/debian/recursor/debian-buster/control index b5216671c574..c9325fc95e2b 100644 --- a/builder-support/debian/recursor/debian-buster/control +++ b/builder-support/debian/recursor/debian-buster/control @@ -1,29 +1,36 @@ Source: pdns-recursor Section: net -Priority: extra -Standards-Version: 4.1.2 -Maintainer: PowerDNS.COM BV +Maintainer: PowerDNS Autobuilder +Priority: optional +Standards-Version: 4.5.1 +Build-Conflicts: libboost-context-dev [mips mipsel] Build-Depends: debhelper (>= 10), dh-autoreconf, - libboost-all-dev, + libboost-context-dev [amd64 arm64 armel armhf i386 ppc64el], + libboost-dev, + libboost-program-options-dev, + libboost-system-dev, + libboost-test-dev, + libboost-thread-dev, libcap-dev, libcurl4-openssl-dev, - libluajit-5.1-dev [!arm64 !s390x], - liblua5.3-dev [arm64 s390x], libfstrm-dev, + libluajit-5.1-dev (>= 2.1.0~beta3+dfsg-5.3) [amd64 arm64] | libluajit-5.1-dev [amd64] | liblua5.3-dev, + libprotobuf-dev, libsnmp-dev, libsodium-dev, libssl-dev, - libsystemd-dev [linux-any], + libsystemd-dev, pkg-config, + protobuf-compiler, ragel, - systemd [linux-any] -Vcs-Git: https://anonscm.debian.org/git/pkg-dns/pdns-recursor.git -Vcs-Browser: https://anonscm.debian.org/cgit/pkg-dns/pdns-recursor.git + systemd Homepage: https://www.powerdns.com/ +Rules-Requires-Root: no Package: pdns-recursor Architecture: any +Pre-Depends: ${misc:Pre-Depends} Depends: adduser, dns-root-data, ${misc:Depends}, diff --git a/builder-support/debian/recursor/debian-buster/copyright b/builder-support/debian/recursor/debian-buster/copyright index 8aba47378c53..b8e649b70869 100644 --- a/builder-support/debian/recursor/debian-buster/copyright +++ b/builder-support/debian/recursor/debian-buster/copyright @@ -1,6 +1,7 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: PowerDNS Source: https://www.powerdns.com/downloads.html +Upstream-Contact: https://mailman.powerdns.com/mailman/listinfo/pdns-users Files: * Copyright: 2002 - 2022 PowerDNS.COM BV and contributors @@ -30,8 +31,8 @@ Files: debian/* Copyright: 2002 - 2004 Wichert Akkermann 2004 - 2013 Matthijs Möhlmann 2012 - 2013 Marc Haber - 2014 - 2016 Chris Hofstaedtler - 2016 PowerDNS.COM BV and contributors + 2014 - 2018 Chris Hofstaedtler + 2016 - 2018 PowerDNS.COM BV and contributors License: GPL-2 Files: ext/yahttp/* diff --git a/builder-support/debian/recursor/debian-buster/pdns-recursor.default b/builder-support/debian/recursor/debian-buster/pdns-recursor.default deleted file mode 100644 index db03e544a138..000000000000 --- a/builder-support/debian/recursor/debian-buster/pdns-recursor.default +++ /dev/null @@ -1,7 +0,0 @@ -# Variables for PowerDNS recursor init script. -# Not honored when systemd is the running init. -# -# Set START to yes to start the pdns-recursor -START=yes -# Run resolvconf? (Deprecated feature.) -RESOLVCONF=no diff --git a/builder-support/debian/recursor/debian-buster/pdns-recursor.init b/builder-support/debian/recursor/debian-buster/pdns-recursor.init deleted file mode 100644 index 8b0f44ed3e91..000000000000 --- a/builder-support/debian/recursor/debian-buster/pdns-recursor.init +++ /dev/null @@ -1,175 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: pdns-recursor -# Required-Start: $network $remote_fs $syslog -# Required-Stop: $network $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: PowerDNS Recursor - Recursive DNS Server -# Description: PowerDNS Recursor - Recursive DNS Server -### END INIT INFO - -# -# Authors: Matthijs Möhlmann -# Christoph Haas -# -# Thanks to: -# Thomas Hood -# -# initscript for PowerDNS recursor - -# Load lsb stuff for systemd redirection (if available). -if [ -e /lib/lsb/init-functions ]; then - . /lib/lsb/init-functions -fi - -PATH=/sbin:/bin:/usr/sbin:/usr/bin -DESC="PowerDNS Recursor" -NAME=pdns_recursor -DAEMON=/usr/sbin/$NAME -# Derive the socket-dir setting from /etc/powerdns/recursor.conf -# or fall back to the default /var/run if not specified there. -PIDDIR=$(awk -F= '/^socket-dir=/ {print $2}' /etc/powerdns/recursor.conf) -if [ -z "$PIDDIR" ]; then PIDDIR=/var/run/pdns-recursor; mkdir -p $PIDDIR; fi -PIDFILE=$PIDDIR/$NAME.pid - -# Gracefully exit if the package has been removed. -test -x $DAEMON || exit 0 - -# Read config file if it is present. -if [ -r /etc/default/pdns-recursor ]; then - . /etc/default/pdns-recursor -fi - -start() { -# Return -# 0 if daemon has been started / was already running -# >0 if daemon could not be started - start-stop-daemon --start --oknodo --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null || return 0 - start-stop-daemon --start --oknodo --quiet --pidfile $PIDFILE --exec $DAEMON -- --daemon=yes || return 2 -} - -start_resolvconf() { - if [ "X$RESOLVCONF" = "Xyes" ] && [ -x /sbin/resolvconf ]; then - echo "nameserver 127.0.0.1" | /sbin/resolvconf -a lo.pdns-recursor - fi - return 0 -} - -stop() { -# Return -# 0 if daemon has been stopped -# 1 if daemon was already stopped -# 2 if daemon could not be stopped -# other if a failure occurred - start-stop-daemon --stop --quiet --pidfile $PIDFILE --name $NAME - RETVAL="$?" - [ "$RETVAL" = 2 ] && return 2 - rm -f $PIDFILE - return "$RETVAL" -} - -stop_resolvconf() { - if [ "X$RESOLVCONF" = "Xyes" ] && [ -x /sbin/resolvconf ]; then - /sbin/resolvconf -d lo.pdns-recursor - fi - return 0 -} - -isrunning() -{ - /usr/bin/rec_control ping > /dev/null - return $? -} - -case "$1" in - start) - if [ "$START" != "yes" ]; then - echo "Not starting $DESC -- disabled." - exit 0 - fi - echo -n "Starting $DESC: $NAME ..." - start - case "$?" in - 0) - start_resolvconf - echo done - break - ;; - 1) - echo "already running" - break - ;; - *) - echo "failed" - exit 1 - ;; - esac - ;; - stop) - stop_resolvconf - echo -n "Stopping $DESC: $NAME ..." - stop - case "$?" in - 0) - echo done - break - ;; - 1) - echo "not running" - break - ;; - *) - echo "failed" - exit 1 - ;; - esac - ;; - restart|force-reload) - if [ "$START" != "yes" ]; then - $0 stop - exit 0 - fi - echo -n "Restarting $DESC ..." - stop - case "$?" in - 0|1) - start - case "$?" in - 0) - echo done - exit 0 - ;; - 1) - echo "failed -- old process still running" - exit 1 - ;; - *) - echo "failed to start" - exit 1 - ;; - esac - ;; - *) - echo "failed to stop" - exit 1 - ;; - esac - ;; - status) - if isrunning; then - echo "$NAME is running" - exit 0 - else - echo "$NAME is not running or not responding" - exit 3 - fi - ;; - *) - echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2 - exit 3 - ;; -esac - -exit 0 - diff --git a/builder-support/debian/recursor/debian-buster/pdns-recursor.lintian-overrides b/builder-support/debian/recursor/debian-buster/pdns-recursor.lintian-overrides index b7f625e555c6..d6aeec23c146 100644 --- a/builder-support/debian/recursor/debian-buster/pdns-recursor.lintian-overrides +++ b/builder-support/debian/recursor/debian-buster/pdns-recursor.lintian-overrides @@ -1,4 +1,2 @@ # Source carries OpenSSL Exception pdns-recursor: possible-gpl-code-linked-with-openssl -# We load lsb-functions conditionally. -pdns-recursor: init.d-script-needs-depends-on-lsb-base diff --git a/builder-support/debian/recursor/debian-buster/pdns-recursor.postinst b/builder-support/debian/recursor/debian-buster/pdns-recursor.postinst index 4e1da7099252..5f83e9d07f37 100644 --- a/builder-support/debian/recursor/debian-buster/pdns-recursor.postinst +++ b/builder-support/debian/recursor/debian-buster/pdns-recursor.postinst @@ -3,17 +3,8 @@ set -e case "$1" in configure) - if [ -z "`getent group pdns`" ]; then - addgroup --system pdns - fi - if [ -z "`getent passwd pdns`" ]; then - adduser --system --home /var/spool/powerdns --shell /bin/false --ingroup pdns --disabled-password --disabled-login --gecos "PowerDNS" pdns - fi - if [ "`stat -c '%U:%G' /etc/powerdns/recursor.conf`" = "root:root" ]; then - chown root:pdns /etc/powerdns/recursor.conf - # Make sure that pdns can read it; the default used to be 0600 - chmod g+r /etc/powerdns/recursor.conf - fi + addgroup --system pdns + adduser --system --home /var/spool/powerdns --shell /bin/false --ingroup pdns --disabled-password --disabled-login --gecos "PowerDNS" pdns ;; *) @@ -22,11 +13,6 @@ case "$1" in ;; esac -# Startup errors should never cause dpkg to fail. -initscript_error() { - return 0 -} - #DEBHELPER# exit 0 diff --git a/builder-support/debian/recursor/debian-buster/pdns-recursor.preinst b/builder-support/debian/recursor/debian-buster/pdns-recursor.preinst new file mode 100644 index 000000000000..691107c9efc2 --- /dev/null +++ b/builder-support/debian/recursor/debian-buster/pdns-recursor.preinst @@ -0,0 +1,30 @@ +#!/bin/sh +set -e + +delete_unchanged() { + if [ -e "$1" ] && echo "$2 $1" | md5sum --check --status; then + echo "Removing unchanged configuration file $1" + rm -f "$1" + fi +} + +backup_conffile() { + if [ -e "$1" ]; then + echo "Moving configuration file $1 to $1.dpkg-bak" + mv -f "$1" "$1".dpkg-bak + fi +} + +case "$1" in + install|upgrade) + # clean up files we no longer ship + delete_unchanged "/etc/default/pdns-recursor" a09916ceb17db9a49ac8cfa84790bf3b + delete_unchanged "/etc/default/pdns-recursor" 076b21b9b76d7ffecc918af47d2963c6 + backup_conffile "/etc/default/pdns-recursor" + delete_unchanged "/etc/init.d/pdns-recursor" e2ea0586c3d99fdbafb76483a769b964 + delete_unchanged "/etc/init.d/pdns-recursor" fb608ec5edc3d068213bac3480782355 + backup_conffile "/etc/init.d/pdns-recursor" + ;; +esac + +#DEBHELPER# diff --git a/builder-support/debian/recursor/debian-buster/pdns-recursor.prerm b/builder-support/debian/recursor/debian-buster/pdns-recursor.prerm deleted file mode 100644 index e78608ccf1ee..000000000000 --- a/builder-support/debian/recursor/debian-buster/pdns-recursor.prerm +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -set -e - -# Startup errors should never cause dpkg to fail. -initscript_error() { - return 0 -} - -#DEBHELPER# - -exit 0 diff --git a/builder-support/debian/recursor/debian-buster/rules b/builder-support/debian/recursor/debian-buster/rules index 651c62797494..c393dcb0c01d 100755 --- a/builder-support/debian/recursor/debian-buster/rules +++ b/builder-support/debian/recursor/debian-buster/rules @@ -1,80 +1,59 @@ #!/usr/bin/make -f -include /usr/share/dpkg/architecture.mk -include /usr/share/dpkg/pkg-info.mk -# Enable hardening features for daemons +# Turn on all hardening flags, as we're a networked daemon. # Note: blhc (build log hardening check) will find these false positives: CPPFLAGS 2 missing, LDFLAGS 1 missing -export DEB_BUILD_MAINT_OPTIONS=hardening=+bindnow,+pie +export DEB_BUILD_MAINT_OPTIONS = hardening=+all +# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* DPKG_EXPORT_BUILDFLAGS = 1 -# Include buildflags.mk so we can append to the vars it sets. -include /usr/share/dpkg/buildflags.mk +include /usr/share/dpkg/default.mk -# Only enable systemd integration on Linux operating systems -ifeq ($(DEB_HOST_ARCH_OS),linux) -CONFIGURE_ARGS += --enable-systemd --with-systemd=/lib/systemd/system -DH_ARGS += --with systemd -else -CONFIGURE_ARGS += --disable-systemd -endif - -# Only disable luajit on arm64 -ifneq ($(DEB_HOST_ARCH),arm64) -CONFIGURE_ARGS += --with-lua=luajit -else -CONFIGURE_ARGS += --with-lua=lua5.3 -endif -# Use new build system %: - dh $@ \ - --with autoreconf \ - $(DH_ARGS) + dh $@ + +override_dh_auto_clean: + dh_auto_clean + rm -f dnslabeltext.cc + chmod +x mkpubsuffixcc || true override_dh_auto_configure: - dh_auto_configure -- \ + PATH=debian/configure-helpers/:$$PATH dh_auto_configure -- \ --sysconfdir=/etc/powerdns \ + --enable-systemd --with-systemd=/lib/systemd/system \ --enable-unit-tests \ - --with-libcap \ - --with-libsodium \ - --enable-dns-over-tls \ - --enable-dnstap \ - --with-net-snmp \ --disable-silent-rules \ --with-service-user=pdns \ --with-service-group=pdns \ - $(CONFIGURE_ARGS) + --with-libcap \ + --with-libsodium \ + --with-lua \ + --with-net-snmp \ + --enable-dns-over-tls \ + --enable-dnstap override_dh_auto_install: dh_auto_install install -d debian/pdns-recursor/usr/share/pdns-recursor/lua-config install -m 644 -t debian/pdns-recursor/usr/share/pdns-recursor/lua-config debian/lua-config/rootkeys.lua install -m 644 -t debian/pdns-recursor/etc/powerdns debian/recursor.lua + install -d debian/pdns-recursor/usr/share/pdns-recursor/snmp + install -m 644 -t debian/pdns-recursor/usr/share/pdns-recursor/snmp RECURSOR-MIB.txt rm -f debian/pdns-recursor/etc/powerdns/recursor.conf-dist - ./pdns_recursor --config=default | sed \ - -e 's!# config-dir=.*!config-dir=/etc/powerdns!' \ - -e 's!# include-dir=.*!&\ninclude-dir=/etc/powerdns/recursor.d!' \ - -e 's!# local-address=.*!local-address=127.0.0.1!' \ - -e 's!# lua-config-file=.*!lua-config-file=/etc/powerdns/recursor.lua!' \ - -e 's!# quiet=.*!quiet=yes!' \ - -e 's!# setgid=.*!setgid=pdns!' \ - -e 's!# setuid=.*!setuid=pdns!' \ - -e 's!# hint-file=.*!&\nhint-file=/usr/share/dns/root.hints!' \ + ./pdns_recursor --no-config --config=default | sed \ + -e 's!^# config-dir=.*!config-dir=/etc/powerdns!' \ + -e 's!^# hint-file=.*!&\nhint-file=/usr/share/dns/root.hints!' \ + -e 's!^# include-dir=.*!&\ninclude-dir=/etc/powerdns/recursor.d!' \ + -e 's!^# local-address=.*!local-address=127.0.0.1!' \ + -e 's!^# lua-config-file=.*!lua-config-file=/etc/powerdns/recursor.lua!' \ + -e 's!^# quiet=.*!quiet=yes!' \ -e '/^# version-string=.*/d' \ > debian/pdns-recursor/etc/powerdns/recursor.conf -override_dh_strip: - dh_strip --ddeb-migration='pdns-recursor-dbg' - -override_dh_installinit: - dh_installinit --error-handler=initscript_error +override_dh_auto_test: +ifeq (,$(filter nocheck,$(DEB_BUILD_OPTIONS))) + dh_auto_test + -cat testrunner.log +endif override_dh_gencontrol: dh_gencontrol -- $(SUBSTVARS) - -override_dh_fixperms: - dh_fixperms -# these files often contain passwords. 640 as it is chowned to root:pdns - chmod 0640 debian/pdns-recursor/etc/powerdns/recursor.conf - -override_dh_builddeb: - dh_builddeb -- -Zgzip diff --git a/builder-support/debian/recursor/debian-buster/source.lintian-overrides b/builder-support/debian/recursor/debian-buster/source.lintian-overrides deleted file mode 100644 index 700fed037b1e..000000000000 --- a/builder-support/debian/recursor/debian-buster/source.lintian-overrides +++ /dev/null @@ -1,2 +0,0 @@ -# Source is in html/js/d3.js -pdns-recursor source: source-is-missing html/js/d3.v3.js line length is 32005 characters (>512) diff --git a/builder-support/debian/recursor/debian-buster/tests/control b/builder-support/debian/recursor/debian-buster/tests/control index a0a6fc4a76c1..bf44d5791726 100644 --- a/builder-support/debian/recursor/debian-buster/tests/control +++ b/builder-support/debian/recursor/debian-buster/tests/control @@ -1,3 +1,4 @@ Tests: smoke -Depends: @, dnsutils +Depends: dnsutils, + @ Restrictions: needs-root diff --git a/builder-support/debian/recursor/debian-buster/tests/smoke b/builder-support/debian/recursor/debian-buster/tests/smoke index 797073364207..23f78fefe0fb 100755 --- a/builder-support/debian/recursor/debian-buster/tests/smoke +++ b/builder-support/debian/recursor/debian-buster/tests/smoke @@ -2,6 +2,12 @@ exec 2>&1 set -ex +restart_failed() { + echo E: service restart failed + journalctl -n200 --no-pager + exit 1 +} + cat <>/etc/powerdns/recursor.conf auth-zones=example.org=/etc/powerdns/example.org.zone EOF @@ -12,11 +18,11 @@ example.org. 172800 IN NS ns1.example.org. smoke.example.org. 172800 IN A 127.0.0.123 EOF -service pdns-recursor restart +service pdns-recursor restart || restart_failed TMPFILE=$(mktemp) cleanup() { - rm -f "$TMPFILE" + rm -f "$TMPFILE" } trap cleanup EXIT From 6c8714d2a73180eb0ea08a39edf3b7c95dde29dc Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Mon, 20 Mar 2023 14:43:49 +0100 Subject: [PATCH 008/909] auth: allow multiple blocks of ips in ifportup() --- pdns/lua-record.cc | 56 ++++++++++++++++++++++++++++++---------------- 1 file changed, 37 insertions(+), 19 deletions(-) diff --git a/pdns/lua-record.cc b/pdns/lua-record.cc index 5665bdbbd04c..b4810b4cf5f6 100644 --- a/pdns/lua-record.cc +++ b/pdns/lua-record.cc @@ -548,13 +548,13 @@ static vector convComboAddressListToString(const vector& i return result; } -static vector convComboAddressList(const iplist_t& items) +static vector convComboAddressList(const iplist_t& items, uint16_t port=0) { vector result; result.reserve(items.size()); for(const auto& item : items) { - result.emplace_back(ComboAddress(item.second)); + result.emplace_back(ComboAddress(item.second, port)); } return result; @@ -832,33 +832,51 @@ static void setupLuaRecords(LuaContext& lua) * * @example ifportup(443, { '1.2.3.4', '5.4.3.2' })" */ - lua.writeFunction("ifportup", [](int port, const vector >& ips, const boost::optional> options) { - vector candidates, unavailables; + lua.writeFunction("ifportup", [](int port, const boost::variant& ips, const boost::optional> options) { + vector> candidates; opts_t opts; - vector conv; std::string selector; + if (port < 0) { + port = 0; + } + if (port > std::numeric_limits::max()) { + port = std::numeric_limits::max(); + } if(options) opts = *options; - for(const auto& i : ips) { - ComboAddress rem(i.second, port); - if(g_up.isUp(rem, opts)) { - candidates.push_back(rem); + + if(auto simple = boost::get(&ips)) { + vector unit = convComboAddressList(*simple, port); + candidates.push_back(unit); + } else { + auto units = boost::get(ips); + for(const auto& u : units) { + vector unit = convComboAddressList(u.second, port); + candidates.push_back(unit); + } + } + + for(const auto& unit : candidates) { + vector available; + for(const auto& c : unit) { + if(g_up.isUp(c, opts)) { + available.push_back(c); + } } - else { - unavailables.push_back(rem); + if(!available.empty()) { + vector res = useSelector(getOptionValue(options, "selector", "random"), s_lua_record_ctx->bestwho, available); + return convComboAddressListToString(res); } } - if(!candidates.empty()) { - // use regular selector - selector = getOptionValue(options, "selector", "random"); - } else { - // All units are down, apply backupSelector on all candidates - candidates = std::move(unavailables); - selector = getOptionValue(options, "backupSelector", "random"); + + // All units down, apply backupSelector on all candidates + vector unavailable{}; + for(const auto& unit : candidates) { + unavailable.insert(unavailable.end(), unit.begin(), unit.end()); } - vector res = useSelector(selector, s_lua_record_ctx->bestwho, candidates); + vector res = useSelector(getOptionValue(options, "backupSelector", "random"), s_lua_record_ctx->bestwho, unavailable); return convComboAddressListToString(res); }); From 04c537836d9dbc27540ad4653c3450239cd302ab Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Tue, 21 Mar 2023 14:58:19 +0100 Subject: [PATCH 009/909] auth: refactor if{url,port}up functions --- pdns/lua-record.cc | 136 +++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 74 deletions(-) diff --git a/pdns/lua-record.cc b/pdns/lua-record.cc index b4810b4cf5f6..639653fede22 100644 --- a/pdns/lua-record.cc +++ b/pdns/lua-record.cc @@ -301,7 +301,6 @@ bool doCompare(const T& var, const std::string& res, const C& cmp) } } - static std::string getGeo(const std::string& ip, GeoIPInterface::GeoIPQueryAttribute qa) { static bool initialized; @@ -560,6 +559,29 @@ static vector convComboAddressList(const iplist_t& items, uint16_t return result; } +/** + * Reads and unify single or multiple sets of ips : + * - {'192.0.2.1', '192.0.2.2'} + * - {{'192.0.2.1', '192.0.2.2'}, {'198.51.100.1'}} + */ + +static vector> convMultiComboAddressList(const boost::variant& items, uint16_t port = 0) +{ + vector> candidates; + + if(auto simple = boost::get(&items)) { + vector unit = convComboAddressList(*simple, port); + candidates.push_back(unit); + } else { + auto units = boost::get(items); + for(const auto& u : units) { + vector unit = convComboAddressList(u.second, port); + candidates.push_back(unit); + } + } + return candidates; +} + static vector convStringList(const iplist_t& items) { vector result; @@ -596,6 +618,37 @@ typedef struct AuthLuaRecordContext static thread_local unique_ptr s_lua_record_ctx; +static vector genericIfUp(const boost::variant& ips, boost::optional options, std::function upcheckf, uint16_t port = 0) { + vector > candidates; + opts_t opts; + if(options) + opts = *options; + + candidates = convMultiComboAddressList(ips, port); + + for(const auto& unit : candidates) { + vector available; + for(const auto& c : unit) { + if (upcheckf(c, opts)) { + available.push_back(c); + } + } + if(!available.empty()) { + vector res = useSelector(getOptionValue(options, "selector", "random"), s_lua_record_ctx->bestwho, available); + return convComboAddressListToString(res); + } + } + + // All units down, apply backupSelector on all candidates + vector ret{}; + for(const auto& unit : candidates) { + ret.insert(ret.end(), unit.begin(), unit.end()); + } + + vector res = useSelector(getOptionValue(options, "backupSelector", "random"), s_lua_record_ctx->bestwho, ret); + return convComboAddressListToString(res); +} + static void setupLuaRecords(LuaContext& lua) { lua.writeFunction("latlon", []() { @@ -833,51 +886,17 @@ static void setupLuaRecords(LuaContext& lua) * @example ifportup(443, { '1.2.3.4', '5.4.3.2' })" */ lua.writeFunction("ifportup", [](int port, const boost::variant& ips, const boost::optional> options) { - vector> candidates; - opts_t opts; - std::string selector; - if (port < 0) { port = 0; } if (port > std::numeric_limits::max()) { port = std::numeric_limits::max(); } - if(options) - opts = *options; - - if(auto simple = boost::get(&ips)) { - vector unit = convComboAddressList(*simple, port); - candidates.push_back(unit); - } else { - auto units = boost::get(ips); - for(const auto& u : units) { - vector unit = convComboAddressList(u.second, port); - candidates.push_back(unit); - } - } - - for(const auto& unit : candidates) { - vector available; - for(const auto& c : unit) { - if(g_up.isUp(c, opts)) { - available.push_back(c); - } - } - if(!available.empty()) { - vector res = useSelector(getOptionValue(options, "selector", "random"), s_lua_record_ctx->bestwho, available); - return convComboAddressListToString(res); - } - } - // All units down, apply backupSelector on all candidates - vector unavailable{}; - for(const auto& unit : candidates) { - unavailable.insert(unavailable.end(), unit.begin(), unit.end()); - } - - vector res = useSelector(getOptionValue(options, "backupSelector", "random"), s_lua_record_ctx->bestwho, unavailable); - return convComboAddressListToString(res); + auto checker = [](const ComboAddress& addr, const opts_t& opts) { + return g_up.isUp(addr, opts); + }; + return genericIfUp(ips, options, checker, port); }); lua.writeFunction("ifurlextup", [](const vector >& ipurls, boost::optional options) { @@ -916,42 +935,11 @@ static void setupLuaRecords(LuaContext& lua) lua.writeFunction("ifurlup", [](const std::string& url, const boost::variant& ips, boost::optional options) { - vector > candidates; - opts_t opts; - if(options) - opts = *options; - if(auto simple = boost::get(&ips)) { - vector unit = convComboAddressList(*simple); - candidates.push_back(unit); - } else { - auto units = boost::get(ips); - for(const auto& u : units) { - vector unit = convComboAddressList(u.second); - candidates.push_back(unit); - } - } - for(const auto& unit : candidates) { - vector available; - for(const auto& c : unit) { - if(g_up.isUp(c, url, opts)) { - available.push_back(c); - } - } - if(!available.empty()) { - vector res = useSelector(getOptionValue(options, "selector", "random"), s_lua_record_ctx->bestwho, available); - return convComboAddressListToString(res); - } - } - - // All units down, apply backupSelector on all candidates - vector ret{}; - for(const auto& unit : candidates) { - ret.insert(ret.end(), unit.begin(), unit.end()); - } - - vector res = useSelector(getOptionValue(options, "backupSelector", "random"), s_lua_record_ctx->bestwho, ret); - return convComboAddressListToString(res); + auto checker = [&url](const ComboAddress& addr, const opts_t& opts) { + return g_up.isUp(addr, url, opts); + }; + return genericIfUp(ips, options, checker); }); /* * Returns a random IP address from the supplied list From 05d6f9ed2d4c0940c6fff6deef31e0e76745aa8b Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Tue, 21 Mar 2023 17:56:40 +0100 Subject: [PATCH 010/909] auth: add regression tests for ip sets arguments to ifup() functions --- regression-tests.auth-py/test_LuaRecords.py | 72 ++++++++++++++++++--- 1 file changed, 64 insertions(+), 8 deletions(-) diff --git a/regression-tests.auth-py/test_LuaRecords.py b/regression-tests.auth-py/test_LuaRecords.py index bbcdb103e117..e9df7c8ba7f4 100644 --- a/regression-tests.auth-py/test_LuaRecords.py +++ b/regression-tests.auth-py/test_LuaRecords.py @@ -60,6 +60,7 @@ class TestLuaRecords(AuthTest): all.ifportup 3600 IN LUA A "ifportup(8080, {{'{prefix}.101', '{prefix}.102'}})" some.ifportup 3600 IN LUA A "ifportup(8080, {{'192.168.42.21', '{prefix}.102'}})" +multi.ifportup 3600 IN LUA A "ifportup(8080, {{ {{'192.168.42.23'}}, {{'192.168.42.21', '{prefix}.102'}}, {{'{prefix}.101'}} }})" none.ifportup 3600 IN LUA A "ifportup(8080, {{'192.168.42.21', '192.168.21.42'}})" all.noneup.ifportup 3600 IN LUA A "ifportup(8080, {{'192.168.42.21', '192.168.21.42'}}, {{ backupSelector='all' }})" @@ -83,21 +84,21 @@ class TestLuaRecords(AuthTest): config IN LUA LUA ("settings={{stringmatch='Programming in Lua'}} " "EUWips={{'{prefix}.101','{prefix}.102'}} " "EUEips={{'192.168.42.101','192.168.42.102'}} " - "NLips={{'{prefix}.111', '{prefix}.112'}} " - "USAips={{'{prefix}.103'}} ") + "NLips={{'{prefix}.111', '{prefix}.112'}} " + "USAips={{'{prefix}.103', '192.168.42.105'}} ") usa IN LUA A ( ";include('config') " "return ifurlup('http://www.lua.org:8080/', " - "{{USAips, EUEips}}, settings) ") + "USAips, settings) ") + +usa-ext IN LUA A ( ";include('config') " + "return ifurlup('http://www.lua.org:8080/', " + "{{EUEips, USAips}}, settings) ") mix.ifurlup IN LUA A ("ifurlup('http://www.other.org:8080/ping.json', " "{{ '192.168.42.101', '{prefix}.101' }}, " "{{ stringmatch='pong' }}) ") -eu-west IN LUA A ( ";include('config') " - "return ifurlup('http://www.lua.org:8080/', " - "{{EUWips, EUEips, USAips}}, settings) ") - ifurlextup IN LUA A "ifurlextup({{{{['192.168.0.1']='http://{prefix}.101:8080/404',['192.168.0.2']='http://{prefix}.102:8080/404'}}, {{['192.168.0.3']='http://{prefix}.101:8080/'}}}})" nl IN LUA A ( ";include('config') " @@ -327,6 +328,33 @@ def testIfportupWithSomeDown(self): self.assertRcodeEqual(res, dns.rcode.NOERROR) self.assertAnyRRsetInAnswer(res, expected) + def testIfportupWithSomeDownMultiset(self): + """ + Basic ifportup() test with some ports DOWN from multiple sets + """ + query = dns.message.make_query('multi.ifportup.example.org', 'A') + expected = [ + dns.rrset.from_text('multi.ifportup.example.org.', 0, dns.rdataclass.IN, 'A', + '192.168.42.21'), + dns.rrset.from_text('multi.ifportup.example.org.', 0, dns.rdataclass.IN, 'A', + '192.168.42.23'), + dns.rrset.from_text('multi.ifportup.example.org.', 0, dns.rdataclass.IN, 'A', + '{prefix}.102'.format(prefix=self._PREFIX)), + dns.rrset.from_text('multi.ifportup.example.org.', 0, dns.rdataclass.IN, 'A', + '{prefix}.101'.format(prefix=self._PREFIX)) + ] + + # we first expect any of the IPs as no check has been performed yet + res = self.sendUDPQuery(query) + self.assertRcodeEqual(res, dns.rcode.NOERROR) + self.assertAnyRRsetInAnswer(res, expected) + + # An ip is up in 2 sets, but we expect only the one from the middle set + expected = [expected[2]] + res = self.sendUDPQuery(query) + self.assertRcodeEqual(res, dns.rcode.NOERROR) + self.assertAnyRRsetInAnswer(res, expected) + def testIfportupWithAllDown(self): """ Basic ifportup() test with all ports DOWN @@ -371,7 +399,7 @@ def testIfurlup(self): reachable = [ '{prefix}.103'.format(prefix=self._PREFIX) ] - unreachable = ['192.168.42.101', '192.168.42.102'] + unreachable = ['192.168.42.105'] ips = reachable + unreachable all_rrs = [] reachable_rrs = [] @@ -392,6 +420,34 @@ def testIfurlup(self): self.assertRcodeEqual(res, dns.rcode.NOERROR) self.assertAnyRRsetInAnswer(res, reachable_rrs) + def testIfurlupMultiSet(self): + """ + Basic ifurlup() test with mutiple sets + """ + reachable = [ + '{prefix}.103'.format(prefix=self._PREFIX) + ] + unreachable = ['192.168.42.101', '192.168.42.102', '192.168.42.105'] + ips = reachable + unreachable + all_rrs = [] + reachable_rrs = [] + for ip in ips: + rr = dns.rrset.from_text('usa-ext.example.org.', 0, dns.rdataclass.IN, 'A', ip) + all_rrs.append(rr) + if ip in reachable: + reachable_rrs.append(rr) + + query = dns.message.make_query('usa-ext.example.org', 'A') + res = self.sendUDPQuery(query) + self.assertRcodeEqual(res, dns.rcode.NOERROR) + self.assertAnyRRsetInAnswer(res, all_rrs) + + # the timeout in the LUA health checker is 2 second, so we make sure to wait slightly longer here + time.sleep(3) + res = self.sendUDPQuery(query) + self.assertRcodeEqual(res, dns.rcode.NOERROR) + self.assertAnyRRsetInAnswer(res, reachable_rrs) + def testIfurlextup(self): expected = [dns.rrset.from_text('ifurlextup.example.org.', 0, dns.rdataclass.IN, dns.rdatatype.A, '192.168.0.3')] From fe8e05d6240b6f1e0ccf35d530b0d65824d55610 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Tue, 21 Mar 2023 18:07:55 +0100 Subject: [PATCH 011/909] auth: explicit documentation about sets for ifportup() --- docs/lua-records/index.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/lua-records/index.rst b/docs/lua-records/index.rst index c3e08efbcde2..66d0b82876ca 100644 --- a/docs/lua-records/index.rst +++ b/docs/lua-records/index.rst @@ -49,6 +49,14 @@ addresses listen on port 443. If either IP address stops listening, only the other address will be returned. If all IP addresses are down, all candidates are returned. +You can also provide multiple sets of IP addresses to prioritize a set over the +rest. If an IP address from the first set is available, it will be returned. If +no addresses work in the first set, the second set is tried. + +For example:: + + www IN LUA A "ifportup(443, {{'192.0.2.1', '192.0.2.2'}, {'192.0.3.1'}})" + Because DNS queries require rapid answers, server availability is not checked synchronously. In the background, a process periodically determines if IP addresses mentioned in availability rules are, in fact, available. From 03e5e4cbfb6c2ebc51b2f28b2e83a77763cfa9b4 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 22 Mar 2023 17:55:42 +0100 Subject: [PATCH 012/909] validate: Stop passing shared pointers all the way down --- pdns/recursordist/aggressive_nsec.cc | 16 ++--- pdns/recursordist/syncres.cc | 14 ++-- pdns/validate.cc | 99 ++++++++++++++-------------- pdns/validate.hh | 16 ++--- 4 files changed, 72 insertions(+), 73 deletions(-) diff --git a/pdns/recursordist/aggressive_nsec.cc b/pdns/recursordist/aggressive_nsec.cc index a3d84a9a6cd8..87500abdaf69 100644 --- a/pdns/recursordist/aggressive_nsec.cc +++ b/pdns/recursordist/aggressive_nsec.cc @@ -342,7 +342,7 @@ void AggressiveNSECCache::insertNSEC(const DNSName& zone, const DNSName& owner, } /* the TTL is already a TTD by now */ - if (!nsec3 && isWildcardExpanded(owner.countLabels(), signatures.at(0))) { + if (!nsec3 && isWildcardExpanded(owner.countLabels(), *signatures.at(0))) { DNSName realOwner = getNSECOwnerName(owner, signatures); auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, std::move(realOwner), std::move(next), record.d_ttl}); if (pair.second) { @@ -557,7 +557,7 @@ bool AggressiveNSECCache::getNSEC3Denial(time_t now, std::shared_ptr(wcEntry.d_record); - denial = matchesNSEC(wc, type.getCode(), wcEntry.d_owner, nsecContent, wcEntry.d_signatures, log); + denial = matchesNSEC(wc, type.getCode(), wcEntry.d_owner, *nsecContent, wcEntry.d_signatures, log); if (denial == dState::NODENIAL || denial == dState::INCONCLUSIVE) { if (wcEntry.d_owner == wc) { diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 122ad98aa54f..3bb05d047410 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -3065,14 +3065,14 @@ static void harvestNXRecords(const vector& records, NegCache::NegCach if (rrsig) { if (rrsig->d_type == QType::SOA) { ne.authoritySOA.signatures.push_back(rec); - if (lowestTTL && isRRSIGNotExpired(now, rrsig)) { + if (lowestTTL && isRRSIGNotExpired(now, *rrsig)) { *lowestTTL = min(*lowestTTL, rec.d_ttl); *lowestTTL = min(*lowestTTL, getRRSIGTTL(now, rrsig)); } } if (nsecTypes.count(rrsig->d_type)) { ne.DNSSECRecords.signatures.push_back(rec); - if (lowestTTL && isRRSIGNotExpired(now, rrsig)) { + if (lowestTTL && isRRSIGNotExpired(now, *rrsig)) { *lowestTTL = min(*lowestTTL, rec.d_ttl); *lowestTTL = min(*lowestTTL, getRRSIGTTL(now, rrsig)); } @@ -3428,7 +3428,7 @@ uint32_t SyncRes::computeLowestTTD(const std::vector& records, const lowestTTD = min(lowestTTD, static_cast(signaturesTTL + d_now.tv_sec)); for (const auto& sig : signatures) { - if (isRRSIGNotExpired(d_now.tv_sec, sig)) { + if (isRRSIGNotExpired(d_now.tv_sec, *sig)) { // we don't decrement d_sigexpire by 'now' because we actually want a TTD, not a TTL */ lowestTTD = min(lowestTTD, static_cast(sig->d_sigexpire)); } @@ -3442,7 +3442,7 @@ uint32_t SyncRes::computeLowestTTD(const std::vector& records, const if (entry->d_type == QType::RRSIG && validationEnabled()) { auto rrsig = getRR(*entry); if (rrsig) { - if (isRRSIGNotExpired(d_now.tv_sec, rrsig)) { + if (isRRSIGNotExpired(d_now.tv_sec, *rrsig)) { // we don't decrement d_sigexpire by 'now' because we actually want a TTD, not a TTL */ lowestTTD = min(lowestTTD, static_cast(rrsig->d_sigexpire)); } @@ -4282,9 +4282,9 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& count can be lower than the name's label count if it was synthesized from the wildcard. Note that the difference might be > 1. */ - if (rec.d_name == qname && isWildcardExpanded(labelCount, rrsig)) { + if (rec.d_name == qname && isWildcardExpanded(labelCount, *rrsig)) { gatherWildcardProof = true; - if (!isWildcardExpandedOntoItself(rec.d_name, labelCount, rrsig)) { + if (!isWildcardExpandedOntoItself(rec.d_name, labelCount, *rrsig)) { /* if we have a wildcard expanded onto itself, we don't need to prove that the exact name doesn't exist because it actually does. We still want to gather the corresponding NSEC/NSEC3 records @@ -4569,7 +4569,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& wildcard in its non-expanded form in the cache to be able to synthesize wildcard answers later */ const auto& rrsig = i->second.signatures.at(0); - if (isWildcardExpanded(labelCount, rrsig) && !isWildcardExpandedOntoItself(i->first.name, labelCount, rrsig)) { + if (isWildcardExpanded(labelCount, *rrsig) && !isWildcardExpandedOntoItself(i->first.name, labelCount, *rrsig)) { DNSName realOwner = getNSECOwnerName(i->first.name, i->second.signatures); std::vector content; diff --git a/pdns/validate.cc b/pdns/validate.cc index da16c70b0e33..af4f9d69af54 100644 --- a/pdns/validate.cc +++ b/pdns/validate.cc @@ -88,22 +88,22 @@ static bool nsecProvesENT(const DNSName& name, const DNSName& begin, const DNSNa using nsec3HashesCache = std::map, std::string>; -static std::string getHashFromNSEC3(const DNSName& qname, const std::shared_ptr& nsec3, nsec3HashesCache& cache) +static std::string getHashFromNSEC3(const DNSName& qname, const NSEC3RecordContent& nsec3, nsec3HashesCache& cache) { std::string result; - if (g_maxNSEC3Iterations && nsec3->d_iterations > g_maxNSEC3Iterations) { + if (g_maxNSEC3Iterations && nsec3.d_iterations > g_maxNSEC3Iterations) { return result; } - auto key = std::make_tuple(qname, nsec3->d_salt, nsec3->d_iterations); + auto key = std::make_tuple(qname, nsec3.d_salt, nsec3.d_iterations); auto it = cache.find(key); if (it != cache.end()) { return it->second; } - result = hashQNameWithSalt(nsec3->d_salt, nsec3->d_iterations, qname); + result = hashQNameWithSalt(nsec3.d_salt, nsec3.d_iterations, qname); cache[key] = result; return result; } @@ -139,7 +139,7 @@ bool denialProvesNoDelegation(const DNSName& zone, const std::vector& continue; } - const string h = getHashFromNSEC3(zone, nsec3, cache); + const string h = getHashFromNSEC3(zone, *nsec3, cache); if (h.empty()) { return false; } @@ -163,9 +163,9 @@ bool denialProvesNoDelegation(const DNSName& zone, const std::vector& Labels field of the covering RRSIG RR, then the RRset and its covering RRSIG RR were created as a result of wildcard expansion." */ -bool isWildcardExpanded(unsigned int labelCount, const std::shared_ptr& sign) +bool isWildcardExpanded(unsigned int labelCount, const RRSIGRecordContent& sign) { - if (sign && sign->d_labels < labelCount) { + if (sign.d_labels < labelCount) { return true; } @@ -180,12 +180,12 @@ static bool isWildcardExpanded(const DNSName& owner, const std::vector& sign) +bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const RRSIGRecordContent& sign) { - if (owner.isWildcard() && (labelCount - 1) == sign->d_labels) { + if (owner.isWildcard() && (labelCount - 1) == sign.d_labels) { /* this is a wildcard alright, but it has not been expanded */ return true; } @@ -200,7 +200,7 @@ static bool isWildcardExpandedOntoItself(const DNSName& owner, const std::vector const auto& sign = signatures.at(0); unsigned int labelsCount = owner.countLabels(); - return isWildcardExpandedOntoItself(owner, labelsCount, sign); + return isWildcardExpandedOntoItself(owner, labelsCount, *sign); } /* if this is a wildcard NSEC, the owner name has been modified @@ -228,17 +228,17 @@ DNSName getNSECOwnerName(const DNSName& initialOwner, const std::vector& nsec) +static bool isNSECAncestorDelegation(const DNSName& signer, const DNSName& owner, const NSECRecordContent& nsec) { - return nsec->isSet(QType::NS) && - !nsec->isSet(QType::SOA) && + return nsec.isSet(QType::NS) && + !nsec.isSet(QType::SOA) && signer.countLabels() < owner.countLabels(); } -bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const std::shared_ptr& nsec3) +bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const NSEC3RecordContent& nsec3) { - return nsec3->isSet(QType::NS) && - !nsec3->isSet(QType::SOA) && + return nsec3.isSet(QType::NS) && + !nsec3.isSet(QType::SOA) && signer.countLabels() < owner.countLabels(); } @@ -262,7 +262,7 @@ static bool provesNoDataWildCard(const DNSName& qname, const uint16_t qtype, con } VLOG(log, qname << ":\tWildcard matches"); - if (qtype == 0 || isTypeDenied(nsec, QType(qtype))) { + if (qtype == 0 || isTypeDenied(*nsec, QType(qtype))) { VLOG_NO_PREFIX(log, " and proves that the type did not exist"<& nsec, const std::vector>& signatures, const OptLog& log) +dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner, const NSECRecordContent& nsec, const std::vector>& signatures, const OptLog& log) { const DNSName signer = getSigner(signatures); if (!name.isPartOf(signer) || !nsecOwner.isPartOf(signer)) { @@ -440,7 +440,7 @@ dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner return dState::NXQTYPE; } - if (name.isPartOf(owner) && nsec->isSet(QType::DNAME)) { + if (name.isPartOf(owner) && nsec.isSet(QType::DNAME)) { /* rfc6672 section 5.3.2: DNAME Bit in NSEC Type Map In any negative response, the NSEC or NSEC3 [RFC5155] record type @@ -454,10 +454,10 @@ dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner return dState::NODENIAL; } - if (isCoveredByNSEC(name, owner, nsec->d_next)) { - VLOG_NO_PREFIX(log, name << ": is covered by ("<d_next<<")"); + if (isCoveredByNSEC(name, owner, nsec.d_next)) { + VLOG_NO_PREFIX(log, name << ": is covered by ("<d_next)) { + if (nsecProvesENT(name, owner, nsec.d_next)) { VLOG_NO_PREFIX(log, " denies existence of type "<& sig) +bool isRRSIGNotExpired(const time_t now, const RRSIGRecordContent& sig) { // Should use https://www.rfc-editor.org/rfc/rfc4034.txt section 3.1.5 - return sig->d_sigexpire >= now; + return sig.d_sigexpire >= now; } -bool isRRSIGIncepted(const time_t now, const shared_ptr& sig) +bool isRRSIGIncepted(const time_t now, const RRSIGRecordContent& sig) { // Should use https://www.rfc-editor.org/rfc/rfc4034.txt section 3.1.5 - return sig->d_siginception - g_signatureInceptionSkew <= now; + return sig.d_siginception - g_signatureInceptionSkew <= now; } -static bool checkSignatureWithKey(const DNSName& qname, time_t now, const shared_ptr& sig, const shared_ptr& key, const std::string& msg, vState& ede, const OptLog& log) +static bool checkSignatureWithKey(const DNSName& qname, time_t now, const RRSIGRecordContent& sig, const DNSKEYRecordContent& key, const std::string& msg, vState& ede, const OptLog& log) { bool result = false; try { @@ -917,16 +917,16 @@ static bool checkSignatureWithKey(const DNSName& qname, time_t now, const shared - The validator's notion of the current time MUST be greater than or equal to the time listed in the RRSIG RR's Inception field. */ if (isRRSIGIncepted(now, sig) && isRRSIGNotExpired(now, sig)) { - auto dke = DNSCryptoKeyEngine::makeFromPublicKeyString(key->d_algorithm, key->d_key); - result = dke->verify(msg, sig->d_signature); - VLOG(log, qname << ": Signature by key with tag "<d_tag<<" and algorithm "<d_algorithm)<<" was " << (result ? "" : "NOT ")<<"valid"<verify(msg, sig.d_signature); + VLOG(log, qname << ": Signature by key with tag "<d_siginception - g_signatureInceptionSkew) > now) ? vState::BogusSignatureNotYetValid : vState::BogusSignatureExpired; - VLOG(log, qname << ": Signature is "<<(ede == vState::BogusSignatureNotYetValid ? "not yet valid" : "expired")<<" (inception: "<d_siginception<<", inception skew: "<d_sigexpire<<", now: "< now) ? vState::BogusSignatureNotYetValid : vState::BogusSignatureExpired; + VLOG(log, qname << ": Signature is "<<(ede == vState::BogusSignatureNotYetValid ? "not yet valid" : "expired")<<" (inception: "< >& signatures); bool denialProvesNoDelegation(const DNSName& zone, const std::vector& dsrecords); -bool isRRSIGNotExpired(const time_t now, const std::shared_ptr& sig); -bool isRRSIGIncepted(const time_t now, const shared_ptr& sig); -bool isWildcardExpanded(unsigned int labelCount, const std::shared_ptr& sign); -bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const std::shared_ptr& sign); +bool isRRSIGNotExpired(const time_t now, const RRSIGRecordContent& sig); +bool isRRSIGIncepted(const time_t now, const RRSIGRecordContent& sig); +bool isWildcardExpanded(unsigned int labelCount, const RRSIGRecordContent& sign); +bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const RRSIGRecordContent& sign); void updateDNSSECValidationState(vState& state, const vState stateUpdate); -dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner, const std::shared_ptr& nsec, const std::vector>& signatures, const OptLog&); +dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner, const NSECRecordContent& nsec, const std::vector>& signatures, const OptLog&); -bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const std::shared_ptr& nsec3); +bool isNSEC3AncestorDelegation(const DNSName& signer, const DNSName& owner, const NSEC3RecordContent& nsec3); DNSName getNSECOwnerName(const DNSName& initialOwner, const std::vector >& signatures); DNSName getClosestEncloserFromNSEC(const DNSName& name, const DNSName& owner, const DNSName& next); template bool isTypeDenied(const NSEC& nsec, const QType& type) { - if (nsec->isSet(type.getCode())) { + if (nsec.isSet(type.getCode())) { return false; } /* RFC 6840 section 4.3 */ - if (nsec->isSet(QType::CNAME)) { + if (nsec.isSet(QType::CNAME)) { return false; } From 648edcba555e476fa1ff90d703c7e2c69f1b5643 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 24 Mar 2023 10:45:08 +0100 Subject: [PATCH 013/909] dnsdist: Wait for the API port to be available before running the tests --- regression-tests.dnsdist/test_API.py | 9 +++++++++ regression-tests.dnsdist/test_Metrics.py | 8 ++++++++ 2 files changed, 17 insertions(+) diff --git a/regression-tests.dnsdist/test_API.py b/regression-tests.dnsdist/test_API.py index bf8684183bb7..f708f9c4c188 100644 --- a/regression-tests.dnsdist/test_API.py +++ b/regression-tests.dnsdist/test_API.py @@ -41,6 +41,15 @@ class APITestsBase(DNSDistTest): 'doh-query-pipe-full', 'doh-response-pipe-full', 'proxy-protocol-invalid', 'tcp-listen-overflows', 'outgoing-doh-query-pipe-full', 'tcp-query-pipe-full', 'tcp-cross-protocol-query-pipe-full', 'tcp-cross-protocol-response-pipe-full'] + _verboseMode = True + + @classmethod + def setUpClass(cls): + cls.startResponders() + cls.startDNSDist() + cls.setUpSockets() + cls.waitForTCPSocket('127.0.0.1', cls._webServerPort) + print("Launching tests..") class TestAPIBasics(APITestsBase): diff --git a/regression-tests.dnsdist/test_Metrics.py b/regression-tests.dnsdist/test_Metrics.py index 5850d954258c..d907b1135463 100644 --- a/regression-tests.dnsdist/test_Metrics.py +++ b/regression-tests.dnsdist/test_Metrics.py @@ -39,6 +39,14 @@ class TestRuleMetrics(DNSDistTest): _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_params = ['_tlsServerPort', '_serverCert', '_serverKey', '_dohServerPort', '_serverCert', '_serverKey', '_testServerPort', '_webServerPort', '_webServerAPIKeyHashed'] + @classmethod + def setUpClass(cls): + cls.startResponders() + cls.startDNSDist() + cls.setUpSockets() + cls.waitForTCPSocket('127.0.0.1', cls._webServerPort) + print("Launching tests..") + def getMetric(self, name): headers = {'x-api-key': self._webServerAPIKey} url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost' From 1953ab6c193cbc88ababd6de43e4ebcf4d56e192 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 24 Mar 2023 10:47:02 +0100 Subject: [PATCH 014/909] dnsdist: Wait the correct port to come up on special case tests --- regression-tests.dnsdist/dnsdisttests.py | 7 ++++++- regression-tests.dnsdist/test_Advanced.py | 2 ++ regression-tests.dnsdist/test_DOH.py | 2 ++ regression-tests.dnsdist/test_TLS.py | 2 ++ 4 files changed, 12 insertions(+), 1 deletion(-) diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 06f71609fdd1..14fc7a6e7127 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -73,6 +73,8 @@ class DNSDistTest(AssertEqualDNSMessageMixin, unittest.TestCase): _checkConfigExpectedOutput = None _verboseMode = False _skipListeningOnCL = False + _alternateListeningAddr = None + _alternateListeningPort = None _backgroundThreads = {} _UDPResponder = None _TCPResponder = None @@ -146,7 +148,10 @@ def startDNSDist(cls): with open(logFile, 'w') as fdLog: cls._dnsdist = subprocess.Popen(dnsdistcmd, close_fds=True, stdout=fdLog, stderr=fdLog) - cls.waitForTCPSocket(cls._dnsDistListeningAddr, cls._dnsDistPort); + if cls._alternateListeningAddr and cls._alternateListeningPort: + cls.waitForTCPSocket(cls._alternateListeningAddr, cls._alternateListeningPort) + else: + cls.waitForTCPSocket(cls._dnsDistListeningAddr, cls._dnsDistPort) if cls._dnsdist.poll() is not None: print(f"\n*** startDNSDist log for {logFile} ***") diff --git a/regression-tests.dnsdist/test_Advanced.py b/regression-tests.dnsdist/test_Advanced.py index 16376c38fed6..1a110e483dad 100644 --- a/regression-tests.dnsdist/test_Advanced.py +++ b/regression-tests.dnsdist/test_Advanced.py @@ -425,6 +425,8 @@ class TestAdvancedGetLocalAddressOnNonDefaultLoopbackBind(DNSDistTest): _config_params = ['_testServerPort', '_dnsDistPort'] _acl = ['127.0.0.1/32'] _skipListeningOnCL = True + _alternateListeningAddr = '127.0.1.19' + _alternateListeningPort = DNSDistTest._dnsDistPort def testAdvancedCheckSourceAddrOnNonDefaultLoopbackBind(self): """ diff --git a/regression-tests.dnsdist/test_DOH.py b/regression-tests.dnsdist/test_DOH.py index 9fcb4b52977a..5ed6382085f6 100644 --- a/regression-tests.dnsdist/test_DOH.py +++ b/regression-tests.dnsdist/test_DOH.py @@ -1173,6 +1173,8 @@ class TestDOHFrontendLimits(DNSDistDOHTest): addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, { maxConcurrentTCPConnections=%d }) """ _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_maxTCPConnsPerDOHFrontend'] + _alternateListeningAddr = '127.0.0.1' + _alternateListeningPort = _dohServerPort def testTCPConnsPerDOHFrontend(self): """ diff --git a/regression-tests.dnsdist/test_TLS.py b/regression-tests.dnsdist/test_TLS.py index ff2ef630cc84..cefe7d26c4c2 100644 --- a/regression-tests.dnsdist/test_TLS.py +++ b/regression-tests.dnsdist/test_TLS.py @@ -393,6 +393,8 @@ class TestTLSFrontendLimits(DNSDistTest): addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="openssl", maxConcurrentTCPConnections=%d }) """ _config_params = ['_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_maxTCPConnsPerTLSFrontend'] + _alternateListeningAddr = '127.0.0.1' + _alternateListeningPort = _tlsServerPort def testTCPConnsPerTLSFrontend(self): """ From 3a0e0c951e8548187a4dac8daf784be3e53a3763 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 24 Mar 2023 10:47:27 +0100 Subject: [PATCH 015/909] dnsdist: Remove a left-over startup delay in the regression tests --- regression-tests.dnsdist/dnsdisttests.py | 1 - regression-tests.dnsdist/test_DNSCrypt.py | 2 -- 2 files changed, 3 deletions(-) diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 14fc7a6e7127..05de5e1bd686 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -58,7 +58,6 @@ class DNSDistTest(AssertEqualDNSMessageMixin, unittest.TestCase): _toResponderQueue = Queue() _fromResponderQueue = Queue() _queueTimeout = 1 - _dnsdistStartupDelay = 2.0 _dnsdist = None _responsesCounter = {} _config_template = """ diff --git a/regression-tests.dnsdist/test_DNSCrypt.py b/regression-tests.dnsdist/test_DNSCrypt.py index 15cc8dc08b57..c67b983558c7 100644 --- a/regression-tests.dnsdist/test_DNSCrypt.py +++ b/regression-tests.dnsdist/test_DNSCrypt.py @@ -29,8 +29,6 @@ class DNSCryptTest(DNSDistTest): _resolverCertificateValidFrom = int(time.time() - 60) _resolverCertificateValidUntil = int(time.time() + 7200) - _dnsdistStartupDelay = 10 - def doDNSCryptQuery(self, client, query, response, tcp): self._toResponderQueue.put(response) data = client.query(query.to_wire(), tcp=tcp) From 13e4e845b16124d4df4017eaf5eb904c3beeb1e5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 27 Mar 2023 10:01:51 +0200 Subject: [PATCH 016/909] dnsdist: Don't test the web server port before the concurrent conns check --- regression-tests.dnsdist/test_API.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/regression-tests.dnsdist/test_API.py b/regression-tests.dnsdist/test_API.py index f708f9c4c188..60b9e54bc2d6 100644 --- a/regression-tests.dnsdist/test_API.py +++ b/regression-tests.dnsdist/test_API.py @@ -777,6 +777,14 @@ class TestWebConcurrentConnections(APITestsBase): setWebserverConfig({password="%s", apiKey="%s", maxConcurrentConnections=%d}) """ + @classmethod + def setUpClass(cls): + cls.startResponders() + cls.startDNSDist() + cls.setUpSockets() + # do no check if the web server socket is up, because this + # might mess up the concurrent connections counter + def testConcurrentConnections(self): """ Web: Concurrent connections From 4b2e8ead56feaf9da6380468017a1b536694873b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 27 Mar 2023 17:03:43 +0200 Subject: [PATCH 017/909] dnsdist: Add an option to write `grepq`'s output to a file --- pdns/dnsdist-console.cc | 2 +- pdns/dnsdist-lua-inspection.cc | 39 +++++++++++++++++++--- pdns/dnsdistdist/docs/reference/config.rst | 12 +++++-- 3 files changed, 45 insertions(+), 8 deletions(-) diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index 86647243ad4e..7eff465774b0 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -548,7 +548,7 @@ const std::vector g_consoleKeywords{ { "getTLSFrontend", true, "n", "returns the TLS frontend with index n" }, { "getTLSFrontendCount", true, "", "returns the number of DoT listeners" }, { "getVerbose", true, "", "get whether log messages at the verbose level will be logged" }, - { "grepq", true, "Netmask|DNS Name|100ms|{\"::1\", \"powerdns.com\", \"100ms\"} [, n]", "shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms" }, + { "grepq", true, "Netmask|DNS Name|100ms|{\"::1\", \"powerdns.com\", \"100ms\"} [, n] [,options]", "shows the last n queries and responses matching the specified client address or range (Netmask), or the specified DNS Name, or slower than 100ms" }, { "hashPassword", true, "password [, workFactor]", "Returns a hashed and salted version of the supplied password, usable with 'setWebserverConfig()'"}, { "HTTPHeaderRule", true, "name, regex", "matches DoH queries with a HTTP header 'name' whose content matches the regular expression 'regex'"}, { "HTTPPathRegexRule", true, "regex", "matches DoH queries whose HTTP path matches 'regex'"}, diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index 86b3e0b5918c..b1f7ac0e095a 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -19,6 +19,8 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include + #include "dnsdist.hh" #include "dnsdist-lua.hh" #include "dnsdist-dynblocks.hh" @@ -408,11 +410,28 @@ void setupLuaInspection(LuaContext& luaCtx) } }); - luaCtx.writeFunction("grepq", [](LuaTypeOrArrayOf inp, boost::optional limit) { + luaCtx.writeFunction("grepq", [](LuaTypeOrArrayOf inp, boost::optional limit, boost::optional> options) { setLuaNoSideEffect(); boost::optional nm; boost::optional dn; int msec=-1; + std::unique_ptr outputFile{nullptr, fclose}; + + if (options) { + if (options->count("outputFile")) { + const std::string& outputFileName = options->at("outputFile"); + int fd = open(outputFileName.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0600); + if (fd < 0) { + g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n"; + return; + } + outputFile = std::unique_ptr(fdopen(fd, "w"), fclose); + if (outputFile == nullptr) { + g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n"; + return; + } + } + } vector vec; auto str=boost::get(&inp); @@ -477,8 +496,13 @@ void setupLuaInspection(LuaContext& luaCtx) std::multimap out; - boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n"); - g_outputBuffer+= (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str(); + boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n"); + if (!outputFile) { + g_outputBuffer += (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str(); + } + else { + fprintf(outputFile.get(), "%s", (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str().c_str()); + } if(msec==-1) { for(const auto& c : qr) { @@ -556,8 +580,13 @@ void setupLuaInspection(LuaContext& luaCtx) } } - for(const auto& p : out) { - g_outputBuffer+=p.second; + for (const auto& p : out) { + if (!outputFile) { + g_outputBuffer += p.second; + } + else { + fprintf(outputFile.get(), "%s", p.second.c_str()); + } } }); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index d7c41e7317e6..d67c0b1c4153 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -1138,8 +1138,11 @@ Status, Statistics and More :param int top: How many rules to return. Default is 10. -.. function:: grepq(selector[, num]) - grepq(selectors[, num]) +.. function:: grepq(selector[, num [, options]]) + grepq(selectors[, num [, options]]) + + .. versionchanged:: 1.9.0 + ``options`` optional parameter table added. Prints the last ``num`` queries and responses matching ``selector`` or ``selectors``. Queries and responses are accounted in separate ring buffers, and answers from the packet cache are not stored in the response ring buffer. @@ -1154,6 +1157,11 @@ Status, Statistics and More :param str selector: Select queries based on this property. :param {str} selectors: A lua table of selectors. Only queries matching all selectors are shown :param int num: Show a maximum of ``num`` recent queries+responses, default is 10. + :param table options: A table with key: value pairs with options described below. + + Options: + + * ``outputFile=path``: string - Write the output of the command to the supplied file, instead of the standard output. .. function:: setVerbose(verbose) From 6528f7f8f6b192717ac25cd3b107f7f334eced4c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 27 Mar 2023 17:17:55 +0200 Subject: [PATCH 018/909] dnsdist: Fix the documentation of the `StatNode` object --- pdns/dnsdist-lua-inspection.cc | 8 ++--- pdns/dnsdistdist/docs/reference/config.rst | 40 ++++++++++++---------- 2 files changed, 26 insertions(+), 22 deletions(-) diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index 86b3e0b5918c..07dd86b68b3b 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -780,10 +780,10 @@ void setupLuaInspection(LuaContext& luaCtx) luaCtx.writeFunction("getRespRing", getRespRing); /* StatNode */ - luaCtx.registerFunction("numChildren", - [](StatNode& sn) -> unsigned int { - return sn.children.size(); - } ); + luaCtx.registerFunction("numChildren", + [](const StatNode& sn) -> unsigned int { + return sn.children.size(); + } ); luaCtx.registerMember("fullname", &StatNode::fullname); luaCtx.registerMember("labelsCount", &StatNode::labelsCount); luaCtx.registerMember("servfails", &StatNode::Stat::servfails); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index d7c41e7317e6..749beea2b96e 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -1549,7 +1549,7 @@ faster than the existing rules. .. versionchanged:: 1.7.0 This visitor function can now optionally return an additional string which will be set as the ``reason`` for the dynamic block. - Set a Lua visitor function that will be called for each label of every domain seen in queries and responses. The function receives a `StatNode` object representing the stats of the parent, a second one with the stats of the current label and one with the stats of the current node plus all its children. + Set a Lua visitor function that will be called for each label of every domain seen in queries and responses. The function receives a :class:`StatNode` object representing the stats of the parent, a :class:`StatNodeStats` one with the stats of the current label and a second :class:`StatNodeStats` with the stats of the current node plus all its children. Note that this function will not be called if a FFI version has been set using :meth:`DynBlockRulesGroup:setSuffixMatchRuleFFI` If the function returns true, the current label will be blocked according to the `seconds`, `reason`, `blockingTime` and `action` parameters. Since 1.7.0, the function can return an additional string, in addition to the boolean, which will be set as the ``reason`` for the dynamic block. Selected domains can be excluded from this processing using the :meth:`DynBlockRulesGroup:excludeDomains` method. @@ -1623,15 +1623,7 @@ StatNode .. class:: StatNode - Represent metrics about a given node, for the visitor functions used with :meth:`DynBlockRulesGroup:setSuffixMatchRule` and :meth:`DynBlockRulesGroup:setSuffixMatchRuleFFI`. Note that some nodes includes the metrics for their children as well as their own. - - .. attribute:: StatNode.bytes - - The number of bytes for all responses returned for that node. - - .. attribute:: StatNode.drops - - The number of drops for that node. + Represent a given node, for the visitor functions used with :meth:`DynBlockRulesGroup:setSuffixMatchRule` and :meth:`DynBlockRulesGroup:setSuffixMatchRuleFFI`. .. attribute:: StatNode.fullname @@ -1641,26 +1633,38 @@ StatNode The number of labels in that node, for example 3 for 'www.powerdns.com'. - .. attribute:: StatNode.noerrors + .. method:: StatNode:numChildren + + The number of children of that node. + +.. class:: StatNodeStats + + Represent the metrics for a given node, for the visitor functions used with :meth:`DynBlockRulesGroup:setSuffixMatchRule` and :meth:`DynBlockRulesGroup:setSuffixMatchRuleFFI`. + + .. attribute:: StatNodeStats.bytes + + The number of bytes for all responses returned for that node. + + .. attribute:: StatNodeStats.drops + + The number of drops for that node. + + .. attribute:: StatNodeStats.noerrors The number of No Error answers returned for that node. - .. attribute:: StatNode.nxdomains + .. attribute:: StatNodeStats.nxdomains The number of NXDomain answers returned for that node. - .. attribute:: StatNode.queries + .. attribute:: StatNodeStats.queries The number of queries for that node. - .. attribute:: StatNode.servfails + .. attribute:: StatNodeStats.servfails The number of Server Failure answers returned for that node. - .. method:: StatNode:numChildren - - The number of children of that node. - SuffixMatchNode ~~~~~~~~~~~~~~~ From f5d73b12a91bea0cad7901ac598ec6f89748ad2e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 28 Mar 2023 09:12:25 +0200 Subject: [PATCH 019/909] dnsdist: Apply suggestions from code review, apply formatting --- pdns/dnsdist-lua-inspection.cc | 68 +++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index b1f7ac0e095a..3e5dcd096a77 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -414,12 +414,12 @@ void setupLuaInspection(LuaContext& luaCtx) setLuaNoSideEffect(); boost::optional nm; boost::optional dn; - int msec=-1; + int msec = -1; std::unique_ptr outputFile{nullptr, fclose}; if (options) { - if (options->count("outputFile")) { - const std::string& outputFileName = options->at("outputFile"); + std::string outputFileName; + if (getOptionalValue(options, "outputFile", outputFileName) > 0) { int fd = open(outputFileName.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0600); if (fd < 0) { g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n"; @@ -428,37 +428,41 @@ void setupLuaInspection(LuaContext& luaCtx) outputFile = std::unique_ptr(fdopen(fd, "w"), fclose); if (outputFile == nullptr) { g_outputBuffer = "Error opening dump file for writing: " + stringerror() + "\n"; + close(fd); return; } } + checkAllParametersConsumed("grepq", options); } vector vec; - auto str=boost::get(&inp); - if(str) + auto str = boost::get(&inp); + if (str) { vec.push_back(*str); + } else { auto v = boost::get>(inp); - for(const auto& a: v) + for (const auto& a: v) { vec.push_back(a.second); + } } - for(const auto& s : vec) { - try - { + for (const auto& s : vec) { + try { nm = Netmask(s); - } - catch(...) { - if(boost::ends_with(s,"ms") && sscanf(s.c_str(), "%ums", &msec)) { + } + catch (...) { + if (boost::ends_with(s,"ms") && sscanf(s.c_str(), "%ums", &msec)) { ; } else { - try { dn=DNSName(s); } - catch(...) - { - g_outputBuffer = "Could not parse '"+s+"' as domain name or netmask"; - return; - } + try { + dn = DNSName(s); + } + catch (...) { + g_outputBuffer = "Could not parse '"+s+"' as domain name or netmask"; + return; + } } } } @@ -497,16 +501,18 @@ void setupLuaInspection(LuaContext& luaCtx) std::multimap out; boost::format fmt("%-7.1f %-47s %-12s %-12s %-5d %-25s %-5s %-6.1f %-2s %-2s %-2s %-s\n"); + const auto headLine = (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str(); if (!outputFile) { - g_outputBuffer += (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str(); + g_outputBuffer += headLine; } else { - fprintf(outputFile.get(), "%s", (fmt % "Time" % "Client" % "Protocol" % "Server" % "ID" % "Name" % "Type" % "Lat." % "TC" % "RD" % "AA" % "Rcode").str().c_str()); + fprintf(outputFile.get(), "%s", headLine.c_str()); } - if(msec==-1) { - for(const auto& c : qr) { - bool nmmatch=true, dnmatch=true; + if (msec == -1) { + for (const auto& c : qr) { + bool nmmatch = true; + bool dnmatch = true; if (nm) { nmmatch = nm->match(c.requestor); } @@ -526,17 +532,19 @@ void setupLuaInspection(LuaContext& luaCtx) } out.emplace(c.when, (fmt % DiffTime(now, c.when) % c.requestor.toStringWithPort() % dnsdist::Protocol(c.protocol).toString() % "" % htons(c.dh.id) % c.name.toString() % qt.toString() % "" % (c.dh.tc ? "TC" : "") % (c.dh.rd ? "RD" : "") % (c.dh.aa ? "AA" : "") % ("Question" + extra)).str()); - if(limit && *limit==++num) + if (limit && *limit == ++num) { break; + } } } } - num=0; - + num = 0; string extra; - for(const auto& c : rr) { - bool nmmatch=true, dnmatch=true, msecmatch=true; + for (const auto& c : rr) { + bool nmmatch = true; + bool dnmatch = true; + bool msecmatch = true; if (nm) { nmmatch = nm->match(c.requestor); } @@ -549,13 +557,13 @@ void setupLuaInspection(LuaContext& luaCtx) } } if (msec != -1) { - msecmatch=(c.usec/1000 > (unsigned int)msec); + msecmatch = (c.usec/1000 > (unsigned int)msec); } if (nmmatch && dnmatch && msecmatch) { QType qt(c.qtype); if (!c.dh.rcode) { - extra=". " +std::to_string(htons(c.dh.ancount))+ " answers"; + extra = ". " +std::to_string(htons(c.dh.ancount)) + " answers"; } else { extra.clear(); From 64d2baa740c011a1f169924b7f9dafcd8104eaf6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 28 Mar 2023 11:09:40 +0200 Subject: [PATCH 020/909] rec: reset EDE in context when starting to resolve Fixes #12691 There is a slight complication here: If QM found an error, a retry without QM is done, and that clears the EDE but might not find an EDE itself (since it does not walk all labels). So remember the original EDE and put it back in place if the last effort attempt failed but did not set an EDE. --- pdns/recursordist/syncres.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index f7670f08c6f9..ba0741d1a397 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1768,11 +1768,18 @@ int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, set& beenthere, Context& context, bool* fromCache, StopAtDelegation* stopAtDelegation) { + context.extendedError.reset(); auto prefix = getPrefix(depth); LOG(prefix << qname << ": Wants " << (d_doDNSSEC ? "" : "NO ") << "DNSSEC processing, " << (d_requireAuthData ? "" : "NO ") << "auth data required by query for " << qtype << endl); From 8997ce47bda0a667ee41e49bdb2131bdedd9ef25 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 28 Mar 2023 14:00:03 +0200 Subject: [PATCH 021/909] Unbreak FreeBSD mthread stack allocation On FreeBSD, MAP_STACK has a completely different meaning compared to OpenBSD. So only use MAP_STACK on OpenBSD. --- pdns/recursordist/lazy_allocator.hh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/lazy_allocator.hh b/pdns/recursordist/lazy_allocator.hh index 720fd4f5ee14..39665b6ad266 100644 --- a/pdns/recursordist/lazy_allocator.hh +++ b/pdns/recursordist/lazy_allocator.hh @@ -28,8 +28,10 @@ #include // On OpenBSD mem used as stack should be marked MAP_STACK -#if !defined(MAP_STACK) -#define MAP_STACK 0 +#ifdef __OpenBSD__ +#define PDNS_MAP_STACK MAP_STACK +#else +#define PDNS_MAP_STACK 0 #endif template @@ -88,7 +90,7 @@ struct lazy_allocator #else const int protection = PROT_NONE; #endif - void* p = mmap(nullptr, allocatedSize, protection, MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0); + void* p = mmap(nullptr, allocatedSize, protection, MAP_PRIVATE | MAP_ANON | PDNS_MAP_STACK, -1, 0); if (p == MAP_FAILED) { throw std::bad_alloc(); } From 03f779fd479f3a7bf74485cc0ca9e0a69ab8bb8c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 28 Mar 2023 14:48:26 +0200 Subject: [PATCH 022/909] Test that an intermediate EDE does not get reported with the final answer --- .../test_AggressiveNSECCache.py | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/regression-tests.recursor-dnssec/test_AggressiveNSECCache.py b/regression-tests.recursor-dnssec/test_AggressiveNSECCache.py index 305ee05ca986..35588e33c6d7 100644 --- a/regression-tests.recursor-dnssec/test_AggressiveNSECCache.py +++ b/regression-tests.recursor-dnssec/test_AggressiveNSECCache.py @@ -46,6 +46,27 @@ def getMetric(self, name): self.assertTrue(False) + def testNoEDE(self): + # This isn't an aggresive cache check, but the strcuture is very similar to the others, + # so letys place it here. + # It test the issue that an intermediate EDE does not get reported with the final answer + # https://github.com/PowerDNS/pdns/pull/12694 + self.wipe() + + res = self.sendQuery('host1.sub.secure.example.', 'TXT') + self.assertRcodeEqual(res, dns.rcode.NOERROR) + self.assertAnswerEmpty(res) + self.assertAuthorityHasSOA(res) + self.assertMessageIsAuthenticated(res) + self.assertEqual(res.edns, 0) + self.assertEqual(len(res.options), 0) + + res = self.sendQuery('host1.sub.secure.example.', 'A') + self.assertRcodeEqual(res, dns.rcode.NOERROR) + self.assertMessageIsAuthenticated(res) + self.assertEqual(res.edns, 0) + self.assertEqual(len(res.options), 0) + def testNoData(self): self.wipe() From 99934d024e29fb7dc8d760998ad595abc59e1bb9 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 28 Mar 2023 16:32:41 +0200 Subject: [PATCH 023/909] rec: fix a race in the negcache unit tests --- pdns/recursordist/negcache.cc | 7 ++----- pdns/recursordist/negcache.hh | 2 +- pdns/recursordist/test-negcache_cc.cc | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/pdns/recursordist/negcache.cc b/pdns/recursordist/negcache.cc index 77cc3e3b8ddf..57ac811e1300 100644 --- a/pdns/recursordist/negcache.cc +++ b/pdns/recursordist/negcache.cc @@ -295,7 +295,7 @@ void NegCache::prune(size_t maxEntries) * * \param fp A pointer to an open FILE object */ -size_t NegCache::doDump(int fd, size_t maxCacheEntries) +size_t NegCache::doDump(int fd, size_t maxCacheEntries, time_t now) { int newfd = dup(fd); if (newfd == -1) { @@ -308,9 +308,6 @@ size_t NegCache::doDump(int fd, size_t maxCacheEntries) } fprintf(fp.get(), "; negcache dump follows\n;\n"); - struct timeval now; - Utility::gettimeofday(&now, nullptr); - size_t ret = 0; size_t shard = 0; @@ -326,7 +323,7 @@ size_t NegCache::doDump(int fd, size_t maxCacheEntries) auto& sidx = m->d_map.get(); for (const NegCacheEntry& ne : sidx) { ret++; - int64_t ttl = ne.d_ttd - now.tv_sec; + int64_t ttl = ne.d_ttd - now; fprintf(fp.get(), "%s %" PRId64 " IN %s VIA %s ; (%s) origttl=%" PRIu32 " ss=%hu\n", ne.d_name.toString().c_str(), ttl, ne.d_qtype.toString().c_str(), ne.d_auth.toString().c_str(), vStateToString(ne.d_validationState).c_str(), ne.d_orig_ttl, ne.d_servedStale); for (const auto& rec : ne.authoritySOA.records) { fprintf(fp.get(), "%s %" PRId64 " IN %s %s ; (%s)\n", rec.d_name.toString().c_str(), ttl, DNSRecordContent::NumberToType(rec.d_type).c_str(), rec.getContent()->getZoneRepresentation().c_str(), vStateToString(ne.d_validationState).c_str()); diff --git a/pdns/recursordist/negcache.hh b/pdns/recursordist/negcache.hh index 0d42afee1099..f8e8ce0be50e 100644 --- a/pdns/recursordist/negcache.hh +++ b/pdns/recursordist/negcache.hh @@ -100,7 +100,7 @@ public: size_t count(const DNSName& qname, QType qtype); void prune(size_t maxEntries); void clear(); - size_t doDump(int fd, size_t maxCacheEntries); + size_t doDump(int fd, size_t maxCacheEntries, time_t now = time(nullptr)); size_t wipe(const DNSName& name, bool subtree = false); size_t wipeTyped(const DNSName& name, QType qtype); size_t size() const; diff --git a/pdns/recursordist/test-negcache_cc.cc b/pdns/recursordist/test-negcache_cc.cc index c432005ad0fe..96172d458faa 100644 --- a/pdns/recursordist/test-negcache_cc.cc +++ b/pdns/recursordist/test-negcache_cc.cc @@ -526,7 +526,7 @@ BOOST_AUTO_TEST_CASE(test_dumpToFile) if (!fp) BOOST_FAIL("Temporary file could not be opened"); - cache.doDump(fileno(fp.get()), 0); + cache.doDump(fileno(fp.get()), 0, now.tv_sec); rewind(fp.get()); char* line = nullptr; From 6a51a2798247850723f978a14e642687de259f12 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 28 Mar 2023 17:22:27 +0200 Subject: [PATCH 024/909] dnsdist: Wait a bit longer for the process to exit before killing it This prevents a long list of ``` kill... ``` when running with TSAN-enabled. In my tests it did not seem to really slow the build: roughly 3% slower but that might even be in the error margin for these tests. --- regression-tests.dnsdist/dnsdisttests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 05de5e1bd686..dfc6ead966b6 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -174,7 +174,7 @@ def killProcess(cls, p): return try: p.terminate() - for count in range(10): + for count in range(20): x = p.poll() if x is not None: break From 5f5cd2fe6ed8d9ed756a199c0ce9bb3b74aa3ffa Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 29 Mar 2023 09:44:10 +0200 Subject: [PATCH 025/909] PowerDNS Security Advisory 2023-02: Deterred spoofing attempts can lead to authoritative servers being marked unavailable (CVE-2023-26437) --- pdns/recursordist/pdns_recursor.cc | 55 +++++++++++++++++++----------- pdns/recursordist/syncres.cc | 9 +++-- 2 files changed, 41 insertions(+), 23 deletions(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index a09b371961b4..1c6ddf5ff269 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -2750,35 +2750,40 @@ static void doResends(MT_t::waiters_t::iterator& iter, const std::shared_ptr pid = boost::any_cast>(var); - ssize_t len; PacketBuffer packet; packet.resize(g_outgoingEDNSBufsize); ComboAddress fromaddr; socklen_t addrlen = sizeof(fromaddr); - len = recvfrom(fd, &packet.at(0), packet.size(), 0, (sockaddr*)&fromaddr, &addrlen); + ssize_t len = recvfrom(fd, &packet.at(0), packet.size(), 0, reinterpret_cast(&fromaddr), &addrlen); - if (len < (ssize_t)sizeof(dnsheader)) { - if (len < 0) - ; // cerr<<"Error on fd "<info(Logr::Error, "Unable to parse packet from remote UDP server", "from", Logging::Loggable(fromaddr))); - } + const ssize_t signed_sizeof_sdnsheader = sizeof(dnsheader); + if (len < 0) { + // len < 0: error on socket t_udpclientsocks->returnSocket(fd); - PacketBuffer empty; + PacketBuffer empty; MT_t::waiters_t::iterator iter = MT->d_waiters.find(pid); - if (iter != MT->d_waiters.end()) + if (iter != MT->d_waiters.end()) { doResends(iter, pid, empty); + } + MT->sendEvent(pid, &empty); // this denotes error (does retry lookup using other NS) + return; + } - MT->sendEvent(pid, &empty); // this denotes error (does lookup again.. at least L1 will be hot) + if (len < signed_sizeof_sdnsheader) { + // We have received a packet that cannot be a valid DNS packet, as it has no complete header + // Drop it, but continue to wait for other packets + t_Counters.at(rec::Counter::serverParseError)++; + if (g_logCommonErrors) { + SLOG(g_log << Logger::Error << "Unable to parse too short packet from remote UDP server " << fromaddr.toString() << ": packet smaller than DNS header" << endl, + g_slogout->info(Logr::Error, "Unable to parse too short packet from remote UDP server", "from", Logging::Loggable(fromaddr))); + } return; } + // We have at least a full header packet.resize(len); dnsheader dh; memcpy(&dh, &packet.at(0), sizeof(dh)); @@ -2800,10 +2805,18 @@ static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var) } else { try { - if (len > 12) - pident->domain = DNSName(reinterpret_cast(packet.data()), len, 12, false, &pident->type); // don't copy this from above - we need to do the actual read + if (len > signed_sizeof_sdnsheader) { + pident->domain = DNSName(reinterpret_cast(packet.data()), len, static_cast(sizeof(dnsheader)), false, &pident->type); // don't copy this from above - we need to do the actual read + } + else { + // len == sizeof(dnsheader), only header case + // We will do a full scan search later to see if we can match this reply even without a domain + pident->domain.clear(); + pident->type = 0; + } } catch (std::exception& e) { + // Parse error, continue waiting for other packets t_Counters.at(rec::Counter::serverParseError)++; // won't be fed to lwres.cc, so we have to increment SLOG(g_log << Logger::Warning << "Error in packet from remote nameserver " << fromaddr.toStringWithPort() << ": " << e.what() << endl, g_slogudpin->error(Logr::Warning, e.what(), "Error in packet from remote nameserver", "from", Logging::Loggable(fromaddr))); @@ -2811,14 +2824,16 @@ static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var) } } - MT_t::waiters_t::iterator iter = MT->d_waiters.find(pident); - if (iter != MT->d_waiters.end()) { - doResends(iter, pident, packet); + if (!pident->domain.empty()) { + MT_t::waiters_t::iterator iter = MT->d_waiters.find(pident); + if (iter != MT->d_waiters.end()) { + doResends(iter, pident, packet); + } } retryWithName: - if (!MT->sendEvent(pident, &packet)) { + if (pident->domain.empty() || MT->sendEvent(pident, &packet) == 0) { /* we did not find a match for this response, something is wrong */ // we do a full scan for outstanding queries on unexpected answers. not too bad since we only accept them on the right port number, which is hard enough to guess diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 124414cc47cf..88b5aaaaaef8 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -5183,6 +5183,12 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, } d_totUsec += lwr.d_usec; + + if (resolveret == LWResult::Result::Spoofed) { + spoofed = true; + return false; + } + accountAuthLatency(lwr.d_usec, remoteIP.sin4.sin_family); ++t_Counters.at(rec::RCode::auth).rcodeCounters.at(static_cast(lwr.d_rcode)); @@ -5214,9 +5220,6 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, LOG(prefix << qname << ": Hit a local resource limit resolving" << (doTCP ? " over TCP" : "") << ", probable error: " << stringerror() << endl); t_Counters.at(rec::Counter::resourceLimits)++; } - else if (resolveret == LWResult::Result::Spoofed) { - spoofed = true; - } else { /* LWResult::Result::PermanentError */ t_Counters.at(rec::Counter::unreachables)++; From 058129d52e784635ac0c732b482488a32d0bf456 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 29 Mar 2023 11:18:54 +0200 Subject: [PATCH 026/909] Start using newly assigned "Synthesized" EDE --- pdns/recursordist/ednsextendederror.hh | 7 ++++++- pdns/recursordist/syncres.cc | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/pdns/recursordist/ednsextendederror.hh b/pdns/recursordist/ednsextendederror.hh index 600aa1453442..5b264fcf69b6 100644 --- a/pdns/recursordist/ednsextendederror.hh +++ b/pdns/recursordist/ednsextendederror.hh @@ -50,7 +50,12 @@ struct EDNSExtendedError NotSupported = 21, NoReachableAuthority = 22, NetworkError = 23, - InvalidData = 24 + InvalidData = 24, + SignatureExpiredBeforeValid = 25, + TooEarly = 26, + UnsupportedNSEC3IterationsValue = 27, + UnableToConformToPolicy = 28, + Synthesized = 29, }; uint16_t infoCode; std::string extraText; diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 124414cc47cf..039b8ecfd3c4 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -2757,7 +2757,7 @@ bool SyncRes::doCacheCheck(const DNSName& qname, const DNSName& authname, bool w giveNegative = true; cachedState = ne.d_validationState; if (s_addExtendedResolutionDNSErrors) { - context.extendedError = EDNSExtendedError{0, "Result synthesized by root-nx-trust"}; + context.extendedError = EDNSExtendedError{static_cast(EDNSExtendedError::code::Synthesized), "Result synthesized by root-nx-trust"}; } } else if (g_negCache->get(qname, qtype, d_now, ne, false, d_serveStale, d_refresh)) { @@ -2779,13 +2779,13 @@ bool SyncRes::doCacheCheck(const DNSName& qname, const DNSName& authname, bool w LOG(prefix << qname << "|" << qtype << ": Is negatively cached via '" << ne.d_auth << "' for another " << sttl << " seconds" << endl); res = RCode::NoError; if (s_addExtendedResolutionDNSErrors) { - context.extendedError = EDNSExtendedError{0, "Result from negative cache"}; + context.extendedError = EDNSExtendedError{static_cast(EDNSExtendedError::code::Synthesized), "Result from negative cache"}; } } else { LOG(prefix << qname << ": Entire name '" << qname << "' is negatively cached via '" << ne.d_auth << "' for another " << sttl << " seconds" << endl); if (s_addExtendedResolutionDNSErrors) { - context.extendedError = EDNSExtendedError{0, "Result from negative cache for entire name"}; + context.extendedError = EDNSExtendedError{static_cast(EDNSExtendedError::code::Synthesized), "Result from negative cache for entire name"}; } } } @@ -2811,7 +2811,7 @@ bool SyncRes::doCacheCheck(const DNSName& qname, const DNSName& authname, bool w cachedState = ne.d_validationState; LOG(prefix << qname << ": Name '" << negCacheName << "' and below, is negatively cached via '" << ne.d_auth << "' for another " << sttl << " seconds" << endl); if (s_addExtendedResolutionDNSErrors) { - context.extendedError = EDNSExtendedError{0, "Result synthesized by nothing-below-nxdomain (RFC8020)"}; + context.extendedError = EDNSExtendedError{static_cast(EDNSExtendedError::code::Synthesized), "Result synthesized by nothing-below-nxdomain (RFC8020)"}; } break; } @@ -2973,7 +2973,7 @@ bool SyncRes::doCacheCheck(const DNSName& qname, const DNSName& authname, bool w if (g_aggressiveNSECCache->getDenial(d_now.tv_sec, qname, qtype, ret, res, d_cacheRemote, d_routingTag, d_doDNSSEC, LogObject(prefix))) { context.state = vState::Secure; if (s_addExtendedResolutionDNSErrors) { - context.extendedError = EDNSExtendedError{0, "Result synthesized from aggressive NSEC cache (RFC8198)"}; + context.extendedError = EDNSExtendedError{static_cast(EDNSExtendedError::code::Synthesized), "Result synthesized from aggressive NSEC cache (RFC8198)"}; } return true; } From 955093f2622956fddadc161fee9ba26039a11788 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 28 Mar 2023 09:51:38 +0200 Subject: [PATCH 027/909] Prep for PowerDNS Security Advisory 2023-02 --- docs/secpoll.zone | 23 ++++++++------- pdns/recursordist/docs/changelog/4.6.rst | 10 +++++++ pdns/recursordist/docs/changelog/4.7.rst | 10 +++++++ pdns/recursordist/docs/changelog/4.8.rst | 10 +++++++ .../powerdns-advisory-2023-02.rst | 28 +++++++++++++++++++ 5 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 pdns/recursordist/docs/security-advisories/powerdns-advisory-2023-02.rst diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 9e20c1bc90f0..aac0af0f9fcf 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023032101 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023032901 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -324,25 +324,28 @@ recursor-4.6.0-rc1.security-status 60 IN TXT "3 Unsupported recursor-4.6.0.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2022-01.html" recursor-4.6.1.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2022-02.html" recursor-4.6.2.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2022-02.html" -recursor-4.6.3.security-status 60 IN TXT "1 OK" -recursor-4.6.4.security-status 60 IN TXT "1 OK" -recursor-4.6.5.security-status 60 IN TXT "1 OK" +recursor-4.6.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" +recursor-4.6.4.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" +recursor-4.6.5.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" +recursor-4.6.6.security-status 60 IN TXT "1 OK" recursor-4.7.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.7.0-beta1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.7.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.7.0.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2022-02.html" recursor-4.7.1.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2022-02.html" -recursor-4.7.2.security-status 60 IN TXT "1 OK" -recursor-4.7.3.security-status 60 IN TXT "1 OK" -recursor-4.7.4.security-status 60 IN TXT "1 OK" +recursor-4.7.2.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" +recursor-4.7.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" +recursor-4.7.4.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" +recursor-4.7.5.security-status 60 IN TXT "1 OK" recursor-4.8.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.8.0-beta1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.8.0-beta2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.8.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.8.0.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-01.html" -recursor-4.8.1.security-status 60 IN TXT "1 OK" -recursor-4.8.2.security-status 60 IN TXT "1 OK" -recursor-4.8.3.security-status 60 IN TXT "1 OK" +recursor-4.8.1.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" +recursor-4.8.2.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" +recursor-4.8.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" +recursor-4.8.4.security-status 60 IN TXT "1 OK" ; Recursor Debian recursor-3.6.2-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/" diff --git a/pdns/recursordist/docs/changelog/4.6.rst b/pdns/recursordist/docs/changelog/4.6.rst index cd433237a1b1..4372face88d1 100644 --- a/pdns/recursordist/docs/changelog/4.6.rst +++ b/pdns/recursordist/docs/changelog/4.6.rst @@ -1,6 +1,16 @@ Changelogs for 4.6.X ==================== +.. changelog:: + :version: 4.6.6 + :released: 29th of March 2023 + + .. change:: + :tags: Bug Fixes + :pullreq: 12702 + + PowerDNS Security Advisory 2023-02: Deterred spoofing attempts can lead to authoritative servers being marked unavailable. + .. changelog:: :version: 4.6.5 :released: 25th of November 2022 diff --git a/pdns/recursordist/docs/changelog/4.7.rst b/pdns/recursordist/docs/changelog/4.7.rst index 9a605e7ad4bc..f30e8f156818 100644 --- a/pdns/recursordist/docs/changelog/4.7.rst +++ b/pdns/recursordist/docs/changelog/4.7.rst @@ -1,6 +1,16 @@ Changelogs for 4.7.X ==================== +.. changelog:: + :version: 4.7.5 + :released: 29th of March 2023 + + .. change:: + :tags: Bug Fixes + :pullreq: 12701 + + PowerDNS Security Advisory 2023-02: Deterred spoofing attempts can lead to authoritative servers being marked unavailable. + .. changelog:: :version: 4.7.4 :released: 25th of November 2022 diff --git a/pdns/recursordist/docs/changelog/4.8.rst b/pdns/recursordist/docs/changelog/4.8.rst index 1bbf0623bf81..888633f8d406 100644 --- a/pdns/recursordist/docs/changelog/4.8.rst +++ b/pdns/recursordist/docs/changelog/4.8.rst @@ -1,6 +1,16 @@ Changelogs for 4.8.X ==================== +.. changelog:: + :version: 4.8.4 + :released: 29th of March 2023 + + .. change:: + :tags: Bug Fixes + :pullreq: 12700 + + PowerDNS Security Advisory 2023-02: Deterred spoofing attempts can lead to authoritative servers being marked unavailable. + .. changelog:: :version: 4.8.3 :released: 7th of March 2023 diff --git a/pdns/recursordist/docs/security-advisories/powerdns-advisory-2023-02.rst b/pdns/recursordist/docs/security-advisories/powerdns-advisory-2023-02.rst new file mode 100644 index 000000000000..f2c4dcc0943b --- /dev/null +++ b/pdns/recursordist/docs/security-advisories/powerdns-advisory-2023-02.rst @@ -0,0 +1,28 @@ +PowerDNS Security Advisory 2023-02: Deterred spoofing attempts can lead to authoritative servers being marked unavailable +========================================================================================================================= + +- CVE: CVE-2023-26437 +- Date: 29th of March 2023 +- Affects: PowerDNS Recursor up to and including 4.6.5, 4.7.4 and 4.8.3 +- Not affected: PowerDNS Recursor 4.6.6, 4.7.5 and 4.8.4 +- Severity: Low +- Impact: Denial of service +- Exploit: Successful spoofing may lead to authoritative servers being marked unavailable +- Risk of system compromise: None +- Solution: Upgrade to patched version + +When the recursor detects and deters a spoofing attempt or receives certain malformed DNS packets, +it throttles the server that was the target of the impersonation attempt so that other authoritative +servers for the same zone will be more likely to be used in the future, in case the attacker +controls the path to one server only. Unfortunately this mechanism can be used by an attacker with +the ability to send queries to the recursor, guess the correct source port of the corresponding +outgoing query and inject packets with a spoofed IP address to force the recursor to mark specific +authoritative servers as not available, leading a denial of service for the zones served by those +servers. + +CVSS 3.0 score: 3.7 (Low) +https://www.first.org/cvss/calculator/3.0#CVSS:3.0/AV:N/AC:H/PR:N/UI:R/S:C/C:N/I:N/A:L + +Thanks to Xiang Li from Network and Information Security Laboratory, Tsinghua University for reporting this issue. + + From e868dd14e734d7cfc782fcf1244ba84002fa411a Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 29 Mar 2023 12:08:50 +0200 Subject: [PATCH 028/909] Spellcheck --- .github/actions/spell-check/expect.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 27c23e81a150..3b625692960a 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -1,3 +1,4 @@ + aaaarecord aaldering abi @@ -791,8 +792,8 @@ MBOXFW mbytes Meerwald Mekking -memlock MEMLOCK +memlock Memusage menuselection metadatabase @@ -1429,6 +1430,7 @@ tsigalgo tsigkey tsigname tsigsecret +Tsinghua tstamp TSU ttls @@ -1551,6 +1553,7 @@ xdp Xek Xeon XForwarded +Xiang xorbooter xpf XRecord From 0750ab79caecd85449e1612e7b835a8a7a85c92c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 29 Mar 2023 16:20:37 +0200 Subject: [PATCH 029/909] Fix entry for memlock 16:20 < Habbie> uppercase requires uppercase, lowercase matches both? 16:20 < Habbie> and putting both in triggers a bug? 16:20 < timeless> Right 16:20 < timeless> More or less --- .github/actions/spell-check/expect.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 3b625692960a..35ff30838990 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -792,7 +792,6 @@ MBOXFW mbytes Meerwald Mekking -MEMLOCK memlock Memusage menuselection From 3b19870ca742c99ead7afcdec8f7a100b5e030a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kan=20Lindqvist?= Date: Wed, 29 Mar 2023 22:25:29 +0200 Subject: [PATCH 030/909] Add reminders for 53/tcp in the NOTRACK rules in docs --- pdns/recursordist/docs/performance.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pdns/recursordist/docs/performance.rst b/pdns/recursordist/docs/performance.rst index 6e5d24616181..ffa66b9f7b44 100644 --- a/pdns/recursordist/docs/performance.rst +++ b/pdns/recursordist/docs/performance.rst @@ -74,6 +74,7 @@ For high load operation (thousands of queries/second), It is advised to either t Sample Linux command lines would be:: ## IPv4 + ## NOTRACK rules for 53/udp, keep in mind that you also need your regular rules for 53/tcp iptables -t raw -I OUTPUT -p udp --dport 53 -j CT --notrack iptables -t raw -I OUTPUT -p udp --sport 53 -j CT --notrack iptables -t raw -I PREROUTING -p udp --dport 53 -j CT --notrack @@ -84,6 +85,7 @@ Sample Linux command lines would be:: iptables -I OUTPUT -p udp --sport 53 -j ACCEPT ## IPv6 + ## NOTRACK rules for 53/udp, keep in mind that you also need your regular rules for 53/tcp ip6tables -t raw -I OUTPUT -p udp --dport 53 -j CT --notrack ip6tables -t raw -I OUTPUT -p udp --sport 53 -j CT --notrack ip6tables -t raw -I PREROUTING -p udp --sport 53 -j CT --notrack @@ -97,6 +99,7 @@ When using FirewallD (Centos 7+ / Red Hat 7+ / Fedora 21+), connection tracking The settings can be made permanent by using the ``--permanent`` flag:: ## IPv4 + ## NOTRACK rules for 53/udp, keep in mind that you also need your regular rules for 53/tcp firewall-cmd --direct --add-rule ipv4 raw OUTPUT 0 -p udp --dport 53 -j CT --notrack firewall-cmd --direct --add-rule ipv4 raw OUTPUT 0 -p udp --sport 53 -j CT --notrack firewall-cmd --direct --add-rule ipv4 raw PREROUTING 0 -p udp --dport 53 -j CT --notrack @@ -107,6 +110,7 @@ The settings can be made permanent by using the ``--permanent`` flag:: firewall-cmd --direct --add-rule ipv4 filter OUTPUT 0 -p udp --sport 53 -j ACCEPT ## IPv6 + ## NOTRACK rules for 53/udp, keep in mind that you also need your regular rules for 53/tcp firewall-cmd --direct --add-rule ipv6 raw OUTPUT 0 -p udp --dport 53 -j CT --notrack firewall-cmd --direct --add-rule ipv6 raw OUTPUT 0 -p udp --sport 53 -j CT --notrack firewall-cmd --direct --add-rule ipv6 raw PREROUTING 0 -p udp --dport 53 -j CT --notrack From 6694214d104668402f333aa558e08b3e69d10ab3 Mon Sep 17 00:00:00 2001 From: Santiago Traversa Date: Thu, 30 Mar 2023 00:39:02 -0300 Subject: [PATCH 031/909] Fixes a typo in pdnsutil clear-zone help output from # pdnsutil clear-zone foo bar Syntax: pdnsutil edit-zone ZONE to # pdnsutil clear-zone foo bar Syntax: pdnsutil clear-zone ZONE --- pdns/pdnsutil.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 6ccd24100e3e..89cf2f638e79 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -3179,7 +3179,7 @@ try } else if (cmds.at(0) == "clear-zone") { if(cmds.size() != 2) { - cerr<<"Syntax: pdnsutil edit-zone ZONE"< Date: Thu, 30 Mar 2023 13:17:16 +0200 Subject: [PATCH 032/909] dnsdist: Prepare ChangeLog and secpoll update for 1.8.0 --- docs/secpoll.zone | 5 +++-- pdns/dnsdistdist/docs/changelog.rst | 22 ++++++++++++++++++++++ pdns/dnsdistdist/docs/eol.rst | 8 ++++++-- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index aac0af0f9fcf..9c2b988f2a56 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023032901 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023033001 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -499,4 +499,5 @@ dnsdist-1.7.2.security-status 60 IN TXT "1 OK" dnsdist-1.7.3.security-status 60 IN TXT "1 OK" dnsdist-1.8.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" dnsdist-1.8.0-rc2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.8.0-rc3.security-status 60 IN TXT "1 Unsupported pre-release" +dnsdist-1.8.0-rc3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" +dnsdist-1.8.0.security-status 60 IN TXT "1 OK" diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index 953b9b8c6c59..33a21b31bd4e 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -1,6 +1,28 @@ Changelog ========= +.. changelog:: + :version: 1.8.0 + :released: 30th of March 2023 + + .. change:: + :tags: Bug Fixes + :pullreq: 12687 + + Fix 'Unknown key' issue for actions and rules parameters + + .. change:: + :tags: Bug Fixes + :pullreq: 12672 + + Fix a dnsheader unaligned case + + .. change:: + :tags: Bug Fixes + :pullreq: 12654 + + secpoll: explicitly include necessary ctime header for time_t + .. changelog:: :version: 1.8.0-rc3 :released: 16th of March 2023 diff --git a/pdns/dnsdistdist/docs/eol.rst b/pdns/dnsdistdist/docs/eol.rst index 259417be1775..29cf31f42387 100644 --- a/pdns/dnsdistdist/docs/eol.rst +++ b/pdns/dnsdistdist/docs/eol.rst @@ -8,18 +8,22 @@ End of life statements - Release date - Security-Only updates - End of Life + * - 1.8 + - March 30 2023 + - + - * - 1.7 - January 17 2022 - - * - 1.6 - May 11 2021 - - + - March 30 2023 - * - 1.5 - July 30 2020 - January 17 2022 - - + - EOL (March 30 2023) * - 1.4 - November 20 2019 - May 2021 From 193e3315beebe8f146e86edb2dab483dfb166fbf Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 30 Mar 2023 16:03:49 +0200 Subject: [PATCH 033/909] change hackerone references to point to yeswehack --- .github/actions/spell-check/expect.txt | 2 +- SECURITY.md | 2 +- docs/common/security-policy.rst | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 35ff30838990..a9008ccf60a5 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -1,4 +1,3 @@ - aaaarecord aaldering abi @@ -1559,6 +1558,7 @@ XRecord XXXXXX yahttp Yehuda +yeswehack Yiu Ylitalo yml diff --git a/SECURITY.md b/SECURITY.md index 07038efceb4a..50bc7f99cdcd 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -13,7 +13,7 @@ This license is included in this documentation. Yes We Hack ----------- Security issues can also be reported on [our YesWeHack page](https://yeswehack.com/programs/powerdns) and might fetch a bounty. -Do note that only the PowerDNS software (PowerDNS Authoritative Server, the PowerDNS Recursor and dnsdist) is in scope for the HackerOne program, not our websites or other infrastructure. +Do note that only the PowerDNS software (PowerDNS Authoritative Server, the PowerDNS Recursor and dnsdist) is in scope for the YesWeHack program, not our websites or other infrastructure. Disclosure Policy ----------------- diff --git a/docs/common/security-policy.rst b/docs/common/security-policy.rst index 3f457a9f4433..d400225b22d8 100644 --- a/docs/common/security-policy.rst +++ b/docs/common/security-policy.rst @@ -12,10 +12,10 @@ This :doc:`license <../common/license>` is included in this documentation. If you believe you have found a security vulnerability that applies to DNS implementations generally, and you want to report this responsibly to a number of implementers, you might consider also using the `Open Source DNS Vulnerability mailing list `_, managed by `DNS-OARC `_. -HackerOne +YesWeHack ^^^^^^^^^ -Security issues can also be reported on `our HackerOne page `_ and might fetch a bounty. -Do note that only the PowerDNS software is in scope for the HackerOne program, not our websites or other infrastructure. +Security issues can also be reported on `our YesWeHack page `_ and might fetch a bounty. +Do note that only the PowerDNS software is in scope for the YesWeHack program, not our websites or other infrastructure. Disclosure Policy ^^^^^^^^^^^^^^^^^ From cb1bad81e3aab8b3f8f92c437fd89a09301b6245 Mon Sep 17 00:00:00 2001 From: Erik Winkels Date: Thu, 30 Mar 2023 16:23:04 +0200 Subject: [PATCH 034/909] Fix EOL table for DNSdist. --- pdns/dnsdistdist/docs/eol.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/eol.rst b/pdns/dnsdistdist/docs/eol.rst index 29cf31f42387..781d0ef52970 100644 --- a/pdns/dnsdistdist/docs/eol.rst +++ b/pdns/dnsdistdist/docs/eol.rst @@ -14,7 +14,7 @@ End of life statements - * - 1.7 - January 17 2022 - - + - March 30 2023 - * - 1.6 - May 11 2021 From 915059183767d9f6db36ed82387bca7b8ab949e4 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 31 Mar 2023 10:02:31 +0200 Subject: [PATCH 035/909] More fine grained capping of packet cache TTL Distinguish between negative answers (NxDomain and NoData), failure to resolve (ServFail and completely empty answers) and ordinary answers when capping the packet cache TTL. A new setting (packetcache-negative-ttl) is created for that. NoData is: empty answer section but SOA record present in authority section. --- pdns/recursordist/docs/settings.rst | 13 +++++++++ pdns/recursordist/pdns_recursor.cc | 29 ++++++++++++++----- pdns/recursordist/rec-main.cc | 9 ++++-- pdns/recursordist/syncres.cc | 1 + pdns/recursordist/syncres.hh | 1 + .../test_PacketCache.py | 9 +++--- 6 files changed, 48 insertions(+), 14 deletions(-) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index bf7b41f6ec8f..457267444614 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -1586,6 +1586,19 @@ If an answer containing an NSEC3 record with more iterations is received, its DN Maximum number of seconds to cache an item in the packet cache, no matter what the original TTL specified. +.. _setting-packetcache-negative-ttl: + +``packetcache-negative-ttl`` +---------------------------- +.. versionadded:: 4.9.0 + +- Integer +- Default: 60 + +Maximum number of seconds to cache an ``NxDomain`` or ``NoData`` answer in the packetcache. +This setting's maximum is capped to `packetcache-ttl`_. +i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-negative-ttl`` at the default will lower ``packetcache-negative-ttl`` to ``15``. + .. _setting-packetcache-servfail-ttl: ``packetcache-servfail-ttl`` diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 1c6ddf5ff269..69c70f5d7ed4 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -420,10 +420,14 @@ static void handleRPZCustom(const DNSRecord& spoofed, const QType& qtype, SyncRe } } -static bool addRecordToPacket(DNSPacketWriter& pw, const DNSRecord& rec, uint32_t& minTTL, uint32_t ttlCap, const uint16_t maxAnswerSize) +static bool addRecordToPacket(DNSPacketWriter& pw, const DNSRecord& rec, uint32_t& minTTL, uint32_t ttlCap, const uint16_t maxAnswerSize, bool& seenAuthSOA) { pw.startRecord(rec.d_name, rec.d_type, (rec.d_ttl > ttlCap ? ttlCap : rec.d_ttl), rec.d_class, rec.d_place); + if (rec.d_type == QType::SOA && rec.d_place == DNSResourceRecord::AUTHORITY) { + seenAuthSOA = true; + } + if (rec.d_type != QType::OPT) // their TTL ain't real minTTL = min(minTTL, rec.d_ttl); @@ -875,6 +879,20 @@ static void dumpTrace(const string& trace, const timeval& timev) // fclose by unique_ptr does implicit flush } +static uint32_t capPacketCacheTTL(const struct dnsheader& hdr, uint32_t ttl, bool seenAuthSOA) +{ + if (hdr.rcode == RCode::NXDomain || (hdr.rcode == RCode::NoError && hdr.ancount == 0 && seenAuthSOA)) { + ttl = std::min(ttl, SyncRes::s_packetcachenegativettl); + } + else if ((hdr.rcode != RCode::NoError && hdr.rcode != RCode::NXDomain) || (hdr.ancount == 0 && hdr.nscount == 0)) { + ttl = min(ttl, SyncRes::s_packetcacheservfailttl); + } + else { + ttl = std::min(ttl, SyncRes::s_packetcachettl); + } + return ttl; +} + void startDoResolve(void* p) { auto dc = std::unique_ptr(reinterpret_cast(p)); @@ -984,6 +1002,7 @@ void startDoResolve(void* p) If we have a TTL cap, this value can't be larger than the cap no matter what. */ uint32_t minTTL = dc->d_ttlCap; + bool seenAuthSOA = false; sr.d_eventTrace = std::move(dc->d_eventTrace); sr.setId(MT->getTid()); @@ -1413,7 +1432,7 @@ void startDoResolve(void* p) continue; } - if (!addRecordToPacket(pw, *i, minTTL, dc->d_ttlCap, maxanswersize)) { + if (!addRecordToPacket(pw, *i, minTTL, dc->d_ttlCap, maxanswersize, seenAuthSOA)) { needCommit = false; break; } @@ -1655,11 +1674,7 @@ void startDoResolve(void* p) } if (t_packetCache && !variableAnswer && !sr.wasVariable()) { - const auto& hdr = pw.getHeader(); - if ((hdr->rcode != RCode::NoError && hdr->rcode != RCode::NXDomain) || (hdr->ancount == 0 && hdr->nscount == 0)) { - minTTL = min(minTTL, SyncRes::s_packetcacheservfailttl); - } - minTTL = min(minTTL, SyncRes::s_packetcachettl); + minTTL = capPacketCacheTTL(*pw.getHeader(), minTTL, seenAuthSOA); t_packetCache->insertResponsePacket(dc->d_tag, dc->d_qhash, std::move(dc->d_query), dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass, string((const char*)&*packet.begin(), packet.size()), diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 82365a91350c..4ea5166d23c8 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1510,10 +1510,12 @@ static int serviceMain(int argc, char* argv[], Logr::log_t log) SyncRes::s_maxnegttl = ::arg().asNum("max-negative-ttl"); SyncRes::s_maxbogusttl = ::arg().asNum("max-cache-bogus-ttl"); SyncRes::s_maxcachettl = max(::arg().asNum("max-cache-ttl"), 15); + SyncRes::s_packetcachettl = ::arg().asNum("packetcache-ttl"); - // Cap the packetcache-servfail-ttl to the packetcache-ttl - uint32_t packetCacheServFailTTL = ::arg().asNum("packetcache-servfail-ttl"); - SyncRes::s_packetcacheservfailttl = (packetCacheServFailTTL > SyncRes::s_packetcachettl) ? SyncRes::s_packetcachettl : packetCacheServFailTTL; + // Cap the packetcache-servfail-ttl and packetcache-negative-ttl to packetcache-ttl + SyncRes::s_packetcacheservfailttl = std::min(static_cast(::arg().asNum("packetcache-servfail-ttl")), SyncRes::s_packetcachettl); + SyncRes::s_packetcachenegativettl = std::min(static_cast(::arg().asNum("packetcache-negative-ttl")), SyncRes::s_packetcachettl); + SyncRes::s_serverdownmaxfails = ::arg().asNum("server-down-max-fails"); SyncRes::s_serverdownthrottletime = ::arg().asNum("server-down-throttle-time"); SyncRes::s_nonresolvingnsmaxfails = ::arg().asNum("non-resolving-ns-max-fails"); @@ -2695,6 +2697,7 @@ int main(int argc, char** argv) ::arg().set("packetcache-ttl", "maximum number of seconds to keep a cached entry in packetcache") = "3600"; ::arg().set("max-packetcache-entries", "maximum number of entries to keep in the packetcache") = "500000"; ::arg().set("packetcache-servfail-ttl", "maximum number of seconds to keep a cached servfail entry in packetcache") = "60"; + ::arg().set("packetcache-negative-ttl", "maximum number of seconds to keep a cached NxDomain or NoData entry in packetcache") = "60"; ::arg().set("server-id", "Returned when queried for 'id.server' TXT or NSID, defaults to hostname, set custom or 'disabled'") = ""; ::arg().set("stats-ringbuffer-entries", "maximum number of packets to store statistics for") = "10000"; ::arg().set("version-string", "string reported on version.pdns or version.bind") = fullVersionString(); diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 88b5aaaaaef8..31654b06ef13 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -436,6 +436,7 @@ unsigned int SyncRes::s_minimumTTL; unsigned int SyncRes::s_minimumECSTTL; unsigned int SyncRes::s_packetcachettl; unsigned int SyncRes::s_packetcacheservfailttl; +unsigned int SyncRes::s_packetcachenegativettl; unsigned int SyncRes::s_serverdownmaxfails; unsigned int SyncRes::s_serverdownthrottletime; unsigned int SyncRes::s_nonresolvingnsmaxfails; diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 74693009a772..496ea28efea1 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -518,6 +518,7 @@ public: static unsigned int s_maxcachettl; static unsigned int s_packetcachettl; static unsigned int s_packetcacheservfailttl; + static unsigned int s_packetcachenegativettl; static unsigned int s_serverdownmaxfails; static unsigned int s_serverdownthrottletime; static unsigned int s_nonresolvingnsmaxfails; diff --git a/regression-tests.recursor-dnssec/test_PacketCache.py b/regression-tests.recursor-dnssec/test_PacketCache.py index f797822d8a00..80b015f6f9dd 100644 --- a/regression-tests.recursor-dnssec/test_PacketCache.py +++ b/regression-tests.recursor-dnssec/test_PacketCache.py @@ -21,6 +21,7 @@ class PacketCacheRecursorTest(RecursorTest): _apiKey = 'secretapikey' _config_template = """ packetcache-ttl=10 + packetcache-negative-ttl=8 packetcache-servfail-ttl=5 auth-zones=example=configs/%s/example.zone webserver=yes @@ -141,13 +142,13 @@ def testPacketCache(self): self.assertRRsetInAnswer(res, expected) self.checkPacketCacheMetrics(6, 4) - # NXDomain should get default packetcache TTL (10) + # NXDomain should get negative packetcache TTL (8) query = dns.message.make_query('nxdomain.example.', 'A', want_dnssec=True) res = self.sendUDPQuery(query) self.assertRcodeEqual(res, dns.rcode.NXDOMAIN) self.checkPacketCacheMetrics(6, 5) - # NoData should get default packetcache TTL (10) + # NoData should get negative packetcache TTL (8) query = dns.message.make_query('a.example.', 'AAAA', want_dnssec=True) res = self.sendUDPQuery(query) self.assertRcodeEqual(res, dns.rcode.NOERROR) @@ -166,8 +167,8 @@ def testPacketCache(self): try: ret = subprocess.check_output(rec_controlCmd, stderr=subprocess.STDOUT) self.assertTrue((b"a.example. 10 A ; tag 0 udp\n" in ret) or (b"a.example. 9 A ; tag 0 udp\n" in ret)) - self.assertTrue((b"nxdomain.example. 10 A ; tag 0 udp\n" in ret) or (b"nxdomain.example. 9 A ; tag 0 udp\n" in ret)) - self.assertTrue((b"a.example. 10 AAAA ; tag 0 udp\n" in ret) or (b"a.example. 9 AAAA ; tag 0 udp\n" in ret)) + self.assertTrue((b"nxdomain.example. 8 A ; tag 0 udp\n" in ret) or (b"nxdomain.example. 7 A ; tag 0 udp\n" in ret)) + self.assertTrue((b"a.example. 8 AAAA ; tag 0 udp\n" in ret) or (b"a.example. 7 AAAA ; tag 0 udp\n" in ret)) self.assertTrue((b"f.example. 5 A ; tag 0 udp\n" in ret) or (b"f.example. 4 A ; tag 0 udp\n" in ret)) except subprocess.CalledProcessError as e: From 4f9f2fd5c170552f2b4e811a4d231f3ca882d0e9 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 31 Mar 2023 13:36:04 +0200 Subject: [PATCH 036/909] Cleanup rcodes enums: base one is 8 bit unisgned, extended one 16 bit unsigned --- pdns/dns.cc | 8 +++++--- pdns/dns.hh | 6 +++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pdns/dns.cc b/pdns/dns.cc index d9fb5096f88c..99bbd72aa65e 100644 --- a/pdns/dns.cc +++ b/pdns/dns.cc @@ -71,8 +71,9 @@ static const std::array rcodes_short_s = { }; std::string RCode::to_s(uint8_t rcode) { - if (rcode > 0xF) + if (rcode > 0xF) { return std::string("ErrOutOfRange"); + } return ERCode::to_s(rcode); } @@ -83,9 +84,10 @@ std::string RCode::to_short_s(uint8_t rcode) { return rcodes_short_s.at(rcode); } -std::string ERCode::to_s(uint8_t rcode) { - if (rcode > RCode::rcodes_s.size()-1) +std::string ERCode::to_s(uint16_t rcode) { + if (rcode >= RCode::rcodes_s.size()) { return std::string("Err#")+std::to_string(rcode); + } return RCode::rcodes_s.at(rcode); } diff --git a/pdns/dns.hh b/pdns/dns.hh index ef44cf813d0b..7ceda1eeecc7 100644 --- a/pdns/dns.hh +++ b/pdns/dns.hh @@ -32,7 +32,7 @@ struct DNSRecord; class RCode { public: - enum rcodes_ { NoError=0, FormErr=1, ServFail=2, NXDomain=3, NotImp=4, Refused=5, YXDomain=6, YXRRSet=7, NXRRSet=8, NotAuth=9, NotZone=10}; + enum rcodes_ : uint8_t { NoError=0, FormErr=1, ServFail=2, NXDomain=3, NotImp=4, Refused=5, YXDomain=6, YXRRSet=7, NXRRSet=8, NotAuth=9, NotZone=10}; static std::string to_s(uint8_t rcode); static std::string to_short_s(uint8_t rcode); const static std::array rcodes_s; @@ -41,8 +41,8 @@ public: class ERCode { public: - enum rcodes_ { BADVERS=16, BADSIG=16, BADKEY=17, BADTIME=18, BADMODE=19, BADNAME=20, BADALG=21, BADTRUNC=22, BADCOOKIE=23 }; - static std::string to_s(uint8_t rcode); + enum rcodes_ : uint16_t { BADVERS=16, BADSIG=16, BADKEY=17, BADTIME=18, BADMODE=19, BADNAME=20, BADALG=21, BADTRUNC=22, BADCOOKIE=23 }; + static std::string to_s(uint16_t rcode); }; class Opcode From 7f8f08937f935cbf136e993cdf1a7d84d5af9629 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 3 Apr 2023 09:20:12 +0200 Subject: [PATCH 037/909] Regression tests should use new EDE --- .../test_AggressiveNSECCache.py | 18 +++++++++--------- .../test_RootNXTrust.py | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/regression-tests.recursor-dnssec/test_AggressiveNSECCache.py b/regression-tests.recursor-dnssec/test_AggressiveNSECCache.py index 35588e33c6d7..2ff833efcd58 100644 --- a/regression-tests.recursor-dnssec/test_AggressiveNSECCache.py +++ b/regression-tests.recursor-dnssec/test_AggressiveNSECCache.py @@ -93,7 +93,7 @@ def testNoData(self): self.assertEqual(res.edns, 0) self.assertEqual(len(res.options), 1) self.assertEqual(res.options[0].otype, 15) - self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)')) + self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)')) class AggressiveNSECCacheNSEC(AggressiveNSECCacheBase): _confdir = 'AggressiveNSECCacheNSEC' @@ -131,7 +131,7 @@ def testNXD(self): self.assertEqual(res.edns, 0) self.assertEqual(len(res.options), 1) self.assertEqual(res.options[0].otype, 15) - self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)')) + self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)')) def testWildcard(self): self.wipe() @@ -158,7 +158,7 @@ def testWildcard(self): self.assertEqual(res.edns, 0) self.assertEqual(len(res.options), 1) self.assertEqual(res.options[0].otype, 15) - self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)')) + self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)')) # now we ask for a type that does not exist at the wildcard hits = self.getMetric('aggressive-nsec-cache-nsec-hits') @@ -173,7 +173,7 @@ def testWildcard(self): self.assertEqual(res.edns, 0) self.assertEqual(len(res.options), 1) self.assertEqual(res.options[0].otype, 15) - self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)')) + self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)')) # we can also ask a different type, for a different name that is covered # by the NSEC and matches the wildcard (but the type does not exist) @@ -189,7 +189,7 @@ def testWildcard(self): self.assertEqual(res.edns, 0) self.assertEqual(len(res.options), 1) self.assertEqual(res.options[0].otype, 15) - self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)')) + self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)')) def test_Bogus(self): self.wipe() @@ -303,7 +303,7 @@ def testNXD(self): self.assertEqual(res.edns, 0) self.assertEqual(len(res.options), 1) self.assertEqual(res.options[0].otype, 15) - self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)')) + self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)')) def testWildcard(self): self.wipe() @@ -336,7 +336,7 @@ def testWildcard(self): self.assertEqual(res.edns, 0) self.assertEqual(len(res.options), 1) self.assertEqual(res.options[0].otype, 15) - self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)')) + self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)')) # now we ask for a type that does not exist at the wildcard nbQueries = self.getMetric('all-outqueries') @@ -349,7 +349,7 @@ def testWildcard(self): self.assertEqual(res.edns, 0) self.assertEqual(len(res.options), 1) self.assertEqual(res.options[0].otype, 15) - self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)')) + self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)')) # we can also ask a different type, for a different name that is covered # by the NSEC3s and matches the wildcard (but the type does not exist) @@ -363,7 +363,7 @@ def testWildcard(self): self.assertEqual(res.edns, 0) self.assertEqual(len(res.options), 1) self.assertEqual(res.options[0].otype, 15) - self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized from aggressive NSEC cache (RFC8198)')) + self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized from aggressive NSEC cache (RFC8198)')) def test_OptOut(self): self.wipe() diff --git a/regression-tests.recursor-dnssec/test_RootNXTrust.py b/regression-tests.recursor-dnssec/test_RootNXTrust.py index 21254b4db272..cb1133641b3e 100644 --- a/regression-tests.recursor-dnssec/test_RootNXTrust.py +++ b/regression-tests.recursor-dnssec/test_RootNXTrust.py @@ -138,4 +138,4 @@ def testRootNXTrust(self): self.assertEqual(res.edns, 0) self.assertEqual(len(res.options), 1) self.assertEqual(res.options[0].otype, 15) - self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(0, b'Result synthesized by root-nx-trust')) + self.assertEqual(res.options[0], extendederrors.ExtendedErrorOption(29, b'Result synthesized by root-nx-trust')) From 035b00466134b5f274cf057b4c193a459851723b Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 3 Apr 2023 10:06:07 +0200 Subject: [PATCH 038/909] docs: update GPG keyblock link --- SECURITY.md | 2 +- docs/common/security-policy.rst | 2 +- docs/common/tarball-pgp-keys.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 07038efceb4a..8a13a0e7f395 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -2,7 +2,7 @@ PowerDNS and dnsdist Security Policy ==================================== If you have a security problem to report, please email us at both peter.van.dijk@powerdns.com and remi.gacogne@powerdns.com. -In case you want to encrypt your report using PGP, please use: https://www.powerdns.com/powerdns-keyblock.asc +In case you want to encrypt your report using PGP, please use: https://doc.powerdns.com/powerdns-keyblock.asc Please do not mail security issues to public lists, nor file a ticket, unless we do not get back to you in a timely manner. We fully credit reporters of security issues, and respond quickly, but please allow us a reasonable timeframe to coordinate a response. diff --git a/docs/common/security-policy.rst b/docs/common/security-policy.rst index 3f457a9f4433..2ba1ca0a4a65 100644 --- a/docs/common/security-policy.rst +++ b/docs/common/security-policy.rst @@ -2,7 +2,7 @@ PowerDNS Security Policy ------------------------ If you have a security problem to report, please email us at both peter.van.dijk@powerdns.com and remi.gacogne@powerdns.com. -In case you want to encrypt your report using PGP, please use: https://www.powerdns.com/powerdns-keyblock.asc +In case you want to encrypt your report using PGP, please use: https://doc.powerdns.com/powerdns-keyblock.asc Please do not mail security issues to public lists, nor file a ticket, unless we do not get back to you in a timely manner. We fully credit reporters of security issues, and respond quickly, but please allow us a reasonable timeframe to coordinate a response. diff --git a/docs/common/tarball-pgp-keys.rst b/docs/common/tarball-pgp-keys.rst index b4eeb7c0b2e3..2c8b05f40d03 100644 --- a/docs/common/tarball-pgp-keys.rst +++ b/docs/common/tarball-pgp-keys.rst @@ -3,7 +3,7 @@ * `16E1 2866 B773 8C73 976A 5743 6FFC 3343 9B0D 04DF `_ * `990C 3D0E AC7C 275D C6B1 8436 EACA B90B 1963 EC2B `_ -There is a PGP keyblock with these keys available on `https://www.powerdns.com/powerdns-keyblock.asc `_. +There is a PGP keyblock with these keys available on `https://doc.powerdns.com/powerdns-keyblock.asc `_. Older releases (4.3.x and earlier) can also be signed with one of the following keys: From 1e3041c07f25e9b9bf5ec71b99a77728a1c86dcd Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 3 Apr 2023 10:57:46 +0200 Subject: [PATCH 039/909] Change default packet TTL to 24 hours --- pdns/recursordist/docs/settings.rst | 6 +++++- pdns/recursordist/rec-main.cc | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 457267444614..fce382f5f042 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -1582,10 +1582,14 @@ If an answer containing an NSEC3 record with more iterations is received, its DN ``packetcache-ttl`` ------------------- - Integer -- Default: 3600 +- Default: 86400 Maximum number of seconds to cache an item in the packet cache, no matter what the original TTL specified. +.. versionchanged:: 4.9.0 + + The default was changed from 3600 (1 hour) to 86400 (24 hours). + .. _setting-packetcache-negative-ttl: ``packetcache-negative-ttl`` diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 4ea5166d23c8..6b84332ba2b0 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2694,7 +2694,7 @@ int main(int argc, char** argv) ::arg().set("max-negative-ttl", "maximum number of seconds to keep a negative cached entry in memory") = "3600"; ::arg().set("max-cache-bogus-ttl", "maximum number of seconds to keep a Bogus (positive or negative) cached entry in memory") = "3600"; ::arg().set("max-cache-ttl", "maximum number of seconds to keep a cached entry in memory") = "86400"; - ::arg().set("packetcache-ttl", "maximum number of seconds to keep a cached entry in packetcache") = "3600"; + ::arg().set("packetcache-ttl", "maximum number of seconds to keep a cached entry in packetcache") = "86400"; ::arg().set("max-packetcache-entries", "maximum number of entries to keep in the packetcache") = "500000"; ::arg().set("packetcache-servfail-ttl", "maximum number of seconds to keep a cached servfail entry in packetcache") = "60"; ::arg().set("packetcache-negative-ttl", "maximum number of seconds to keep a cached NxDomain or NoData entry in packetcache") = "60"; From 3e5afd940a5492dc6326080a38451503563ad645 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 1 Feb 2023 13:44:47 +0100 Subject: [PATCH 040/909] rec: process hints with multiple addresses per name correctly. Fixes #12486 --- pdns/recursordist/reczones.cc | 58 ++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 21 deletions(-) diff --git a/pdns/recursordist/reczones.cc b/pdns/recursordist/reczones.cc index 62aaf25d62d4..94181f751751 100644 --- a/pdns/recursordist/reczones.cc +++ b/pdns/recursordist/reczones.cc @@ -35,12 +35,24 @@ extern int g_argc; extern char** g_argv; +static void putIntoCache(time_t now, QType qtype, vState state, const ComboAddress& from, const set& seen, const std::multimap& allRecords) +{ + for (const auto& name : seen) { + auto records = allRecords.equal_range(name); + vector aset; + for (auto elem = records.first; elem != records.second; ++elem) { + aset.push_back(elem->second); + } + g_recCache->replace(now, name, qtype, aset, vector>(), vector>(), true, g_rootdnsname, boost::none, boost::none, state, from); // auth, etc see above + } +} + bool primeHints(time_t ignored) { // prime root cache const vState validationState = vState::Insecure; const ComboAddress from("255.255.255.255"); - vector nsset; + vector nsvec; time_t now = time(nullptr); @@ -90,7 +102,7 @@ bool primeHints(time_t ignored) g_recCache->replace(now, DNSName(templ), QType(QType::AAAA), aaaaset, vector>(), vector>(), false, g_rootdnsname, boost::none, boost::none, validationState, from); } - nsset.push_back(nsrr); + nsvec.push_back(nsrr); } } else { @@ -102,37 +114,41 @@ bool primeHints(time_t ignored) set seenA; set seenAAAA; + std::multimap aRecords; + std::multimap aaaaRecords; + while (zpt.get(rr)) { rr.ttl += now; - if (rr.qtype.getCode() == QType::A) { + switch (rr.qtype) { + case QType::A: seenA.insert(rr.qname); - vector aset; - aset.push_back(DNSRecord(rr)); - g_recCache->replace(now, rr.qname, QType(QType::A), aset, vector>(), vector>(), true, g_rootdnsname, boost::none, boost::none, validationState, from); // auth, etc see above - } - else if (rr.qtype.getCode() == QType::AAAA) { + aRecords.insert({rr.qname, DNSRecord(rr)}); + break; + case QType::AAAA: seenAAAA.insert(rr.qname); - vector aaaaset; - aaaaset.push_back(DNSRecord(rr)); - g_recCache->replace(now, rr.qname, QType(QType::AAAA), aaaaset, vector>(), vector>(), true, g_rootdnsname, boost::none, boost::none, validationState, from); - } - else if (rr.qtype.getCode() == QType::NS) { + aaaaRecords.insert({rr.qname, DNSRecord(rr)}); + break; + case QType::NS: seenNS.insert(DNSName(rr.content)); rr.content = toLower(rr.content); - nsset.push_back(DNSRecord(rr)); + nsvec.emplace_back(rr); + break; } } - // Check reachability of A and AAAA records - bool reachableA = false, reachableAAAA = false; - for (auto const& r : seenA) { - if (seenNS.count(r)) { + putIntoCache(now, QType::A, validationState, from, seenA, aRecords); + putIntoCache(now, QType::AAAA, validationState, from, seenAAAA, aaaaRecords); + + bool reachableA = false; + for (auto const& record : seenA) { + if (seenNS.count(record) != 0) { reachableA = true; break; } } - for (auto const& r : seenAAAA) { - if (seenNS.count(r)) { + bool reachableAAAA = false; + for (auto const& record : seenAAAA) { + if (seenNS.count(record) != 0) { reachableAAAA = true; break; } @@ -155,7 +171,7 @@ bool primeHints(time_t ignored) } g_recCache->doWipeCache(g_rootdnsname, false, QType::NS); - g_recCache->replace(now, g_rootdnsname, QType(QType::NS), nsset, vector>(), vector>(), false, g_rootdnsname, boost::none, boost::none, validationState, from); // and stuff in the cache + g_recCache->replace(now, g_rootdnsname, QType(QType::NS), nsvec, {}, {}, false, g_rootdnsname, boost::none, boost::none, validationState, from); // and stuff in the cache return true; } From 5c7e7d4880494ddfa280d3b50857fee721cd32fa Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 6 Feb 2023 08:57:31 +0100 Subject: [PATCH 041/909] Refactor of root priming code --- pdns/recursordist/reczones.cc | 248 +++++++++++++++------------ pdns/recursordist/root-addresses.hh | 9 +- pdns/recursordist/test-syncres_cc.cc | 6 +- 3 files changed, 144 insertions(+), 119 deletions(-) diff --git a/pdns/recursordist/reczones.cc b/pdns/recursordist/reczones.cc index 94181f751751..81e6774bd9d0 100644 --- a/pdns/recursordist/reczones.cc +++ b/pdns/recursordist/reczones.cc @@ -41,138 +41,162 @@ static void putIntoCache(time_t now, QType qtype, vState state, const ComboAddre auto records = allRecords.equal_range(name); vector aset; for (auto elem = records.first; elem != records.second; ++elem) { - aset.push_back(elem->second); + aset.emplace_back(elem->second); } - g_recCache->replace(now, name, qtype, aset, vector>(), vector>(), true, g_rootdnsname, boost::none, boost::none, state, from); // auth, etc see above + // Put non-default root hints into cache as authoritative. As argued below in + // putDefaultHintsIntoCache, this is actually wrong, but people might depend on it by having + // root-hints that refer to servers that aren't actually capable or willing to serve root data. + g_recCache->replace(now, name, qtype, aset, {}, {}, true, g_rootdnsname, boost::none, boost::none, state, from); } } -bool primeHints(time_t ignored) +static void parseHintFile(time_t now, const std::string& hintfile, set& seenA, set& seenAAAA, set& seenNS, std::multimap& aRecords, std::multimap& aaaaRecords, vector& nsvec) +{ + ZoneParserTNG zpt(hintfile); + zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps")); + zpt.setMaxIncludes(::arg().asNum("max-include-depth")); + DNSResourceRecord rrecord; + + while (zpt.get(rrecord)) { + rrecord.ttl += now; + switch (rrecord.qtype) { + case QType::A: + seenA.insert(rrecord.qname); + aRecords.emplace(rrecord.qname, DNSRecord(rrecord)); + break; + case QType::AAAA: + seenAAAA.insert(rrecord.qname); + aaaaRecords.emplace(rrecord.qname, DNSRecord(rrecord)); + break; + case QType::NS: + seenNS.emplace(rrecord.content); + rrecord.content = toLower(rrecord.content); + nsvec.emplace_back(rrecord); + break; + } + } +} + +static bool determineReachable(const set& names, const set& nameservers) +{ + bool reachable = false; + for (auto const& record : names) { + if (nameservers.count(record) != 0) { + reachable = true; + break; + } + } + return reachable; +} + +static bool readHintsIntoCache(time_t now, const std::string& hintfile, std::vector& nsvec) { - // prime root cache - const vState validationState = vState::Insecure; const ComboAddress from("255.255.255.255"); - vector nsvec; + set seenNS; + set seenA; + set seenAAAA; + + std::multimap aRecords; + std::multimap aaaaRecords; - time_t now = time(nullptr); + parseHintFile(now, hintfile, seenA, seenAAAA, seenNS, aRecords, aaaaRecords, nsvec); + + putIntoCache(now, QType::A, vState::Insecure, from, seenA, aRecords); + putIntoCache(now, QType::AAAA, vState::Insecure, from, seenAAAA, aaaaRecords); + + bool reachableA = determineReachable(seenA, seenNS); + bool reachableAAAA = determineReachable(seenAAAA, seenNS); auto log = g_slog->withName("config"); - const string hintfile = ::arg()["hint-file"]; - if (hintfile == "no") { - SLOG(g_log << Logger::Debug << "Priming root disabled by hint-file=no" << endl, - log->info(Logr::Debug, "Priming root disabled by hint-file=no")); - return true; + if (SyncRes::s_doIPv4 && !SyncRes::s_doIPv6 && !reachableA) { + SLOG(g_log << Logger::Error << "Running IPv4 only but no IPv4 root hints" << endl, + log->info(Logr::Error, "Running IPv4 only but no IPv4 root hints")); + return false; } - if (hintfile.empty()) { - DNSRecord arr, aaaarr, nsrr; - nsrr.d_name = g_rootdnsname; - arr.d_type = QType::A; - aaaarr.d_type = QType::AAAA; - nsrr.d_type = QType::NS; - - arr.d_ttl = aaaarr.d_ttl = nsrr.d_ttl = now + 3600000; - - for (char c = 'a'; c <= 'm'; ++c) { - char templ[40]; - strncpy(templ, "a.root-servers.net.", sizeof(templ) - 1); - templ[sizeof(templ) - 1] = '\0'; - *templ = c; - aaaarr.d_name = arr.d_name = DNSName(templ); - nsrr.setContent(std::make_shared(DNSName(templ))); - arr.setContent(std::make_shared(ComboAddress(rootIps4[c - 'a']))); - vector aset; - aset.push_back(arr); + if (!SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableAAAA) { + SLOG(g_log << Logger::Error << "Running IPv6 only but no IPv6 root hints" << endl, + log->info(Logr::Error, "Running IPv6 only but no IPv6 root hints")); + return false; + } + if (SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableA && !reachableAAAA) { + SLOG(g_log << Logger::Error << "No valid root hints" << endl, + log->info(Logr::Error, "No valid root hints")); + return false; + } + return true; +} + +static void putDefaultHintsIntoCache(time_t now, std::vector& nsvec) +{ + const ComboAddress from("255.255.255.255"); + + DNSRecord arr; + DNSRecord aaaarr; + DNSRecord nsrr; + + nsrr.d_name = g_rootdnsname; + arr.d_type = QType::A; + aaaarr.d_type = QType::AAAA; + nsrr.d_type = QType::NS; + arr.d_ttl = aaaarr.d_ttl = nsrr.d_ttl = now + 3600000; + + string templ = "a.root-servers.net."; + + static_assert(rootIps4.size() == rootIps6.size()); + + for (size_t letter = 0; letter < rootIps4.size(); ++letter) { + templ.at(0) = static_cast(letter + 'a'); + aaaarr.d_name = arr.d_name = DNSName(templ); + nsrr.setContent(std::make_shared(DNSName(templ))); + nsvec.push_back(nsrr); + + if (!rootIps4.at(letter).empty()) { + arr.setContent(std::make_shared(ComboAddress(rootIps4.at(letter)))); /* - * Originally the hint records were inserted with the auth flag set, with the consequence that data from AUTHORITY and - * ADDITIONAL sections (as seen in a . NS response) were not used. This (together with the long ttl) caused outdated - * hint to be kept in cache. So insert as non-auth, and the extra sections in the . NS refreshing cause the cached - * records to be updated with up-to-date information received from a real root server. + * Originally the hint records were inserted with the auth flag set, with the consequence that + * data from AUTHORITY and ADDITIONAL sections (as seen in a . NS response) were not used. This + * (together with the long ttl) caused outdated hint to be kept in cache. So insert as non-auth, + * and the extra sections in the . NS refreshing cause the cached records to be updated with + * up-to-date information received from a real root server. * - * Note that if a user query is done for one of the root-server.net names, it will be inserted into the cache with the - * auth bit set. Further NS refreshes will not update that entry. If all root names are queried at the same time by a user, - * all root-server.net names will be marked auth and will expire at the same time. A re-prime is then triggered, - * as before, when the records were inserted with the auth bit set and the TTD comes. + * Note that if a user query is done for one of the root-server.net names, it will be inserted + * into the cache with the auth bit set. Further NS refreshes will not update that entry. If all + * root names are queried at the same time by a user, all root-server.net names will be marked + * auth and will expire at the same time. A re-prime is then triggered, as before, when the + * records were inserted with the auth bit set and the TTD comes. */ - g_recCache->replace(now, DNSName(templ), QType(QType::A), aset, vector>(), vector>(), false, g_rootdnsname, boost::none, boost::none, validationState, from); // auth, nuke it all - if (rootIps6[c - 'a'] != NULL) { - aaaarr.setContent(std::make_shared(ComboAddress(rootIps6[c - 'a']))); - - vector aaaaset; - aaaaset.push_back(aaaarr); - g_recCache->replace(now, DNSName(templ), QType(QType::AAAA), aaaaset, vector>(), vector>(), false, g_rootdnsname, boost::none, boost::none, validationState, from); - } - - nsvec.push_back(nsrr); + g_recCache->replace(now, DNSName(templ), QType::A, {arr}, {}, {}, false, g_rootdnsname, boost::none, boost::none, vState::Insecure, from); } - } - else { - ZoneParserTNG zpt(hintfile); - zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps")); - zpt.setMaxIncludes(::arg().asNum("max-include-depth")); - DNSResourceRecord rr; - set seenNS; - set seenA; - set seenAAAA; - - std::multimap aRecords; - std::multimap aaaaRecords; - - while (zpt.get(rr)) { - rr.ttl += now; - switch (rr.qtype) { - case QType::A: - seenA.insert(rr.qname); - aRecords.insert({rr.qname, DNSRecord(rr)}); - break; - case QType::AAAA: - seenAAAA.insert(rr.qname); - aaaaRecords.insert({rr.qname, DNSRecord(rr)}); - break; - case QType::NS: - seenNS.insert(DNSName(rr.content)); - rr.content = toLower(rr.content); - nsvec.emplace_back(rr); - break; - } + if (!rootIps6.at(letter).empty()) { + aaaarr.setContent(std::make_shared(ComboAddress(rootIps6.at(letter)))); + g_recCache->replace(now, DNSName(templ), QType::AAAA, {aaaarr}, {}, {}, false, g_rootdnsname, boost::none, boost::none, vState::Insecure, from); } + } +} - putIntoCache(now, QType::A, validationState, from, seenA, aRecords); - putIntoCache(now, QType::AAAA, validationState, from, seenAAAA, aaaaRecords); +bool primeHints(time_t now) +{ + const string hintfile = ::arg()["hint-file"]; + vector nsvec; + bool ret = true; - bool reachableA = false; - for (auto const& record : seenA) { - if (seenNS.count(record) != 0) { - reachableA = true; - break; - } - } - bool reachableAAAA = false; - for (auto const& record : seenAAAA) { - if (seenNS.count(record) != 0) { - reachableAAAA = true; - break; - } - } - if (SyncRes::s_doIPv4 && !SyncRes::s_doIPv6 && !reachableA) { - SLOG(g_log << Logger::Error << "Running IPv4 only but no IPv4 root hints" << endl, - log->info(Logr::Error, "Running IPv4 only but no IPv4 root hints")); - return false; - } - if (!SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableAAAA) { - SLOG(g_log << Logger::Error << "Running IPv6 only but no IPv6 root hints" << endl, - log->info(Logr::Error, "Running IPv6 only but no IPv6 root hints")); - return false; - } - if (SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableA && !reachableAAAA) { - SLOG(g_log << Logger::Error << "No valid root hints" << endl, - log->info(Logr::Error, "No valid root hints")); - return false; - } + if (hintfile == "no") { + auto log = g_slog->withName("config"); + SLOG(g_log << Logger::Debug << "Priming root disabled by hint-file=no" << endl, + log->info(Logr::Debug, "Priming root disabled by hint-file=no")); + return ret; + } + + if (hintfile.empty()) { + putDefaultHintsIntoCache(now, nsvec); + } + else { + ret = readHintsIntoCache(now, hintfile, nsvec); } g_recCache->doWipeCache(g_rootdnsname, false, QType::NS); - g_recCache->replace(now, g_rootdnsname, QType(QType::NS), nsvec, {}, {}, false, g_rootdnsname, boost::none, boost::none, validationState, from); // and stuff in the cache - return true; + g_recCache->replace(now, g_rootdnsname, QType::NS, nsvec, {}, {}, false, g_rootdnsname, boost::none, boost::none, vState::Insecure, ComboAddress("255.255.255.255")); // and stuff in the cache + return ret; } static void convertServersForAD(const std::string& zone, const std::string& input, SyncRes::AuthDomain& ad, const char* sepa, Logr::log_t log, bool verbose = true) diff --git a/pdns/recursordist/root-addresses.hh b/pdns/recursordist/root-addresses.hh index 3455b9bcfea8..e766fd9490ad 100644 --- a/pdns/recursordist/root-addresses.hh +++ b/pdns/recursordist/root-addresses.hh @@ -21,7 +21,10 @@ */ #pragma once -static const char* const rootIps4[] = { +#include +#include + +const std::array rootIps4 = { "198.41.0.4", // a.root-servers.net. "199.9.14.201", // b.root-servers.net. "192.33.4.12", // c.root-servers.net. @@ -36,9 +39,8 @@ static const char* const rootIps4[] = { "199.7.83.42", // l.root-servers.net. "202.12.27.33" // m.root-servers.net. }; -static size_t const rootIps4Count = sizeof(rootIps4) / sizeof(*rootIps4); -static const char* const rootIps6[] = { +const std::array rootIps6 = { "2001:503:ba3e::2:30", // a.root-servers.net. "2001:500:200::b", // b.root-servers.net. "2001:500:2::c", // c.root-servers.net. @@ -53,4 +55,3 @@ static const char* const rootIps6[] = { "2001:500:9f::42", // l.root-servers.net. "2001:dc3::35" // m.root-servers.net. }; -static size_t const rootIps6Count = sizeof(rootIps6) / sizeof(*rootIps6); diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index 52b773c7658d..ae574ebe0383 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -101,7 +101,7 @@ bool primeHints(time_t now) vector aset; aset.push_back(arr); g_recCache->replace(now, DNSName(templ), QType(QType::A), aset, vector>(), vector>(), false, g_rootdnsname); - if (rootIps6[c - 'a'] != NULL) { + if (!rootIps6[c - 'a'].empty()) { aaaarr.setContent(std::make_shared(ComboAddress(rootIps6[c - 'a']))); vector aaaaset; @@ -273,14 +273,14 @@ void addRecordToLW(LWResult* res, const std::string& name, uint16_t type, const bool isRootServer(const ComboAddress& ip) { if (ip.isIPv4()) { - for (size_t idx = 0; idx < rootIps4Count; idx++) { + for (size_t idx = 0; idx < rootIps4.size(); idx++) { if (ip.toString() == rootIps4[idx]) { return true; } } } else { - for (size_t idx = 0; idx < rootIps6Count; idx++) { + for (size_t idx = 0; idx < rootIps6.size(); idx++) { if (ip.toString() == rootIps6[idx]) { return true; } From c6d824078691814f57fe1870d246668e796255a7 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 3 Apr 2023 12:18:02 +0200 Subject: [PATCH 042/909] Add test, with some reorganization as reczones is not linked into testrunner. So move a few functions to reczones-helpers.cc --- pdns/recursordist/reczones-helpers.cc | 142 ++++++++++++++++++++ pdns/recursordist/reczones-helpers.hh | 3 + pdns/recursordist/reczones.cc | 146 +-------------------- pdns/recursordist/test-reczones-helpers.cc | 44 +++++++ 4 files changed, 192 insertions(+), 143 deletions(-) diff --git a/pdns/recursordist/reczones-helpers.cc b/pdns/recursordist/reczones-helpers.cc index 41a36dc7f021..721a8d2e7db4 100644 --- a/pdns/recursordist/reczones-helpers.cc +++ b/pdns/recursordist/reczones-helpers.cc @@ -24,8 +24,150 @@ #include "config.h" #endif +#include "arguments.hh" #include "syncres.hh" #include "reczones-helpers.hh" +#include "root-addresses.hh" +#include "zoneparser-tng.hh" + +static void putIntoCache(time_t now, QType qtype, vState state, const ComboAddress& from, const set& seen, const std::multimap& allRecords) +{ + for (const auto& name : seen) { + auto records = allRecords.equal_range(name); + vector aset; + for (auto elem = records.first; elem != records.second; ++elem) { + aset.emplace_back(elem->second); + } + // Put non-default root hints into cache as authoritative. As argued below in + // putDefaultHintsIntoCache, this is actually wrong, but people might depend on it by having + // root-hints that refer to servers that aren't actually capable or willing to serve root data. + g_recCache->replace(now, name, qtype, aset, {}, {}, true, g_rootdnsname, boost::none, boost::none, state, from); + } +} + +static void parseHintFile(time_t now, const std::string& hintfile, set& seenA, set& seenAAAA, set& seenNS, std::multimap& aRecords, std::multimap& aaaaRecords, vector& nsvec) +{ + ZoneParserTNG zpt(hintfile); + zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps")); + zpt.setMaxIncludes(::arg().asNum("max-include-depth")); + DNSResourceRecord rrecord; + + while (zpt.get(rrecord)) { + rrecord.ttl += now; + switch (rrecord.qtype) { + case QType::A: + seenA.insert(rrecord.qname); + aRecords.emplace(rrecord.qname, DNSRecord(rrecord)); + break; + case QType::AAAA: + seenAAAA.insert(rrecord.qname); + aaaaRecords.emplace(rrecord.qname, DNSRecord(rrecord)); + break; + case QType::NS: + seenNS.emplace(rrecord.content); + rrecord.content = toLower(rrecord.content); + nsvec.emplace_back(rrecord); + break; + } + } +} + +static bool determineReachable(const set& names, const set& nameservers) +{ + bool reachable = false; + for (auto const& record : names) { + if (nameservers.count(record) != 0) { + reachable = true; + break; + } + } + return reachable; +} + +bool readHintsIntoCache(time_t now, const std::string& hintfile, std::vector& nsvec) +{ + const ComboAddress from("255.255.255.255"); + set seenNS; + set seenA; + set seenAAAA; + + std::multimap aRecords; + std::multimap aaaaRecords; + + parseHintFile(now, hintfile, seenA, seenAAAA, seenNS, aRecords, aaaaRecords, nsvec); + + putIntoCache(now, QType::A, vState::Insecure, from, seenA, aRecords); + putIntoCache(now, QType::AAAA, vState::Insecure, from, seenAAAA, aaaaRecords); + + bool reachableA = determineReachable(seenA, seenNS); + bool reachableAAAA = determineReachable(seenAAAA, seenNS); + + auto log = g_slog->withName("config"); + if (SyncRes::s_doIPv4 && !SyncRes::s_doIPv6 && !reachableA) { + SLOG(g_log << Logger::Error << "Running IPv4 only but no IPv4 root hints" << endl, + log->info(Logr::Error, "Running IPv4 only but no IPv4 root hints")); + return false; + } + if (!SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableAAAA) { + SLOG(g_log << Logger::Error << "Running IPv6 only but no IPv6 root hints" << endl, + log->info(Logr::Error, "Running IPv6 only but no IPv6 root hints")); + return false; + } + if (SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableA && !reachableAAAA) { + SLOG(g_log << Logger::Error << "No valid root hints" << endl, + log->info(Logr::Error, "No valid root hints")); + return false; + } + return true; +} + +void putDefaultHintsIntoCache(time_t now, std::vector& nsvec) +{ + const ComboAddress from("255.255.255.255"); + + DNSRecord arr; + DNSRecord aaaarr; + DNSRecord nsrr; + + nsrr.d_name = g_rootdnsname; + arr.d_type = QType::A; + aaaarr.d_type = QType::AAAA; + nsrr.d_type = QType::NS; + arr.d_ttl = aaaarr.d_ttl = nsrr.d_ttl = now + 3600000; + + string templ = "a.root-servers.net."; + + static_assert(rootIps4.size() == rootIps6.size()); + + for (size_t letter = 0; letter < rootIps4.size(); ++letter) { + templ.at(0) = static_cast(letter + 'a'); + aaaarr.d_name = arr.d_name = DNSName(templ); + nsrr.setContent(std::make_shared(DNSName(templ))); + nsvec.push_back(nsrr); + + if (!rootIps4.at(letter).empty()) { + arr.setContent(std::make_shared(ComboAddress(rootIps4.at(letter)))); + /* + * Originally the hint records were inserted with the auth flag set, with the consequence that + * data from AUTHORITY and ADDITIONAL sections (as seen in a . NS response) were not used. This + * (together with the long ttl) caused outdated hint to be kept in cache. So insert as non-auth, + * and the extra sections in the . NS refreshing cause the cached records to be updated with + * up-to-date information received from a real root server. + * + * Note that if a user query is done for one of the root-server.net names, it will be inserted + * into the cache with the auth bit set. Further NS refreshes will not update that entry. If all + * root names are queried at the same time by a user, all root-server.net names will be marked + * auth and will expire at the same time. A re-prime is then triggered, as before, when the + * records were inserted with the auth bit set and the TTD comes. + */ + g_recCache->replace(now, DNSName(templ), QType::A, {arr}, {}, {}, false, g_rootdnsname, boost::none, boost::none, vState::Insecure, from); + } + if (!rootIps6.at(letter).empty()) { + aaaarr.setContent(std::make_shared(ComboAddress(rootIps6.at(letter)))); + g_recCache->replace(now, DNSName(templ), QType::AAAA, {aaaarr}, {}, {}, false, g_rootdnsname, boost::none, boost::none, vState::Insecure, from); + } + } +} template static SyncRes::AuthDomain makeSOAAndNSNodes(DNSRecord& dr, T content) diff --git a/pdns/recursordist/reczones-helpers.hh b/pdns/recursordist/reczones-helpers.hh index e68fed2ec08a..dafeee4daf9f 100644 --- a/pdns/recursordist/reczones-helpers.hh +++ b/pdns/recursordist/reczones-helpers.hh @@ -32,6 +32,9 @@ #include "syncres.hh" #include "logger.hh" +bool readHintsIntoCache(time_t now, const std::string& hintfile, std::vector& nsvec); +void putDefaultHintsIntoCache(time_t now, std::vector& nsvec); + void makeIPToNamesZone(const std::shared_ptr& newMap, const vector& parts, Logr::log_t log); diff --git a/pdns/recursordist/reczones.cc b/pdns/recursordist/reczones.cc index 81e6774bd9d0..ba658b19c2be 100644 --- a/pdns/recursordist/reczones.cc +++ b/pdns/recursordist/reczones.cc @@ -25,155 +25,15 @@ #endif #include "reczones-helpers.hh" -#include "syncres.hh" #include "arguments.hh" -#include "zoneparser-tng.hh" -#include "logger.hh" #include "dnsrecords.hh" -#include "root-addresses.hh" +#include "logger.hh" +#include "syncres.hh" +#include "zoneparser-tng.hh" extern int g_argc; extern char** g_argv; -static void putIntoCache(time_t now, QType qtype, vState state, const ComboAddress& from, const set& seen, const std::multimap& allRecords) -{ - for (const auto& name : seen) { - auto records = allRecords.equal_range(name); - vector aset; - for (auto elem = records.first; elem != records.second; ++elem) { - aset.emplace_back(elem->second); - } - // Put non-default root hints into cache as authoritative. As argued below in - // putDefaultHintsIntoCache, this is actually wrong, but people might depend on it by having - // root-hints that refer to servers that aren't actually capable or willing to serve root data. - g_recCache->replace(now, name, qtype, aset, {}, {}, true, g_rootdnsname, boost::none, boost::none, state, from); - } -} - -static void parseHintFile(time_t now, const std::string& hintfile, set& seenA, set& seenAAAA, set& seenNS, std::multimap& aRecords, std::multimap& aaaaRecords, vector& nsvec) -{ - ZoneParserTNG zpt(hintfile); - zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps")); - zpt.setMaxIncludes(::arg().asNum("max-include-depth")); - DNSResourceRecord rrecord; - - while (zpt.get(rrecord)) { - rrecord.ttl += now; - switch (rrecord.qtype) { - case QType::A: - seenA.insert(rrecord.qname); - aRecords.emplace(rrecord.qname, DNSRecord(rrecord)); - break; - case QType::AAAA: - seenAAAA.insert(rrecord.qname); - aaaaRecords.emplace(rrecord.qname, DNSRecord(rrecord)); - break; - case QType::NS: - seenNS.emplace(rrecord.content); - rrecord.content = toLower(rrecord.content); - nsvec.emplace_back(rrecord); - break; - } - } -} - -static bool determineReachable(const set& names, const set& nameservers) -{ - bool reachable = false; - for (auto const& record : names) { - if (nameservers.count(record) != 0) { - reachable = true; - break; - } - } - return reachable; -} - -static bool readHintsIntoCache(time_t now, const std::string& hintfile, std::vector& nsvec) -{ - const ComboAddress from("255.255.255.255"); - set seenNS; - set seenA; - set seenAAAA; - - std::multimap aRecords; - std::multimap aaaaRecords; - - parseHintFile(now, hintfile, seenA, seenAAAA, seenNS, aRecords, aaaaRecords, nsvec); - - putIntoCache(now, QType::A, vState::Insecure, from, seenA, aRecords); - putIntoCache(now, QType::AAAA, vState::Insecure, from, seenAAAA, aaaaRecords); - - bool reachableA = determineReachable(seenA, seenNS); - bool reachableAAAA = determineReachable(seenAAAA, seenNS); - - auto log = g_slog->withName("config"); - if (SyncRes::s_doIPv4 && !SyncRes::s_doIPv6 && !reachableA) { - SLOG(g_log << Logger::Error << "Running IPv4 only but no IPv4 root hints" << endl, - log->info(Logr::Error, "Running IPv4 only but no IPv4 root hints")); - return false; - } - if (!SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableAAAA) { - SLOG(g_log << Logger::Error << "Running IPv6 only but no IPv6 root hints" << endl, - log->info(Logr::Error, "Running IPv6 only but no IPv6 root hints")); - return false; - } - if (SyncRes::s_doIPv4 && SyncRes::s_doIPv6 && !reachableA && !reachableAAAA) { - SLOG(g_log << Logger::Error << "No valid root hints" << endl, - log->info(Logr::Error, "No valid root hints")); - return false; - } - return true; -} - -static void putDefaultHintsIntoCache(time_t now, std::vector& nsvec) -{ - const ComboAddress from("255.255.255.255"); - - DNSRecord arr; - DNSRecord aaaarr; - DNSRecord nsrr; - - nsrr.d_name = g_rootdnsname; - arr.d_type = QType::A; - aaaarr.d_type = QType::AAAA; - nsrr.d_type = QType::NS; - arr.d_ttl = aaaarr.d_ttl = nsrr.d_ttl = now + 3600000; - - string templ = "a.root-servers.net."; - - static_assert(rootIps4.size() == rootIps6.size()); - - for (size_t letter = 0; letter < rootIps4.size(); ++letter) { - templ.at(0) = static_cast(letter + 'a'); - aaaarr.d_name = arr.d_name = DNSName(templ); - nsrr.setContent(std::make_shared(DNSName(templ))); - nsvec.push_back(nsrr); - - if (!rootIps4.at(letter).empty()) { - arr.setContent(std::make_shared(ComboAddress(rootIps4.at(letter)))); - /* - * Originally the hint records were inserted with the auth flag set, with the consequence that - * data from AUTHORITY and ADDITIONAL sections (as seen in a . NS response) were not used. This - * (together with the long ttl) caused outdated hint to be kept in cache. So insert as non-auth, - * and the extra sections in the . NS refreshing cause the cached records to be updated with - * up-to-date information received from a real root server. - * - * Note that if a user query is done for one of the root-server.net names, it will be inserted - * into the cache with the auth bit set. Further NS refreshes will not update that entry. If all - * root names are queried at the same time by a user, all root-server.net names will be marked - * auth and will expire at the same time. A re-prime is then triggered, as before, when the - * records were inserted with the auth bit set and the TTD comes. - */ - g_recCache->replace(now, DNSName(templ), QType::A, {arr}, {}, {}, false, g_rootdnsname, boost::none, boost::none, vState::Insecure, from); - } - if (!rootIps6.at(letter).empty()) { - aaaarr.setContent(std::make_shared(ComboAddress(rootIps6.at(letter)))); - g_recCache->replace(now, DNSName(templ), QType::AAAA, {aaaarr}, {}, {}, false, g_rootdnsname, boost::none, boost::none, vState::Insecure, from); - } - } -} - bool primeHints(time_t now) { const string hintfile = ::arg()["hint-file"]; diff --git a/pdns/recursordist/test-reczones-helpers.cc b/pdns/recursordist/test-reczones-helpers.cc index 4a7aa30e78d0..921c7d1f11c4 100644 --- a/pdns/recursordist/test-reczones-helpers.cc +++ b/pdns/recursordist/test-reczones-helpers.cc @@ -258,4 +258,48 @@ BOOST_FIXTURE_TEST_CASE(test_loading_etc_hosts, Fixture) BOOST_TEST_MESSAGE("-----------------------------------------------------"); } +const std::string hints = ". 3600 IN NS ns.\n" + ". 3600 IN NS ns1.\n" + "ns. 3600 IN A 192.168.178.16\n" + "ns. 3600 IN A 192.168.178.17\n" + "ns. 3600 IN A 192.168.178.18\n" + "ns. 3600 IN AAAA 1::2\n" + "ns. 3600 IN AAAA 1::3\n" + "ns1. 3600 IN A 192.168.178.18\n"; + +BOOST_AUTO_TEST_CASE(test_UserHints) +{ + + g_recCache = make_unique(); + + ::arg().set("max-generate-steps") = "0"; + ::arg().set("max-include-depth") = "0"; + char temp[] = "/tmp/hintsXXXXXXXXXX"; + int fd = mkstemp(temp); + BOOST_REQUIRE(fd > 0); + FILE* fp = fdopen(fd, "w"); + BOOST_REQUIRE(fp != nullptr); + size_t written = fwrite(hints.data(), 1, hints.length(), fp); + BOOST_REQUIRE(written == hints.length()); + BOOST_REQUIRE(fclose(fp) == 0); + + time_t now = time(nullptr); + std::vector nsvec; + + auto ok = readHintsIntoCache(now, std::string(temp), nsvec); + BOOST_CHECK(ok); + BOOST_CHECK_EQUAL(nsvec.size(), 2U); + + const MemRecursorCache::Flags flags = 0; + + BOOST_CHECK(g_recCache->get(now, DNSName("ns"), QType::A, flags, &nsvec, ComboAddress()) > 0); + BOOST_CHECK_EQUAL(nsvec.size(), 3U); + + BOOST_CHECK(g_recCache->get(now, DNSName("ns"), QType::AAAA, flags, &nsvec, ComboAddress()) > 0); + BOOST_CHECK_EQUAL(nsvec.size(), 2U); + + BOOST_CHECK(g_recCache->get(now, DNSName("ns1"), QType::A, flags, &nsvec, ComboAddress()) > 0); + BOOST_CHECK_EQUAL(nsvec.size(), 1U); +} + BOOST_AUTO_TEST_SUITE_END() From 25b22b8d2ca15992e8be0c013f190d9cd02ad91c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 22 Feb 2023 14:53:08 +0100 Subject: [PATCH 043/909] Cleanup --- pdns/recursordist/recpacketcache.cc | 69 ++++++++++++----------------- pdns/recursordist/recpacketcache.hh | 66 ++++++++++++++++----------- 2 files changed, 68 insertions(+), 67 deletions(-) diff --git a/pdns/recursordist/recpacketcache.cc b/pdns/recursordist/recpacketcache.cc index 8756aecbfcb2..205faf50b7f0 100644 --- a/pdns/recursordist/recpacketcache.cc +++ b/pdns/recursordist/recpacketcache.cc @@ -23,16 +23,18 @@ int RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qtype, } } else { - if (iter->d_name != name) + if (iter->d_name != name) { break; + } } if (qtype == 0xffff || iter->d_type == qtype) { iter = idx.erase(iter); count++; } - else + else { ++iter; + } } return count; } @@ -59,7 +61,7 @@ bool RecursorPacketCache::checkResponseMatches(std::paird_ttd) { // it is right, it is fresh! *age = static_cast(now - iter->d_creation); // we know ttl is > 0 - uint32_t ttl = static_cast(iter->d_ttd - now); + auto ttl = static_cast(iter->d_ttd - now); if (s_refresh_ttlperc > 0 && !iter->d_submitted) { const uint32_t deadline = iter->getOrigTTL() * s_refresh_ttlperc / 100; const bool almostExpired = ttl <= deadline; @@ -91,33 +93,15 @@ bool RecursorPacketCache::checkResponseMatches(std::pair s_skipOptions = {EDNSOptionCode::ECS, EDNSOptionCode::COOKIE}; bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, @@ -147,7 +131,7 @@ bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& return false; } - qname = DNSName(queryPacket.c_str(), queryPacket.length(), sizeof(dnsheader), false, qtype, qclass, 0); + qname = DNSName(queryPacket.c_str(), static_cast(queryPacket.length()), sizeof(dnsheader), false, qtype, qclass); return checkResponseMatches(range, queryPacket, qname, *qtype, *qclass, now, responsePacket, age, valState, pbdata); } @@ -177,12 +161,12 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, return; } - struct Entry e(qname, qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState); + struct Entry entry(qname, qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState); if (pbdata) { - e.d_pbdata = std::move(*pbdata); + entry.d_pbdata = std::move(*pbdata); } - d_packetCache.insert(e); + d_packetCache.insert(entry); if (d_packetCache.size() > d_maxSize) { auto& seq_idx = d_packetCache.get(); @@ -193,37 +177,42 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, uint64_t RecursorPacketCache::bytes() const { uint64_t sum = 0; - for (const auto& e : d_packetCache) { - sum += sizeof(e) + e.d_packet.length() + 4; + for (const auto& entry : d_packetCache) { + sum += sizeof(entry) + entry.d_packet.length() + 4; } return sum; } -void RecursorPacketCache::doPruneTo(size_t maxCached) +void RecursorPacketCache::doPruneTo(size_t maxSize) { - pruneCollection(d_packetCache, maxCached); + pruneCollection(d_packetCache, maxSize); } -uint64_t RecursorPacketCache::doDump(int fd) +uint64_t RecursorPacketCache::doDump(int file) { - auto fp = std::unique_ptr(fdopen(dup(fd), "w"), fclose); - if (!fp) { // dup probably failed + int fdupped = dup(file); + if (fdupped == -1) { + return 0; + } + auto filePtr = std::unique_ptr(fdopen(fdupped, "w"), fclose); + if (!filePtr) { + close(fdupped); return 0; } - fprintf(fp.get(), "; main packet cache dump from thread follows\n;\n"); + fprintf(filePtr.get(), "; main packet cache dump from thread follows\n;\n"); const auto& sidx = d_packetCache.get(); uint64_t count = 0; time_t now = time(nullptr); - for (const auto& i : sidx) { + for (const auto& entry : sidx) { count++; try { - fprintf(fp.get(), "%s %" PRId64 " %s ; tag %d %s\n", i.d_name.toString().c_str(), static_cast(i.d_ttd - now), DNSRecordContent::NumberToType(i.d_type).c_str(), i.d_tag, i.d_tcp ? "tcp" : "udp"); + fprintf(filePtr.get(), "%s %" PRId64 " %s ; tag %d %s\n", entry.d_name.toString().c_str(), static_cast(entry.d_ttd - now), DNSRecordContent::NumberToType(entry.d_type).c_str(), entry.d_tag, entry.d_tcp ? "tcp" : "udp"); } catch (...) { - fprintf(fp.get(), "; error printing '%s'\n", i.d_name.empty() ? "EMPTY" : i.d_name.toString().c_str()); + fprintf(filePtr.get(), "; error printing '%s'\n", entry.d_name.empty() ? "EMPTY" : entry.d_name.toString().c_str()); } } return count; diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index 45ba4298ee92..b0a344db9833 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -43,8 +43,8 @@ using namespace ::boost::multi_index; //! Stores whole packets, ready for lobbing back at the client. Not threadsafe. /* Note: we store answers as value AND KEY, and with careful work, we make sure that - you can use a query as a key too. But query and answer must compare as identical! - + you can use a query as a key too. But query and answer must compare as identical! + This precludes doing anything smart with EDNS directly from the packet */ class RecursorPacketCache : public PacketCache { @@ -57,44 +57,53 @@ public: std::string d_response; bool d_tagged; }; - typedef boost::optional OptPBData; + using OptPBData = boost::optional; RecursorPacketCache(size_t maxsize) : d_maxSize(maxsize) { } - bool getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now, std::string* responsePacket, uint32_t* age, uint32_t* qhash); - bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, uint32_t* qhash); + bool getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now, + std::string* responsePacket, uint32_t* age, uint32_t* qhash) + { + DNSName qname; + uint16_t qtype{0}; + uint16_t qclass{0}; + vState valState{vState::Indeterminate}; + return getResponsePacket(tag, queryPacket, qname, &qtype, &qclass, now, responsePacket, age, &valState, qhash, nullptr, false); + } + + bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, + std::string* responsePacket, uint32_t* age, uint32_t* qhash) + { + vState valState{vState::Indeterminate}; + return getResponsePacket(tag, queryPacket, qname, qtype, qclass, now, responsePacket, age, &valState, qhash, nullptr, false); + } + bool getResponsePacket(unsigned int tag, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp); bool getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp); void insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, OptPBData&& pbdata, bool tcp); void doPruneTo(size_t maxSize = 250000); - uint64_t doDump(int fd); + uint64_t doDump(int file); int doWipePacketCache(const DNSName& name, uint16_t qtype = 0xffff, bool subtree = false); - void setMaxSize(size_t sz) + void setMaxSize(size_t size) { - d_maxSize = sz; + d_maxSize = size; } - uint64_t size() const + [[nodiscard]] uint64_t size() const { return d_packetCache.size(); } - uint64_t bytes() const; + [[nodiscard]] uint64_t bytes() const; uint64_t d_hits{0}; uint64_t d_misses{0}; private: - struct HashTag - { - }; - struct NameTag - { - }; struct Entry { Entry(const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& packet, std::string&& query, bool tcp, @@ -129,20 +138,23 @@ private: } }; + struct HashTag + { + }; + struct NameTag + { + }; struct SequencedTag { }; - typedef multi_index_container< - Entry, - indexed_by< - hashed_non_unique, - composite_key, - member, - member>>, - sequenced>, - ordered_non_unique, member, CanonDNSNameCompare>>> - packetCache_t; + using packetCache_t = multi_index_container, + composite_key, + member, + member>>, + sequenced>, + ordered_non_unique, member, CanonDNSNameCompare>>>; packetCache_t d_packetCache; size_t d_maxSize; From 7d926c9f9e6ae2ebb8559dbbed8133470c94d879 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 22 Feb 2023 16:03:41 +0100 Subject: [PATCH 044/909] Make packet cache sharded Unit test run fine, but recursor itself has not been adapted yet --- pdns/recursordist/recpacketcache.cc | 111 +++++++++++++++++----------- pdns/recursordist/recpacketcache.hh | 79 +++++++++++++++++--- 2 files changed, 136 insertions(+), 54 deletions(-) diff --git a/pdns/recursordist/recpacketcache.cc b/pdns/recursordist/recpacketcache.cc index 205faf50b7f0..054efc971462 100644 --- a/pdns/recursordist/recpacketcache.cc +++ b/pdns/recursordist/recpacketcache.cc @@ -12,28 +12,31 @@ unsigned int RecursorPacketCache::s_refresh_ttlperc{0}; -int RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qtype, bool subtree) +uint64_t RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qtype, bool subtree) { - int count = 0; - auto& idx = d_packetCache.get(); - for (auto iter = idx.lower_bound(name); iter != idx.end();) { - if (subtree) { - if (!iter->d_name.isPartOf(name)) { // this is case insensitive - break; + uint64_t count = 0; + for (auto& map : d_maps) { + auto shard = map.lock(); + auto& idx = shard->d_map.get(); + for (auto iter = idx.lower_bound(name); iter != idx.end();) { + if (subtree) { + if (!iter->d_name.isPartOf(name)) { // this is case insensitive + break; + } } - } - else { - if (iter->d_name != name) { - break; + else { + if (iter->d_name != name) { + break; + } + } + if (qtype == 0xffff || iter->d_type == qtype) { + iter = idx.erase(iter); + map.d_entriesCount--; + count++; + } + else { + ++iter; } - } - - if (qtype == 0xffff || iter->d_type == qtype) { - iter = idx.erase(iter); - count++; - } - else { - ++iter; } } return count; @@ -50,7 +53,7 @@ bool RecursorPacketCache::qrMatch(const packetCache_t::index::type::ite return queryMatches(iter->d_query, queryPacket, qname, optionsToSkip); } -bool RecursorPacketCache::checkResponseMatches(std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata) +bool RecursorPacketCache::checkResponseMatches(packetCache_t& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata) { for (auto iter = range.first; iter != range.second; ++iter) { // the possibility is VERY real that we get hits that are not right - birthday paradox @@ -80,7 +83,7 @@ bool RecursorPacketCache::checkResponseMatches(std::pair(d_packetCache, iter); + moveCacheItemToBack(shard, iter); if (pbdata != nullptr) { if (iter->d_pbdata) { @@ -108,7 +111,8 @@ bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp) { *qhash = canHashPacket(queryPacket, s_skipOptions); - const auto& idx = d_packetCache.get(); + auto shard = getMap(tag, *qhash, tcp).lock(); + const auto& idx = shard->d_map.get(); auto range = idx.equal_range(std::tie(tag, *qhash, tcp)); if (range.first == range.second) { @@ -116,14 +120,15 @@ bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& return false; } - return checkResponseMatches(range, queryPacket, qname, qtype, qclass, now, responsePacket, age, valState, pbdata); + return checkResponseMatches(shard->d_map, range, queryPacket, qname, qtype, qclass, now, responsePacket, age, valState, pbdata); } bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp) { *qhash = canHashPacket(queryPacket, s_skipOptions); - const auto& idx = d_packetCache.get(); + auto shard = getMap(tag, *qhash, tcp).lock(); + const auto& idx = shard->d_map.get(); auto range = idx.equal_range(std::tie(tag, *qhash, tcp)); if (range.first == range.second) { @@ -133,12 +138,14 @@ bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& qname = DNSName(queryPacket.c_str(), static_cast(queryPacket.length()), sizeof(dnsheader), false, qtype, qclass); - return checkResponseMatches(range, queryPacket, qname, *qtype, *qclass, now, responsePacket, age, valState, pbdata); + return checkResponseMatches(shard->d_map, range, queryPacket, qname, *qtype, *qclass, now, responsePacket, age, valState, pbdata); } void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, OptPBData&& pbdata, bool tcp) { - auto& idx = d_packetCache.get(); + auto& map = getMap(tag, qhash, tcp); + auto shard = map.lock(); + auto& idx = shard->d_map.get(); auto range = idx.equal_range(std::tie(tag, qhash, tcp)); auto iter = range.first; @@ -147,7 +154,7 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, continue; } - moveCacheItemToBack(d_packetCache, iter); + moveCacheItemToBack(shard->d_map, iter); iter->d_packet = std::move(responsePacket); iter->d_query = std::move(query); iter->d_ttd = now + ttl; @@ -166,26 +173,33 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, entry.d_pbdata = std::move(*pbdata); } - d_packetCache.insert(entry); + shard->d_map.insert(entry); + map.d_entriesCount++; - if (d_packetCache.size() > d_maxSize) { - auto& seq_idx = d_packetCache.get(); + if (shard->d_map.size() > d_maxSize / d_maps.size()) { + auto& seq_idx = shard->d_map.get(); seq_idx.erase(seq_idx.begin()); + map.d_entriesCount--; } + assert(map.d_entriesCount == shard->d_map.size()); // XXX } -uint64_t RecursorPacketCache::bytes() const +uint64_t RecursorPacketCache::bytes() { uint64_t sum = 0; - for (const auto& entry : d_packetCache) { - sum += sizeof(entry) + entry.d_packet.length() + 4; + for (auto& shard : d_maps) { + auto lock = shard.lock(); + for (const auto& entry : lock->d_map) { + sum += sizeof(entry) + entry.d_packet.length() + 4; + } } return sum; } void RecursorPacketCache::doPruneTo(size_t maxSize) { - pruneCollection(d_packetCache, maxSize); + size_t cacheSize = size(); + pruneMutexCollectionsVector(*this, d_maps, maxSize, cacheSize); } uint64_t RecursorPacketCache::doDump(int file) @@ -200,20 +214,31 @@ uint64_t RecursorPacketCache::doDump(int file) return 0; } - fprintf(filePtr.get(), "; main packet cache dump from thread follows\n;\n"); - - const auto& sidx = d_packetCache.get(); uint64_t count = 0; time_t now = time(nullptr); + size_t shardNum = 0; + size_t min = std::numeric_limits::max(); + size_t max = 0; + + for (auto& shard : d_maps) { + auto lock = shard.lock(); + const auto& sidx = lock->d_map.get(); + const auto shardSize = lock->d_map.size(); + fprintf(filePtr.get(), "; packetcache shard %zu; size %zu\n", shardNum, shardSize); + min = std::min(min, shardSize); + max = std::max(max, shardSize); + shardNum++; for (const auto& entry : sidx) { - count++; - try { - fprintf(filePtr.get(), "%s %" PRId64 " %s ; tag %d %s\n", entry.d_name.toString().c_str(), static_cast(entry.d_ttd - now), DNSRecordContent::NumberToType(entry.d_type).c_str(), entry.d_tag, entry.d_tcp ? "tcp" : "udp"); - } - catch (...) { - fprintf(filePtr.get(), "; error printing '%s'\n", entry.d_name.empty() ? "EMPTY" : entry.d_name.toString().c_str()); + count++; + try { + fprintf(filePtr.get(), "%s %" PRId64 " %s ; tag %d %s\n", entry.d_name.toString().c_str(), static_cast(entry.d_ttd - now), DNSRecordContent::NumberToType(entry.d_type).c_str(), entry.d_tag, entry.d_tcp ? "tcp" : "udp"); + } + catch (...) { + fprintf(filePtr.get(), "; error printing '%s'\n", entry.d_name.empty() ? "EMPTY" : entry.d_name.toString().c_str()); + } } } + fprintf(filePtr.get(), "; packetcache size: %" PRIu64 "/%zu shards: %zu min/max shard size: %zu/%zu\n", size(), d_maxSize, d_maps.size(), min, max); return count; } diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index b0a344db9833..72f58d526ac6 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -34,6 +34,8 @@ #include "packetcache.hh" #include "validate.hh" +#include "lock.hh" +#include "stat_t.hh" #ifdef HAVE_CONFIG_H #include "config.h" @@ -41,11 +43,6 @@ using namespace ::boost::multi_index; -//! Stores whole packets, ready for lobbing back at the client. Not threadsafe. -/* Note: we store answers as value AND KEY, and with careful work, we make sure that - you can use a query as a key too. But query and answer must compare as identical! - - This precludes doing anything smart with EDNS directly from the packet */ class RecursorPacketCache : public PacketCache { public: @@ -59,9 +56,13 @@ public: }; using OptPBData = boost::optional; - RecursorPacketCache(size_t maxsize) : + RecursorPacketCache(size_t maxsize, size_t shards = 1024) : + d_maps(shards), d_maxSize(maxsize) { + if (d_maxSize / d_maps.size() == 0) { + d_maxSize = d_maps.size(); + } } bool getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now, @@ -87,7 +88,7 @@ public: void insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, OptPBData&& pbdata, bool tcp); void doPruneTo(size_t maxSize = 250000); uint64_t doDump(int file); - int doWipePacketCache(const DNSName& name, uint16_t qtype = 0xffff, bool subtree = false); + uint64_t doWipePacketCache(const DNSName& name, uint16_t qtype = 0xffff, bool subtree = false); void setMaxSize(size_t size) { @@ -96,9 +97,13 @@ public: [[nodiscard]] uint64_t size() const { - return d_packetCache.size(); + uint64_t count = 0; + for (const auto& map : d_maps) { + count += map.d_entriesCount; + } + return count; } - [[nodiscard]] uint64_t bytes() const; + [[nodiscard]] uint64_t bytes(); uint64_t d_hits{0}; uint64_t d_misses{0}; @@ -156,9 +161,61 @@ private: sequenced>, ordered_non_unique, member, CanonDNSNameCompare>>>; - packetCache_t d_packetCache; + struct MapCombo + { + MapCombo() {} + MapCombo(const MapCombo&) = delete; + MapCombo& operator=(const MapCombo&) = delete; + struct LockedContent + { + packetCache_t d_map; + uint64_t d_contended_count{0}; + uint64_t d_acquired_count{0}; + void invalidate() {} + }; + pdns::stat_t d_entriesCount{0}; + + LockGuardedTryHolder lock() + { + auto locked = d_content.try_lock(); + if (!locked.owns_lock()) { + locked.lock(); + ++locked->d_contended_count; + } + ++locked->d_acquired_count; + return locked; + } + + private: + LockGuarded d_content; + }; + + vector d_maps; + + size_t combine(unsigned int tag, uint32_t hash, bool tcp) const + { + size_t ret = 0; + boost::hash_combine(ret, tag); + boost::hash_combine(ret, hash); + boost::hash_combine(ret, tcp); + return ret; + } + + MapCombo& getMap(unsigned int tag, uint32_t hash, bool tcp) + { + return d_maps.at(combine(tag, hash, tcp) % d_maps.size()); + } + // const MapCombo& getMap(unsigned int tag, uint32_t hash, bool tcp) const + // { + // return d_maps.at(combine(hash, hash, tcp) % d_maps.size()); + // } + size_t d_maxSize; static bool qrMatch(const packetCache_t::index::type::iterator& iter, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass); - bool checkResponseMatches(std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); + bool checkResponseMatches(packetCache_t& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); +public: + void preRemoval(MapCombo::LockedContent& map, const Entry& entry) + { + } }; From 39e4242426d5ebffe4b3556eadfdf0b2a9fae7fa Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 22 Feb 2023 16:30:48 +0100 Subject: [PATCH 045/909] Initial integration with recursor --- pdns/recursordist/pdns_recursor.cc | 12 ++--- pdns/recursordist/rec-main.cc | 37 ++++++-------- pdns/recursordist/rec-main.hh | 2 +- pdns/recursordist/rec-tcounters.hh | 2 + pdns/recursordist/rec_channel_rec.cc | 56 +++------------------ pdns/recursordist/recpacketcache.cc | 75 ++++++++++++++++++++-------- pdns/recursordist/recpacketcache.hh | 18 +++---- pdns/recursordist/syncres.hh | 2 - 8 files changed, 90 insertions(+), 114 deletions(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 69c70f5d7ed4..071c09d20117 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -49,8 +49,8 @@ thread_local ProtobufServersInfo t_outgoingProtobufServers; thread_local std::unique_ptr MT; // the big MTasker std::unique_ptr g_recCache; std::unique_ptr g_negCache; +std::unique_ptr g_packetCache; -thread_local std::unique_ptr t_packetCache; thread_local std::unique_ptr t_fdm; thread_local std::unique_ptr t_remotes, t_servfailremotes, t_largeanswerremotes, t_bogusremotes; thread_local std::unique_ptr>> t_queryring, t_servfailqueryring, t_bogusqueryring; @@ -1673,9 +1673,9 @@ void startDoResolve(void* p) #endif } - if (t_packetCache && !variableAnswer && !sr.wasVariable()) { + if (g_packetCache && !variableAnswer && !sr.wasVariable()) { minTTL = capPacketCacheTTL(*pw.getHeader(), minTTL, seenAuthSOA); - t_packetCache->insertResponsePacket(dc->d_tag, dc->d_qhash, std::move(dc->d_query), dc->d_mdp.d_qname, + g_packetCache->insertResponsePacket(dc->d_tag, dc->d_qhash, std::move(dc->d_query), dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass, string((const char*)&*packet.begin(), packet.size()), g_now.tv_sec, @@ -1957,7 +1957,7 @@ bool checkForCacheHit(bool qnameParsed, unsigned int tag, const string& data, string& response, uint32_t& qhash, RecursorPacketCache::OptPBData& pbData, bool tcp, const ComboAddress& source, const ComboAddress& mappedSource) { - if (!t_packetCache) { + if (!g_packetCache) { return false; } bool cacheHit = false; @@ -1965,10 +1965,10 @@ bool checkForCacheHit(bool qnameParsed, unsigned int tag, const string& data, vState valState; if (qnameParsed) { - cacheHit = t_packetCache->getResponsePacket(tag, data, qname, qtype, qclass, now.tv_sec, &response, &age, &valState, &qhash, &pbData, tcp); + cacheHit = g_packetCache->getResponsePacket(tag, data, qname, qtype, qclass, now.tv_sec, &response, &age, &valState, &qhash, &pbData, tcp); } else { - cacheHit = t_packetCache->getResponsePacket(tag, data, qname, &qtype, &qclass, now.tv_sec, &response, &age, &valState, &qhash, &pbData, tcp); + cacheHit = g_packetCache->getResponsePacket(tag, data, qname, &qtype, &qclass, now.tv_sec, &response, &age, &valState, &qhash, &pbData, tcp); } if (cacheHit) { diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 6b84332ba2b0..4720cca1b3f8 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -992,8 +992,8 @@ static void doStats(void) auto taskPushes = getTaskPushes(); auto taskExpired = getTaskExpired(); auto taskSize = getTaskSize(); - uint64_t pcSize = broadcastAccFunction(pleaseGetPacketCacheSize); - uint64_t pcHits = broadcastAccFunction(pleaseGetPacketCacheHits); + uint64_t pcSize = g_packetCache ? g_packetCache->size() : 0; + uint64_t pcHits = g_packetCache ? g_packetCache->getHits() : 0; auto log = g_slog->withName("stats"); @@ -2139,14 +2139,6 @@ static void houseKeeping(void*) t_Counters.updateSnap(now, g_regressionTestMode); // Below are the tasks that run for every recursorThread, including handler and taskThread - if (t_packetCache) { - static thread_local PeriodicTask packetCacheTask{"packetCacheTask", 5}; - packetCacheTask.runIfDue(now, []() { - size_t sz = g_maxPacketCacheEntries / (RecThreadInfo::numWorkers() + RecThreadInfo::numDistributors()); - t_packetCache->setMaxSize(sz); // g_maxPacketCacheEntries might have changed by rec_control - t_packetCache->doPruneTo(sz); - }); - } static thread_local PeriodicTask pruneTCPTask{"pruneTCPTask", 5}; pruneTCPTask.runIfDue(now, [now]() { @@ -2184,6 +2176,13 @@ static void houseKeeping(void*) }); } else if (info.isHandler()) { + if (g_packetCache) { + static PeriodicTask packetCacheTask{"packetCacheTask", 5}; + packetCacheTask.runIfDue(now, []() { + g_packetCache->setMaxSize(g_maxPacketCacheEntries); // g_maxPacketCacheEntries might have changed by rec_control + g_packetCache->doPruneTo(g_maxPacketCacheEntries); + }); + } static PeriodicTask recordCachePruneTask{"RecordCachePruneTask", 5}; recordCachePruneTask.runIfDue(now, []() { g_recCache->doPrune(g_maxCacheEntries); @@ -2362,11 +2361,6 @@ static void recursorThread() } } - if (!::arg().mustDo("disable-packetcache") && (threadInfo.isDistributor() || threadInfo.isWorker())) { - // Only enable packet cache for thread processing queries from the outside world - t_packetCache = std::make_unique(g_maxPacketCacheEntries / (RecThreadInfo::numWorkers() + RecThreadInfo::numDistributors())); - } - #ifdef NOD_ENABLED if (threadInfo.isWorker()) setupNODThread(log); @@ -3035,6 +3029,10 @@ int main(int argc, char** argv) g_recCache = std::make_unique(::arg().asNum("record-cache-shards")); g_negCache = std::make_unique(::arg().asNum("record-cache-shards") / 8); + if (!::arg().mustDo("disable-packetcache")) { + // Only enable packet cache for thread processing queries from the outside world + g_packetCache = std::make_unique(g_maxPacketCacheEntries /*, shards */); + } ret = serviceMain(argc, argv, startupLog); } @@ -3126,11 +3124,6 @@ string doTraceRegex(FDWrapper file, vector::const_iterator begin, vector return broadcastAccFunction([=] { return pleaseUseNewTraceRegex(begin != end ? *begin : "", fileno); }); } -static uint64_t* pleaseWipePacketCache(const DNSName& canon, bool subtree, uint16_t qtype) -{ - return new uint64_t(t_packetCache ? t_packetCache->doWipePacketCache(canon, qtype, subtree) : 0); -} - struct WipeCacheResult wipeCaches(const DNSName& canon, bool subtree, uint16_t qtype) { struct WipeCacheResult res; @@ -3138,7 +3131,9 @@ struct WipeCacheResult wipeCaches(const DNSName& canon, bool subtree, uint16_t q try { res.record_count = g_recCache->doWipeCache(canon, subtree, qtype); // scanbuild complains here about an allocated function object that is being leaked. Needs investigation - res.packet_count = broadcastAccFunction([=] { return pleaseWipePacketCache(canon, subtree, qtype); }); + if (g_packetCache) { + res.packet_count = g_packetCache->doWipePacketCache(canon, qtype, subtree); + } res.negative_record_count = g_negCache->wipe(canon, subtree); if (g_aggressiveNSECCache) { g_aggressiveNSECCache->removeZoneInfo(canon, subtree); diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index 1a1c9ee63006..72ded229e7dd 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -187,7 +187,7 @@ enum class PaddingMode typedef MTasker, PacketBuffer, PacketIDCompare> MT_t; extern thread_local std::unique_ptr MT; // the big MTasker -extern thread_local std::unique_ptr t_packetCache; +extern std::unique_ptr g_packetCache; using RemoteLoggerStats_t = std::unordered_map; diff --git a/pdns/recursordist/rec-tcounters.hh b/pdns/recursordist/rec-tcounters.hh index 7d59bde46cfc..db5b31119240 100644 --- a/pdns/recursordist/rec-tcounters.hh +++ b/pdns/recursordist/rec-tcounters.hh @@ -95,6 +95,8 @@ enum class Counter : uint8_t maintenanceUsec, maintenanceCalls, + pcHits, + pcMisses, numberOfCounters }; diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index 2766c7cf5741..9bbc49df6e09 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -334,11 +334,6 @@ static uint64_t dumpAggressiveNSECCache(int fd) return g_aggressiveNSECCache->dumpToFile(fp, now); } -static uint64_t* pleaseDump(int fd) -{ - return new uint64_t(t_packetCache ? t_packetCache->doDump(fd) : 0); -} - static uint64_t* pleaseDumpEDNSMap(int fd) { return new uint64_t(SyncRes::doEDNSDump(fd)); @@ -416,7 +411,8 @@ static RecursorControlChannel::Answer doDumpCache(int s) uint64_t total = 0; try { int fd = fdw; - total = g_recCache->doDump(fd, g_maxCacheEntries.load()) + g_negCache->doDump(fd, g_maxCacheEntries.load() / 8) + broadcastAccFunction([fd] { return pleaseDump(fd); }) + dumpAggressiveNSECCache(fd); + total = g_recCache->doDump(fd, g_maxCacheEntries.load()) + g_negCache->doDump(fd, g_maxCacheEntries.load() / 8) + + (g_packetCache ? g_packetCache->doDump(fd) : 0) + dumpAggressiveNSECCache(fd); } catch (...) { } @@ -1078,46 +1074,6 @@ static uint64_t doGetCacheMisses() return g_recCache->cacheMisses; } -uint64_t* pleaseGetPacketCacheSize() -{ - return new uint64_t(t_packetCache ? t_packetCache->size() : 0); -} - -static uint64_t* pleaseGetPacketCacheBytes() -{ - return new uint64_t(t_packetCache ? t_packetCache->bytes() : 0); -} - -static uint64_t doGetPacketCacheSize() -{ - return broadcastAccFunction(pleaseGetPacketCacheSize); -} - -static uint64_t doGetPacketCacheBytes() -{ - return broadcastAccFunction(pleaseGetPacketCacheBytes); -} - -uint64_t* pleaseGetPacketCacheHits() -{ - return new uint64_t(t_packetCache ? t_packetCache->d_hits : 0); -} - -static uint64_t doGetPacketCacheHits() -{ - return broadcastAccFunction(pleaseGetPacketCacheHits); -} - -static uint64_t* pleaseGetPacketCacheMisses() -{ - return new uint64_t(t_packetCache ? t_packetCache->d_misses : 0); -} - -static uint64_t doGetPacketCacheMisses() -{ - return broadcastAccFunction(pleaseGetPacketCacheMisses); -} - static uint64_t doGetMallocated() { // this turned out to be broken @@ -1306,10 +1262,10 @@ static void registerAllStats1() addGetStat("record-cache-contended", []() { return g_recCache->stats().first; }); addGetStat("record-cache-acquired", []() { return g_recCache->stats().second; }); - addGetStat("packetcache-hits", doGetPacketCacheHits); - addGetStat("packetcache-misses", doGetPacketCacheMisses); - addGetStat("packetcache-entries", doGetPacketCacheSize); - addGetStat("packetcache-bytes", doGetPacketCacheBytes); + addGetStat("packetcache-hits", [] { return g_packetCache ? g_packetCache->getHits() : 0; }); + addGetStat("packetcache-misses", [] { return g_packetCache ? g_packetCache->getMisses() : 0; }); + addGetStat("packetcache-entries", [] { return g_packetCache ? g_packetCache->size() : 0; }); + addGetStat("packetcache-bytes", [] { return g_packetCache ? g_packetCache->bytes() : 0; });; addGetStat("aggressive-nsec-cache-entries", []() { return g_aggressiveNSECCache ? g_aggressiveNSECCache->getEntriesCount() : 0; }); addGetStat("aggressive-nsec-cache-nsec-hits", []() { return g_aggressiveNSECCache ? g_aggressiveNSECCache->getNSECHits() : 0; }); diff --git a/pdns/recursordist/recpacketcache.cc b/pdns/recursordist/recpacketcache.cc index 054efc971462..10fa9cbd1d9e 100644 --- a/pdns/recursordist/recpacketcache.cc +++ b/pdns/recursordist/recpacketcache.cc @@ -12,6 +12,47 @@ unsigned int RecursorPacketCache::s_refresh_ttlperc{0}; +uint64_t RecursorPacketCache::size() const +{ + uint64_t count = 0; + for (const auto& map : d_maps) { + count += map.d_entriesCount; + } + return count; +} + +uint64_t RecursorPacketCache::bytes() +{ + uint64_t sum = 0; + for (auto& shard : d_maps) { + auto lock = shard.lock(); + for (const auto& entry : lock->d_map) { + sum += sizeof(entry) + entry.d_packet.length() + 4; + } + } + return sum; +} + +uint64_t RecursorPacketCache::getHits() +{ + uint64_t sum = 0; + for (auto& shard : d_maps) { + auto lock = shard.lock(); + sum += lock->d_hits; + } + return sum; +} + +uint64_t RecursorPacketCache::getMisses() +{ + uint64_t sum = 0; + for (auto& shard : d_maps) { + auto lock = shard.lock(); + sum += lock->d_misses; + } + return sum; +} + uint64_t RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qtype, bool subtree) { uint64_t count = 0; @@ -53,7 +94,7 @@ bool RecursorPacketCache::qrMatch(const packetCache_t::index::type::ite return queryMatches(iter->d_query, queryPacket, qname, optionsToSkip); } -bool RecursorPacketCache::checkResponseMatches(packetCache_t& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata) +bool RecursorPacketCache::checkResponseMatches(MapCombo::LockedContent& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata) { for (auto iter = range.first; iter != range.second; ++iter) { // the possibility is VERY real that we get hits that are not right - birthday paradox @@ -82,8 +123,8 @@ bool RecursorPacketCache::checkResponseMatches(packetCache_t& shard, std::pair

replace(sizeof(dnsheader), wirelength, queryPacket, sizeof(dnsheader), wirelength); } - d_hits++; - moveCacheItemToBack(shard, iter); + shard.d_hits++; + moveCacheItemToBack(shard.d_map, iter); if (pbdata != nullptr) { if (iter->d_pbdata) { @@ -98,7 +139,7 @@ bool RecursorPacketCache::checkResponseMatches(packetCache_t& shard, std::pair

d_map.get(); auto range = idx.equal_range(std::tie(tag, *qhash, tcp)); if (range.first == range.second) { - d_misses++; + shard->d_misses++; return false; } - return checkResponseMatches(shard->d_map, range, queryPacket, qname, qtype, qclass, now, responsePacket, age, valState, pbdata); + return checkResponseMatches(*shard, range, queryPacket, qname, qtype, qclass, now, responsePacket, age, valState, pbdata); } bool RecursorPacketCache::getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp) { *qhash = canHashPacket(queryPacket, s_skipOptions); - auto shard = getMap(tag, *qhash, tcp).lock(); + auto& map = getMap(tag, *qhash, tcp); + auto shard = map.lock(); const auto& idx = shard->d_map.get(); auto range = idx.equal_range(std::tie(tag, *qhash, tcp)); if (range.first == range.second) { - d_misses++; + shard->d_misses++; return false; } qname = DNSName(queryPacket.c_str(), static_cast(queryPacket.length()), sizeof(dnsheader), false, qtype, qclass); - return checkResponseMatches(shard->d_map, range, queryPacket, qname, *qtype, *qclass, now, responsePacket, age, valState, pbdata); + return checkResponseMatches(*shard, range, queryPacket, qname, *qtype, *qclass, now, responsePacket, age, valState, pbdata); } void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, OptPBData&& pbdata, bool tcp) @@ -184,18 +227,6 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, assert(map.d_entriesCount == shard->d_map.size()); // XXX } -uint64_t RecursorPacketCache::bytes() -{ - uint64_t sum = 0; - for (auto& shard : d_maps) { - auto lock = shard.lock(); - for (const auto& entry : lock->d_map) { - sum += sizeof(entry) + entry.d_packet.length() + 4; - } - } - return sum; -} - void RecursorPacketCache::doPruneTo(size_t maxSize) { size_t cacheSize = size(); diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index 72f58d526ac6..8ebc46ecd4cd 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -95,18 +95,10 @@ public: d_maxSize = size; } - [[nodiscard]] uint64_t size() const - { - uint64_t count = 0; - for (const auto& map : d_maps) { - count += map.d_entriesCount; - } - return count; - } + [[nodiscard]] uint64_t size() const; [[nodiscard]] uint64_t bytes(); - - uint64_t d_hits{0}; - uint64_t d_misses{0}; + [[nodiscard]] uint64_t getHits(); + [[nodiscard]] uint64_t getMisses(); private: struct Entry @@ -169,6 +161,8 @@ private: struct LockedContent { packetCache_t d_map; + uint64_t d_hits{0}; + uint64_t d_misses{0}; uint64_t d_contended_count{0}; uint64_t d_acquired_count{0}; void invalidate() {} @@ -213,7 +207,7 @@ private: size_t d_maxSize; static bool qrMatch(const packetCache_t::index::type::iterator& iter, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass); - bool checkResponseMatches(packetCache_t& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); +bool checkResponseMatches(MapCombo::LockedContent& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); public: void preRemoval(MapCombo::LockedContent& map, const Entry& entry) { diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 496ea28efea1..fef7b96178b2 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -922,8 +922,6 @@ uint64_t* pleaseGetNsSpeedsSize(); uint64_t* pleaseGetFailedServersSize(); uint64_t* pleaseGetConcurrentQueries(); uint64_t* pleaseGetThrottleSize(); -uint64_t* pleaseGetPacketCacheHits(); -uint64_t* pleaseGetPacketCacheSize(); void doCarbonDump(void*); bool primeHints(time_t now = time(nullptr)); const char* isoDateTimeMillis(const struct timeval& tv, char* buf, size_t sz); From 2c8d4dc0f7233344762611599cd6e6e5791a200c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 24 Feb 2023 11:32:22 +0100 Subject: [PATCH 046/909] Add contention/acquired stats to sharded packet cache --- pdns/recursordist/RECURSOR-MIB.txt | 19 +++++++++++++++++++ pdns/recursordist/rec-snmp.cc | 5 +++++ pdns/recursordist/rec_channel_rec.cc | 15 +++++++++------ pdns/recursordist/recpacketcache.cc | 14 +++++++++++++- pdns/recursordist/recpacketcache.hh | 4 +++- pdns/recursordist/ws-recursor.cc | 10 +++++++++- 6 files changed, 58 insertions(+), 9 deletions(-) diff --git a/pdns/recursordist/RECURSOR-MIB.txt b/pdns/recursordist/RECURSOR-MIB.txt index 816fc47d0eea..5d04fa74f611 100644 --- a/pdns/recursordist/RECURSOR-MIB.txt +++ b/pdns/recursordist/RECURSOR-MIB.txt @@ -54,6 +54,9 @@ rec MODULE-IDENTITY REVISION "202209120000Z" DESCRIPTION "Added metrics for answers from auths by rcode" + REVISION "202302240000Z" + DESCRIPTION "Added metrics for sharded packet cache contrntion" + ::= { powerdns 2 } powerdns OBJECT IDENTIFIER ::= { enterprises 43315 } @@ -1212,6 +1215,22 @@ authrcode15Count OBJECT-TYPE "Number of rcode 15 answers received" ::= { stats 144 } +packetCacheContended OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of contended packet cache lock acquisitions" + ::= { stats 145 } + +packetCacheAcquired OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of packet cache lock acquisitions" + ::= { stats 146 } + --- --- Traps / Notifications diff --git a/pdns/recursordist/rec-snmp.cc b/pdns/recursordist/rec-snmp.cc index 7ffce2acb184..d7a4ad64f97c 100644 --- a/pdns/recursordist/rec-snmp.cc +++ b/pdns/recursordist/rec-snmp.cc @@ -167,6 +167,9 @@ static const oid rcode13AnswersOID[] = {RECURSOR_STATS_OID, 142}; static const oid rcode14AnswersOID[] = {RECURSOR_STATS_OID, 143}; static const oid rcode15AnswersOID[] = {RECURSOR_STATS_OID, 144}; +static const oid packetCacheContendedOID[] = {RECURSOR_STATS_OID, 145}; +static const oid packetCacheAcquiredOID[] = {RECURSOR_STATS_OID, 146}; + static std::unordered_map s_statsMap; /* We are never called for a GETNEXT if it's registered as a @@ -401,6 +404,8 @@ RecursorSNMPAgent::RecursorSNMPAgent(const std::string& name, const std::string& registerCounter64Stat("non-resolving-nameserver-entries", nonResolvingNameserverEntriesOID, OID_LENGTH(nonResolvingNameserverEntriesOID)); registerCounter64Stat("maintenance-usec", maintenanceUSecOID, OID_LENGTH(maintenanceUSecOID)); registerCounter64Stat("maintenance-calls", maintenanceCallsOID, OID_LENGTH(maintenanceCallsOID)); + registerCounter64Stat("packetcache-contended", packetCacheContendedOID, OID_LENGTH(packetCacheContendedOID)); + registerCounter64Stat("packetcache-acquired", packetCacheAcquiredOID, OID_LENGTH(packetCacheAcquiredOID)); #define RCODE(num) registerCounter64Stat("auth-" + RCode::to_short_s(num) + "-answers", rcode##num##AnswersOID, OID_LENGTH(rcode##num##AnswersOID)) RCODE(0); diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index 9bbc49df6e09..4e82cf604141 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -401,18 +401,19 @@ static RecursorControlChannel::Answer doDumpToFile(int s, uint64_t* (*function)( } // Does not follow the generic dump to file pattern, has a more complex lambda -static RecursorControlChannel::Answer doDumpCache(int s) +static RecursorControlChannel::Answer doDumpCache(int socket) { - auto fdw = getfd(s); + auto fdw = getfd(socket); if (fdw < 0) { return {1, "Error opening dump file for writing: " + stringerror() + "\n"}; } uint64_t total = 0; try { - int fd = fdw; - total = g_recCache->doDump(fd, g_maxCacheEntries.load()) + g_negCache->doDump(fd, g_maxCacheEntries.load() / 8) + - (g_packetCache ? g_packetCache->doDump(fd) : 0) + dumpAggressiveNSECCache(fd); + total += g_recCache->doDump(fdw, g_maxCacheEntries.load()); + total += g_negCache->doDump(fdw, g_maxCacheEntries.load() / 8); + total += g_packetCache ? g_packetCache->doDump(fdw) : 0; + total += dumpAggressiveNSECCache(fdw); } catch (...) { } @@ -1265,7 +1266,9 @@ static void registerAllStats1() addGetStat("packetcache-hits", [] { return g_packetCache ? g_packetCache->getHits() : 0; }); addGetStat("packetcache-misses", [] { return g_packetCache ? g_packetCache->getMisses() : 0; }); addGetStat("packetcache-entries", [] { return g_packetCache ? g_packetCache->size() : 0; }); - addGetStat("packetcache-bytes", [] { return g_packetCache ? g_packetCache->bytes() : 0; });; + addGetStat("packetcache-bytes", [] { return g_packetCache ? g_packetCache->bytes() : 0; }); + addGetStat("packetcache-contended", []() { return g_packetCache ? g_packetCache->stats().first : 0; }); + addGetStat("packetcache-acquired", []() { return g_packetCache ? g_packetCache->stats().second : 0; }); addGetStat("aggressive-nsec-cache-entries", []() { return g_aggressiveNSECCache ? g_aggressiveNSECCache->getEntriesCount() : 0; }); addGetStat("aggressive-nsec-cache-nsec-hits", []() { return g_aggressiveNSECCache ? g_aggressiveNSECCache->getNSECHits() : 0; }); diff --git a/pdns/recursordist/recpacketcache.cc b/pdns/recursordist/recpacketcache.cc index 10fa9cbd1d9e..48fb138fc3f1 100644 --- a/pdns/recursordist/recpacketcache.cc +++ b/pdns/recursordist/recpacketcache.cc @@ -53,6 +53,18 @@ uint64_t RecursorPacketCache::getMisses() return sum; } +pair RecursorPacketCache::stats() +{ + uint64_t contended = 0; + uint64_t acquired = 0; + for (auto& shard : d_maps) { + auto content = shard.lock(); + contended += content->d_contended_count; + acquired += content->d_acquired_count; + } + return {contended, acquired}; +} + uint64_t RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qtype, bool subtree) { uint64_t count = 0; @@ -260,7 +272,7 @@ uint64_t RecursorPacketCache::doDump(int file) min = std::min(min, shardSize); max = std::max(max, shardSize); shardNum++; - for (const auto& entry : sidx) { + for (const auto& entry : sidx) { count++; try { fprintf(filePtr.get(), "%s %" PRId64 " %s ; tag %d %s\n", entry.d_name.toString().c_str(), static_cast(entry.d_ttd - now), DNSRecordContent::NumberToType(entry.d_type).c_str(), entry.d_tag, entry.d_tcp ? "tcp" : "udp"); diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index 8ebc46ecd4cd..10a005b8975c 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -99,6 +99,7 @@ public: [[nodiscard]] uint64_t bytes(); [[nodiscard]] uint64_t getHits(); [[nodiscard]] uint64_t getMisses(); + [[nodiscard]] pair stats(); private: struct Entry @@ -207,7 +208,8 @@ private: size_t d_maxSize; static bool qrMatch(const packetCache_t::index::type::iterator& iter, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass); -bool checkResponseMatches(MapCombo::LockedContent& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); + bool checkResponseMatches(MapCombo::LockedContent& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); + public: void preRemoval(MapCombo::LockedContent& map, const Entry& entry) { diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index b1d11ae170df..ae0cde21e1d5 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -1070,7 +1070,15 @@ const std::map MetricDefinitionStorage::d_metrics {"record-cache-contended", MetricDefinition(PrometheusMetricType::counter, - "Number of contented record cache lock acquisitions")}, + "Number of contended record cache lock acquisitions")}, + + {"packetcache-acquired", + MetricDefinition(PrometheusMetricType::counter, + "Number of packet cache lock acquisitions")}, + + {"packetcache-contended", + MetricDefinition(PrometheusMetricType::counter, + "Number of contended packet cache lock acquisitions")}, {"taskqueue-expired", MetricDefinition(PrometheusMetricType::counter, From 95f43121f2d016bc1bc664bd4ff7a1ad8f4f77f1 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 27 Feb 2023 10:37:11 +0100 Subject: [PATCH 047/909] Add contention info about PC in stats report --- pdns/recursordist/rec-main.cc | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 4720cca1b3f8..5512d8ae8592 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -987,7 +987,9 @@ static void doStats(void) uint64_t cacheMisses = g_recCache->cacheMisses; uint64_t cacheSize = g_recCache->size(); auto rc_stats = g_recCache->stats(); - double r = rc_stats.second == 0 ? 0.0 : (100.0 * rc_stats.first / rc_stats.second); + auto pc_stats = g_packetCache ? g_packetCache->stats() : std::pair{0, 0}; + double rrc = rc_stats.second == 0 ? 0.0 : (100.0 * rc_stats.first / rc_stats.second); + double rpc = pc_stats.second == 0 ? 0.0 : (100.0 * pc_stats.first / pc_stats.second); uint64_t negCacheSize = g_negCache->size(); auto taskPushes = getTaskPushes(); auto taskExpired = getTaskExpired(); @@ -1007,7 +1009,8 @@ static void doStats(void) if (qcounter > 0 && (cacheHits + cacheMisses) > 0 && syncresqueries > 0 && outqueries > 0) { if (!g_slogStructured) { g_log << Logger::Notice << "stats: " << qcounter << " questions, " << cacheSize << " cache entries, " << negCacheSize << " negative entries, " << ratePercentage(cacheHits, cacheHits + cacheMisses) << "% cache hits" << endl; - g_log << Logger::Notice << "stats: cache contended/acquired " << rc_stats.first << '/' << rc_stats.second << " = " << r << '%' << endl; + g_log << Logger::Notice << "stats: record cache contended/acquired " << rc_stats.first << '/' << rc_stats.second << " = " << rrc << '%' << endl; + g_log << Logger::Notice << "stats: packet cache contended/acquired " << pc_stats.first << '/' << pc_stats.second << " = " << rpc << '%' << endl; g_log << Logger::Notice << "stats: throttle map: " << SyncRes::getThrottledServersSize() << ", ns speeds: " @@ -1034,7 +1037,10 @@ static void doStats(void) "record-cache-hitratio-perc", Logging::Loggable(ratePercentage(cacheHits, cacheHits + cacheMisses)), "record-cache-contended", Logging::Loggable(rc_stats.first), "record-cache-acquired", Logging::Loggable(rc_stats.second), - "record-cache-contended-perc", Logging::Loggable(r)); + "record-cache-contended-perc", Logging::Loggable(rrc), + "packet-cache-contended", Logging::Loggable(pc_stats.first), + "packet-cache-acquired", Logging::Loggable(pc_stats.second), + "packet-cache-contended-perc", Logging::Loggable(rpc)); log->info(Logr::Info, m, "throttle-entries", Logging::Loggable(SyncRes::getThrottledServersSize()), "nsspeed-entries", Logging::Loggable(SyncRes::getNSSpeedsSize()), From a793f3990a6ec5a1f2218b8c25f5ccf76a46e08f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 27 Feb 2023 11:29:46 +0100 Subject: [PATCH 048/909] Account for size per shard --- pdns/recursordist/rec-main.cc | 6 ++---- pdns/recursordist/rec_channel_rec.cc | 1 + pdns/recursordist/recpacketcache.cc | 16 +++++++++++++--- pdns/recursordist/recpacketcache.hh | 19 ++++++++++--------- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 5512d8ae8592..b514e7b2e054 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1447,7 +1447,6 @@ static int serviceMain(int argc, char* argv[], Logr::log_t log) g_maxNSEC3Iterations = ::arg().asNum("nsec3-max-iterations"); g_maxCacheEntries = ::arg().asNum("max-cache-entries"); - g_maxPacketCacheEntries = ::arg().asNum("max-packetcache-entries"); luaConfigDelayedThreads delayedLuaThreads; try { @@ -2185,7 +2184,6 @@ static void houseKeeping(void*) if (g_packetCache) { static PeriodicTask packetCacheTask{"packetCacheTask", 5}; packetCacheTask.runIfDue(now, []() { - g_packetCache->setMaxSize(g_maxPacketCacheEntries); // g_maxPacketCacheEntries might have changed by rec_control g_packetCache->doPruneTo(g_maxPacketCacheEntries); }); } @@ -3036,8 +3034,8 @@ int main(int argc, char** argv) g_recCache = std::make_unique(::arg().asNum("record-cache-shards")); g_negCache = std::make_unique(::arg().asNum("record-cache-shards") / 8); if (!::arg().mustDo("disable-packetcache")) { - // Only enable packet cache for thread processing queries from the outside world - g_packetCache = std::make_unique(g_maxPacketCacheEntries /*, shards */); + g_maxPacketCacheEntries = ::arg().asNum("max-packetcache-entries"); + g_packetCache = std::make_unique(g_maxPacketCacheEntries, ::arg().asNum("record-cache-shards")); // XXX } ret = serviceMain(argc, argv, startupLog); diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index 4e82cf604141..f2a7d628e78d 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -844,6 +844,7 @@ static string setMaxPacketCacheEntries(T begin, T end) } try { g_maxPacketCacheEntries = pdns::checked_stoi(*begin); + g_packetCache->setMaxSize(g_maxPacketCacheEntries); return "New max packetcache entries: " + std::to_string(g_maxPacketCacheEntries) + "\n"; } catch (const std::exception& e) { diff --git a/pdns/recursordist/recpacketcache.cc b/pdns/recursordist/recpacketcache.cc index 48fb138fc3f1..184555ebd8e7 100644 --- a/pdns/recursordist/recpacketcache.cc +++ b/pdns/recursordist/recpacketcache.cc @@ -12,6 +12,14 @@ unsigned int RecursorPacketCache::s_refresh_ttlperc{0}; +void RecursorPacketCache::setShardSizes(size_t shardSize) +{ + for (auto& shard : d_maps) { + auto lock = shard.lock(); + lock->d_shardSize = shardSize; + } +} + uint64_t RecursorPacketCache::size() const { uint64_t count = 0; @@ -231,7 +239,7 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, shard->d_map.insert(entry); map.d_entriesCount++; - if (shard->d_map.size() > d_maxSize / d_maps.size()) { + if (shard->d_map.size() > shard->d_shardSize) { auto& seq_idx = shard->d_map.get(); seq_idx.erase(seq_idx.begin()); map.d_entriesCount--; @@ -263,14 +271,16 @@ uint64_t RecursorPacketCache::doDump(int file) size_t shardNum = 0; size_t min = std::numeric_limits::max(); size_t max = 0; + uint64_t maxSize = 0; for (auto& shard : d_maps) { auto lock = shard.lock(); const auto& sidx = lock->d_map.get(); const auto shardSize = lock->d_map.size(); - fprintf(filePtr.get(), "; packetcache shard %zu; size %zu\n", shardNum, shardSize); + fprintf(filePtr.get(), "; packetcache shard %zu; size %zu/%zu\n", shardNum, shardSize, lock->d_shardSize); min = std::min(min, shardSize); max = std::max(max, shardSize); + maxSize += lock->d_shardSize; shardNum++; for (const auto& entry : sidx) { count++; @@ -282,6 +292,6 @@ uint64_t RecursorPacketCache::doDump(int file) } } } - fprintf(filePtr.get(), "; packetcache size: %" PRIu64 "/%zu shards: %zu min/max shard size: %zu/%zu\n", size(), d_maxSize, d_maps.size(), min, max); + fprintf(filePtr.get(), "; packetcache size: %" PRIu64 "/%" PRIu64 " shards: %zu min/max shard size: %zu/%zu\n", size(), maxSize, d_maps.size(), min, max); return count; } diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index 10a005b8975c..be7611f93dbd 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -57,12 +57,9 @@ public: using OptPBData = boost::optional; RecursorPacketCache(size_t maxsize, size_t shards = 1024) : - d_maps(shards), - d_maxSize(maxsize) + d_maps(shards) { - if (d_maxSize / d_maps.size() == 0) { - d_maxSize = d_maps.size(); - } + setMaxSize(maxsize); } bool getResponsePacket(unsigned int tag, const std::string& queryPacket, time_t now, @@ -86,13 +83,16 @@ public: bool getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp); void insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, OptPBData&& pbdata, bool tcp); - void doPruneTo(size_t maxSize = 250000); + void doPruneTo(size_t maxSize); uint64_t doDump(int file); uint64_t doWipePacketCache(const DNSName& name, uint16_t qtype = 0xffff, bool subtree = false); void setMaxSize(size_t size) { - d_maxSize = size; + if (size < d_maps.size()) { + size = d_maps.size(); + } + setShardSizes(size / d_maps.size()); } [[nodiscard]] uint64_t size() const; @@ -162,6 +162,7 @@ private: struct LockedContent { packetCache_t d_map; + size_t d_shardSize{0}; uint64_t d_hits{0}; uint64_t d_misses{0}; uint64_t d_contended_count{0}; @@ -205,11 +206,11 @@ private: // return d_maps.at(combine(hash, hash, tcp) % d_maps.size()); // } - size_t d_maxSize; - static bool qrMatch(const packetCache_t::index::type::iterator& iter, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass); bool checkResponseMatches(MapCombo::LockedContent& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); + void setShardSizes(size_t shardSize); + public: void preRemoval(MapCombo::LockedContent& map, const Entry& entry) { From 3a833b8d9871bf0582af7a94ee731c69d0f7f719 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 27 Feb 2023 15:11:08 +0100 Subject: [PATCH 049/909] Stop disabling packet cache for bulk tests --- regression-tests/recursor-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests/recursor-test b/regression-tests/recursor-test index 7e6f67d3525e..1af12822fca2 100755 --- a/regression-tests/recursor-test +++ b/regression-tests/recursor-test @@ -31,7 +31,7 @@ rm -f recursor.pid pdns_recursor.pid system CPU seconds%S wallclock seconds%e %% CPU used%P -' ${RECURSOR} --daemon=no --local-port=$port --socket-dir=./ --trace=$TRACE --config-dir=. --max-mthreads=$mthreads --query-local-address="0.0.0.0${QLA6}" --threads=$threads --record-cache-shards=$shards --disable-packetcache --refresh-on-ttl-perc=10 --dnssec=validate > recursor.log 2>&1 & +' ${RECURSOR} --daemon=no --local-port=$port --socket-dir=./ --trace=$TRACE --config-dir=. --max-mthreads=$mthreads --query-local-address="0.0.0.0${QLA6}" --threads=$threads --record-cache-shards=$shards --refresh-on-ttl-perc=10 --dnssec=validate > recursor.log 2>&1 & sleep 3 if [ ! -e pdns_recursor.pid ]; then cat recursor.log From bc22758124d4f8e06dea06bb3f86c6ba9b74750c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 27 Feb 2023 15:14:14 +0100 Subject: [PATCH 050/909] Tweaks --- pdns/recursordist/recpacketcache.hh | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index be7611f93dbd..d082aec04180 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -156,7 +156,7 @@ private: struct MapCombo { - MapCombo() {} + MapCombo() = default; MapCombo(const MapCombo&) = delete; MapCombo& operator=(const MapCombo&) = delete; struct LockedContent @@ -188,7 +188,7 @@ private: vector d_maps; - size_t combine(unsigned int tag, uint32_t hash, bool tcp) const + static size_t combine(unsigned int tag, uint32_t hash, bool tcp) { size_t ret = 0; boost::hash_combine(ret, tag); @@ -201,10 +201,11 @@ private: { return d_maps.at(combine(tag, hash, tcp) % d_maps.size()); } - // const MapCombo& getMap(unsigned int tag, uint32_t hash, bool tcp) const - // { - // return d_maps.at(combine(hash, hash, tcp) % d_maps.size()); - // } + + [[nodiscard]] const MapCombo& getMap(unsigned int tag, uint32_t hash, bool tcp) const + { + return d_maps.at(combine(hash, hash, tcp) % d_maps.size()); + } static bool qrMatch(const packetCache_t::index::type::iterator& iter, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass); bool checkResponseMatches(MapCombo::LockedContent& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); From 503813cd9c080d2a089484af7cc73d9e9ef42f82 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 17 Mar 2023 14:09:00 +0100 Subject: [PATCH 051/909] A separate setting for packet cache shards. --- pdns/recursordist/RECURSOR-MIB.txt | 6 ++++-- pdns/recursordist/docs/settings.rst | 13 +++++++++++++ pdns/recursordist/rec-main.cc | 11 +++++++---- pdns/recursordist/rec-tcounters.hh | 2 -- 4 files changed, 24 insertions(+), 8 deletions(-) diff --git a/pdns/recursordist/RECURSOR-MIB.txt b/pdns/recursordist/RECURSOR-MIB.txt index 5d04fa74f611..40b26617a90a 100644 --- a/pdns/recursordist/RECURSOR-MIB.txt +++ b/pdns/recursordist/RECURSOR-MIB.txt @@ -55,7 +55,7 @@ rec MODULE-IDENTITY DESCRIPTION "Added metrics for answers from auths by rcode" REVISION "202302240000Z" - DESCRIPTION "Added metrics for sharded packet cache contrntion" + DESCRIPTION "Added metrics for sharded packet cache contention" ::= { powerdns 2 } @@ -1423,7 +1423,9 @@ recGroup OBJECT-GROUP authrcode12Count, authrcode13Count, authrcode14Count, - authrcode15Count + authrcode15Count, + packetCacheContended, + packetCacheAcquired } STATUS current DESCRIPTION "Objects conformance group for PowerDNS Recursor" diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index fce382f5f042..ec4c60e65faa 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -1618,6 +1618,19 @@ Before version 4.6.0 only ``ServFail`` answers were considered as such. Starting This setting's maximum is capped to `packetcache-ttl`_. i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-servfail-ttl`` at the default will lower ``packetcache-servfail-ttl`` to ``15``. + +.. _setting-packetcache-shards: + +``packetcache-shards`` +------------------------ +.. versionadded:: 4.9.0 + +- Integer +- Default: 1024 + +Sets the number of shards in the packet cache. If you have high contention as reported by ``packetcache-contented/packetcache-acquired``, +you can try to enlarge this value or run with fewer threads. + .. _setting-pdns-distributes-queries: ``pdns-distributes-queries`` diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index b514e7b2e054..52dfa60d2217 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1038,9 +1038,9 @@ static void doStats(void) "record-cache-contended", Logging::Loggable(rc_stats.first), "record-cache-acquired", Logging::Loggable(rc_stats.second), "record-cache-contended-perc", Logging::Loggable(rrc), - "packet-cache-contended", Logging::Loggable(pc_stats.first), - "packet-cache-acquired", Logging::Loggable(pc_stats.second), - "packet-cache-contended-perc", Logging::Loggable(rpc)); + "packetcache-contended", Logging::Loggable(pc_stats.first), + "packetcache-acquired", Logging::Loggable(pc_stats.second), + "packetcache-contended-perc", Logging::Loggable(rpc)); log->info(Logr::Info, m, "throttle-entries", Logging::Loggable(SyncRes::getThrottledServersSize()), "nsspeed-entries", Logging::Loggable(SyncRes::getNSSpeedsSize()), @@ -2808,7 +2808,10 @@ int main(int argc, char** argv) ::arg().setSwitch("nothing-below-nxdomain", "When an NXDOMAIN exists in cache for a name with fewer labels than the qname, send NXDOMAIN without doing a lookup (see RFC 8020)") = "dnssec"; ::arg().set("max-generate-steps", "Maximum number of $GENERATE steps when loading a zone from a file") = "0"; ::arg().set("max-include-depth", "Maximum nested $INCLUDE depth when loading a zone from a file") = "20"; + ::arg().set("record-cache-shards", "Number of shards in the record cache") = "1024"; + ::arg().set("packetcache-shards", "Number of shards in the packet cache") = "1024"; + ::arg().set("refresh-on-ttl-perc", "If a record is requested from the cache and only this % of original TTL remains, refetch") = "0"; ::arg().set("record-cache-locked-ttl-perc", "Replace records in record cache only after this % of original TTL has passed") = "0"; @@ -3035,7 +3038,7 @@ int main(int argc, char** argv) g_negCache = std::make_unique(::arg().asNum("record-cache-shards") / 8); if (!::arg().mustDo("disable-packetcache")) { g_maxPacketCacheEntries = ::arg().asNum("max-packetcache-entries"); - g_packetCache = std::make_unique(g_maxPacketCacheEntries, ::arg().asNum("record-cache-shards")); // XXX + g_packetCache = std::make_unique(g_maxPacketCacheEntries, ::arg().asNum("packetcache-shards")); } ret = serviceMain(argc, argv, startupLog); diff --git a/pdns/recursordist/rec-tcounters.hh b/pdns/recursordist/rec-tcounters.hh index db5b31119240..7d59bde46cfc 100644 --- a/pdns/recursordist/rec-tcounters.hh +++ b/pdns/recursordist/rec-tcounters.hh @@ -95,8 +95,6 @@ enum class Counter : uint8_t maintenanceUsec, maintenanceCalls, - pcHits, - pcMisses, numberOfCounters }; From f20bacd270aa18c16be21d3d5d94cb1f48950478 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 22 Mar 2023 10:53:00 +0100 Subject: [PATCH 052/909] Another case of a test calling the API before it is ready --- regression-tests.recursor-dnssec/test_PacketCache.py | 1 + 1 file changed, 1 insertion(+) diff --git a/regression-tests.recursor-dnssec/test_PacketCache.py b/regression-tests.recursor-dnssec/test_PacketCache.py index 80b015f6f9dd..ba8c102ddde4 100644 --- a/regression-tests.recursor-dnssec/test_PacketCache.py +++ b/regression-tests.recursor-dnssec/test_PacketCache.py @@ -47,6 +47,7 @@ def generateRecursorConfig(cls, confdir): super(PacketCacheRecursorTest, cls).generateRecursorConfig(confdir) def checkPacketCacheMetrics(self, expectedHits, expectedMisses): + self.waitForTCPSocket("127.0.0.1", self._wsPort) headers = {'x-api-key': self._apiKey} url = 'http://127.0.0.1:' + str(self._wsPort) + '/api/v1/servers/localhost/statistics' r = requests.get(url, headers=headers, timeout=self._wsTimeout) From 0395763008931e604e5d9fb2d28bcdd0f6d88715 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 3 Apr 2023 11:14:00 +0200 Subject: [PATCH 053/909] Change defaults to pdns-distributes-queries = no and reuseport = yes --- pdns/recursordist/docs/settings.rst | 25 +++++++++++++++++-------- pdns/recursordist/rec-main.cc | 7 +++++-- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index ec4c60e65faa..ba22422f980e 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -466,8 +466,7 @@ overloaded, but it will be at the cost of an increased latency. - Default: 1 if `pdns-distributes-queries`_ is set, 0 otherwise If `pdns-distributes-queries`_ is set, spawn this number of distributor threads on startup. Distributor threads -handle incoming queries and distribute them to other threads based on a hash of the query, to maximize the cache hit -ratio. +handle incoming queries and distribute them to other threads based on a hash of the query. .. _setting-dot-to-auth-names: @@ -1636,12 +1635,17 @@ you can try to enlarge this value or run with fewer threads. ``pdns-distributes-queries`` ---------------------------- - Boolean -- Default: yes +- Default: no If set, PowerDNS will use distinct threads to listen to client sockets and distribute that work to worker-threads using a hash of the query. -This feature should maximize the cache hit ratio. -To use more than one thread set `distributor-threads` in version 4.2.0 or newer. -Enabling should improve performance for medium sized resolvers. +This feature should maximize the cache hit ratio on versions before 4.9.0. +To use more than one thread set `distributor-threads`_ in version 4.2.0 or newer. +Enabling should improve performance on systems where `reuseport`_ does not have the effect of +balancing the queries evenly over multiple worker threads. + +.. versionchanged:: 4.9.0 + + Default changed to ``no``, previously it was ``yes``. .. _setting-protobuf-use-kernel-timestamp: @@ -1801,11 +1805,16 @@ A typical value is 10. If the value is zero, this functionality is disabled. ``reuseport`` ------------- - Boolean -- Default: no +- Default: yes If ``SO_REUSEPORT`` support is available, allows multiple threads and processes to open listening sockets for the same port. -Since 4.1.0, when ``pdns-distributes-queries`` is set to false and ``reuseport`` is enabled, every worker-thread will open a separate listening socket to let the kernel distribute the incoming queries instead of running a distributor thread (which could otherwise be a bottleneck) and avoiding thundering herd issues, thus leading to much higher performance on multi-core boxes. +Since 4.1.0, when `pdns-distributes-queries`_ is disabled and `reuseport`_ is enabled, every worker-thread will open a separate listening socket to let the kernel distribute the incoming queries instead of running a distributor thread (which could otherwise be a bottleneck) and avoiding thundering herd issues, thus leading to much higher performance on multi-core boxes. + +.. versionchanged:: 4.9.0 + + The default is changed to ``yes``, previously it was ``no``. + If ``SO_REUSEPORT`` support is not available, the setting defaults to ``no``. .. _setting-rng: diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 52dfa60d2217..7de44b7187ca 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2739,7 +2739,7 @@ int main(int argc, char** argv) ::arg().set("ecs-add-for", "List of client netmasks for which EDNS Client Subnet will be added") = "0.0.0.0/0, ::/0, " LOCAL_NETS_INVERSE; ::arg().set("ecs-scope-zero-address", "Address to send to allow-listed authoritative servers for incoming queries with ECS prefix-length source of 0") = ""; ::arg().setSwitch("use-incoming-edns-subnet", "Pass along received EDNS Client Subnet information") = "no"; - ::arg().setSwitch("pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads") = "yes"; + ::arg().setSwitch("pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads") = "no"; ::arg().setSwitch("root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist") = "yes"; ::arg().setSwitch("any-to-tcp", "Answer ANY queries with tc=1, shunting to TCP") = "no"; ::arg().setSwitch("lowercase-outgoing", "Force outgoing questions to lowercase") = "no"; @@ -2759,8 +2759,11 @@ int main(int argc, char** argv) ::arg().set("include-dir", "Include *.conf files from this directory") = ""; ::arg().set("security-poll-suffix", "Domain name from which to query security update notifications") = "secpoll.powerdns.com."; +#ifdef SO_REUSEPORT + ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "yes"; +#else ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "no"; - +#endif ::arg().setSwitch("snmp-agent", "If set, register as an SNMP agent") = "no"; ::arg().set("snmp-master-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon (deprecated)") = ""; ::arg().set("snmp-daemon-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon") = ""; From 580ad9a0dffb58a1f5ea2e1c63007def744b52a7 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 4 Apr 2023 08:45:52 +0200 Subject: [PATCH 054/909] rec: followup to #10072: add missing boost-filesystem dependency Fixes #12715: NOD functionality was lost due to a missing boost-filesystem dependency. Add the dependency and explicitly enable NOD. --- builder-support/debian/recursor/debian-buster/control | 1 + builder-support/debian/recursor/debian-buster/rules | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/builder-support/debian/recursor/debian-buster/control b/builder-support/debian/recursor/debian-buster/control index c9325fc95e2b..f7e5349a5d14 100644 --- a/builder-support/debian/recursor/debian-buster/control +++ b/builder-support/debian/recursor/debian-buster/control @@ -8,6 +8,7 @@ Build-Depends: debhelper (>= 10), dh-autoreconf, libboost-context-dev [amd64 arm64 armel armhf i386 ppc64el], libboost-dev, + libboost-filesystem-dev, libboost-program-options-dev, libboost-system-dev, libboost-test-dev, diff --git a/builder-support/debian/recursor/debian-buster/rules b/builder-support/debian/recursor/debian-buster/rules index c393dcb0c01d..f8340c43393c 100755 --- a/builder-support/debian/recursor/debian-buster/rules +++ b/builder-support/debian/recursor/debian-buster/rules @@ -29,7 +29,8 @@ override_dh_auto_configure: --with-lua \ --with-net-snmp \ --enable-dns-over-tls \ - --enable-dnstap + --enable-dnstap \ + --enable-nod override_dh_auto_install: dh_auto_install From e225c8e66764902d299951ed3ea4a3677ca62f08 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 4 Apr 2023 08:52:02 +0200 Subject: [PATCH 055/909] Also enable NOD explictly in spec file --- builder-support/specs/pdns-recursor.spec | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/builder-support/specs/pdns-recursor.spec b/builder-support/specs/pdns-recursor.spec index 9916738a402e..75a2690f7ec9 100644 --- a/builder-support/specs/pdns-recursor.spec +++ b/builder-support/specs/pdns-recursor.spec @@ -69,7 +69,8 @@ export LDFLAGS=-L/usr/lib64/boost169 --with-libsodium \ --with-net-snmp \ %endif - --enable-systemd --with-systemd=%{_unitdir} + --enable-systemd --with-systemd=%{_unitdir} \ + --enable-nod make %{?_smp_mflags} From bb24f4c86cdacfcb6b400eff700b094f72411699 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 4 Apr 2023 09:23:59 +0200 Subject: [PATCH 056/909] More consistent naming and some general clang-tidy cleanup --- pdns/recursordist/recursor_cache.cc | 182 ++++++++++++++-------------- 1 file changed, 92 insertions(+), 90 deletions(-) diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index e5d96c3d5de3..a95f153516df 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -62,30 +62,31 @@ MemRecursorCache::MemRecursorCache(size_t mapsCount) : size_t MemRecursorCache::size() const { size_t count = 0; - for (const auto& map : d_maps) { - count += map.d_entriesCount; + for (const auto& shard : d_maps) { + count += shard.d_entriesCount; } return count; } pair MemRecursorCache::stats() { - uint64_t c = 0, a = 0; - for (auto& mc : d_maps) { - auto content = mc.lock(); - c += content->d_contended_count; - a += content->d_acquired_count; - } - return pair(c, a); + uint64_t contended = 0; + uint64_t acquired = 0; + for (auto& shard : d_maps) { + auto lockedShard = shard.lock(); + contended += lockedShard->d_contended_count; + acquired += lockedShard->d_acquired_count; + } + return {contended, acquired}; } size_t MemRecursorCache::ecsIndexSize() { // XXX! size_t count = 0; - for (auto& mc : d_maps) { - auto content = mc.lock(); - count += content->d_ecsIndex.size(); + for (auto& shard : d_maps) { + auto lockedShard = shard.lock(); + count += lockedShard->d_ecsIndex.size(); } return count; } @@ -94,12 +95,12 @@ size_t MemRecursorCache::ecsIndexSize() size_t MemRecursorCache::bytes() { size_t ret = 0; - for (auto& mc : d_maps) { - auto m = mc.lock(); - for (const auto& i : m->d_map) { + for (auto& shard : d_maps) { + auto lockedShard = shard.lock(); + for (const auto& entry : lockedShard->d_map) { ret += sizeof(struct CacheEntry); - ret += i.d_qname.toString().length(); - for (const auto& record : i.d_records) { + ret += entry.d_qname.toString().length(); + for (const auto& record : entry.d_records) { ret += sizeof(record); // XXX WRONG we don't know the stored size! } } @@ -145,45 +146,45 @@ time_t MemRecursorCache::handleHit(MapCombo::LockedContent& content, MemRecursor time_t ttd = entry->d_ttd; origTTL = entry->d_orig_ttl; - if (variable && (!entry->d_netmask.empty() || entry->d_rtag)) { + if (variable != nullptr && (!entry->d_netmask.empty() || entry->d_rtag)) { *variable = true; } - if (res) { + if (res != nullptr) { res->reserve(res->size() + entry->d_records.size()); - for (const auto& k : entry->d_records) { - DNSRecord dr; - dr.d_name = qname; - dr.d_type = entry->d_qtype; - dr.d_class = QClass::IN; - dr.setContent(k); + for (const auto& record : entry->d_records) { + DNSRecord result; + result.d_name = qname; + result.d_type = entry->d_qtype; + result.d_class = QClass::IN; + result.setContent(record); // coverity[store_truncates_time_t] - dr.d_ttl = static_cast(entry->d_ttd); - dr.d_place = DNSResourceRecord::ANSWER; - res->push_back(std::move(dr)); + result.d_ttl = static_cast(entry->d_ttd); + result.d_place = DNSResourceRecord::ANSWER; + res->push_back(std::move(result)); } } - if (signatures) { + if (signatures != nullptr) { signatures->insert(signatures->end(), entry->d_signatures.begin(), entry->d_signatures.end()); } - if (authorityRecs) { + if (authorityRecs != nullptr) { authorityRecs->insert(authorityRecs->end(), entry->d_authorityRecs.begin(), entry->d_authorityRecs.end()); } updateDNSSECValidationStateFromCache(state, entry->d_state); - if (wasAuth) { + if (wasAuth != nullptr) { *wasAuth = *wasAuth && entry->d_auth; } - if (fromAuthZone) { + if (fromAuthZone != nullptr) { *fromAuthZone = entry->d_authZone; } - if (fromAuthIP) { + if (fromAuthIP != nullptr) { *fromAuthIP = entry->d_from; } @@ -354,32 +355,32 @@ time_t MemRecursorCache::get(time_t now, const DNSName& qname, const QType qt, F boost::optional cachedState{boost::none}; uint32_t origTTL; - if (res) { + if (res != nullptr) { res->clear(); } const uint16_t qtype = qt.getCode(); - if (wasAuth) { + if (wasAuth != nullptr) { // we might retrieve more than one entry, we need to set that to true // so it will be set to false if at least one entry is not auth *wasAuth = true; } - auto& mc = getMap(qname); - auto map = mc.lock(); + auto& shard = getMap(qname); + auto lockedShard = shard.lock(); /* If we don't have any netmask-specific entries at all, let's just skip this to be able to use the nice d_cachecache hack. */ - if (qtype != QType::ANY && !map->d_ecsIndex.empty() && !routingTag) { + if (qtype != QType::ANY && !lockedShard->d_ecsIndex.empty() && !routingTag) { if (qtype == QType::ADDR) { time_t ret = -1; - auto entryA = getEntryUsingECSIndex(*map, now, qname, QType::A, requireAuth, who, serveStale); - if (entryA != map->d_map.end()) { - ret = handleHit(*map, entryA, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP); + auto entryA = getEntryUsingECSIndex(*lockedShard, now, qname, QType::A, requireAuth, who, serveStale); + if (entryA != lockedShard->d_map.end()) { + ret = handleHit(*lockedShard, entryA, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP); } - auto entryAAAA = getEntryUsingECSIndex(*map, now, qname, QType::AAAA, requireAuth, who, serveStale); - if (entryAAAA != map->d_map.end()) { - time_t ttdAAAA = handleHit(*map, entryAAAA, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP); + auto entryAAAA = getEntryUsingECSIndex(*lockedShard, now, qname, QType::AAAA, requireAuth, who, serveStale); + if (entryAAAA != lockedShard->d_map.end()) { + time_t ttdAAAA = handleHit(*lockedShard, entryAAAA, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP); if (ret > 0) { ret = std::min(ret, ttdAAAA); } @@ -395,9 +396,9 @@ time_t MemRecursorCache::get(time_t now, const DNSName& qname, const QType qt, F return ret > 0 ? (ret - now) : ret; } else { - auto entry = getEntryUsingECSIndex(*map, now, qname, qtype, requireAuth, who, serveStale); - if (entry != map->d_map.end()) { - time_t ret = handleHit(*map, entry, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP); + auto entry = getEntryUsingECSIndex(*lockedShard, now, qname, qtype, requireAuth, who, serveStale); + if (entry != lockedShard->d_map.end()) { + time_t ret = handleHit(*lockedShard, entry, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP); if (state && cachedState) { *state = *cachedState; } @@ -408,18 +409,18 @@ time_t MemRecursorCache::get(time_t now, const DNSName& qname, const QType qt, F } if (routingTag) { - auto entries = getEntries(*map, qname, qt, routingTag); + auto entries = getEntries(*lockedShard, qname, qt, routingTag); bool found = false; time_t ttd; if (entries.first != entries.second) { OrderedTagIterator_t firstIndexIterator; for (auto i = entries.first; i != entries.second; ++i) { - firstIndexIterator = map->d_map.project(i); + firstIndexIterator = lockedShard->d_map.project(i); // When serving stale, we consider expired records if (!i->isEntryUsable(now, serveStale)) { - moveCacheItemToFront(map->d_map, firstIndexIterator); + moveCacheItemToFront(lockedShard->d_map, firstIndexIterator); continue; } @@ -430,7 +431,7 @@ time_t MemRecursorCache::get(time_t now, const DNSName& qname, const QType qt, F handleServeStaleBookkeeping(now, serveStale, firstIndexIterator); - ttd = handleHit(*map, firstIndexIterator, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP); + ttd = handleHit(*lockedShard, firstIndexIterator, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP); if (qt != QType::ANY && qt != QType::ADDR) { // normally if we have a hit, we are done break; @@ -448,7 +449,7 @@ time_t MemRecursorCache::get(time_t now, const DNSName& qname, const QType qt, F } } // Try (again) without tag - auto entries = getEntries(*map, qname, qt, boost::none); + auto entries = getEntries(*lockedShard, qname, qt, boost::none); if (entries.first != entries.second) { OrderedTagIterator_t firstIndexIterator; @@ -456,11 +457,11 @@ time_t MemRecursorCache::get(time_t now, const DNSName& qname, const QType qt, F time_t ttd; for (auto i = entries.first; i != entries.second; ++i) { - firstIndexIterator = map->d_map.project(i); + firstIndexIterator = lockedShard->d_map.project(i); // When serving stale, we consider expired records if (!i->isEntryUsable(now, serveStale)) { - moveCacheItemToFront(map->d_map, firstIndexIterator); + moveCacheItemToFront(lockedShard->d_map, firstIndexIterator); continue; } @@ -471,7 +472,7 @@ time_t MemRecursorCache::get(time_t now, const DNSName& qname, const QType qt, F handleServeStaleBookkeeping(now, serveStale, firstIndexIterator); - ttd = handleHit(*map, firstIndexIterator, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP); + ttd = handleHit(*lockedShard, firstIndexIterator, qname, origTTL, res, signatures, authorityRecs, variable, cachedState, wasAuth, fromAuthZone, fromAuthIP); if (qt != QType::ANY && qt != QType::ADDR) { // normally if we have a hit, we are done break; @@ -532,10 +533,10 @@ bool MemRecursorCache::CacheEntry::shouldReplace(time_t now, bool auth, vState s void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, const DNSName& authZone, boost::optional ednsmask, const OptTag& routingTag, vState state, boost::optional from, bool refresh) { - auto& mc = getMap(qname); - auto map = mc.lock(); + auto& shard = getMap(qname); + auto lockedShard = shard.lock(); - map->d_cachecachevalid = false; + lockedShard->d_cachecachevalid = false; if (ednsmask) { ednsmask = ednsmask->getNormalized(); } @@ -544,10 +545,10 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, // We only store an ednsmask if we do not have a tag and we do have a mask. auto key = std::make_tuple(qname, qt.getCode(), ednsmask ? routingTag : boost::none, (ednsmask && !routingTag) ? *ednsmask : Netmask()); bool isNew = false; - cache_t::iterator stored = map->d_map.find(key); - if (stored == map->d_map.end()) { - stored = map->d_map.insert(CacheEntry(key, auth)).first; - ++mc.d_entriesCount; + cache_t::iterator stored = lockedShard->d_map.find(key); + if (stored == lockedShard->d_map.end()) { + stored = lockedShard->d_map.insert(CacheEntry(key, auth)).first; + ++shard.d_entriesCount; isNew = true; } @@ -560,9 +561,9 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, /* don't bother building an ecsIndex if we don't have any netmask-specific entries */ if (!routingTag && ednsmask && !ednsmask->empty()) { auto ecsIndexKey = std::make_tuple(qname, qt.getCode()); - auto ecsIndex = map->d_ecsIndex.find(ecsIndexKey); - if (ecsIndex == map->d_ecsIndex.end()) { - ecsIndex = map->d_ecsIndex.insert(ECSIndexEntry(qname, qt.getCode())).first; + auto ecsIndex = lockedShard->d_ecsIndex.find(ecsIndexKey); + if (ecsIndex == lockedShard->d_ecsIndex.end()) { + ecsIndex = lockedShard->d_ecsIndex.insert(ECSIndexEntry(qname, qt.getCode())).first; } ecsIndex->addMask(*ednsmask); } @@ -611,11 +612,11 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, } if (!isNew) { - moveCacheItemToBack(map->d_map, stored); + moveCacheItemToBack(lockedShard->d_map, stored); } ce.d_submitted = false; ce.d_servedStale = 0; - map->d_map.replace(stored, ce); + lockedShard->d_map.replace(stored, ce); } size_t MemRecursorCache::doWipeCache(const DNSName& name, bool sub, const QType qtype) @@ -623,17 +624,17 @@ size_t MemRecursorCache::doWipeCache(const DNSName& name, bool sub, const QType size_t count = 0; if (!sub) { - auto& mc = getMap(name); - auto map = mc.lock(); - map->d_cachecachevalid = false; - auto& idx = map->d_map.get(); + auto& shard = getMap(name); + auto lockedShard = shard.lock(); + lockedShard->d_cachecachevalid = false; + auto& idx = lockedShard->d_map.get(); auto range = idx.equal_range(name); auto i = range.first; while (i != range.second) { if (i->d_qtype == qtype || qtype == 0xffff) { i = idx.erase(i); count++; - --mc.d_entriesCount; + --shard.d_entriesCount; } else { ++i; @@ -641,12 +642,12 @@ size_t MemRecursorCache::doWipeCache(const DNSName& name, bool sub, const QType } if (qtype == 0xffff) { - auto& ecsIdx = map->d_ecsIndex.get(); + auto& ecsIdx = lockedShard->d_ecsIndex.get(); auto ecsIndexRange = ecsIdx.equal_range(name); ecsIdx.erase(ecsIndexRange.first, ecsIndexRange.second); } else { - auto& ecsIdx = map->d_ecsIndex.get(); + auto& ecsIdx = lockedShard->d_ecsIndex.get(); auto ecsIndexRange = ecsIdx.equal_range(std::tie(name, qtype)); ecsIdx.erase(ecsIndexRange.first, ecsIndexRange.second); } @@ -687,26 +688,27 @@ size_t MemRecursorCache::doWipeCache(const DNSName& name, bool sub, const QType // Name should be doLimitTime or so bool MemRecursorCache::doAgeCache(time_t now, const DNSName& name, const QType qtype, uint32_t newTTL) { - auto& mc = getMap(name); - auto map = mc.lock(); - cache_t::iterator iter = map->d_map.find(std::tie(name, qtype)); - if (iter == map->d_map.end()) { + auto& shard = getMap(name); + auto lockedShard = shard.lock(); + cache_t::iterator iter = lockedShard->d_map.find(std::tie(name, qtype)); + if (iter == lockedShard->d_map.end()) { return false; } CacheEntry ce = *iter; - if (ce.d_ttd < now) + if (ce.d_ttd < now) { return false; // would be dead anyhow + } uint32_t maxTTL = static_cast(ce.d_ttd - now); if (maxTTL > newTTL) { - map->d_cachecachevalid = false; + lockedShard->d_cachecachevalid = false; time_t newTTD = now + newTTL; if (ce.d_ttd > newTTD) { ce.d_ttd = newTTD; - map->d_map.replace(iter, ce); + lockedShard->d_map.replace(iter, ce); } return true; } @@ -775,17 +777,17 @@ uint64_t MemRecursorCache::doDump(int fd, size_t maxCacheEntries) fprintf(fp.get(), "; main record cache dump follows\n;\n"); uint64_t count = 0; - size_t shard = 0; + size_t shardNumber = 0; size_t min = std::numeric_limits::max(); size_t max = 0; - for (auto& mc : d_maps) { - auto map = mc.lock(); - const auto shardSize = map->d_map.size(); - fprintf(fp.get(), "; record cache shard %zu; size %zu\n", shard, shardSize); + for (auto& shard : d_maps) { + auto lockedShard = shard.lock(); + const auto shardSize = lockedShard->d_map.size(); + fprintf(fp.get(), "; record cache shard %zu; size %zu\n", shardNumber, shardSize); min = std::min(min, shardSize); max = std::max(max, shardSize); - shard++; - const auto& sidx = map->d_map.get(); + shardNumber++; + const auto& sidx = lockedShard->d_map.get(); time_t now = time(nullptr); for (const auto& i : sidx) { for (const auto& j : i.d_records) { @@ -820,8 +822,8 @@ void MemRecursorCache::doPrune(size_t keep) namespace boost { -size_t hash_value(const MemRecursorCache::OptTag& o) +size_t hash_value(const MemRecursorCache::OptTag& rtag) { - return o ? hash_value(o.get()) : 0xcafebaaf; + return rtag ? hash_value(rtag.get()) : 0xcafebaaf; } } From 5744c332f30a89249327d573901707fb38faaff3 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 4 Apr 2023 12:01:30 +0200 Subject: [PATCH 057/909] The bulk tests (with it's one client) do not work well with reuseport=yes and many workers Use (the now non-default) reuseport=no --- regression-tests/recursor-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests/recursor-test b/regression-tests/recursor-test index 1af12822fca2..f58f936eb8ae 100755 --- a/regression-tests/recursor-test +++ b/regression-tests/recursor-test @@ -31,7 +31,7 @@ rm -f recursor.pid pdns_recursor.pid system CPU seconds%S wallclock seconds%e %% CPU used%P -' ${RECURSOR} --daemon=no --local-port=$port --socket-dir=./ --trace=$TRACE --config-dir=. --max-mthreads=$mthreads --query-local-address="0.0.0.0${QLA6}" --threads=$threads --record-cache-shards=$shards --refresh-on-ttl-perc=10 --dnssec=validate > recursor.log 2>&1 & +' ${RECURSOR} --daemon=no --local-port=$port --socket-dir=./ --trace=$TRACE --config-dir=. --max-mthreads=$mthreads --query-local-address="0.0.0.0${QLA6}" --threads=$threads --record-cache-shards=$shards --refresh-on-ttl-perc=10 --dnssec=validate --reuseport=no > recursor.log 2>&1 & sleep 3 if [ ! -e pdns_recursor.pid ]; then cat recursor.log From 8b428a6b987418274bf43727858f4fab4ad89bce Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Fri, 17 Feb 2023 13:38:00 +0100 Subject: [PATCH 058/909] rec: Fix unused parameter warnings --- pdns/gss_context.cc | 22 +++--- pdns/gss_context.hh | 25 ++++-- pdns/libssl.cc | 8 +- pdns/recursordist/aggressive_nsec.cc | 6 +- pdns/recursordist/logr.hh | 6 +- pdns/recursordist/lua-recursor4.cc | 24 +++--- pdns/recursordist/mtasker_context.hh | 7 +- pdns/recursordist/negcache.hh | 4 +- pdns/recursordist/nod.cc | 2 +- pdns/recursordist/pdns_recursor.cc | 6 +- pdns/recursordist/rec-main.cc | 6 +- pdns/recursordist/rec-snmp.cc | 4 +- pdns/recursordist/rec-tcp.cc | 2 +- pdns/recursordist/recursor_cache.cc | 2 +- pdns/recursordist/syncres.cc | 4 +- pdns/recursordist/syncres.hh | 2 +- pdns/recursordist/test-aggressive_nsec_cc.cc | 20 ++--- pdns/recursordist/test-mtasker.cc | 2 +- pdns/recursordist/test-nod_cc.cc | 2 +- pdns/recursordist/test-syncres_cc.cc | 10 +-- pdns/recursordist/test-syncres_cc1.cc | 82 ++++++++++---------- pdns/recursordist/test-syncres_cc10.cc | 34 ++++---- pdns/recursordist/test-syncres_cc2.cc | 60 +++++++------- pdns/recursordist/test-syncres_cc3.cc | 68 ++++++++-------- pdns/recursordist/test-syncres_cc4.cc | 46 +++++------ pdns/recursordist/test-syncres_cc5.cc | 50 ++++++------ pdns/recursordist/test-syncres_cc6.cc | 40 +++++----- pdns/recursordist/test-syncres_cc7.cc | 34 ++++---- pdns/recursordist/test-syncres_cc8.cc | 14 ++-- pdns/recursordist/test-syncres_cc9.cc | 40 +++++----- pdns/snmp-agent.cc | 2 +- pdns/tcpiohandler.cc | 2 +- pdns/test-mplexer.cc | 8 +- 33 files changed, 327 insertions(+), 317 deletions(-) diff --git a/pdns/gss_context.cc b/pdns/gss_context.cc index 1c2337100101..b76ca1a21845 100644 --- a/pdns/gss_context.cc +++ b/pdns/gss_context.cc @@ -29,21 +29,21 @@ std::tuple GssContext::getCounts() { return std::make_tu bool GssContext::supported() { return false; } GssContext::GssContext() : d_error(GSS_CONTEXT_UNSUPPORTED), d_type(GSS_CONTEXT_NONE) {} -GssContext::GssContext(const DNSName& label) : +GssContext::GssContext(const DNSName& /* label */) : d_error(GSS_CONTEXT_UNSUPPORTED), d_type(GSS_CONTEXT_NONE) {} -void GssContext::setLocalPrincipal(const std::string& name) {} -bool GssContext::getLocalPrincipal(std::string& name) { return false; } -void GssContext::setPeerPrincipal(const std::string& name) {} -bool GssContext::getPeerPrincipal(std::string& name) { return false; } -void GssContext::generateLabel(const std::string& suffix) {} -void GssContext::setLabel(const DNSName& label) {} -bool GssContext::init(const std::string& input, std::string& output) { return false; } -bool GssContext::accept(const std::string& input, std::string& output) { return false; } +void GssContext::setLocalPrincipal(const std::string& /* name */) {} +bool GssContext::getLocalPrincipal(std::string& /* name */) { return false; } +void GssContext::setPeerPrincipal(const std::string& /* name */) {} +bool GssContext::getPeerPrincipal(std::string& /* name */) { return false; } +void GssContext::generateLabel(const std::string& /* suffix */) {} +void GssContext::setLabel(const DNSName& /* label */) {} +bool GssContext::init(const std::string& /* input */, std::string& /* output */) { return false; } +bool GssContext::accept(const std::string& /* input */, std::string& /* output */) { return false; } bool GssContext::destroy() { return false; } bool GssContext::expired() { return false; } bool GssContext::valid() { return false; } -bool GssContext::sign(const std::string& input, std::string& output) { return false; } -bool GssContext::verify(const std::string& input, const std::string& signature) { return false; } +bool GssContext::sign(const std::string& /* input */, std::string& /* output */) { return false; } +bool GssContext::verify(const std::string& /* input */, const std::string& /* signature */) { return false; } GssContextError GssContext::getError() { return GSS_CONTEXT_UNSUPPORTED; } #else diff --git a/pdns/gss_context.hh b/pdns/gss_context.hh index 4c746befab51..ba2e545e92bc 100644 --- a/pdns/gss_context.hh +++ b/pdns/gss_context.hh @@ -74,10 +74,10 @@ public: setName(name); }; +#ifdef ENABLE_GSS_TSIG //! Parse name into native representation bool setName(const std::string& name) { -#ifdef ENABLE_GSS_TSIG gss_buffer_desc buffer; d_name = GSS_C_NO_NAME; @@ -89,9 +89,13 @@ public: } return true; -#endif + } +#else + bool setName(const std::string& /* name */) + { return false; - }; + } +#endif ~GssName() { @@ -101,24 +105,28 @@ public: #endif }; +#ifdef ENABLE_GSS_TSIG //! Compare two Gss Names, if no gss support is compiled in, returns false always //! This is not necessarily same as string comparison between two non-parsed names bool operator==(const GssName& rhs) { -#ifdef ENABLE_GSS_TSIG OM_uint32 maj, min; int result; maj = gss_compare_name(&min, d_name, rhs.d_name, &result); return (maj == GSS_S_COMPLETE && result != 0); -#endif + } +#else + bool operator==(const GssName& /* rhs */) + { return false; } +#endif +#ifdef ENABLE_GSS_TSIG //! Compare two Gss Names, if no gss support is compiled in, returns false always //! This is not necessarily same as string comparison between two non-parsed names bool match(const std::string& name) { -#ifdef ENABLE_GSS_TSIG OM_uint32 maj, min; int result; gss_name_t comp; @@ -132,10 +140,13 @@ public: maj = gss_compare_name(&min, d_name, comp, &result); gss_release_name(&min, &comp); return (maj == GSS_S_COMPLETE && result != 0); + } #else + bool match(const std::string& /* name */) + { return false; + } #endif - }; //! Check if GSS name was parsed successfully. bool valid() diff --git a/pdns/libssl.cc b/pdns/libssl.cc index a85c5f2da6b5..24fd774a73a8 100644 --- a/pdns/libssl.cc +++ b/pdns/libssl.cc @@ -254,9 +254,9 @@ void libssl_set_ticket_key_callback_data(SSL_CTX* ctx, void* data) } #if OPENSSL_VERSION_MAJOR >= 3 -int libssl_ticket_key_callback(SSL* s, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx, int enc) +int libssl_ticket_key_callback(SSL* /* s */, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx, int enc) #else -int libssl_ticket_key_callback(SSL* s, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx, int enc) +int libssl_ticket_key_callback(SSL* /* s */, OpenSSLTLSTicketKeysRing& keyring, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* iv, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx, int enc) #endif { if (enc != 0) { @@ -300,7 +300,7 @@ static long libssl_server_name_callback(SSL* ssl, int* al, void* arg) return SSL_TLSEXT_ERR_NOACK; } -static void libssl_info_callback(const SSL *ssl, int where, int ret) +static void libssl_info_callback(const SSL *ssl, int where, int /* ret */) { SSL_CTX* sslCtx = SSL_get_SSL_CTX(ssl); if (sslCtx == nullptr) { @@ -680,7 +680,7 @@ void OpenSSLTLSTicketKeysRing::loadTicketsKeys(const std::string& keyFile) file.close(); } -void OpenSSLTLSTicketKeysRing::rotateTicketsKey(time_t now) +void OpenSSLTLSTicketKeysRing::rotateTicketsKey(time_t /* now */) { auto newKey = std::make_shared(); addKey(newKey); diff --git a/pdns/recursordist/aggressive_nsec.cc b/pdns/recursordist/aggressive_nsec.cc index 87500abdaf69..58c2cc56c7d8 100644 --- a/pdns/recursordist/aggressive_nsec.cc +++ b/pdns/recursordist/aggressive_nsec.cc @@ -463,7 +463,7 @@ static void addToRRSet(const time_t now, std::vector& recordSet, std: } } -static void addRecordToRRSet(time_t now, const DNSName& owner, const QType& type, uint32_t ttl, std::shared_ptr& content, std::vector> signatures, bool doDNSSEC, std::vector& ret) +static void addRecordToRRSet(time_t /* now */, const DNSName& owner, const QType& type, uint32_t ttl, std::shared_ptr& content, std::vector> signatures, bool doDNSSEC, std::vector& ret) { DNSRecord nsecRec; nsecRec.d_type = type.getCode(); @@ -488,7 +488,7 @@ static void addRecordToRRSet(time_t now, const DNSName& owner, const QType& type } } -bool AggressiveNSECCache::synthesizeFromNSEC3Wildcard(time_t now, const DNSName& name, const QType& type, std::vector& ret, int& res, bool doDNSSEC, ZoneEntry::CacheEntry& nextCloser, const DNSName& wildcardName, const OptLog& log) +bool AggressiveNSECCache::synthesizeFromNSEC3Wildcard(time_t now, const DNSName& name, const QType& type, std::vector& ret, int& /* res */, bool doDNSSEC, ZoneEntry::CacheEntry& nextCloser, const DNSName& wildcardName, const OptLog& log) { vState cachedState; @@ -510,7 +510,7 @@ bool AggressiveNSECCache::synthesizeFromNSEC3Wildcard(time_t now, const DNSName& return true; } -bool AggressiveNSECCache::synthesizeFromNSECWildcard(time_t now, const DNSName& name, const QType& type, std::vector& ret, int& res, bool doDNSSEC, ZoneEntry::CacheEntry& nsec, const DNSName& wildcardName, const OptLog& log) +bool AggressiveNSECCache::synthesizeFromNSECWildcard(time_t now, const DNSName& name, const QType& type, std::vector& ret, int& /* res */, bool doDNSSEC, ZoneEntry::CacheEntry& nsec, const DNSName& wildcardName, const OptLog& log) { vState cachedState; diff --git a/pdns/recursordist/logr.hh b/pdns/recursordist/logr.hh index 55959d177f34..dea00b806f74 100644 --- a/pdns/recursordist/logr.hh +++ b/pdns/recursordist/logr.hh @@ -170,10 +170,8 @@ private: map.emplace(key, value.to_string()); mapArguments(map, args...); } - void mapArguments(std::map& map) const - { - return; - } + + void mapArguments(std::map& /* map */) const {} }; using log_t = const std::shared_ptr&; diff --git a/pdns/recursordist/lua-recursor4.cc b/pdns/recursordist/lua-recursor4.cc index df2a1bb52454..b35cfd0d9433 100644 --- a/pdns/recursordist/lua-recursor4.cc +++ b/pdns/recursordist/lua-recursor4.cc @@ -156,13 +156,13 @@ struct DynMetric void RecursorLua4::postPrepareContext() { - d_lw->registerMember("qname", [](const DNSQuestion& dq) -> const DNSName& { return dq.qname; }, [](DNSQuestion& dq, const DNSName& newName) { (void) newName; }); - d_lw->registerMember("qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.qtype; }, [](DNSQuestion& dq, uint16_t newType) { (void) newType; }); - d_lw->registerMember("isTcp", [](const DNSQuestion& dq) -> bool { return dq.isTcp; }, [](DNSQuestion& dq, bool newTcp) { (void) newTcp; }); - d_lw->registerMember("localaddr", [](const DNSQuestion& dq) -> const ComboAddress& { return dq.local; }, [](DNSQuestion& dq, const ComboAddress& newLocal) { (void) newLocal; }); - d_lw->registerMember("remoteaddr", [](const DNSQuestion& dq) -> const ComboAddress& { return dq.remote; }, [](DNSQuestion& dq, const ComboAddress& newRemote) { (void) newRemote; }); - d_lw->registerMember("validationState", [](const DNSQuestion& dq) -> uint8_t { return (vStateIsBogus(dq.validationState) ? /* in order not to break older scripts */ static_cast(255) : static_cast(dq.validationState)); }, [](DNSQuestion& dq, uint8_t newState) { (void) newState; }); - d_lw->registerMember("detailedValidationState", [](const DNSQuestion& dq) -> vState { return dq.validationState; }, [](DNSQuestion& dq, vState newState) { (void) newState; }); + d_lw->registerMember("qname", [](const DNSQuestion& dq) -> const DNSName& { return dq.qname; }, [](DNSQuestion& /* dq */, const DNSName& newName) { (void) newName; }); + d_lw->registerMember("qtype", [](const DNSQuestion& dq) -> uint16_t { return dq.qtype; }, [](DNSQuestion& /* dq */, uint16_t newType) { (void) newType; }); + d_lw->registerMember("isTcp", [](const DNSQuestion& dq) -> bool { return dq.isTcp; }, [](DNSQuestion& /* dq */, bool newTcp) { (void) newTcp; }); + d_lw->registerMember("localaddr", [](const DNSQuestion& dq) -> const ComboAddress& { return dq.local; }, [](DNSQuestion& /* dq */, const ComboAddress& newLocal) { (void) newLocal; }); + d_lw->registerMember("remoteaddr", [](const DNSQuestion& dq) -> const ComboAddress& { return dq.remote; }, [](DNSQuestion& /* dq */, const ComboAddress& newRemote) { (void) newRemote; }); + d_lw->registerMember("validationState", [](const DNSQuestion& dq) -> uint8_t { return (vStateIsBogus(dq.validationState) ? /* in order not to break older scripts */ static_cast(255) : static_cast(dq.validationState)); }, [](DNSQuestion& /* dq */, uint8_t newState) { (void) newState; }); + d_lw->registerMember("detailedValidationState", [](const DNSQuestion& dq) -> vState { return dq.validationState; }, [](DNSQuestion& /* dq */, vState newState) { (void) newState; }); d_lw->registerMember("variable", [](const DNSQuestion& dq) -> bool { return dq.variable; }, [](DNSQuestion& dq, bool newVariable) { dq.variable = newVariable; }); d_lw->registerMember("wantsRPZ", [](const DNSQuestion& dq) -> bool { return dq.wantsRPZ; }, [](DNSQuestion& dq, bool newWantsRPZ) { dq.wantsRPZ = newWantsRPZ; }); @@ -274,7 +274,7 @@ void RecursorLua4::postPrepareContext() } return result; }, - [](EDNSOptionView& option, uint16_t newSize) { (void) newSize; }); + [](EDNSOptionView& /* option */, uint16_t newSize) { (void) newSize; }); d_lw->registerFunction("getContent", [](const EDNSOptionView& option) { if (option.values.empty()) { return std::string(); @@ -436,10 +436,10 @@ void RecursorLua4::postPrepareContext() return getRegisteredName(dname); }); - d_lw->registerMember("qname", [](const PolicyEvent& event) -> const DNSName& { return event.qname; }, [](PolicyEvent& event, const DNSName& newName) { (void) newName; }); - d_lw->registerMember("qtype", [](const PolicyEvent& event) -> uint16_t { return event.qtype.getCode(); }, [](PolicyEvent& event, uint16_t newType) { (void) newType; }); - d_lw->registerMember("isTcp", [](const PolicyEvent& event) -> bool { return event.isTcp; }, [](PolicyEvent& event, bool newTcp) { (void) newTcp; }); - d_lw->registerMember("remote", [](const PolicyEvent& event) -> const ComboAddress& { return event.remote; }, [](PolicyEvent& event, const ComboAddress& newRemote) { (void) newRemote; }); + d_lw->registerMember("qname", [](const PolicyEvent& event) -> const DNSName& { return event.qname; }, [](PolicyEvent& /* event */, const DNSName& newName) { (void) newName; }); + d_lw->registerMember("qtype", [](const PolicyEvent& event) -> uint16_t { return event.qtype.getCode(); }, [](PolicyEvent& /* event */, uint16_t newType) { (void) newType; }); + d_lw->registerMember("isTcp", [](const PolicyEvent& event) -> bool { return event.isTcp; }, [](PolicyEvent& /* event */, bool newTcp) { (void) newTcp; }); + d_lw->registerMember("remote", [](const PolicyEvent& event) -> const ComboAddress& { return event.remote; }, [](PolicyEvent& /* event */, const ComboAddress& newRemote) { (void) newRemote; }); d_lw->registerMember("appliedPolicy", &PolicyEvent::appliedPolicy); d_lw->registerFunction("addPolicyTag", [](PolicyEvent& event, const std::string& tag) { if (event.policyTags) { event.policyTags->insert(tag); } }); d_lw->registerFunction >&)>("setPolicyTags", [](PolicyEvent& event, const std::vector >& tags) { diff --git a/pdns/recursordist/mtasker_context.hh b/pdns/recursordist/mtasker_context.hh index fe8c1757ca9f..dbc5683f2964 100644 --- a/pdns/recursordist/mtasker_context.hh +++ b/pdns/recursordist/mtasker_context.hh @@ -54,12 +54,15 @@ extern __thread void* t_mainStack; extern __thread size_t t_mainStackSize; #endif /* HAVE_FIBER_SANITIZER */ +#ifdef HAVE_FIBER_SANITIZER static inline void notifyStackSwitch(const void* startOfStack, size_t stackSize) { -#ifdef HAVE_FIBER_SANITIZER __sanitizer_start_switch_fiber(nullptr, startOfStack, stackSize); -#endif /* HAVE_FIBER_SANITIZER */ } +#else +static inline void notifyStackSwitch(const void* /* startOfStack */, size_t /* stackSize */) +{} +#endif /* HAVE_FIBER_SANITIZER */ static inline void notifyStackSwitchToKernel() { diff --git a/pdns/recursordist/negcache.hh b/pdns/recursordist/negcache.hh index f8e8ce0be50e..90d64ee822fb 100644 --- a/pdns/recursordist/negcache.hh +++ b/pdns/recursordist/negcache.hh @@ -170,7 +170,5 @@ private: } public: - void preRemoval(MapCombo::LockedContent& map, const NegCacheEntry& entry) - { - } + void preRemoval(MapCombo::LockedContent& /* map */, const NegCacheEntry& /* entry */) {} }; diff --git a/pdns/recursordist/nod.cc b/pdns/recursordist/nod.cc index f2f064f2bef9..e35fc699b002 100644 --- a/pdns/recursordist/nod.cc +++ b/pdns/recursordist/nod.cc @@ -40,7 +40,7 @@ namespace filesystem = boost::filesystem; std::mutex PersistentSBF::d_cachedir_mutex; -void PersistentSBF::remove_tmp_files(const filesystem::path& p, std::lock_guard& lock) +void PersistentSBF::remove_tmp_files(const filesystem::path& p, std::lock_guard& /* lock */) { Regex file_regex(d_prefix + ".*\\." + bf_suffix + "\\..{8}$"); for (filesystem::directory_iterator i(p); i != filesystem::directory_iterator(); ++i) { diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 071c09d20117..f6e0c6bb0303 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -263,7 +263,7 @@ static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t&); thread_local std::unique_ptr t_udpclientsocks; /* these two functions are used by LWRes */ -LWResult::Result asendto(const char* data, size_t len, int flags, +LWResult::Result asendto(const char* data, size_t len, int /* flags */, const ComboAddress& toaddr, uint16_t id, const DNSName& domain, uint16_t qtype, bool ecs, int* fd) { @@ -315,7 +315,7 @@ LWResult::Result asendto(const char* data, size_t len, int flags, return LWResult::Result::Success; } -LWResult::Result arecvfrom(PacketBuffer& packet, int flags, const ComboAddress& fromaddr, size_t* d_len, +LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAddress& fromaddr, size_t* d_len, uint16_t id, const DNSName& domain, uint16_t qtype, int fd, const struct timeval* now) { static const unsigned int nearMissLimit = ::arg().asNum("spoof-nearmiss-max"); @@ -2322,7 +2322,7 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr return 0; } -static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& var) +static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) { ssize_t len; static const size_t maxIncomingQuerySize = g_proxyProtocolACL.empty() ? 512 : (512 + g_proxyProtocolMaximumSize); diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 7de44b7187ca..f13c7ff27472 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1362,7 +1362,7 @@ template ThreadTimes broadcastAccFunction(const std::function& f template ProxyMappingStats_t broadcastAccFunction(const std::function& fun); template RemoteLoggerStats_t broadcastAccFunction(const std::function& fun); -static int serviceMain(int argc, char* argv[], Logr::log_t log) +static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) { g_log.setName(g_programname); g_log.disableSyslog(::arg().mustDo("disable-syslog")); @@ -2015,7 +2015,7 @@ static int serviceMain(int argc, char* argv[], Logr::log_t log) return RecThreadInfo::runThreads(log); } -static void handlePipeRequest(int fd, FDMultiplexer::funcparam_t& var) +static void handlePipeRequest(int fd, FDMultiplexer::funcparam_t& /* var */) { ThreadMSG* tmsg = nullptr; @@ -2049,7 +2049,7 @@ static void handlePipeRequest(int fd, FDMultiplexer::funcparam_t& var) delete tmsg; } -static void handleRCC(int fd, FDMultiplexer::funcparam_t& var) +static void handleRCC(int fd, FDMultiplexer::funcparam_t& /* var */) { auto log = g_slog->withName("control"); try { diff --git a/pdns/recursordist/rec-snmp.cc b/pdns/recursordist/rec-snmp.cc index d7a4ad64f97c..35519347618a 100644 --- a/pdns/recursordist/rec-snmp.cc +++ b/pdns/recursordist/rec-snmp.cc @@ -177,7 +177,7 @@ static std::unordered_map s_statsMap; /* a instance handler also only hands us one request at a time, so we don't need to loop over a list of requests; we'll only get one. */ -static int handleCounter64Stats(netsnmp_mib_handler* handler, +static int handleCounter64Stats(netsnmp_mib_handler* /* handler */, netsnmp_handler_registration* reginfo, netsnmp_agent_request_info* reqinfo, netsnmp_request_info* requests) @@ -204,7 +204,7 @@ static int handleCounter64Stats(netsnmp_mib_handler* handler, } } -static int handleDisabledCounter64Stats(netsnmp_mib_handler* handler, +static int handleDisabledCounter64Stats(netsnmp_mib_handler* /* handler */, netsnmp_handler_registration* reginfo, netsnmp_agent_request_info* reqinfo, netsnmp_request_info* requests) diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index fcb5c42fffaf..fb78c064c0aa 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -189,7 +189,7 @@ class RunningTCPQuestionGuard { d_fd = -1; } - bool handleTCPReadResult(int fd, ssize_t bytes) + bool handleTCPReadResult(int /* fd */, ssize_t bytes) { if (bytes == 0) { /* EOF */ diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index a95f153516df..4c95c052c55c 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -292,7 +292,7 @@ MemRecursorCache::cache_t::const_iterator MemRecursorCache::getEntryUsingECSInde return map.d_map.end(); } -MemRecursorCache::Entries MemRecursorCache::getEntries(MapCombo::LockedContent& map, const DNSName& qname, const QType qt, const OptTag& rtag) +MemRecursorCache::Entries MemRecursorCache::getEntries(MapCombo::LockedContent& map, const DNSName& qname, const QType /* qt */, const OptTag& rtag) { // MUTEX SHOULD BE ACQUIRED if (!map.d_cachecachevalid || map.d_cachedqname != qname || map.d_cachedrtag != rtag) { diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 83c6e9cc56f5..f7270474f106 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1009,7 +1009,7 @@ bool SyncRes::doOOBResolve(const AuthDomain& domain, const DNSName& qname, const return true; } -bool SyncRes::doOOBResolve(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res) +bool SyncRes::doOOBResolve(const DNSName& qname, const QType qtype, vector& ret, unsigned int /* depth */, const string& prefix, int& res) { DNSName authdomain(qname); domainmap_t::const_iterator iter = getBestAuthZone(&authdomain); @@ -3329,7 +3329,7 @@ bool SyncRes::nameserverIPBlockedByRPZ(const DNSFilterEngine& dfe, const ComboAd return false; } -vector SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector>::const_iterator& tns, const unsigned int depth, set& beenthere, const vector>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& flawedNSSet, bool cacheOnly, unsigned int& nretrieveAddressesForNS) +vector SyncRes::retrieveAddressesForNS(const std::string& prefix, const DNSName& qname, std::vector>::const_iterator& tns, const unsigned int depth, set& beenthere, const vector>& rnameservers, NsSet& nameservers, bool& sendRDQuery, bool& pierceDontQuery, bool& /* flawedNSSet */, bool cacheOnly, unsigned int& nretrieveAddressesForNS) { vector result; diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index fef7b96178b2..b271acfbfaf6 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -764,7 +764,7 @@ struct PacketID TCPAction highState{TCPAction::DoingRead}; IOState lowState{IOState::NeedRead}; - bool operator<(const PacketID& b) const + bool operator<(const PacketID& /* b */) const { // We don't want explicit PacketID compare here, but always via predicate classes below assert(0); diff --git a/pdns/recursordist/test-aggressive_nsec_cc.cc b/pdns/recursordist/test-aggressive_nsec_cc.cc index 73d75ec6cd6f..f5424e608a76 100644 --- a/pdns/recursordist/test-aggressive_nsec_cc.cc +++ b/pdns/recursordist/test-aggressive_nsec_cc.cc @@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_nxdomain) size_t queriesCount = 0; - sr->setAsyncCallback([target1, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target1, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -147,7 +147,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_nodata) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -233,7 +233,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_nodata_wildcard) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -326,7 +326,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_ancestor) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -440,7 +440,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_wildcard_synthesis) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -557,7 +557,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_nxdomain) size_t queriesCount = 0; - sr->setAsyncCallback([target1, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target1, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -660,7 +660,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_nodata) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -747,7 +747,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_nodata_wildcard) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -852,7 +852,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_ancestor) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -972,7 +972,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_wildcard_synthesis) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { diff --git a/pdns/recursordist/test-mtasker.cc b/pdns/recursordist/test-mtasker.cc index 246924298c98..dd716cae0e5c 100644 --- a/pdns/recursordist/test-mtasker.cc +++ b/pdns/recursordist/test-mtasker.cc @@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE(test_MtaskerException) #else -static void willThrow(void* p) +static void willThrow(void* /* p */) { throw std::runtime_error("Help!"); } diff --git a/pdns/recursordist/test-nod_cc.cc b/pdns/recursordist/test-nod_cc.cc index 9748b55783d8..d76457041940 100644 --- a/pdns/recursordist/test-nod_cc.cc +++ b/pdns/recursordist/test-nod_cc.cc @@ -9,7 +9,7 @@ using namespace nod; BOOST_AUTO_TEST_SUITE(nod_cc) -static bool pdns_exception(PDNSException const& ex) { return true; } +static bool pdns_exception(PDNSException const& /* ex */) { return true; } BOOST_AUTO_TEST_CASE(test_basic) { diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index ae574ebe0383..f291661e90f1 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -32,16 +32,16 @@ BaseLua4::~BaseLua4() { } -void BaseLua4::getFeatures(Features&) +void BaseLua4::getFeatures(Features& /* features */) { } -bool RecursorLua4::preoutquery(const ComboAddress& ns, const ComboAddress& requestor, const DNSName& query, const QType& qtype, bool isTcp, vector& res, int& ret, RecEventTrace& et, const struct timeval& tv) const +bool RecursorLua4::preoutquery(const ComboAddress& /* ns */, const ComboAddress& /* requestor */, const DNSName& /* query */, const QType& /* qtype */, bool /* isTcp */, vector& /* res */, int& /* ret */, RecEventTrace& /* et */, const struct timeval& /* tv */) const { return false; } -bool RecursorLua4::policyHitEventFilter(const ComboAddress& remote, const DNSName& qname, const QType& qtype, bool tcp, DNSFilterEngine::Policy& policy, std::unordered_set& tags, std::unordered_map& discardedPolicies) const +bool RecursorLua4::policyHitEventFilter(const ComboAddress& /* remote */, const DNSName& /* qname */, const QType& /* qtype */, bool /* tcp */, DNSFilterEngine::Policy& /* policy */, std::unordered_set& /* tags */, std::unordered_map& /* discardedPolicies */) const { return false; } @@ -58,11 +58,11 @@ void RecursorLua4::postLoad() { } -void RecursorLua4::getFeatures(Features& features) +void RecursorLua4::getFeatures(Features& /* features */) { } -LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, const std::shared_ptr>>& outgoingLoggers, const std::shared_ptr>>& fstrmLoggers, const std::set& exportTypes, LWResult* res, bool* chained) +LWResult::Result asyncresolve(const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, const std::shared_ptr>>& /* outgoingLoggers */, const std::shared_ptr>>& /* fstrmLoggers */, const std::set& /* exportTypes */, LWResult* /* res */, bool* /* chained */) { return LWResult::Result::Timeout; } diff --git a/pdns/recursordist/test-syncres_cc1.cc b/pdns/recursordist/test-syncres_cc1.cc index e218e86c4374..9d1c19d420c8 100644 --- a/pdns/recursordist/test-syncres_cc1.cc +++ b/pdns/recursordist/test-syncres_cc1.cc @@ -47,7 +47,7 @@ BOOST_AUTO_TEST_CASE(test_root_primed_ns) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -82,7 +82,7 @@ BOOST_AUTO_TEST_CASE(test_root_not_primed) size_t queriesCount = 0; - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == g_rootdnsname && type == QType::NS) { @@ -118,7 +118,7 @@ BOOST_AUTO_TEST_CASE(test_root_not_primed_and_no_response) then call getRootNS(), for which at least one of the root servers needs to answer. None will, so it should ServFail. */ - sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { downServers.insert(ip); return LWResult::Result::Timeout; }); @@ -142,7 +142,7 @@ BOOST_AUTO_TEST_CASE(test_root_ns_poison_resistance) primeHints(); const DNSName target("www.example.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (domain == g_rootdnsname && type == QType::NS) { setLWResult(res, 0, true, false, true); @@ -207,7 +207,7 @@ BOOST_AUTO_TEST_CASE(test_root_primed_ns_update) size_t queriesCount = 0; - auto asynccb = [target, &queriesCount, aroot, newA, newAAAA](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + auto asynccb = [target, &queriesCount, aroot, newA, newAAAA](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -262,7 +262,7 @@ static void test_edns_formerr_fallback_f(bool sample) size_t queriesWithEDNS = 0; size_t queriesWithoutEDNS = 0; - sr->setAsyncCallback([&queriesWithEDNS, &queriesWithoutEDNS, &noEDNSServer, sample](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesWithEDNS, &queriesWithoutEDNS, &noEDNSServer, sample](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool /* sendRDQuery */, int EDNS0Level, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (EDNS0Level != 0) { queriesWithEDNS++; noEDNSServer = ip; @@ -320,7 +320,7 @@ BOOST_AUTO_TEST_CASE(test_edns_formerr_but_edns_enabled) size_t queriesWithoutEDNS = 0; std::set usedServers; - sr->setAsyncCallback([&queriesWithEDNS, &queriesWithoutEDNS, &usedServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesWithEDNS, &queriesWithoutEDNS, &usedServers](const ComboAddress& ip, const DNSName& /* domain */, int type, bool /* doTCP */, bool /* sendRDQuery */, int EDNS0Level, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (EDNS0Level > 0) { queriesWithEDNS++; } @@ -365,7 +365,7 @@ BOOST_AUTO_TEST_CASE(test_meta_types) for (const auto qtype : invalidTypes) { size_t queriesCount = 0; - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; }); @@ -385,7 +385,7 @@ BOOST_AUTO_TEST_CASE(test_tc_fallback_to_tcp) std::unique_ptr sr; initSR(sr); - sr->setAsyncCallback([](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([](const ComboAddress& /* ip */, const DNSName& domain, int type, bool doTCP, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (!doTCP) { setLWResult(res, 0, false, true, false); return LWResult::Result::Success; @@ -414,7 +414,7 @@ BOOST_AUTO_TEST_CASE(test_tc_over_tcp) size_t tcpQueriesCount = 0; - sr->setAsyncCallback([&tcpQueriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&tcpQueriesCount](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool doTCP, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (!doTCP) { setLWResult(res, 0, true, true, false); return LWResult::Result::Success; @@ -449,7 +449,7 @@ BOOST_AUTO_TEST_CASE(test_all_nss_down) primeHints(); - sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -496,7 +496,7 @@ BOOST_AUTO_TEST_CASE(test_all_nss_network_error) primeHints(); - sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -545,7 +545,7 @@ BOOST_AUTO_TEST_CASE(test_all_nss_send_tc_then_garbage_over_tcp) std::set downServers; - sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool doTCP, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "lock-up.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -591,7 +591,7 @@ BOOST_AUTO_TEST_CASE(test_all_nss_send_garbage_over_udp) std::set downServers; size_t queriesCount = 0; - sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "lock-up.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -635,7 +635,7 @@ BOOST_AUTO_TEST_CASE(test_regular_ns_send_refused) std::set downServers; size_t queriesCount = 0; - sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "refused.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -687,7 +687,7 @@ BOOST_AUTO_TEST_CASE(test_forward_ns_send_refused) ad.d_servers = forwardedNSs; (*SyncRes::t_sstorage.domainmap)[target] = ad; - sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "refused.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -738,7 +738,7 @@ BOOST_AUTO_TEST_CASE(test_forward_ns_send_servfail) ad.d_servers = forwardedNSs; (*SyncRes::t_sstorage.domainmap)[DNSName("refused.")] = ad; - sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, &downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "refused.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -781,7 +781,7 @@ BOOST_AUTO_TEST_CASE(test_only_one_ns_up_resolving_itself_with_glue) DNSName target("www.powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); if (domain == target) { @@ -835,7 +835,7 @@ BOOST_AUTO_TEST_CASE(test_os_limit_errors) primeHints(); - sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&downServers](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -892,7 +892,7 @@ BOOST_AUTO_TEST_CASE(test_glued_referral) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ if (domain != target) { return LWResult::Result::Timeout; @@ -942,7 +942,7 @@ BOOST_AUTO_TEST_CASE(test_glueless_referral) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -1011,7 +1011,7 @@ BOOST_AUTO_TEST_CASE(test_glueless_referral_aaaa_task) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -1099,7 +1099,7 @@ BOOST_AUTO_TEST_CASE(test_edns_subnet_by_domain) incomingECS.source = Netmask("192.0.2.128/32"); sr->setQuerySource(ComboAddress(), boost::optional(incomingECS)); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { BOOST_REQUIRE(srcmask); BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24"); @@ -1159,7 +1159,7 @@ BOOST_AUTO_TEST_CASE(test_edns_subnet_by_addr) incomingECS.source = Netmask("2001:DB8::FF/128"); sr->setQuerySource(ComboAddress(), boost::optional(incomingECS)); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { BOOST_REQUIRE(!srcmask); @@ -1211,7 +1211,7 @@ BOOST_AUTO_TEST_CASE(test_ecs_use_requestor) // No incoming ECS data sr->setQuerySource(ComboAddress("192.0.2.127"), boost::none); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { BOOST_REQUIRE(!srcmask); @@ -1255,7 +1255,7 @@ BOOST_AUTO_TEST_CASE(test_ecs_use_scope_zero) // No incoming ECS data, Requestor IP not in ecs-add-for sr->setQuerySource(ComboAddress("192.0.2.127"), boost::none); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { BOOST_REQUIRE(!srcmask); @@ -1300,7 +1300,7 @@ BOOST_AUTO_TEST_CASE(test_ecs_honor_incoming_mask) incomingECS.source = Netmask("192.0.0.0/16"); sr->setQuerySource(ComboAddress("192.0.2.127"), boost::optional(incomingECS)); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { BOOST_REQUIRE(!srcmask); @@ -1345,7 +1345,7 @@ BOOST_AUTO_TEST_CASE(test_ecs_honor_incoming_mask_zero) incomingECS.source = Netmask("0.0.0.0/0"); sr->setQuerySource(ComboAddress("192.0.2.127"), boost::optional(incomingECS)); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { BOOST_REQUIRE(!srcmask); @@ -1385,7 +1385,7 @@ BOOST_AUTO_TEST_CASE(test_following_cname) const DNSName target("cname.powerdns.com."); const DNSName cnameTarget("cname-target.powerdns.com"); - sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, domain, QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -1430,7 +1430,7 @@ BOOST_AUTO_TEST_CASE(test_cname_nxdomain) const DNSName target("cname.powerdns.com."); const DNSName cnameTarget("cname-target.powerdns.com"); - sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "powerdns.com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -1488,7 +1488,7 @@ BOOST_AUTO_TEST_CASE(test_included_poisonous_cname) const DNSName target("cname.powerdns.com."); const DNSName cnameTarget("cname-target.powerdns.com"); - sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -1539,7 +1539,7 @@ BOOST_AUTO_TEST_CASE(test_cname_loop) size_t count = 0; const DNSName target("cname.powerdns.com."); - sr->setAsyncCallback([target, &count](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &count](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { count++; if (isRootServer(ip)) { @@ -1592,7 +1592,7 @@ BOOST_AUTO_TEST_CASE(test_cname_long_loop) const DNSName target3("cname3.powerdns.com."); const DNSName target4("cname4.powerdns.com."); - sr->setAsyncCallback([target1, target2, target3, target4, &count](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target1, target2, target3, target4, &count](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { count++; if (isRootServer(ip)) { @@ -1657,7 +1657,7 @@ BOOST_AUTO_TEST_CASE(test_cname_depth) size_t depth = 0; const DNSName target("cname.powerdns.com."); - sr->setAsyncCallback([target, &depth](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &depth](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -1694,7 +1694,7 @@ BOOST_AUTO_TEST_CASE(test_time_limit) size_t queries = 0; const DNSName target("cname.powerdns.com."); - sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; if (isRootServer(ip)) { @@ -1750,7 +1750,7 @@ BOOST_AUTO_TEST_CASE(test_dname_processing) size_t queries = 0; - sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, uncachedTarget, uncachedCNAMETarget, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, uncachedTarget, uncachedCNAMETarget, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; if (isRootServer(ip)) { @@ -1894,7 +1894,7 @@ BOOST_AUTO_TEST_CASE(test_dname_dnssec_secure) size_t queries = 0; - sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; /* We don't use the genericDSAndDNSKEYHandler here, as it would deny names existing at the wrong level of the tree, due to the way computeZoneCuts works * As such, we need to do some more work to make the answers correct. @@ -2045,7 +2045,7 @@ BOOST_AUTO_TEST_CASE(test_dname_plus_ns_dnssec_secure) size_t queries = 0; - sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; if (type == QType::DS || type == QType::DNSKEY) { @@ -2152,7 +2152,7 @@ BOOST_AUTO_TEST_CASE(test_dname_dnssec_insecure) size_t queries = 0; - sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, keys, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; if (isRootServer(ip)) { @@ -2281,7 +2281,7 @@ BOOST_AUTO_TEST_CASE(test_dname_processing_no_CNAME) size_t queries = 0; - sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([dnameOwner, dnameTarget, target, cnameTarget, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; if (isRootServer(ip)) { @@ -2372,7 +2372,7 @@ BOOST_AUTO_TEST_CASE(test_glued_referral_child_ns_set_wrong) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ if (domain != target) { return LWResult::Result::Timeout; diff --git a/pdns/recursordist/test-syncres_cc10.cc b/pdns/recursordist/test-syncres_cc10.cc index a20dfc489e7a..0218cf39ffbe 100644 --- a/pdns/recursordist/test-syncres_cc10.cc +++ b/pdns/recursordist/test-syncres_cc10.cc @@ -17,7 +17,7 @@ BOOST_AUTO_TEST_CASE(test_outgoing_v4_only) int queries = 0; const DNSName target("powerdns.com."); - sr->setAsyncCallback([target, &v4Hit, &v6Hit, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &v4Hit, &v6Hit, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE(test_outgoing_v4_only_no_A_in_delegation) int queries = 0; const DNSName target("powerdns.com."); - sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -109,7 +109,7 @@ BOOST_AUTO_TEST_CASE(test_outgoing_v6_only_no_AAAA_in_delegation) int queries = 0; const DNSName target("powerdns.com."); - sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -160,7 +160,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_skipped_cut_invalid_ds_denia size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_wrong_rrsig_fake_signer) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -406,7 +406,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_missing_soa) size_t queriesCount = 0; - sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -552,7 +552,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_missing_dnskey) size_t queriesCount = 0; - sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -682,7 +682,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_nxd_dnskey) size_t queriesCount = 0; - sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -812,7 +812,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_nxd_ds) size_t queriesCount = 0; - sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -945,7 +945,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_loop) size_t queriesCount = 0; - sr->setAsyncCallback([targetAddr, &queriesCount, keys, wrongKeys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([targetAddr, &queriesCount, keys, wrongKeys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -1075,7 +1075,7 @@ BOOST_AUTO_TEST_CASE(test_servestale) const int theTTL = 5; - sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ if (downServers.find(ip) != downServers.end()) { downCount++; @@ -1213,7 +1213,7 @@ BOOST_AUTO_TEST_CASE(test_servestale_neg) const int theTTL = 5; - sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ if (downServers.find(ip) != downServers.end()) { downCount++; @@ -1348,7 +1348,7 @@ BOOST_AUTO_TEST_CASE(test_servestale_neg_to_available) const int theTTL = 5; const int negTTL = 60; - sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &negLookup, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &negLookup, target](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ if (downServers.find(ip) != downServers.end()) { downCount++; @@ -1491,7 +1491,7 @@ BOOST_AUTO_TEST_CASE(test_servestale_cname_to_nxdomain) const int theTTL = 5; const int negTTL = 60; - sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &cnameOK, target, auth](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &cnameOK, target, auth](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ if (downServers.find(ip) != downServers.end()) { downCount++; @@ -1716,7 +1716,7 @@ BOOST_AUTO_TEST_CASE(test_glued_referral_additional_update) const DNSName target1("powerdns.com."); const DNSName target2("pdns.com."); - sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ if (domain != target1 && domain != target2) { return LWResult::Result::Timeout; @@ -1807,7 +1807,7 @@ BOOST_AUTO_TEST_CASE(test_glued_referral_additional_no_update_because_locked) const DNSName target1("powerdns.com."); const DNSName target2("pdns.com."); - sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ if (domain != target1 && domain != target2) { return LWResult::Result::Timeout; @@ -1897,7 +1897,7 @@ BOOST_AUTO_TEST_CASE(test_locked_nonauth_update_to_auth) const DNSName target("powerdns.com."); - sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([=](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ if (domain != target) { return LWResult::Result::Timeout; diff --git a/pdns/recursordist/test-syncres_cc2.cc b/pdns/recursordist/test-syncres_cc2.cc index 32372fe3e02e..8d4bb74b50d1 100644 --- a/pdns/recursordist/test-syncres_cc2.cc +++ b/pdns/recursordist/test-syncres_cc2.cc @@ -17,7 +17,7 @@ static void do_test_referral_depth(bool limited) size_t queries = 0; const DNSName target("www.powerdns.com."); - sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; if (isRootServer(ip)) { @@ -115,7 +115,7 @@ BOOST_AUTO_TEST_CASE(test_glueless_referral_loop) const DNSName target2("powerdns.org."); size_t queriesToNS = 0; - sr->setAsyncCallback([target1, target2, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target1, target2, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesToNS++; if (isRootServer(ip)) { @@ -181,7 +181,7 @@ BOOST_AUTO_TEST_CASE(test_glueless_referral_loop_with_nonresolving) const DNSName target2("powerdns.org."); size_t queriesToNS = 0; - sr->setAsyncCallback([target1, target2, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target1, target2, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesToNS++; if (isRootServer(ip)) { @@ -246,7 +246,7 @@ BOOST_AUTO_TEST_CASE(test_glueless_referral_with_non_resolving) size_t queryCount = 0; - sr->setAsyncCallback([target, &queryCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queryCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -341,7 +341,7 @@ BOOST_AUTO_TEST_CASE(test_cname_qperq) size_t queries = 0; const DNSName target("cname.powerdns.com."); - sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queries](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queries++; if (isRootServer(ip)) { @@ -385,7 +385,7 @@ BOOST_AUTO_TEST_CASE(test_throttled_server) const ComboAddress ns("192.0.2.1:53"); size_t queriesToNS = 0; - sr->setAsyncCallback([target, ns, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, ns, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -471,7 +471,7 @@ BOOST_AUTO_TEST_CASE(test_dont_query_server) const ComboAddress ns("192.0.2.1:53"); size_t queriesToNS = 0; - sr->setAsyncCallback([target, ns, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, ns, &queriesToNS](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -515,7 +515,7 @@ BOOST_AUTO_TEST_CASE(test_root_nx_trust) const ComboAddress ns("192.0.2.1:53"); size_t queriesCount = 0; - sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (isRootServer(ip)) { @@ -580,7 +580,7 @@ BOOST_AUTO_TEST_CASE(test_root_nx_trust_specific) /* This time the root denies target1 with a "com." SOA instead of a "." one. We should add target1 to the negcache, but not "com.". */ - sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (isRootServer(ip)) { @@ -642,7 +642,7 @@ BOOST_AUTO_TEST_CASE(test_root_nx_dont_trust) const ComboAddress ns("192.0.2.1:53"); size_t queriesCount = 0; - sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target1, target2, ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (isRootServer(ip)) { @@ -705,7 +705,7 @@ BOOST_AUTO_TEST_CASE(test_rfc8020_nothing_underneath) const ComboAddress ns("192.0.2.1:53"); size_t queriesCount = 0; - sr->setAsyncCallback([ns, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([ns, &queriesCount](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (isRootServer(ip)) { @@ -814,7 +814,7 @@ BOOST_AUTO_TEST_CASE(test_rfc8020_nothing_underneath_dnssec) size_t queriesCount = 0; - sr->setAsyncCallback([target1, target2, target3, target4, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target1, target2, target3, target4, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -974,7 +974,7 @@ BOOST_AUTO_TEST_CASE(test_rfc8020_nodata) const ComboAddress ns("192.0.2.1:53"); size_t queriesCount = 0; - sr->setAsyncCallback([ns, target1, target2, target3, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([ns, target1, target2, target3, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (isRootServer(ip)) { @@ -1048,7 +1048,7 @@ BOOST_AUTO_TEST_CASE(test_rfc8020_nodata_bis) const ComboAddress ns("192.0.2.1:53"); size_t queriesCount = 0; - sr->setAsyncCallback([ns, target1, target2, target3, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([ns, target1, target2, target3, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (isRootServer(ip)) { @@ -1124,7 +1124,7 @@ BOOST_AUTO_TEST_CASE(test_dont_skip_negcache_for_variable_response) incomingECS.source = Netmask("192.0.2.128/32"); sr->setQuerySource(ComboAddress(), boost::optional(incomingECS)); - sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { BOOST_REQUIRE(srcmask); BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24"); @@ -1180,7 +1180,7 @@ BOOST_AUTO_TEST_CASE(test_ecs_cache_limit_allowed) sr->setQuerySource(ComboAddress(), boost::optional(incomingECS)); SyncRes::s_ecsipv4cachelimit = 24; - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { BOOST_REQUIRE(srcmask); BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24"); @@ -1219,7 +1219,7 @@ BOOST_AUTO_TEST_CASE(test_ecs_cache_limit_no_ttl_limit_allowed) sr->setQuerySource(ComboAddress(), boost::optional(incomingECS)); SyncRes::s_ecsipv4cachelimit = 16; - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { BOOST_REQUIRE(srcmask); BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24"); @@ -1258,7 +1258,7 @@ BOOST_AUTO_TEST_CASE(test_ecs_cache_ttllimit_allowed) sr->setQuerySource(ComboAddress(), boost::optional(incomingECS)); SyncRes::s_ecscachelimitttl = 30; - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { BOOST_REQUIRE(srcmask); BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24"); @@ -1298,7 +1298,7 @@ BOOST_AUTO_TEST_CASE(test_ecs_cache_ttllimit_and_scope_allowed) SyncRes::s_ecscachelimitttl = 100; SyncRes::s_ecsipv4cachelimit = 24; - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { BOOST_REQUIRE(srcmask); BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24"); @@ -1338,7 +1338,7 @@ BOOST_AUTO_TEST_CASE(test_ecs_cache_ttllimit_notallowed) SyncRes::s_ecscachelimitttl = 100; SyncRes::s_ecsipv4cachelimit = 16; - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { BOOST_REQUIRE(srcmask); BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24"); @@ -1372,7 +1372,7 @@ BOOST_AUTO_TEST_CASE(test_ns_speed) std::map nsCounts; - sr->setAsyncCallback([target, &nsCounts](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &nsCounts](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, domain, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 172800); @@ -1441,7 +1441,7 @@ BOOST_AUTO_TEST_CASE(test_flawed_nsset) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, domain, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 172800); @@ -1483,7 +1483,7 @@ BOOST_AUTO_TEST_CASE(test_completely_flawed_nsset) const DNSName target("powerdns.com."); size_t queriesCount = 0; - sr->setAsyncCallback([&queriesCount, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (isRootServer(ip) && domain == target) { @@ -1519,7 +1519,7 @@ BOOST_AUTO_TEST_CASE(test_completely_flawed_big_nsset) const DNSName target("powerdns.com."); size_t queriesCount = 0; - sr->setAsyncCallback([&queriesCount, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (isRootServer(ip) && domain == target) { @@ -1561,7 +1561,7 @@ BOOST_AUTO_TEST_CASE(test_cache_hit) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { return LWResult::Result::Timeout; }); @@ -1591,7 +1591,7 @@ BOOST_AUTO_TEST_CASE(test_no_rd) sr->setCacheOnly(); - sr->setAsyncCallback([target, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; }); @@ -1613,7 +1613,7 @@ BOOST_AUTO_TEST_CASE(test_cache_min_max_ttl) const DNSName target("cachettl.powerdns.com."); const ComboAddress ns("192.0.2.1:53"); - sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -1671,7 +1671,7 @@ BOOST_AUTO_TEST_CASE(test_cache_min_max_ecs_ttl) sr->setQuerySource(ComboAddress(), boost::optional(incomingECS)); SyncRes::addEDNSDomain(target); - sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& srcmask, boost::optional /* context */, LWResult* res, bool* /* chained */) { BOOST_REQUIRE(srcmask); BOOST_CHECK_EQUAL(srcmask->toString(), "192.0.2.0/24"); @@ -1735,7 +1735,7 @@ BOOST_AUTO_TEST_CASE(test_cache_expired_ttl) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, domain, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 172800); @@ -1780,7 +1780,7 @@ BOOST_AUTO_TEST_CASE(test_cache_almost_expired_ttl) const DNSName target("powerdns.com."); - auto cb = [target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + auto cb = [target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, domain, QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, 172800); diff --git a/pdns/recursordist/test-syncres_cc3.cc b/pdns/recursordist/test-syncres_cc3.cc index 6f9b3bb4cb03..7acdb4f4ca65 100644 --- a/pdns/recursordist/test-syncres_cc3.cc +++ b/pdns/recursordist/test-syncres_cc3.cc @@ -16,7 +16,7 @@ BOOST_AUTO_TEST_CASE(test_cache_auth) check that we only return one result, and we only cache one too. */ const DNSName target("cache-auth.powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { setLWResult(res, 0, true, false, true); addRecordToLW(res, domain, QType::A, "192.0.2.2", DNSResourceRecord::ANSWER, 10); addRecordToLW(res, domain, QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 10); @@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(test_unauth_any) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -86,9 +86,9 @@ static void test_no_data_f(bool qmin) const DNSName target("powerdns.com."); sr->setAsyncCallback( - [target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, - struct timeval* now, boost::optional& srcmask, boost::optional context, - LWResult* res, bool* chained) { + [target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, + struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, + LWResult* res, bool* /* chained */) { setLWResult(res, 0, true, false, true); return LWResult::Result::Success; }); @@ -121,7 +121,7 @@ BOOST_AUTO_TEST_CASE(test_extra_answers) const DNSName target2("www2.powerdns.com."); // in bailiwick, but not asked for const DNSName target3("www.random.net."); // out of bailiwick and not asked for - sr->setAsyncCallback([target, target2, target3](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, target2, target3](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "powerdns.com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -185,7 +185,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_extra_answers) generateKeyMaterial(DNSName("powerdns.com"), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys, luaconfsCopy.dsAnchors); g_luaconfs.setState(luaconfsCopy); - sr->setAsyncCallback([target, target2, target3, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, target2, target3, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (type == QType::DS || type == QType::DNSKEY) { return genericDSAndDNSKEYHandler(res, domain, domain, type, keys, false); } @@ -245,7 +245,7 @@ BOOST_AUTO_TEST_CASE(test_skip_opt_any) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { setLWResult(res, 0, true, false, true); addRecordToLW(res, domain, QType::A, "192.0.2.42"); addRecordToLW(res, domain, QType::ANY, "\\# 0"); @@ -268,7 +268,7 @@ BOOST_AUTO_TEST_CASE(test_nodata_nsec_nodnssec) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { setLWResult(res, 0, true, false, true); addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600); /* the NSEC and RRSIG contents are complete garbage, please ignore them */ @@ -293,7 +293,7 @@ BOOST_AUTO_TEST_CASE(test_nodata_nsec_dnssec) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { setLWResult(res, 0, true, false, true); addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600); /* the NSEC and RRSIG contents are complete garbage, please ignore them */ @@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(test_nx_nsec_nodnssec) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { setLWResult(res, RCode::NXDomain, true, false, true); addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600); /* the NSEC and RRSIG contents are complete garbage, please ignore them */ @@ -343,7 +343,7 @@ BOOST_AUTO_TEST_CASE(test_nx_nsec_dnssec) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { setLWResult(res, RCode::NXDomain, true, false, true); addRecordToLW(res, domain, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY, 3600); /* the NSEC and RRSIG contents are complete garbage, please ignore them */ @@ -369,7 +369,7 @@ BOOST_AUTO_TEST_CASE(test_qclass_none) /* apart from special names and QClass::ANY, anything else than QClass::IN should be rejected right away */ size_t queriesCount = 0; - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; }); @@ -391,7 +391,7 @@ BOOST_AUTO_TEST_CASE(test_answer_no_aa) const DNSName target("powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { setLWResult(res, 0, false, false, true); addRecordToLW(res, domain, QType::A, "192.0.2.1"); return LWResult::Result::Success; @@ -421,7 +421,7 @@ BOOST_AUTO_TEST_CASE(test_special_types) /* {A,I}XFR, RRSIG and NSEC3 should be rejected right away */ size_t queriesCount = 0; - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { cerr << "asyncresolve called to ask " << ip.toStringWithPort() << " about " << domain.toString() << " / " << QType(type).toString() << " over " << (doTCP ? "TCP" : "UDP") << " (rd: " << sendRDQuery << ", EDNS0 level: " << EDNS0Level << ")" << endl; queriesCount++; return LWResult::Result::Timeout; @@ -461,7 +461,7 @@ BOOST_AUTO_TEST_CASE(test_special_names) size_t queriesCount = 0; - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; }); @@ -584,7 +584,7 @@ BOOST_AUTO_TEST_CASE(test_nameserver_ipv4_rpz) const DNSName target("rpz.powerdns.com."); const ComboAddress ns("192.0.2.1:53"); - sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, false, true, false, true); addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -625,7 +625,7 @@ BOOST_AUTO_TEST_CASE(test_nameserver_ipv6_rpz) const DNSName target("rpz.powerdns.com."); const ComboAddress ns("[2001:DB8::42]:53"); - sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, ns](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); @@ -667,7 +667,7 @@ BOOST_AUTO_TEST_CASE(test_nameserver_name_rpz) const ComboAddress ns("192.0.2.1:53"); const DNSName nsName("ns1.powerdns.com."); - sr->setAsyncCallback([target, ns, nsName](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, ns, nsName](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, domain, QType::NS, nsName.toString(), DNSResourceRecord::AUTHORITY, 172800); @@ -709,7 +709,7 @@ BOOST_AUTO_TEST_CASE(test_nameserver_name_rpz_disabled) const ComboAddress ns("192.0.2.1:53"); const DNSName nsName("ns1.powerdns.com."); - sr->setAsyncCallback([target, ns, nsName](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, ns, nsName](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, domain, QType::NS, nsName.toString(), DNSResourceRecord::AUTHORITY, 172800); @@ -764,7 +764,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_nord) size_t queriesCount = 0; - sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { ++queriesCount; if (ip == forwardedNS) { BOOST_CHECK_EQUAL(sendRDQuery, false); @@ -823,7 +823,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_rd) ad.d_servers.push_back(forwardedNS); (*SyncRes::t_sstorage.domainmap)[target] = ad; - sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (ip == forwardedNS) { @@ -874,7 +874,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_nord) size_t queriesCount = 0; - sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { ++queriesCount; if (ip == forwardedNS) { BOOST_CHECK_EQUAL(sendRDQuery, true); @@ -932,7 +932,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_rd) ad.d_servers.push_back(forwardedNS); (*SyncRes::t_sstorage.domainmap)[target] = ad; - sr->setAsyncCallback([forwardedNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([forwardedNS](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (ip == forwardedNS) { BOOST_CHECK_EQUAL(sendRDQuery, true); @@ -978,7 +978,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_rd_dnssec) ad.d_servers.push_back(forwardedNS); (*SyncRes::t_sstorage.domainmap)[g_rootdnsname] = ad; - sr->setAsyncCallback([target, cnameTarget, keys, forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cnameTarget, keys, forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; BOOST_CHECK_EQUAL(sendRDQuery, true); @@ -1049,7 +1049,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_nord_dnssec) ad.d_servers.push_back(forwardedNS); (*SyncRes::t_sstorage.domainmap)[DNSName("test.")] = ad; - sr->setAsyncCallback([parent, target1, target2, keys, forwardedNS, &queriesCount, &DSforParentCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([parent, target1, target2, keys, forwardedNS, &queriesCount, &DSforParentCount](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; BOOST_CHECK_EQUAL(sendRDQuery, false); @@ -1153,7 +1153,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_rd_dnssec_bogus) ad.d_servers.push_back(forwardedNS); (*SyncRes::t_sstorage.domainmap)[g_rootdnsname] = ad; - sr->setAsyncCallback([target, cnameTarget, keys, forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cnameTarget, keys, forwardedNS, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; BOOST_CHECK_EQUAL(sendRDQuery, true); @@ -1221,7 +1221,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_rd_dnssec_nodata_bogus) size_t queriesCount = 0; - sr->setAsyncCallback([target, forwardedNS, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, forwardedNS, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool sendRDQuery, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; BOOST_CHECK_EQUAL(sendRDQuery, true); @@ -1284,7 +1284,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_oob) (*SyncRes::t_sstorage.domainmap)[authZone] = ad; - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; }); @@ -1352,7 +1352,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_oob_cname) (*SyncRes::t_sstorage.domainmap)[authZone] = ad; - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; }); @@ -1423,7 +1423,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone) (*map)[target] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; setLWResult(res, 0, true, false, true); addRecordToLW(res, domain, QType::A, "192.0.2.42"); @@ -1472,7 +1472,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_cname_lead_to_oob) (*map)[authZone] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount, target, authZone](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, target, authZone](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target) { @@ -1528,7 +1528,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_oob_lead_to_outgoing_queryb) (*map)[target] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount, externalCNAME, addr](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, externalCNAME, addr](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == externalCNAME) { @@ -1584,7 +1584,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_ds) (*map)[target] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type != QType::DS) { setLWResult(res, 0, true, false, true); diff --git a/pdns/recursordist/test-syncres_cc4.cc b/pdns/recursordist/test-syncres_cc4.cc index 840ed3a497aa..3e02e501bc12 100644 --- a/pdns/recursordist/test-syncres_cc4.cc +++ b/pdns/recursordist/test-syncres_cc4.cc @@ -37,7 +37,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_nodata) (*map)[authZone] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; @@ -76,7 +76,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_nx) (*map)[authZone] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; @@ -143,7 +143,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_delegation) takes too long. */ const time_t fixedNow = sr->getNow().tv_sec; - sr->setAsyncCallback([&queriesCount, target, targetAddr, nsAddr, authZone, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, target, targetAddr, nsAddr, authZone, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { return genericDSAndDNSKEYHandler(res, domain, DNSName("."), type, keys, domain == DNSName("com.") || domain == authZone, fixedNow); @@ -210,7 +210,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_delegation_point) (*map)[authZone] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount, nsAddr, target, targetAddr](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, nsAddr, target, targetAddr](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (ip == ComboAddress(nsAddr.toString(), 53) && domain == target) { @@ -263,7 +263,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_wildcard) (*map)[authZone] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; @@ -318,7 +318,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_wildcard_with_ent) (*map)[authZone] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; @@ -368,7 +368,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_wildcard_nodata) (*map)[authZone] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* /* res */, bool* /* chained */) { queriesCount++; return LWResult::Result::Timeout; @@ -414,7 +414,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_cache_only) (*map)[target] = ad; SyncRes::setDomainMap(map); - sr->setAsyncCallback([&queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; setLWResult(res, 0, true, false, true); addRecordToLW(res, domain, QType::A, "192.0.2.42"); @@ -480,7 +480,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_root_validation_csk) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -565,7 +565,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_root_validation_ksk_zsk) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, zskeys, kskeys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, zskeys, kskeys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -633,7 +633,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_no_dnskey) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -709,7 +709,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_without_zone_flag) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -785,7 +785,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_revoked) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -868,7 +868,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_dnskey_doesnt_match_ds) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -979,7 +979,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_rrsig_signed_with_unknown_dnskey) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys, rrsigkeys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys, rrsigkeys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -1046,7 +1046,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_no_rrsig) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -1121,7 +1121,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_no_rrsig_noaa) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -1210,7 +1210,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_unknown_ds_algorithm) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -1290,7 +1290,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_unknown_ds_digest) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -1363,7 +1363,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_bad_sig) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -1431,7 +1431,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_bad_algo) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -1502,7 +1502,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_unsigned_ds) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -1583,7 +1583,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_unsigned_ds_direct) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; diff --git a/pdns/recursordist/test-syncres_cc5.cc b/pdns/recursordist/test-syncres_cc5.cc index 1af1d8719665..bb893939f1b6 100644 --- a/pdns/recursordist/test-syncres_cc5.cc +++ b/pdns/recursordist/test-syncres_cc5.cc @@ -33,7 +33,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_various_algos) const time_t fixedNow = sr->getNow().tv_sec; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -129,7 +129,7 @@ static void testFixedPointInTime(time_t fixedNow) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -254,7 +254,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_a_then_ns) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -357,7 +357,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_a_then_ns) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -463,7 +463,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_with_nta) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -564,7 +564,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_with_nta) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -648,7 +648,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nsec) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -739,7 +739,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nxdomain_nsec) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -855,7 +855,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nsec_wildcard) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -974,7 +974,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nsec_wildcard_proof_before_rrsig) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1089,7 +1089,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nsec_nodata_nowildcard) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1169,7 +1169,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nsec3_nodata_nowildcard) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1260,7 +1260,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nsec3_nodata_nowildcard_duplicated_n size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1355,7 +1355,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nsec3_nodata_nowildcard_too_many_ite size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1448,7 +1448,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nsec3_wildcard) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1570,7 +1570,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nsec3_wildcard_too_many_iterations) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1685,7 +1685,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_nsec_wildcard_missing) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1789,7 +1789,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_wildcard_expanded_onto_itself) g_luaconfs.setState(luaconfsCopy); - sr->setAsyncCallback([target, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (type == QType::DS || type == QType::DNSKEY) { if (domain == target) { const auto auth = DNSName("powerdns.com."); @@ -1844,7 +1844,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_wildcard_expanded_onto_itself_nodata g_luaconfs.setState(luaconfsCopy); - sr->setAsyncCallback([target, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (type == QType::DS || type == QType::DNSKEY) { if (domain == target) { const auto auth = DNSName("powerdns.com."); @@ -1898,7 +1898,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_wildcard_like_expanded_from_wildcard g_luaconfs.setState(luaconfsCopy); - sr->setAsyncCallback([target, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (type == QType::DS || type == QType::DNSKEY) { if (domain == target) { const auto auth = DNSName("powerdns.com."); @@ -1963,7 +1963,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm) size_t queriesCount = 0; - sr->setAsyncCallback([&queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth(domain); @@ -2096,7 +2096,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_servfail_ds) const time_t fixedNow = sr->getNow().tv_sec; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -2179,7 +2179,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_servfail_ds) } } -static void dnssec_secure_servfail_dnskey(DNSSECMode mode, vState expectedValidationResult) +static void dnssec_secure_servfail_dnskey(DNSSECMode mode, vState /* expectedValidationResult */) { std::unique_ptr sr; initSR(sr, true); @@ -2207,7 +2207,7 @@ static void dnssec_secure_servfail_dnskey(DNSSECMode mode, vState expectedValida const time_t fixedNow = sr->getNow().tv_sec; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -2329,7 +2329,7 @@ static void dnssec_secure_servfail_dnskey_insecure(DNSSECMode mode, vState expec const time_t fixedNow = sr->getNow().tv_sec; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, pdnskeys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, pdnskeys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; diff --git a/pdns/recursordist/test-syncres_cc6.cc b/pdns/recursordist/test-syncres_cc6.cc index 9a335c617743..bae815c34d17 100644 --- a/pdns/recursordist/test-syncres_cc6.cc +++ b/pdns/recursordist/test-syncres_cc6.cc @@ -27,7 +27,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_no_ds_on_referral_secure) size_t queriesCount = 0; size_t dsQueriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, &dsQueriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, &dsQueriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -146,7 +146,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_ds_sign_loop) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -265,7 +265,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_ds_denial_loop) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DNSKEY || (type == QType::DS && domain != target)) { @@ -341,7 +341,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_ds_root) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -402,7 +402,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_dnskey_signed_child) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -510,7 +510,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_dnskey_unpublished) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -612,7 +612,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_dnskey_unpublished_nsec3) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -713,7 +713,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_no_ds_on_referral_insecure) size_t queriesCount = 0; size_t dsQueriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, &dsQueriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, &dsQueriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -823,7 +823,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_bogus_unsigned_nsec) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -911,7 +911,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_bogus_no_nsec) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -999,7 +999,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -1111,7 +1111,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_optout) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -1228,7 +1228,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_nxd_optout) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -1338,7 +1338,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_direct_ds) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1404,7 +1404,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_direct_ds) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1468,7 +1468,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_skipped_cut) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -1593,7 +1593,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_secure_without_ds) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -1692,7 +1692,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_broken_without_ds) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -1794,7 +1794,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_broken_cname_ds) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, pdnskeys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, pdnskeys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -1903,7 +1903,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_cname_for_ds) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { diff --git a/pdns/recursordist/test-syncres_cc7.cc b/pdns/recursordist/test-syncres_cc7.cc index 9ee88d298e27..cac1e94e3945 100644 --- a/pdns/recursordist/test-syncres_cc7.cc +++ b/pdns/recursordist/test-syncres_cc7.cc @@ -28,7 +28,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_to_ta_skipped_cut) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -153,7 +153,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_nodata) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -285,7 +285,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_cname) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -415,7 +415,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_cname_glue) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetCName1, targetCName2, targetCName2Addr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetCName1, targetCName2, targetCName2Addr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -537,7 +537,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_to_secure_cname) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -664,7 +664,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_to_secure_cname) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -760,7 +760,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_bogus_cname) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -856,7 +856,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_secure_cname) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -952,7 +952,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_to_insecure_cname) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -1073,7 +1073,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_ta) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DNSKEY) { @@ -1169,7 +1169,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_ta_norrsig) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DNSKEY) { @@ -1263,7 +1263,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_nta) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -1329,7 +1329,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_no_ta) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain == target && type == QType::NS) { @@ -1387,7 +1387,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nodata) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1599,7 +1599,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_bogus_nxdomain) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1663,7 +1663,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_secure_to_insecure_cut_with_cname_at_apex) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { @@ -1802,7 +1802,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_cname_inside_secure_zone) size_t queriesCount = 0; - sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetCName, targetCNameAddr, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS) { diff --git a/pdns/recursordist/test-syncres_cc8.cc b/pdns/recursordist/test-syncres_cc8.cc index 49df518eebfa..2026f607fb71 100644 --- a/pdns/recursordist/test-syncres_cc8.cc +++ b/pdns/recursordist/test-syncres_cc8.cc @@ -1028,7 +1028,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_rrsig_negcache_validity) size_t queriesCount = 0; const time_t fixedNow = sr->getNow().tv_sec; - sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -1096,7 +1096,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_rrsig_negcache_bogus_validity) size_t queriesCount = 0; const time_t fixedNow = sr->getNow().tv_sec; - sr->setAsyncCallback([&queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -1168,7 +1168,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_rrsig_cache_validity) size_t queriesCount = 0; const time_t tnow = sr->getNow().tv_sec; - sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, tnow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, targetAddr, &queriesCount, keys, tnow](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -1236,7 +1236,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_cache_secure) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1302,7 +1302,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_cache_insecure) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1368,7 +1368,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_cache_bogus) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1456,7 +1456,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_cache_secure_any) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { diff --git a/pdns/recursordist/test-syncres_cc9.cc b/pdns/recursordist/test-syncres_cc9.cc index bcf1be33a0d4..5a2dfab2c525 100644 --- a/pdns/recursordist/test-syncres_cc9.cc +++ b/pdns/recursordist/test-syncres_cc9.cc @@ -30,7 +30,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_cname_cache_secure) size_t queriesCount = 0; - sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -105,7 +105,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_cname_cache_insecure) size_t queriesCount = 0; - sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -178,7 +178,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_cname_cache_bogus) size_t queriesCount = 0; - sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cnameTarget, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -273,7 +273,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_additional_without_rrsig) size_t queriesCount = 0; - sr->setAsyncCallback([target, addTarget, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, addTarget, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -357,7 +357,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_negcache_secure) size_t queriesCount = 0; const time_t fixedNow = sr->getNow().tv_sec; - sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys, fixedNow](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -442,7 +442,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_negcache_secure_ds) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -498,7 +498,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_negcache_insecure) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -575,7 +575,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_from_negcache_bogus) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; DNSName auth = domain; @@ -675,7 +675,7 @@ BOOST_AUTO_TEST_CASE(test_lowercase_outgoing) const DNSName target("WWW.POWERDNS.COM"); const DNSName cname("WWW.PowerDNS.org"); - sr->setAsyncCallback([target, cname, &sentOutQnames](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cname, &sentOutQnames](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { sentOutQnames.push_back(domain); if (isRootServer(ip)) { @@ -749,7 +749,7 @@ BOOST_AUTO_TEST_CASE(test_getDSRecords_multialgo) auto rootkey = keys.find(g_rootdnsname); keys2.insert(*rootkey); - sr->setAsyncCallback([target, keys, keys2](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, keys, keys2](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { DNSName auth = domain; auth.chopOff(); if (type == QType::DS || type == QType::DNSKEY) { @@ -799,7 +799,7 @@ BOOST_AUTO_TEST_CASE(test_getDSRecords_multialgo_all_sha) // But add the existing root key otherwise no RRSIG can be created keys3.insert(*rootkey); - sr->setAsyncCallback([target, keys, keys2, keys3](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, keys, keys2, keys3](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { DNSName auth = domain; auth.chopOff(); if (type == QType::DS || type == QType::DNSKEY) { @@ -852,7 +852,7 @@ BOOST_AUTO_TEST_CASE(test_getDSRecords_multialgo_two_highest) // But add the existing root key otherwise no RRSIG can be created keys3.insert(*rootkey); - sr->setAsyncCallback([target, keys, keys2, keys3](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, keys, keys2, keys3](const ComboAddress& /* ip */, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { DNSName auth = domain; auth.chopOff(); if (type == QType::DS || type == QType::DNSKEY) { @@ -889,7 +889,7 @@ BOOST_AUTO_TEST_CASE(test_cname_plus_authority_ns_ttl) const DNSName cnameTarget("cname-target.powerdns.com"); size_t queriesCount = 0; - sr->setAsyncCallback([target, cnameTarget, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, cnameTarget, &queriesCount](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (isRootServer(ip)) { @@ -968,7 +968,7 @@ BOOST_AUTO_TEST_CASE(test_bogus_does_not_replace_secure_in_the_cache) generateKeyMaterial(DNSName("powerdns.com."), DNSSECKeeper::ECDSA256, DNSSECKeeper::DIGEST_SHA256, keys); g_luaconfs.setState(luaconfsCopy); - sr->setAsyncCallback([keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (type == QType::DS || type == QType::DNSKEY) { if (domain == DNSName("cname.powerdns.com.")) { return genericDSAndDNSKEYHandler(res, domain, domain, type, keys, false /* no cut */); @@ -1040,7 +1040,7 @@ BOOST_AUTO_TEST_CASE(test_records_sanitization_general) const DNSName target("sanitization.powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { setLWResult(res, 0, true, false, true); addRecordToLW(res, domain, QType::A, "192.0.2.1"); /* should be scrubbed because it doesn't match the QType */ @@ -1086,7 +1086,7 @@ BOOST_AUTO_TEST_CASE(test_records_sanitization_keep_relevant_additional_aaaa) const DNSName target("sanitization.powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { setLWResult(res, 0, true, false, true); addRecordToLW(res, domain, QType::A, "192.0.2.1"); addRecordToLW(res, domain, QType::AAAA, "2001:db8::1", DNSResourceRecord::ADDITIONAL); @@ -1120,7 +1120,7 @@ BOOST_AUTO_TEST_CASE(test_records_sanitization_keep_glue) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (isRootServer(ip)) { @@ -1190,7 +1190,7 @@ BOOST_AUTO_TEST_CASE(test_records_sanitization_scrubs_ns_nxd) const DNSName target("sanitization-ns-nxd.powerdns.com."); - sr->setAsyncCallback([target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target](const ComboAddress& /* ip */, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { setLWResult(res, RCode::NXDomain, true, false, true); addRecordToLW(res, "powerdns.com.", QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 3600", DNSResourceRecord::AUTHORITY); addRecordToLW(res, "powerdns.com.", QType::NS, "spoofed.ns.", DNSResourceRecord::AUTHORITY, 172800); @@ -1240,7 +1240,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_referral_on_ds_query_insecure) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain.isPartOf(DNSName("signed.ds-ignorant.com.")) && ip == ComboAddress("192.0.2.1:53")) { @@ -1329,7 +1329,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_validation_referral_on_ds_query_secure) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (domain.isPartOf(DNSName("signed.ds-ignorant.com.")) && ip == ComboAddress("192.0.2.1:53")) { diff --git a/pdns/snmp-agent.cc b/pdns/snmp-agent.cc index f00bf6d6c96a..18a088ea4353 100644 --- a/pdns/snmp-agent.cc +++ b/pdns/snmp-agent.cc @@ -78,7 +78,7 @@ void SNMPAgent::handleSNMPQueryEvent(int fd) snmp_read2(&fdset); } -void SNMPAgent::handleTrapsCB(int fd, FDMultiplexer::funcparam_t& var) +void SNMPAgent::handleTrapsCB(int /* fd */, FDMultiplexer::funcparam_t& var) { SNMPAgent** agent = boost::any_cast(&var); if (!agent || !*agent) diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index 3cb2aad8c7d3..8f4d32123901 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -859,7 +859,7 @@ class OpenSSLTLSIOCtx: public TLSCtx private: /* called in a client context, if the client advertised more than one ALPN values and the server returned more than one as well, to select the one to use. */ #ifndef DISABLE_NPN - static int npnSelectCallback(SSL* s, unsigned char** out, unsigned char* outlen, const unsigned char* in, unsigned int inlen, void* arg) + static int npnSelectCallback(SSL* /* s */, unsigned char** out, unsigned char* outlen, const unsigned char* in, unsigned int inlen, void* arg) { if (!arg) { return SSL_TLSEXT_ERR_ALERT_WARNING; diff --git a/pdns/test-mplexer.cc b/pdns/test-mplexer.cc index 5a6bbde62b1d..4c2b44d9bad6 100644 --- a/pdns/test-mplexer.cc +++ b/pdns/test-mplexer.cc @@ -51,7 +51,7 @@ BOOST_AUTO_TEST_CASE(test_MPlexer) ttd.tv_sec -= 5; bool writeCBCalled = false; - auto writeCB = [](int fd, FDMultiplexer::funcparam_t& param) { + auto writeCB = [](int /* fd */, FDMultiplexer::funcparam_t& param) { auto calledPtr = boost::any_cast(param); BOOST_REQUIRE(calledPtr != nullptr); *calledPtr = true; @@ -100,7 +100,7 @@ BOOST_AUTO_TEST_CASE(test_MPlexer) BOOST_CHECK_EQUAL(ready, 0); bool readCBCalled = false; - auto readCB = [](int fd, FDMultiplexer::funcparam_t& param) { + auto readCB = [](int /* fd */, FDMultiplexer::funcparam_t& param) { auto calledPtr = boost::any_cast(param); BOOST_REQUIRE(calledPtr != nullptr); *calledPtr = true; @@ -243,12 +243,12 @@ BOOST_AUTO_TEST_CASE(test_MPlexer_ReadAndWrite) bool readCBCalled = false; bool writeCBCalled = false; - auto readCB = [](int fd, FDMultiplexer::funcparam_t& param) { + auto readCB = [](int /* fd */, FDMultiplexer::funcparam_t& param) { auto calledPtr = boost::any_cast(param); BOOST_REQUIRE(calledPtr != nullptr); *calledPtr = true; }; - auto writeCB = [](int fd, FDMultiplexer::funcparam_t& param) { + auto writeCB = [](int /* fd */, FDMultiplexer::funcparam_t& param) { auto calledPtr = boost::any_cast(param); BOOST_REQUIRE(calledPtr != nullptr); *calledPtr = true; From 0936b1704c8b7d3adef3dc9e087944af646c53ef Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Mon, 20 Feb 2023 11:59:53 +0100 Subject: [PATCH 059/909] rec: Remove -Wno-unused-parameter from default C(XX)FLAGS --- pdns/recursordist/configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index e8c86edb2fd9..8f7e900b7e1d 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -12,8 +12,8 @@ AC_CONFIG_HEADERS([config.h]) AC_CANONICAL_HOST # Add some default CFLAGS and CXXFLAGS, can be appended to using the environment variables -CFLAGS="-Wall -Wextra -Wshadow -Wno-unused-parameter -Wmissing-declarations -Wredundant-decls -fvisibility=hidden -g -O2 $CFLAGS" -CXXFLAGS="-Wall -Wextra -Wshadow -Wno-unused-parameter -Wmissing-declarations -Wredundant-decls -fvisibility=hidden -g -O2 $CXXFLAGS" +CFLAGS="-Wall -Wextra -Wshadow -Wmissing-declarations -Wredundant-decls -fvisibility=hidden -g -O2 $CFLAGS" +CXXFLAGS="-Wall -Wextra -Wshadow -Wmissing-declarations -Wredundant-decls -fvisibility=hidden -g -O2 $CXXFLAGS" AC_SUBST([pdns_configure_args],["$ac_configure_args"]) AC_DEFINE_UNQUOTED([PDNS_CONFIG_ARGS], From 3bb98d9719c66bb8756f2b033335e7ef81806306 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 4 Apr 2023 16:23:20 +0200 Subject: [PATCH 060/909] Fix cases mentioned in review, plus a few spotted on macOS --- pdns/capabilities.cc | 2 +- pdns/iputils.cc | 2 +- pdns/minicurl.cc | 4 ++-- pdns/misc.cc | 14 +++++++------- pdns/opensslsigners.cc | 2 +- pdns/recursordist/aggressive_nsec.cc | 6 ++++-- pdns/recursordist/lwres.cc | 4 ++-- pdns/recursordist/rec-main.cc | 2 +- pdns/recursordist/rec-tcp.cc | 2 +- pdns/recursordist/recpacketcache.hh | 4 ++-- pdns/recursordist/test-syncres_cc10.cc | 2 +- pdns/recursordist/test-syncres_cc7.cc | 4 ++-- pdns/unix_utility.cc | 6 +++--- 13 files changed, 28 insertions(+), 26 deletions(-) diff --git a/pdns/capabilities.cc b/pdns/capabilities.cc index e073d2c77bd6..2747fc93f57e 100644 --- a/pdns/capabilities.cc +++ b/pdns/capabilities.cc @@ -33,7 +33,7 @@ #include "capabilities.hh" #include "misc.hh" -bool dropCapabilities(std::set capabilitiesToKeep) +bool dropCapabilities([[maybe_unused]] std::set capabilitiesToKeep) { #ifdef HAVE_LIBCAP cap_t caps = cap_get_proc(); diff --git a/pdns/iputils.cc b/pdns/iputils.cc index e0c7218f775c..31ac2a9773e3 100644 --- a/pdns/iputils.cc +++ b/pdns/iputils.cc @@ -147,7 +147,7 @@ int SSetsockopt(int sockfd, int level, int opname, int value) return ret; } -void setSocketIgnorePMTU(int sockfd, int family) +void setSocketIgnorePMTU([[maybe_unused]] int sockfd, [[maybe_unused]] int family) { if (family == AF_INET) { #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) diff --git a/pdns/minicurl.cc b/pdns/minicurl.cc index 5d45406f1e5c..c1e16b810c7a 100644 --- a/pdns/minicurl.cc +++ b/pdns/minicurl.cc @@ -116,7 +116,7 @@ static string extractHostFromURL(const std::string& url) return url.substr(pos, endpos-pos); } -void MiniCurl::setupURL(const std::string& str, const ComboAddress* rem, const ComboAddress* src, int timeout, size_t byteslimit, bool fastopen, bool verify) +void MiniCurl::setupURL(const std::string& str, const ComboAddress* rem, const ComboAddress* src, int timeout, size_t byteslimit, [[maybe_unused]] bool fastopen, bool verify) { if (!d_fresh) { curl_easy_reset(getCURLPtr(d_curl)); @@ -198,7 +198,7 @@ void MiniCurl::setupURL(const std::string& str, const ComboAddress* rem, const C d_data.clear(); } -std::string MiniCurl::getURL(const std::string& str, const ComboAddress* rem, const ComboAddress* src, int timeout, bool fastopen, bool verify, size_t byteslimit) +std::string MiniCurl::getURL(const std::string& str, const ComboAddress* rem, const ComboAddress* src, int timeout, [[maybe_unused]] bool fastopen, bool verify, size_t byteslimit) { setupURL(str, rem, src, timeout, byteslimit, fastopen, verify); auto res = curl_easy_perform(getCURLPtr(d_curl)); diff --git a/pdns/misc.cc b/pdns/misc.cc index b28b4a2b0c7a..4cfe6d4196cc 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -1014,7 +1014,7 @@ bool isNonBlocking(int sock) return flags & O_NONBLOCK; } -bool setReceiveSocketErrors(int sock, int af) +bool setReceiveSocketErrors([[maybe_unused]] int sock, [[maybe_unused]] int af) { #ifdef __linux__ int tmp = 1, ret; @@ -1159,7 +1159,7 @@ int getMACAddress(const ComboAddress& ca, char* dest, size_t destLen) return foundMAC ? 0 : ENOENT; } #else -int getMACAddress(const ComboAddress& ca, char* dest, size_t len) +int getMACAddress(const ComboAddress& /* ca */, char* /* dest */, size_t /* len */) { return ENOENT; } @@ -1175,7 +1175,7 @@ string getMACAddress(const ComboAddress& ca) return ret; } -uint64_t udpErrorStats(const std::string& str) +uint64_t udpErrorStats([[maybe_unused]] const std::string& str) { #ifdef __linux__ ifstream ifs("/proc/net/snmp"); @@ -1217,7 +1217,7 @@ uint64_t udpErrorStats(const std::string& str) return 0; } -uint64_t udp6ErrorStats(const std::string& str) +uint64_t udp6ErrorStats([[maybe_unused]] const std::string& str) { #ifdef __linux__ const std::map keys = { @@ -1545,7 +1545,7 @@ bool isSettingThreadCPUAffinitySupported() #endif } -int mapThreadToCPUList(pthread_t tid, const std::set& cpus) +int mapThreadToCPUList([[maybe_unused]] pthread_t tid, [[maybe_unused]] const std::set& cpus) { #ifdef HAVE_PTHREAD_SETAFFINITY_NP # ifdef __NetBSD__ @@ -1613,7 +1613,7 @@ std::vector getResolvers(const std::string& resolvConfPath) return results; } -size_t getPipeBufferSize(int fd) +size_t getPipeBufferSize([[maybe_unused]] int fd) { #ifdef F_GETPIPE_SZ int res = fcntl(fd, F_GETPIPE_SZ); @@ -1627,7 +1627,7 @@ size_t getPipeBufferSize(int fd) #endif /* F_GETPIPE_SZ */ } -bool setPipeBufferSize(int fd, size_t size) +bool setPipeBufferSize([[maybe_unused]] int fd, [[maybe_unused]] size_t size) { #ifdef F_SETPIPE_SZ if (size > static_cast(std::numeric_limits::max())) { diff --git a/pdns/opensslsigners.cc b/pdns/opensslsigners.cc index f734089e9dd4..a8ca7c071262 100644 --- a/pdns/opensslsigners.cc +++ b/pdns/opensslsigners.cc @@ -1843,7 +1843,7 @@ int OpenSSLEDDSADNSCryptoKeyEngine::getBits() const return (int)d_len << 3; } -bool OpenSSLEDDSADNSCryptoKeyEngine::checkKey(std::optional>> errorMessages) const +bool OpenSSLEDDSADNSCryptoKeyEngine::checkKey([[maybe_unused]] std::optional>> errorMessages) const { #if OPENSSL_VERSION_MAJOR >= 3 auto ctx = KeyContext{EVP_PKEY_CTX_new_from_pkey(nullptr, d_edkey.get(), nullptr), EVP_PKEY_CTX_free}; diff --git a/pdns/recursordist/aggressive_nsec.cc b/pdns/recursordist/aggressive_nsec.cc index 58c2cc56c7d8..1b947a6601d1 100644 --- a/pdns/recursordist/aggressive_nsec.cc +++ b/pdns/recursordist/aggressive_nsec.cc @@ -488,7 +488,7 @@ static void addRecordToRRSet(time_t /* now */, const DNSName& owner, const QType } } -bool AggressiveNSECCache::synthesizeFromNSEC3Wildcard(time_t now, const DNSName& name, const QType& type, std::vector& ret, int& /* res */, bool doDNSSEC, ZoneEntry::CacheEntry& nextCloser, const DNSName& wildcardName, const OptLog& log) +bool AggressiveNSECCache::synthesizeFromNSEC3Wildcard(time_t now, const DNSName& name, const QType& type, std::vector& ret, int& res, bool doDNSSEC, ZoneEntry::CacheEntry& nextCloser, const DNSName& wildcardName, const OptLog& log) { vState cachedState; @@ -507,10 +507,11 @@ bool AggressiveNSECCache::synthesizeFromNSEC3Wildcard(time_t now, const DNSName& VLOG(log, name << ": Synthesized valid answer from NSEC3s and wildcard!" << endl); ++d_nsec3WildcardHits; + res = RCode::NoError; return true; } -bool AggressiveNSECCache::synthesizeFromNSECWildcard(time_t now, const DNSName& name, const QType& type, std::vector& ret, int& /* res */, bool doDNSSEC, ZoneEntry::CacheEntry& nsec, const DNSName& wildcardName, const OptLog& log) +bool AggressiveNSECCache::synthesizeFromNSECWildcard(time_t now, const DNSName& name, const QType& type, std::vector& ret, int& res, bool doDNSSEC, ZoneEntry::CacheEntry& nsec, const DNSName& wildcardName, const OptLog& log) { vState cachedState; @@ -527,6 +528,7 @@ bool AggressiveNSECCache::synthesizeFromNSECWildcard(time_t now, const DNSName& VLOG(log, name << ": Synthesized valid answer from NSECs and wildcard!" << endl); ++d_nsecWildcardHits; + res = RCode::NoError; return true; } diff --git a/pdns/recursordist/lwres.cc b/pdns/recursordist/lwres.cc index 0d520669400c..833ae7ffc148 100644 --- a/pdns/recursordist/lwres.cc +++ b/pdns/recursordist/lwres.cc @@ -282,7 +282,7 @@ static void logIncomingResponse(const std::shared_ptrd_nsName.empty()) { nsName = context->d_nsName.toStringNoDot(); } - isNew = tcpconnect(*now, ip, connection, dnsOverTLS, nsName); + isNew = tcpconnect(ip, connection, dnsOverTLS, nsName); ret = tcpsendrecv(ip, connection, localip, vpacket, len, buf); #ifdef HAVE_FSTRM if (fstrmQEnabled) { diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index f13c7ff27472..36401172383a 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -832,7 +832,7 @@ static void usr2Handler(int) ::arg().set("quiet") = g_quiet ? "" : "no"; } -static void checkLinuxIPv6Limits(Logr::log_t log) +static void checkLinuxIPv6Limits([[maybe_unused]] Logr::log_t log) { #ifdef __linux__ string line; diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index fb78c064c0aa..3da26229019c 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -858,7 +858,7 @@ static void TCPIOHandlerIO(int fd, FDMultiplexer::funcparam_t& var) TCPIOHandlerStateChange(pid->lowState, newstate, pid); } -void checkFastOpenSysctl(bool active, Logr::log_t log) +void checkFastOpenSysctl([[maybe_unused]] bool active, [[maybe_unused]] Logr::log_t log) { #ifdef __linux__ string line; diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index d082aec04180..5ff974fefdce 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -204,7 +204,7 @@ private: [[nodiscard]] const MapCombo& getMap(unsigned int tag, uint32_t hash, bool tcp) const { - return d_maps.at(combine(hash, hash, tcp) % d_maps.size()); + return d_maps.at(combine(tag, hash, tcp) % d_maps.size()); } static bool qrMatch(const packetCache_t::index::type::iterator& iter, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass); @@ -213,7 +213,7 @@ private: void setShardSizes(size_t shardSize); public: - void preRemoval(MapCombo::LockedContent& map, const Entry& entry) + void preRemoval(MapCombo::LockedContent& /* map */, const Entry& /* entry */) { } }; diff --git a/pdns/recursordist/test-syncres_cc10.cc b/pdns/recursordist/test-syncres_cc10.cc index 0218cf39ffbe..4353d843fc44 100644 --- a/pdns/recursordist/test-syncres_cc10.cc +++ b/pdns/recursordist/test-syncres_cc10.cc @@ -1642,7 +1642,7 @@ BOOST_AUTO_TEST_CASE(test_servestale_immediateservfail) const int theTTL = 5; - sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([&downServers, &downCount, &lookupCount, target](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ if (downServers.find(ip) != downServers.end()) { diff --git a/pdns/recursordist/test-syncres_cc7.cc b/pdns/recursordist/test-syncres_cc7.cc index cac1e94e3945..df5fb0850aac 100644 --- a/pdns/recursordist/test-syncres_cc7.cc +++ b/pdns/recursordist/test-syncres_cc7.cc @@ -1448,7 +1448,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_missing_soa_on_nodata) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { @@ -1523,7 +1523,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_insecure_missing_soa_on_nxd) size_t queriesCount = 0; - sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, LWResult* res, bool* chained) { + sr->setAsyncCallback([target, &queriesCount, keys](const ComboAddress& ip, const DNSName& domain, int type, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { queriesCount++; if (type == QType::DS || type == QType::DNSKEY) { diff --git a/pdns/unix_utility.cc b/pdns/unix_utility.cc index b3e95ad51f4c..26c0782e1c53 100644 --- a/pdns/unix_utility.cc +++ b/pdns/unix_utility.cc @@ -78,7 +78,7 @@ int Utility::timed_connect( Utility::sock_t sock, -void Utility::setBindAny(int af, sock_t sock) +void Utility::setBindAny([[maybe_unused]] int af, [[maybe_unused]] sock_t sock) { const int one = 1; @@ -199,9 +199,9 @@ Utility::pid_t Utility::getpid( ) // Returns the current time. -int Utility::gettimeofday( struct timeval *tv, void *tz ) +int Utility::gettimeofday( struct timeval *tv, void * /* tz */) { - return ::gettimeofday(tv,nullptr); + return ::gettimeofday(tv, nullptr); } // Sets the random seed. From e9e8fbcd986ccaafa7b859a5c6b7e61f5b193097 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 5 Apr 2023 10:07:00 +0200 Subject: [PATCH 061/909] Remove unused `now` argument from addRecordToRRSet --- pdns/recursordist/aggressive_nsec.cc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/pdns/recursordist/aggressive_nsec.cc b/pdns/recursordist/aggressive_nsec.cc index 1b947a6601d1..96c1c20359f3 100644 --- a/pdns/recursordist/aggressive_nsec.cc +++ b/pdns/recursordist/aggressive_nsec.cc @@ -463,7 +463,7 @@ static void addToRRSet(const time_t now, std::vector& recordSet, std: } } -static void addRecordToRRSet(time_t /* now */, const DNSName& owner, const QType& type, uint32_t ttl, std::shared_ptr& content, std::vector> signatures, bool doDNSSEC, std::vector& ret) +static void addRecordToRRSet(const DNSName& owner, const QType& type, uint32_t ttl, std::shared_ptr& content, std::vector> signatures, bool doDNSSEC, std::vector& ret) { DNSRecord nsecRec; nsecRec.d_type = type.getCode(); @@ -502,7 +502,7 @@ bool AggressiveNSECCache::synthesizeFromNSEC3Wildcard(time_t now, const DNSName& addToRRSet(now, wcSet, wcSignatures, name, doDNSSEC, ret, DNSResourceRecord::ANSWER); /* no need for closest encloser proof, the wildcard is there */ - addRecordToRRSet(now, nextCloser.d_owner, QType::NSEC3, nextCloser.d_ttd - now, nextCloser.d_record, nextCloser.d_signatures, doDNSSEC, ret); + addRecordToRRSet(nextCloser.d_owner, QType::NSEC3, nextCloser.d_ttd - now, nextCloser.d_record, nextCloser.d_signatures, doDNSSEC, ret); /* and of course we won't deny the wildcard either */ VLOG(log, name << ": Synthesized valid answer from NSEC3s and wildcard!" << endl); @@ -524,7 +524,7 @@ bool AggressiveNSECCache::synthesizeFromNSECWildcard(time_t now, const DNSName& } addToRRSet(now, wcSet, wcSignatures, name, doDNSSEC, ret, DNSResourceRecord::ANSWER); - addRecordToRRSet(now, nsec.d_owner, QType::NSEC, nsec.d_ttd - now, nsec.d_record, nsec.d_signatures, doDNSSEC, ret); + addRecordToRRSet(nsec.d_owner, QType::NSEC, nsec.d_ttd - now, nsec.d_record, nsec.d_signatures, doDNSSEC, ret); VLOG(log, name << ": Synthesized valid answer from NSECs and wildcard!" << endl); ++d_nsecWildcardHits; @@ -587,7 +587,7 @@ bool AggressiveNSECCache::getNSEC3Denial(time_t now, std::shared_ptr Date: Wed, 5 Apr 2023 13:04:24 +0200 Subject: [PATCH 062/909] rec: Also set pdns-distributes-quqeries for bulk tests. Large imbalance seen without. --- regression-tests/recursor-test | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests/recursor-test b/regression-tests/recursor-test index f58f936eb8ae..e75817b5204d 100755 --- a/regression-tests/recursor-test +++ b/regression-tests/recursor-test @@ -31,7 +31,7 @@ rm -f recursor.pid pdns_recursor.pid system CPU seconds%S wallclock seconds%e %% CPU used%P -' ${RECURSOR} --daemon=no --local-port=$port --socket-dir=./ --trace=$TRACE --config-dir=. --max-mthreads=$mthreads --query-local-address="0.0.0.0${QLA6}" --threads=$threads --record-cache-shards=$shards --refresh-on-ttl-perc=10 --dnssec=validate --reuseport=no > recursor.log 2>&1 & +' ${RECURSOR} --daemon=no --local-port=$port --socket-dir=./ --trace=$TRACE --config-dir=. --max-mthreads=$mthreads --query-local-address="0.0.0.0${QLA6}" --threads=$threads --record-cache-shards=$shards --refresh-on-ttl-perc=10 --dnssec=validate --pdns-distributes-queries --reuseport=no > recursor.log 2>&1 & sleep 3 if [ ! -e pdns_recursor.pid ]; then cat recursor.log From 890add843df1af4a76f3c6bab441895275e0bf64 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Tue, 11 Apr 2023 05:59:39 +0000 Subject: [PATCH 063/909] Fix spelling of PKCS --- .github/actions/spell-check/allow.txt | 1 - pdns/dnsdistdist/docs/changelog.rst | 2 +- pdns/dnsdistdist/docs/reference/config.rst | 6 +++--- pdns/pkcs11signers.cc | 12 ++++++------ regression-tests.dnsdist/test_DOH.py | 4 ++-- 5 files changed, 12 insertions(+), 13 deletions(-) diff --git a/.github/actions/spell-check/allow.txt b/.github/actions/spell-check/allow.txt index bb94e3fc0225..cc0e68a3b3d8 100644 --- a/.github/actions/spell-check/allow.txt +++ b/.github/actions/spell-check/allow.txt @@ -2548,7 +2548,6 @@ PBpq pbtag pcall PCDNSSEC -PCKS PCmissing pcomp pcount diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index 33a21b31bd4e..e3a4123ed48f 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -923,7 +923,7 @@ Changelog :tags: New Features, DNS over HTTPS, DNS over TLS :pullreq: 11027 - Add support for password protected PCKS12 files for TLS configuration + Add support for password protected PKCS12 files for TLS configuration .. change:: :tags: New Features diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index d67c0b1c4153..22839b6369a0 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -1885,18 +1885,18 @@ Other functions PKCS12 files are only supported by the ``openssl`` provider, password-protected or not. - :param string pathToCert: Path to a file containing the certificate or a PCKS12 file containing both a certificate and a key. + :param string pathToCert: Path to a file containing the certificate or a PKCS12 file containing both a certificate and a key. :param table options: A table with key: value pairs with additional options. Options: * ``key="path/to/key"``: string - Path to a file containing the key corresponding to the certificate. - * ``password="pass"``: string - Password protecting the PCKS12 file if appropriate. + * ``password="pass"``: string - Password protecting the PKCS12 file if appropriate. .. code-block:: lua newTLSCertificate("path/to/pub.crt", {key="path/to/private.pem"}) - newTLSCertificate("path/to/domain.p12", {password="passphrase"}) -- use a password protected PCKS12 file + newTLSCertificate("path/to/domain.p12", {password="passphrase"}) -- use a password protected PKCS12 file DOHFrontend ~~~~~~~~~~~ diff --git a/pdns/pkcs11signers.cc b/pdns/pkcs11signers.cc index 1d12e85afade..9269c9e5f8af 100644 --- a/pdns/pkcs11signers.cc +++ b/pdns/pkcs11signers.cc @@ -376,7 +376,7 @@ class Pkcs11Token { attr.push_back(P11KitAttribute(CKA_LABEL, d_label)); FindObjects2(*slot, attr, key, 1); if (key.size() == 0) { - g_log< Date: Wed, 5 Apr 2023 14:44:09 +0200 Subject: [PATCH 064/909] rec: Do not generate large not really useful test files containing names in powerdnssec.org in bulk test by default --- build-scripts/test-recursor-bulk | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build-scripts/test-recursor-bulk b/build-scripts/test-recursor-bulk index c91a9a3b6c32..e4258e2da028 100755 --- a/build-scripts/test-recursor-bulk +++ b/build-scripts/test-recursor-bulk @@ -23,13 +23,16 @@ if [ ! -z "$1" ]; then numdomains="$1" fi +if false; then set +x for prefix in 'www' 'wildcard'; do + rm -f ${prefix}.csv for num in $(seq 0 1000000); do echo "${num},${prefix}.powerdnssec.org" >> ${prefix}.csv done done set -x +fi EXIT=0 From bc563730871f5b671b5665f0045b1ae4589689d9 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 11 Apr 2023 11:37:53 +0200 Subject: [PATCH 065/909] dnsdist: fix formatting and `external` description --- pdns/dnsdistdist/docs/reference/ebpf.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/reference/ebpf.rst b/pdns/dnsdistdist/docs/reference/ebpf.rst index 2a3b4f71f139..99e508a8ff0a 100644 --- a/pdns/dnsdistdist/docs/reference/ebpf.rst +++ b/pdns/dnsdistdist/docs/reference/ebpf.rst @@ -28,6 +28,7 @@ These are all the functions, objects and methods related to the :doc:`../advance :param table options: A table with key: value pairs with options. Options: + * ``ipv4MaxItems``: int - The maximum number of entries in the IPv4 map. Default is 0 which will not allow any entry at all. * ``ipv4PinnedPath``: str - The filesystem path this map should be pinned to. * ``ipv6MaxItems``: int - The maximum number of entries in the IPv6 map. Default is 0 which will not allow any entry at all. @@ -38,7 +39,7 @@ These are all the functions, objects and methods related to the :doc:`../advance * ``cidr6PinnedPath``: str - The filesystem path this map should be pinned to. * ``qnamesMaxItems``: int - The maximum number of entries in the qname map. Default is 0 which will not allow any entry at all. * ``qnamesPinnedPath``: str - The filesystem path this map should be pinned to. - * ``external``: bool - If set to true, DNSDist can to load the internal eBPF program. + * ``external``: bool - If set to true, DNSDist does not load the internal eBPF program. .. function:: newDynBPFFilter(bpf) -> DynBPFFilter From d9f1c2becb988001b6aa0e43203df171d774f363 Mon Sep 17 00:00:00 2001 From: Chris H Date: Tue, 11 Apr 2023 14:05:00 +0200 Subject: [PATCH 066/909] recursor: restore explicit gzip compression for Ubuntu reprepro for builder.powerdns.com cannot handle xz compression yet, but newer Debian and Ubuntu dh_builddeb turn it on by default. Was accidentally removed in #10072. --- builder-support/debian/recursor/debian-buster/rules | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/builder-support/debian/recursor/debian-buster/rules b/builder-support/debian/recursor/debian-buster/rules index f8340c43393c..bcfd5f65a17e 100755 --- a/builder-support/debian/recursor/debian-buster/rules +++ b/builder-support/debian/recursor/debian-buster/rules @@ -58,3 +58,9 @@ endif override_dh_gencontrol: dh_gencontrol -- $(SUBSTVARS) + +# Explicitly set a compression method, as Debian and Ubuntu defaults vary widely, +# and xz support is not available in all tools yet. Removing this override can +# make reprepro fail. +override_dh_builddeb: + dh_builddeb -- -Zgzip From 4976f6ade2a8fef7ba7a003bf2b25f8c6a1c49c2 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 3 Apr 2023 14:57:47 +0200 Subject: [PATCH 067/909] Prep for rec-4.9.0-alpha1 --- .github/actions/spell-check/expect.txt | 1 + docs/secpoll.zone | 3 +- pdns/recursordist/docs/changelog/4.9.rst | 199 +++++++++++++++++++++ pdns/recursordist/docs/changelog/index.rst | 1 + pdns/recursordist/docs/performance.rst | 20 ++- pdns/recursordist/docs/settings.rst | 6 +- pdns/recursordist/docs/upgrade.rst | 20 ++- 7 files changed, 241 insertions(+), 9 deletions(-) create mode 100644 pdns/recursordist/docs/changelog/4.9.rst diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index a9008ccf60a5..43b7f2bacdf5 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -1368,6 +1368,7 @@ Tarnell taskqueue tbhandler tcely +TCounters tcp tcpconnecttimeouts tcpdump diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 9c2b988f2a56..abd2209fe278 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023033001 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023041201 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -346,6 +346,7 @@ recursor-4.8.1.security-status 60 IN TXT "3 Upgrade now recursor-4.8.2.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.8.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.8.4.security-status 60 IN TXT "1 OK" +recursor-4.9.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release" ; Recursor Debian recursor-3.6.2-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/" diff --git a/pdns/recursordist/docs/changelog/4.9.rst b/pdns/recursordist/docs/changelog/4.9.rst new file mode 100644 index 000000000000..b0976cb1267e --- /dev/null +++ b/pdns/recursordist/docs/changelog/4.9.rst @@ -0,0 +1,199 @@ +Changelogs for 4.9.X +==================== + +.. changelog:: + :version: 4.9.0-alpha1 + :released: 14th of April 2023 + + .. change:: + :tags: Improvements + :pullreq: 12710 + + Cleanup rcode enums: base one is 8 bit unsigned, extended one 16 bit unsigned + + .. change:: + :tags: Improvements + :pullreq: 12594 + + Sharded and shared packet cache. + + .. change:: + :tags: Improvements + :pullreq: 12709 + + More fine grained capping of packet cache TTL. + + .. change:: + :tags: Bug Fixes + :pullreq: 12655 + :tickets: 12486 + + Rework root priming code to allow multiple addresses per NS. + + .. change:: + :tags: Improvements + :pullreq: 10072,12716 + + Update Debian packaging for Recursor (Chris Hofstaedtler). + + .. change:: + :tags: Improvements + :pullreq: 12497 + + Unify shorthands for seconds in log messages (Josh Soref). + + .. change:: + :tags: Improvements + :pullreq: 12674 + + Validate: Stop passing shared pointers all the way down. + + .. change:: + :tags: Improvements + :pullreq: 12688 + + Re-establish "recursion depth is always increasing" invariant. + + .. change:: + :tags: Bug Fixes + :pullreq: 12672 + + Fix a dnsheader unaligned case. + + .. change:: + :tags: Improvements + :pullreq: 12550,12540,12524,12516,12515,12513,12502,12501,12462,12412,12401 + + OpenSSL 3.0 compatibility. + + .. change:: + :tags: Bug Fixes + :pullreq: 12554 + + Serve-stale-extensions works on 30s so an hour should be 120. (Andreas Jakum) + + .. change:: + :tags: Bug Fixes + :pullreq: 12539 + + Fix doc typo (Matt Nordhoff). + + .. change:: + :tags: Improvements + :pullreq: 12493 + + Only store NSEC3 records in aggressive cache if we expect them to be effective. + + .. change:: + :tags: Improvements + :pullreq: 11777 + + rec_control trace-regex: trace to a file or stdout instead of the general log. + + .. change:: + :tags: Bug Fixes + :pullreq: 12495 + + Logging tweaks (Josh Soref). + + .. change:: + :tags: Improvements + :pullreq: 12434 + + Unify trace logging code in syncres and validator. + + .. change:: + :tags: Improvements + :pullreq: 12446,12695 + + Stack protector for mthread stacks. + + .. change:: + :tags: Improvements + :pullreq: 12425 + + Change the way RD=0 forwarded queries are handled. + + .. change:: + :tags: Improvements + :pullreq: 12381 + + Enable FORTIFY_SOURCE=3 when supported by the compiler. + + .. change:: + :tags: Bug Fixes + :pullreq: 12419 + :tickets: 12374 + + Negcache dump code: close fd on fdopen fail. + + .. change:: + :tags: Improvements + :pullreq: 12396 + + Introduce a thread-safe version of stringerror(). + + .. change:: + :tags: Improvements + :pullreq: 12399 + :tickets: 11138 + + Name recursor threads consistently with a "rec/" prefix. + + .. change:: + :tags: Bug Fixes + :pullreq: 12392 + + Be more careful saving errno in makeClientSocket() and closesocket() + + .. change:: + :tags: Improvements + :pullreq: 12373 + + Rec: Warn on high (90%) mthread stack usage. + + .. change:: + :tags: Improvements + :pullreq: 12334,12691,12698 + + Rec: Generate EDE in more cases, specifically on unreachable auths or synthesized results. + + .. change:: + :tags: Bug Fixes + :pullreq: 12368 + + Add the 'parse packet from auth' error message to structured logging. + + .. change:: + :tags: Improvements + :pullreq: 12292 + + Wrap the CURL raw pointers in smart pointers. + + .. change:: + :tags: Improvements + :pullreq: 12318 + :tickets: 12241 + + Reorganization: move recursor specific files to recursordist. + + .. change:: + :tags: Improvements + :pullreq: 12193,12348,12323 + + Introducing TCounters. + + .. change:: + :tags: Improvements + :pullreq: 12120 + :tickets: 12090 + + If we encounter a loop in QM, continue with the next iteration. + + .. change:: + :tags: Improvements + :pullreq: 12121 + :tickets: 12080 + + More clear trace message for cache-only lookups. + diff --git a/pdns/recursordist/docs/changelog/index.rst b/pdns/recursordist/docs/changelog/index.rst index 2db2f634bd3e..56b0bd0e9975 100644 --- a/pdns/recursordist/docs/changelog/index.rst +++ b/pdns/recursordist/docs/changelog/index.rst @@ -6,6 +6,7 @@ The changelogs for the recursor are split between release trains. .. toctree:: :maxdepth: 2 + 4.9 4.8 4.7 4.6 diff --git a/pdns/recursordist/docs/performance.rst b/pdns/recursordist/docs/performance.rst index ffa66b9f7b44..3834a68eaf2b 100644 --- a/pdns/recursordist/docs/performance.rst +++ b/pdns/recursordist/docs/performance.rst @@ -15,21 +15,26 @@ See below for more information about the various caches. When deploying (large scale) IPv6, please be aware some Linux distributions leave IPv6 routing cache tables at very small default values. Please check and if necessary raise ``sysctl net.ipv6.route.max_size``. -Set :ref:`setting-threads` to your number of CPU cores minus the number of distributor threads (but values above 8 rarely improve performance). +Set :ref:`setting-threads` to your number of CPU cores minus the number of distributor threads. Threading and distribution of queries ------------------------------------- -When running with several threads, you can either ask PowerDNS to start one or more special threads to dispatch the incoming queries to the workers by setting :ref:`setting-pdns-distributes-queries` to true, or let the worker threads handle the incoming queries themselves. +When running with several threads, you can either ask PowerDNS to start one or more special threads to dispatch the incoming queries to the workers by setting :ref:`setting-pdns-distributes-queries` to ``yes``, or let the worker threads handle the incoming queries themselves. +The latter is the default since version 4.9.0. The dispatch thread enabled by :ref:`setting-pdns-distributes-queries` tries to send the same queries to the same thread to maximize the cache-hit ratio. If the incoming query rate is so high that the dispatch thread becomes a bottleneck, you can increase :ref:`setting-distributor-threads` to use more than one. -If :ref:`setting-pdns-distributes-queries` is set to false and either ``SO_REUSEPORT`` support is not available or the :ref:`setting-reuseport` directive is set to false, all worker threads share the same listening sockets. +If :ref:`setting-pdns-distributes-queries` is set to ``no`` and either ``SO_REUSEPORT`` support is not available or the :ref:`setting-reuseport` directive is set to ``no``, all worker threads share the same listening sockets. This prevents a single thread from having to handle every incoming queries, but can lead to thundering herd issues where all threads are awoken at once when a query arrives. -If ``SO_REUSEPORT`` support is available and :ref:`setting-reuseport` is set to true, separate listening sockets are opened for each worker thread and the query distributions is handled by the kernel, avoiding any thundering herd issue as well as preventing the distributor thread from becoming the bottleneck. +If ``SO_REUSEPORT`` support is available and :ref:`setting-reuseport` is set to ``yes``, which is the +default since version 4.9.0, separate listening sockets are opened for each worker thread and the query distributions is handled by the kernel, avoiding any thundering herd issue as well as preventing the distributor thread from becoming the bottleneck. + +On some systems setting :ref:`setting-reuseport` to ``yes`` does not have the desired effect. +If your systems shows imbalance in the number of queries processed per thread (as reported by the periodic statistics report), try switching :ref:`setting-reuseport` to ``no`` and/or setting :ref:`setting-pdns-distributes-queries` to ``yes``. .. versionadded:: 4.1.0 The :ref:`setting-cpu-map` parameter can be used to pin worker threads to specific CPUs, in order to keep caches as warm as possible and optimize memory access on NUMA systems. @@ -37,6 +42,13 @@ If ``SO_REUSEPORT`` support is available and :ref:`setting-reuseport` is set to .. versionadded:: 4.2.0 The :ref:`setting-distributor-threads` parameter can be used to run more than one distributor thread. +.. versionchanged:: 4.9.0 + The :ref:`setting-reuseport` parameter now defaults to ``yes``. + +.. versionchanged:: 4.9.0 + The :ref:`setting-pdns-distributes-queries` parameter now defaults to ``no``. + + MTasker and MThreads -------------------- diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index ba22422f980e..427b39904f73 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -42,12 +42,11 @@ In this case the address ``128.66.1.2`` is excluded from the addresses allowed a The number of records to cache in the aggressive cache. If set to a value greater than 0, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in :rfc:`8198`. To use this, DNSSEC processing or validation must be enabled by setting `dnssec`_ to ``process``, ``log-fail`` or ``validate``. -.. _setting-aggressive-cache-max-nsec3-hit-ratio: +.. _setting-aggressive-cache-min-nsec3-hit-ratio: ``aggressive-cache-min-nsec3-hit-ratio`` ---------------------------------------- - -.. versionadded: 4.9.0 +.. versionadded:: 4.9.0 - Integer - Default: 2000 @@ -1611,6 +1610,7 @@ i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-negative-ttl`` at Maximum number of seconds to cache an answer indicating a failure to resolve in the packet cache. Before version 4.6.0 only ``ServFail`` answers were considered as such. Starting with 4.6.0, all responses with a code other than ``NoError`` and ``NXDomain``, or without records in the answer and authority sections, are considered as a failure to resolve. +Since 4.9.0, negative answers are handled separately from resolving failures. .. versionchanged:: 4.0.0 diff --git a/pdns/recursordist/docs/upgrade.rst b/pdns/recursordist/docs/upgrade.rst index 5f5e2b6c07a5..871186e6d3e7 100644 --- a/pdns/recursordist/docs/upgrade.rst +++ b/pdns/recursordist/docs/upgrade.rst @@ -15,6 +15,25 @@ This is now resolved, but has the consequence that some metrics (in particular r This affects the results shown by ``rec_control get-qtypelist`` and the ``response-by-qtype``, ``response-sizes`` and ``response-by-rcode`` items returned by the ``/api/v1/servers/localhost/statistics`` API endpoint. Additionally, most ``RCodes`` and ``QTypes`` that are marked ``Unassigned``, ``Reserved`` or ``Obsolete`` by IANA are not accounted, to reduce the memory consumed by these metrics. +New settings +~~~~~~~~~~~~ +- The :ref:`setting-packetcache-negative-ttl` settings to control the TTL of negative (NxDomain or NoData) answers in the packet cache has been introduced. +- The :ref:`setting-stack-cache-size` setting to control the number of allocated mthread stacks has been introduced. +- The :ref:`setting-packetcache-shards` settings to control the number of shards in the packet cache has been introduced. +- The :ref:`setting-aggressive-cache-min-nsec3-hit-ratio` setting to control which NSEC3 records are stored in the aggressive NSEC cache has been introduced. + +Changed settings +~~~~~~~~~~~~~~~~ +The first two settings below have effect on the way the recursor distributes queries over threads. +In some rare cases, this can have negative performance impact. +In those cases it might be needed to change these settings. +See :doc:`performance`. + +- The :ref:`setting-pdns-distributes-queries` default has been changed to ``no``. +- The :ref:`setting-reuseport` default has been changed to ``yes``. + +- The :ref:`setting-packetcache-ttl` default has been changed to 24 hours. + :program:`rec_control` ^^^^^^^^^^^^^^^^^^^^^^ The ``trace_regex`` subcommand has been changed to take a file argument. @@ -61,7 +80,6 @@ Additionally, the ``dump-edns`` command now only lists IPs that have a not OK s The ``dump-nsspeeds`` command has changed format to make it more readable and lists the last round trip time recorded for each address. The ``get-proxymapping-stats`` and ``get-remotelogger-stats`` subcommands have been added. - 4.7.2 to 4.7.3 -------------- From 69182331d7c985b70f441f26913e0f7460d6650c Mon Sep 17 00:00:00 2001 From: Niels Date: Tue, 11 Apr 2023 20:34:21 +0200 Subject: [PATCH 068/909] Some webserver parameters were removed with 1.8.0 --- pdns/dnsdistdist/docs/reference/config.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 22839b6369a0..9db5b528ee6a 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -333,7 +333,7 @@ Webserver configuration The ``password`` parameter is now optional. The use of optional parameters is now deprecated. Please use :func:`setWebserverConfig` instead. - .. versionchanged:: 1.7.0 + .. versionchanged:: 1.8.0 The ``password``, ``apikey``, ``customHeaders`` and ``acl`` parameters is no longer supported. Please use :func:`setWebserverConfig` instead. From d85c923f52d1e2140f3ecf5467b513c7b54a856e Mon Sep 17 00:00:00 2001 From: Winfried Angele Date: Wed, 12 Apr 2023 10:30:45 +0200 Subject: [PATCH 069/909] Undo an accidentally change 'disableZeroScope' was accidentally changed to 'disableZeroScoping' in commit 597a91a3cec373ebd4172d167a0f9c7500781027 --- pdns/dnsdist-lua.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 6e3252f809a3..9efa59dd2837 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -498,7 +498,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) getOptionalValue(vars, "useClientSubnet", config.useECS); getOptionalValue(vars, "useProxyProtocol", config.useProxyProtocol); - getOptionalValue(vars, "disableZeroScoping", config.disableZeroScope); + getOptionalValue(vars, "disableZeroScope", config.disableZeroScope); getOptionalValue(vars, "ipBindAddrNoPort", config.ipBindAddrNoPort); getOptionalIntegerValue("newServer", vars, "addXPF", config.xpfRRCode); From d6126b8b6de2f6c6254ca0b7b16af1410c8f7d85 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 11 Apr 2023 13:53:18 +0200 Subject: [PATCH 070/909] rec: Fix uninited var causing wrong `bytes` field reported in protobuf log in rare cases Reported by gcc build: wres.cc: In function 'asyncresolve': lwres.cc:631:26: warning: 'len' may be used uninitialized in this function [-Wmaybe-uninitialized] 631 | logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes); | ^ lwres.cc:390:10: note: 'len' was declared here 390 | size_t len; | ^ While there, replace some mandatory pointers by refs --- pdns/recursordist/lwres.cc | 2 +- pdns/recursordist/lwres.hh | 4 ++-- pdns/recursordist/pdns_recursor.cc | 9 +++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/pdns/recursordist/lwres.cc b/pdns/recursordist/lwres.cc index 833ae7ffc148..ad9bcbb81d5c 100644 --- a/pdns/recursordist/lwres.cc +++ b/pdns/recursordist/lwres.cc @@ -495,7 +495,7 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma #endif /* HAVE_FSTRM */ // sleep until we see an answer to this, interface to mtasker - ret = arecvfrom(buf, 0, ip, &len, qid, domain, type, queryfd, now); + ret = arecvfrom(buf, 0, ip, len, qid, domain, type, queryfd, *now); } else { bool isNew; diff --git a/pdns/recursordist/lwres.hh b/pdns/recursordist/lwres.hh index 1f4e22eb41d2..52ed30ec1ad5 100644 --- a/pdns/recursordist/lwres.hh +++ b/pdns/recursordist/lwres.hh @@ -85,7 +85,7 @@ public: LWResult::Result asendto(const char* data, size_t len, int flags, const ComboAddress& ip, uint16_t id, const DNSName& domain, uint16_t qtype, bool ecs, int* fd); -LWResult::Result arecvfrom(PacketBuffer& packet, int flags, const ComboAddress& ip, size_t* d_len, uint16_t id, - const DNSName& domain, uint16_t qtype, int fd, const struct timeval* now); +LWResult::Result arecvfrom(PacketBuffer& packet, int flags, const ComboAddress& ip, size_t& len, uint16_t id, + const DNSName& domain, uint16_t qtype, int fd, const struct timeval& now); LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, const std::shared_ptr>>& outgoingLoggers, const std::shared_ptr>>& fstrmLoggers, const std::set& exportTypes, LWResult* res, bool* chained); diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index f6e0c6bb0303..e05ac3077636 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -315,8 +315,8 @@ LWResult::Result asendto(const char* data, size_t len, int /* flags */, return LWResult::Result::Success; } -LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAddress& fromaddr, size_t* d_len, - uint16_t id, const DNSName& domain, uint16_t qtype, int fd, const struct timeval* now) +LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAddress& fromaddr, size_t& len, + uint16_t id, const DNSName& domain, uint16_t qtype, int fd, const struct timeval& now) { static const unsigned int nearMissLimit = ::arg().asNum("spoof-nearmiss-max"); @@ -327,16 +327,17 @@ LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAdd pident->type = qtype; pident->remote = fromaddr; - int ret = MT->waitEvent(pident, &packet, g_networkTimeoutMsec, now); + int ret = MT->waitEvent(pident, &packet, g_networkTimeoutMsec, &now); /* -1 means error, 0 means timeout, 1 means a result from handleUDPServerResponse() which might still be an error */ if (ret > 0) { /* handleUDPServerResponse() will close the socket for us no matter what */ if (packet.empty()) { // means "error" + len = 0; return LWResult::Result::PermanentError; } - *d_len = packet.size(); + len = packet.size(); if (nearMissLimit > 0 && pident->nearMisses > nearMissLimit) { /* we have received more than nearMissLimit answers on the right IP and port, from the right source (we are using connected sockets), From 28e7226a809c522d69913e2aab2c55fbb55646e3 Mon Sep 17 00:00:00 2001 From: Erik Winkels Date: Fri, 24 Mar 2023 16:28:03 +0100 Subject: [PATCH 071/909] Print reported versions when testing repos. Remove Ubuntu Bionic for auth-48 and dnsdist-18. Remove rec-45 from repo test script since it is end-of-life. Add rec-49 to repo test script. --- .../docker/repo-test/generate-repo-files.py | 47 ++++++++++++++----- 1 file changed, 35 insertions(+), 12 deletions(-) diff --git a/build-scripts/docker/repo-test/generate-repo-files.py b/build-scripts/docker/repo-test/generate-repo-files.py index e43531721796..7e4cc8b76839 100755 --- a/build-scripts/docker/repo-test/generate-repo-files.py +++ b/build-scripts/docker/repo-test/generate-repo-files.py @@ -13,6 +13,7 @@ # Modules import argparse +import re import subprocess import sys @@ -24,7 +25,7 @@ # Globals -g_version = '0.0.1' +g_version = '1.0.2' g_verbose = False @@ -46,7 +47,7 @@ def init_argparser(): 'auth-44', 'auth-45', 'auth-46', 'auth-47', 'auth-48', 'auth-master', # Recursor - 'rec-45', 'rec-46', 'rec-47', 'rec-48', + 'rec-46', 'rec-47', 'rec-48', 'rec-49', 'rec-master', # DNSDist 'dnsdist-15', 'dnsdist-16', 'dnsdist-17', @@ -142,7 +143,7 @@ def write_release_files (release): if release in ['auth-44', 'auth-45', 'auth-46', 'auth-47', 'auth-48', 'auth-master', - 'rec-45', 'rec-46', 'rec-47', 'rec-48', + 'rec-46', 'rec-47', 'rec-48', 'rec-49', 'rec-master', 'dnsdist-15', 'dnsdist-16', 'dnsdist-17', 'dnsdist-18', 'dnsdist-master']: @@ -151,8 +152,6 @@ def write_release_files (release): write_dockerfile('el', '8', release) write_dockerfile('debian', 'buster', release) write_list_file('debian', 'buster', release) - write_dockerfile('ubuntu', 'bionic', release) - write_list_file('ubuntu', 'bionic', release) write_dockerfile('ubuntu', 'focal', release) write_list_file('ubuntu', 'focal', release) @@ -161,19 +160,25 @@ def write_release_files (release): write_list_file('raspbian', 'buster', release) if release in ['auth-46', 'auth-47', 'auth-48', 'auth-master', - 'rec-45', 'rec-46', 'rec-47', 'rec-48', 'rec-master', + 'rec-46', 'rec-47', 'rec-48', 'rec-49', 'rec-master', 'dnsdist-16', 'dnsdist-17', 'dnsdist-18', 'dnsdist-master']: write_dockerfile('debian', 'bullseye', release) write_list_file('debian', 'bullseye', release) + if release in ['auth-46', 'auth-47', 'auth-master', + 'rec-46', 'rec-47', 'rec-48', 'rec-49', 'rec-master', + 'dnsdist-15', 'dnsdist-16', 'dnsdist-17', 'dnsdist-master']: + write_dockerfile('ubuntu', 'bionic', release) + write_list_file('ubuntu', 'bionic', release) + if release in ['auth-46', 'auth-47', 'auth-48', 'auth-master', - 'rec-46', 'rec-47', 'rec-48', 'rec-master', + 'rec-46', 'rec-47', 'rec-48', 'rec-49', 'rec-master', 'dnsdist-17', 'dnsdist-18', 'dnsdist-master']: write_dockerfile('ubuntu', 'jammy', release) write_list_file('ubuntu', 'jammy', release) if release in ['auth-47', 'auth-48', 'auth-master', - 'rec-47', 'rec-48', 'rec-master', + 'rec-47', 'rec-48', 'rec-49', 'rec-master', 'dnsdist-17', 'dnsdist-18', 'dnsdist-master']: write_dockerfile('el', '9', release) @@ -205,13 +210,21 @@ def run (tag): capture_run_output = not(g_verbose) print('Running Docker container tagged {}...'.format(tag)) cp = subprocess.run(['docker', 'run', tag], - capture_output=capture_run_output) + stdout=subprocess.PIPE, stderr=subprocess.STDOUT) + version = re.search('(PowerDNS Authoritative Server|PowerDNS Recursor|' + + 'dnsdist) (\d+\.\d+\.\d+(-\w+)?)', + cp.stdout.decode()) + if g_verbose: + print(cp.stdout.decode()) # for some reason 99 is returned on `cmd --version` :shrug: if cp.returncode != 0 and cp.returncode != 99: # FIXME write failed output to log print('Error running {}: {}'.format(tag, repr(cp.returncode))) return cp.returncode - return cp.returncode + if version and version.group(2): + return cp.returncode, version.group(2) + else: + return cp.returncode, None def collect_dockerfiles (release): @@ -230,6 +243,7 @@ def test_release (release): dockerfiles = sorted(collect_dockerfiles(release)) failed_builds = [] failed_runs = [] + returned_versions = [] print('=== testing {} ==='.format(release)) for df in dockerfiles: if g_verbose: @@ -243,10 +257,13 @@ def test_release (release): print('Skipping running {} due to undetermined tag.'.format(df)) failed_builds.append((str(df), returncode)) else: - returncode = run(tag) - # for some reason 99 is returned on `cmd --version` :shrug: + (returncode, return_version) = run(tag) + # for some reason 99 is returned on `cmd --version` :shrug: + # (not sure if this is true since using `stdout=PIPE...`) if returncode != 0 and returncode != 99: failed_runs.append((tag, returncode)) + if return_version: + returned_versions.append((tag, return_version)) print('Test done.') if len(failed_builds) > 0: print('- failed builds:') @@ -256,6 +273,12 @@ def test_release (release): print('- failed runs:') for fr in failed_runs: print(' - {}'.format(fr)) + if len(returned_versions) > 0: + print('- returned versions:') + for rv in returned_versions: + print(' - {}: {}'.format(rv[0], rv[1])) + else: + print('- ERROR: no returned versions (unsupported product?)') # Main Program From edacfa5d5f9735805e07e8f86425917f5ff1ea77 Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Thu, 13 Apr 2023 00:49:24 +0200 Subject: [PATCH 072/909] auth: fix nsec at delegation point --- pdns/dnssecsigner.cc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/pdns/dnssecsigner.cc b/pdns/dnssecsigner.cc index fae036e523bf..7fd7d532532b 100644 --- a/pdns/dnssecsigner.cc +++ b/pdns/dnssecsigner.cc @@ -205,7 +205,7 @@ void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set& authSet, { stable_sort(rrs.begin(), rrs.end(), rrsigncomp); - DNSName signQName, wildcardQName; + DNSName authQName, signQName, wildcardQName; uint16_t signQType=0; uint32_t signTTL=0; uint32_t origTTL=0; @@ -219,11 +219,20 @@ void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set& authSet, DNSName signer; for(auto pos = rrs.cbegin(); pos != rrs.cend(); ++pos) { if(pos != rrs.cbegin() && (signQType != pos->dr.d_type || signQName != pos->dr.d_name)) { - if(getBestAuthFromSet(authSet, signQName, signer)) + if (getBestAuthFromSet(authSet, authQName, signer)) addSignature(dk, db, signer, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, signedRecords, origTTL); } signedRecords.push_back(*pos); - signQName= pos->dr.d_name.makeLowerCase(); + signQName = pos->dr.d_name.makeLowerCase(); + if (pos->dr.d_type == QType::NSEC) { + authQName = signQName.getCommonLabels(getRR(pos->dr)->d_next); + if (authQName.empty()) { + authQName = g_rootdnsname; + } + } + else { + authQName = signQName; + } if(!pos->wildcardname.empty()) wildcardQName = pos->wildcardname.makeLowerCase(); else @@ -239,7 +248,7 @@ void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set& authSet, toSign.insert(pos->dr.getContent()); // so ponder.. should this be a deep copy perhaps? } } - if(getBestAuthFromSet(authSet, signQName, signer)) + if (getBestAuthFromSet(authSet, authQName, signer)) addSignature(dk, db, signer, signQName, wildcardQName, signQType, signTTL, signPlace, toSign, signedRecords, origTTL); rrs.swap(signedRecords); } From 0f074be5c1b0b283d33de603d1ca92d914a15b33 Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Thu, 13 Apr 2023 00:50:08 +0200 Subject: [PATCH 073/909] auth: add nsec at delegation point test --- modules/tinydnsbackend/data | 1 + modules/tinydnsbackend/data.cdb | Bin 1356255 -> 1356349 bytes .../tinydns-data-check/command | 1 + .../tinydns-data-check/expected_result | 5 +++-- regression-tests/tests/axfr/expected_result | 1 + .../tests/axfr/expected_result.dnssec | 6 +++++- .../tests/axfr/expected_result.nsec3 | 4 ++++ .../tests/axfr/expected_result.nsec3-optout | 4 ++++ .../expected_result.nsec3-optout | 2 +- .../expected_result.dnssec | 4 ++-- .../tests/nsec-at-delegation/command | 2 ++ .../tests/nsec-at-delegation/description | 1 + .../tests/nsec-at-delegation/expected_result | 9 +++++++++ .../nsec-at-delegation/expected_result.narrow | 9 +++++++++ .../nsec-at-delegation/expected_result.nsec3 | 9 +++++++++ .../expected_result.nsec3-optout | 9 +++++++++ .../tests/nsec-at-delegation/skip.nodnssec | 0 regression-tests/zones/dnssec-parent.com | 1 + 18 files changed, 62 insertions(+), 6 deletions(-) create mode 100755 regression-tests/tests/nsec-at-delegation/command create mode 100644 regression-tests/tests/nsec-at-delegation/description create mode 100644 regression-tests/tests/nsec-at-delegation/expected_result create mode 100644 regression-tests/tests/nsec-at-delegation/expected_result.narrow create mode 100644 regression-tests/tests/nsec-at-delegation/expected_result.nsec3 create mode 100644 regression-tests/tests/nsec-at-delegation/expected_result.nsec3-optout create mode 100644 regression-tests/tests/nsec-at-delegation/skip.nodnssec diff --git a/modules/tinydnsbackend/data b/modules/tinydnsbackend/data index a6685097350d..7a262b3edac8 100644 --- a/modules/tinydnsbackend/data +++ b/modules/tinydnsbackend/data @@ -20271,6 +20271,7 @@ Znztest.com:ns1.nztest.com.:ahu.example.com.:2005092501:28800:7200:604800:86400: +ns2.secure-delegated.dnssec-parent.com:5.6.7.8:3600 +something1.auth-ent.dnssec-parent.com:1.1.2.3:3600 :secure-delegated.dnssec-parent.com:43:\324\057\010\002\240\271\303\214\323\044\030\052\360\357f\203\015\012\016\205\241\325\211y\311\203N\030\310qw\236\004\010W\267:3600 +C\052.dnssec-parent.com:secure-delegated.dnssec-parent.com.:3600 Cwww.dnssec-parent.com:www.insecure.dnssec-parent.com.:3600 Zdnssec-parent.com:ns1.dnssec-parent.com.:ahu.example.com.:2005092501:28800:7200:604800:86400:3600 #2000081501 auto axfr-get diff --git a/modules/tinydnsbackend/data.cdb b/modules/tinydnsbackend/data.cdb index e70be8d883affea4a2ecc871b705679efb0befe5..b71ae2d51ecda7103f1a61fb5fa10ea28aebb0ab 100644 GIT binary patch delta 3491 zcmZuzdw5J|8vkY{$>cIK=Sn3t+NgCYLnJnF8)}2rWzei9-DPYwZkz33L&-zNkhamq z5EespB1@>)PDo{XG|W=6L78M%HV)4^A+{*VWZg@)(f!W*j_M!H^L)=Q@8!F^zxVf^ zXRiDwBk)azOF6=j0zydW7-GjshOAKSQw;f#qVXI<@>RQ@AuCmE2%{X1UuMWY>bEsB zq>Q5D217nk?G}cVs(2^tf5?yuYAfyNSAKwfE@F;k$z~b|#IU58qT9rhZR$pWg@Y_z zFdpp6l1u z(Tb+CP_gn3OV+C!XR~A(Mf2}jsMzd4JG77mCW4F6_U7R}cRoJczKR7VyoLBc=UPO2 z5erP%x3IvFvpDSEN&WPGVlQLKR`q4&SfSU)l6BPXsKg2bUxb-Cf=pPBV_u*p>_5Yj z8k+B`M+SV2EUBip^WRu$s2StNZ;=Ue8^%NTS>jSDvbSSJmZw;eS<3+<#wZS$P+~Z; zgyy-899ctA;V>TTgmG^?M@rOqHx63ncm-{HZ?vrzL~}9+tyNMvU_=?lxnM)!H4Zdj zAHyLN<2h2K9yp1EmULvG-S)N zwBY*_M~+P`|qq50yGz^F+)uPQkc&Do^&(2iSgt=$ygBGz7AF=yhNoPY%+!bw2u?i@@(9 z&O9EebMip7xd72u$b(oMYk3fty@*F`Y~fKG+j-E8r35dq?B>ZiwFTwKg!2Fo^B(Z? z_Y{7$Or+Lv84;pTgNy7G~k>pfcmX(3BZhZ8pZ=N1<*oZu0UKc9u5IM znZZQ@%)57~02**F7eE7Emq1$8hZYJj9m*O3m{QhbUT_ooeOvKi&K>w*YpDRex9-8h z%=_`7!HO^whXfZ?hS>gzXT9l;1b%7CSNi> z>Y13J%tn7OM+7Ep3lM{gFwc=Ef;KEp5i}E6C1P(^V}&8N2(7hl#sZDSB7PrAMfhIC z825@G4#x*i^sArfHFRm|($N(`S0r6gbg8jux?<>xr7Mmu16@YCOwtoQW7!=kPy$js z+^5V7o{QTVljq(6riaw?uZ;2SzP&$V2;(!fRNsgp%r1NmGw=zsuAdl&U)O z-=*tz9ArGBZZmx(`M3P6XibweJezlQ(d?FvF6Za=d-3BchHPs~k?O_F7yDji0O?x~f15$LAIZ zqdV*FV0xldzfEY3)uvWRf!#vxP*43;A!g302EY4GERplN)y)~HA#&x0q;ongkv}Wk zo$zu5k>^G4GknSrxpe0EU3F;NRGa!A?xQI0zq#ZEJ=j!VL_Yh``dUXc*e6um>ur3M z)u~cQ^c-jsqN8LnxqsI;Jxa6CeSlo_QA2w+y|wks#srDp`sl;Y`!`eVhW}*IXeus= zBJ!vmYt}SHfS^Xodo~Z>_;(YL+l#k$Z;g7E`yPeHcXWTYCrUWiCgho%Kw`L95m@t@f5#Kx{ay;d*&zl$9 z7wDc}RIgl5PS<<-HwlS)`IG(qa{a_JzgdXyEE{I`yO>Ykf2wZbg$b0Pg2DcpuRN7D zcIagJ+NP}BBlOwnp(@KdTE?mJDY0Ksw3H8cI+o(i(JgKBf6|ez%g2qqMbGf1UFx3s zliQnjRu~pWdg|zfdU@EgK@(dd)f)!t<#)3eU!Jao-Z8Ra=lPNqKlV;4xhB|cTs-|i z-EhacvckAUG9-z|bo|$Jz;EvO$Lk$oOsbNU6frYF(;y9+BrY)NqMuFEvFT!&J}!z5 U<=yxD&pF$SQju2A65qD{ACv~%nE(I) delta 3494 zcmYLJ2~-qU7X94~G;9B=`sEWLqyqaT7*z+JkX#*fG;20D5 zGmbGN6$b1sYNzibT+E^EdS)e1p}m|#pHkgj2^BiN4lr{RnDBWZ&QTk%pXE?3jZgOi z1L@~ER6}*?XQ211j?U2^Dz_JY&QY%rhpGFdi+VakeNP z8UftiDXDze#1sy*Rx_>aBcNouFs|@EEBgz`!! z%%cMR!s$F~i8~eS=`-O1>uiYk%mu$RpJy{5{hen_*#80O$mUTsy+>LZu&?FWETsRF zN5}O06`5yL;m@F=&K*4Kv2Qoew!*)UXG13+;8Bi#pcMSpa-MC6trE^jRXi%v{WXwa z=QliTLv4VGvpk!AxdC)XBQW5QF9!Zxf{Oi3P^s%W1S&01VW%Jb@&oWokKvs31eov| z1@sL~z!NI43cVJAO~0+1z$&%&5Ew(&IDs)_iwD2#9s&VMlE5l*j}T!0#|Vr8w++yf zBCy`$R|Up|cPhkr?BMs#5YXo|fzG!8r8xrI21ka#dhJ*!po7%!Uj%k(3A4*c$`OFN zl>(#MyBaV(Phi7h-5{{x!UY1%#x?~sb4q!m(6kxc62rEzyBTP@X5H<^5LUn!r-Q6L;(+dJzeF$ShiYM$lpbR3633~#8 zHTx@J58=@S5*bGrGo9lJ>#cP%VKX4v37dZZn}jiAp9Ox$JA}=GV*x=jTaQJAeKO@G zgzdXMo3I(Mtsra$>@q>EdZKxRZHJOi7*on7h?BQ~J$*YQChdZR{Vu|K?=ObJyrqz+ zToGX65Rq9$_G&Ol#|i7H_at1P)DhNeTo0&t;R4%_gbkbHC(x~z!S8B@%H21iQg1sj zpgaJycMvuc3KCHrEyxohi;N;UQe@u&yC9;&)Zvd7S*6|{BHIeTRfO5-D>BNZ=fRH$ zgKkd{Q64=fCyQ+FU86+SBF8uprawhwy|=$AvaL|2iL7NdITZqIGeyRPG+P7)=0box zAMB1ykul-_0MM}n;&6`0X2Y8+vYAO=EwbLGuZIeijUsEUZz~k&-YK%#@VG?wy$Ew3 z5ZQ3xwU5o~ADazSj8sfif~W*j38A9h{LL&Q;vbC5sY?!G{&dwC#d(Y- zp%TOKOPCX}Ayd8Ao3l-bIa-5J-1(ggo7ycX?ssMBAG%I)h&m;MyCE5WRn?@e+<+Bv zA>|lNyl1{wTNQyOn$Pc@rRx+A25_!(xrMhHqSQhQzo3t?ty(n=uP7_1)uqyeZ}+wP&7qGQVtk1j?+RI{dz_Q|zx6o#4~c4DYJOXyLaM z)3k%w8OL!0)&8@Dd7*{^H9td;yBq$dhUW?k2KN|!7^5BSN$TnVo(W(^RiNwxB|^W^ zh5_pL%|d6Gsb3A4o!450V}_+_QJXL#NLcU2==0LL+}iCvauK5O&MGkwiSvz^;8 zClY4StTm<i5*ZiY5JOqkY|r; zWjB^Z)BC#D4k{Q&-x+w1U$(;#xXS*%av=jA!P<;9OIlx~L~I*-w=UD@3~C~A@mfsN zsNg9Uq%DtZoA6rjvunT1+aLQJ4UU{Y_+qZvIkt(!ShOZrMdV^i)tZr2wI`kR%_P>j z@-hjNZ%k-u|A6MOdKQ)rg^-kDO=KufDs5`Hkzjx=wXnRS$AmC|;2h~6PF z%2K$OR*^C1cI59N&fI1aNHyq83C zn3!6Uc8!vDVB6Tu-&t5=tXj_%lPBGxISeV4o=l=|u3GJ!a*n>~%f3}sXjcDdCT~yU z>#H!jzA;=5qYI$pD{5wf=rIYohcLRa>p!o!1K4~>9g{4k#TwSBTc(Q+i>anMuqnOX b7K_ah)fE`sT{`r=`lb;0cwL((zBTRtTQt+} diff --git a/regression-tests.nobackend/tinydns-data-check/command b/regression-tests.nobackend/tinydns-data-check/command index 81e2dcd51611..0139d4987db3 100755 --- a/regression-tests.nobackend/tinydns-data-check/command +++ b/regression-tests.nobackend/tinydns-data-check/command @@ -8,4 +8,5 @@ for zone in `cat ../regression-tests/named.conf | grep 'zone ' | cut -f 2 -d \"` do ${MD5SUM} ../regression-tests/zones/$zone done +${MD5SUM} ../modules/tinydnsbackend/data ${MD5SUM} ../modules/tinydnsbackend/data.cdb diff --git a/regression-tests.nobackend/tinydns-data-check/expected_result b/regression-tests.nobackend/tinydns-data-check/expected_result index bba64c82c866..71c0ebda7acb 100644 --- a/regression-tests.nobackend/tinydns-data-check/expected_result +++ b/regression-tests.nobackend/tinydns-data-check/expected_result @@ -4,7 +4,7 @@ e5e3ee998d151fe194b98997eaa36c53 ../regression-tests/zones/test.dyndns dee3e8b568549d9450134b555ca73990 ../regression-tests/zones/sub.test.dyndns e7c0fd528e8aaedb1ea3b6daaead4de2 ../regression-tests/zones/wtest.com 42b442de632686e94bde75acf66cf524 ../regression-tests/zones/nztest.com -b06133eb32c5bdf346223563501ba8f8 ../regression-tests/zones/dnssec-parent.com +7f79c98efdb1d3d2318ac666d2fb5642 ../regression-tests/zones/dnssec-parent.com e9be89b6e5e0da8910c69e46f35d20ab ../regression-tests/zones/insecure.dnssec-parent.com 6510bf48aa3ca3501b73a1f510852a34 ../regression-tests/zones/delegated.dnssec-parent.com a63dc120391d9df0003f2ec4f461a6af ../regression-tests/zones/secure-delegated.dnssec-parent.com @@ -15,4 +15,5 @@ a98864b315f16bcf49ce577426063c42 ../regression-tests/zones/cdnskey-cds-test.com 9aeed2c26d0c3ba3baf22dfa9568c451 ../regression-tests/zones/2.0.192.in-addr.arpa 99c73e8b5db5781fec1ac3fa6a2662a9 ../regression-tests/zones/cryptokeys.org 1f9e19be0cff67330f3a0a5347654f91 ../regression-tests/zones/hiddencryptokeys.org -ab699fca1a52598202a1494cddd192ff ../modules/tinydnsbackend/data.cdb +964425367cec0d828222b144c4e1c540 ../modules/tinydnsbackend/data +f3932b1df41d683f47516455b571c358 ../modules/tinydnsbackend/data.cdb diff --git a/regression-tests/tests/axfr/expected_result b/regression-tests/tests/axfr/expected_result index d831426e482d..09e9dfaeb3b4 100644 --- a/regression-tests/tests/axfr/expected_result +++ b/regression-tests/tests/axfr/expected_result @@ -1,3 +1,4 @@ +*.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com. delegated.dnssec-parent.com. 3600 IN NS ns1.delegated.dnssec-parent.com. delegated.dnssec-parent.com. 3600 IN NS ns2.delegated.dnssec-parent.com. dnssec-parent.com. 3600 IN A 9.9.9.9 diff --git a/regression-tests/tests/axfr/expected_result.dnssec b/regression-tests/tests/axfr/expected_result.dnssec index 4aac677664f6..6930c4ce2592 100644 --- a/regression-tests/tests/axfr/expected_result.dnssec +++ b/regression-tests/tests/axfr/expected_result.dnssec @@ -1,3 +1,7 @@ +*.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com. +*.dnssec-parent.com. 3600 IN NSEC insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. CNAME RRSIG NSEC +*.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +*.dnssec-parent.com. 3600 IN RRSIG NSEC 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... delegated.dnssec-parent.com. 3600 IN NS ns1.delegated.dnssec-parent.com. delegated.dnssec-parent.com. 3600 IN NS ns2.delegated.dnssec-parent.com. delegated.dnssec-parent.com. 3600 IN NSEC insecure.dnssec-parent.com. NS RRSIG NSEC @@ -5,7 +9,7 @@ delegated.dnssec-parent.com. 3600 IN RRSIG NSEC 13 3 3600 [expiry] [inception] [ dnssec-parent.com. 3600 IN A 9.9.9.9 dnssec-parent.com. 3600 IN NS ns1.dnssec-parent.com. dnssec-parent.com. 3600 IN NS ns2.dnssec-parent.com. -dnssec-parent.com. 3600 IN NSEC insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY +dnssec-parent.com. 3600 IN NSEC *.dnssec-parent.com. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY dnssec-parent.com. 3600 IN RRSIG A 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG NS 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... dnssec-parent.com. 3600 IN RRSIG NSEC 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... diff --git a/regression-tests/tests/axfr/expected_result.nsec3 b/regression-tests/tests/axfr/expected_result.nsec3 index 8b9d290b3ba6..15b816217930 100644 --- a/regression-tests/tests/axfr/expected_result.nsec3 +++ b/regression-tests/tests/axfr/expected_result.nsec3 @@ -1,3 +1,7 @@ +*.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com. +*.dnssec-parent.com. 3600 IN NSEC3 1 0 1 abcd [next owner] CNAME RRSIG +*.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +*.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... auth-ent.dnssec-parent.com. 3600 IN NSEC3 1 0 1 abcd [next owner] auth-ent.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... delegated.dnssec-parent.com. 3600 IN NS ns1.delegated.dnssec-parent.com. diff --git a/regression-tests/tests/axfr/expected_result.nsec3-optout b/regression-tests/tests/axfr/expected_result.nsec3-optout index c4da9a3352cc..ad6ce2201f5e 100644 --- a/regression-tests/tests/axfr/expected_result.nsec3-optout +++ b/regression-tests/tests/axfr/expected_result.nsec3-optout @@ -1,3 +1,7 @@ +*.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com. +*.dnssec-parent.com. 3600 IN NSEC3 1 1 1 abcd [next owner] CNAME RRSIG +*.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +*.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... auth-ent.dnssec-parent.com. 3600 IN NSEC3 1 1 1 abcd [next owner] auth-ent.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... delegated.dnssec-parent.com. 3600 IN NS ns1.delegated.dnssec-parent.com. diff --git a/regression-tests/tests/ds-at-unsecure-zone-cut/expected_result.nsec3-optout b/regression-tests/tests/ds-at-unsecure-zone-cut/expected_result.nsec3-optout index 96aff471d89f..680fef8692f4 100644 --- a/regression-tests/tests/ds-at-unsecure-zone-cut/expected_result.nsec3-optout +++ b/regression-tests/tests/ds-at-unsecure-zone-cut/expected_result.nsec3-optout @@ -2,7 +2,7 @@ 1 7on3vems0f8k9999ikei0ig4lfijekdr.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 1 dnssec-parent.com. 3600 IN RRSIG SOA 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 1 dnssec-parent.com. 3600 IN SOA ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 -1 dvkuo8kja65gcsq600e6di9u719lsj8u.dnssec-parent.com. 3600 IN NSEC3 1 1 1 abcd NIH4L3ODLUG7EN20PENJ8DGNU4OHC98F A NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY +1 dvkuo8kja65gcsq600e6di9u719lsj8u.dnssec-parent.com. 3600 IN NSEC3 1 1 1 abcd K25OPIULTRKGKRMR3UC09CSK20QHT1LJ A NS SOA RRSIG DNSKEY NSEC3PARAM CDS CDNSKEY 1 dvkuo8kja65gcsq600e6di9u719lsj8u.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 2 . 32768 IN OPT Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 diff --git a/regression-tests/tests/ent-unsigned-delegation/expected_result.dnssec b/regression-tests/tests/ent-unsigned-delegation/expected_result.dnssec index 6a7cb568584a..c9444d0f6c7d 100644 --- a/regression-tests/tests/ent-unsigned-delegation/expected_result.dnssec +++ b/regression-tests/tests/ent-unsigned-delegation/expected_result.dnssec @@ -1,5 +1,5 @@ -1 dnssec-parent.com. 3600 IN NSEC insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. A NS SOA RRSIG NSEC DNSKEY CDS CDNSKEY -1 dnssec-parent.com. 3600 IN RRSIG NSEC 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +1 *.dnssec-parent.com. 3600 IN NSEC insecure-delegated.ent.ent.auth-ent.dnssec-parent.com. CNAME RRSIG NSEC +1 *.dnssec-parent.com. 3600 IN RRSIG NSEC 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 1 dnssec-parent.com. 3600 IN RRSIG SOA 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... 1 dnssec-parent.com. 3600 IN SOA ns1.dnssec-parent.com. ahu.example.com. 2005092501 28800 7200 604800 86400 2 . 32768 IN OPT diff --git a/regression-tests/tests/nsec-at-delegation/command b/regression-tests/tests/nsec-at-delegation/command new file mode 100755 index 000000000000..58ee8e88e1ab --- /dev/null +++ b/regression-tests/tests/nsec-at-delegation/command @@ -0,0 +1,2 @@ +#!/bin/sh +cleandig secure-delegated1.dnssec-parent.com A dnssec diff --git a/regression-tests/tests/nsec-at-delegation/description b/regression-tests/tests/nsec-at-delegation/description new file mode 100644 index 000000000000..d59bcc584568 --- /dev/null +++ b/regression-tests/tests/nsec-at-delegation/description @@ -0,0 +1 @@ +Check that we generate the right NSECs when the NSEC name is a delegation point. diff --git a/regression-tests/tests/nsec-at-delegation/expected_result b/regression-tests/tests/nsec-at-delegation/expected_result new file mode 100644 index 000000000000..19f980e09021 --- /dev/null +++ b/regression-tests/tests/nsec-at-delegation/expected_result @@ -0,0 +1,9 @@ +0 secure-delegated.dnssec-parent.com. 3600 IN A 9.9.9.9 +0 secure-delegated.dnssec-parent.com. 3600 IN RRSIG A 8 3 3600 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ... +0 secure-delegated1.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com. +0 secure-delegated1.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +1 secure-delegated.dnssec-parent.com. 3600 IN NSEC www.dnssec-parent.com. NS DS RRSIG NSEC +1 secure-delegated.dnssec-parent.com. 3600 IN RRSIG NSEC 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +2 . 32768 IN OPT +Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='secure-delegated1.dnssec-parent.com.', qtype=A diff --git a/regression-tests/tests/nsec-at-delegation/expected_result.narrow b/regression-tests/tests/nsec-at-delegation/expected_result.narrow new file mode 100644 index 000000000000..dafbed64916a --- /dev/null +++ b/regression-tests/tests/nsec-at-delegation/expected_result.narrow @@ -0,0 +1,9 @@ +0 secure-delegated.dnssec-parent.com. 3600 IN A 9.9.9.9 +0 secure-delegated.dnssec-parent.com. 3600 IN RRSIG A 8 3 3600 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ... +0 secure-delegated1.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com. +0 secure-delegated1.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +1 1an9kidorpirlabrh3be2n8k5taoe1v0.dnssec-parent.com. 3600 IN NSEC3 1 [flags] 1 abcd 1AN9KIDORPIRLABRH3BE2N8K5TAOE1V2 +1 1an9kidorpirlabrh3be2n8k5taoe1v0.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +2 . 32768 IN OPT +Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='secure-delegated1.dnssec-parent.com.', qtype=A diff --git a/regression-tests/tests/nsec-at-delegation/expected_result.nsec3 b/regression-tests/tests/nsec-at-delegation/expected_result.nsec3 new file mode 100644 index 000000000000..e65ad7a6777f --- /dev/null +++ b/regression-tests/tests/nsec-at-delegation/expected_result.nsec3 @@ -0,0 +1,9 @@ +0 secure-delegated.dnssec-parent.com. 3600 IN A 9.9.9.9 +0 secure-delegated.dnssec-parent.com. 3600 IN RRSIG A 8 3 3600 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ... +0 secure-delegated1.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com. +0 secure-delegated1.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +1 u97st412oa8b4bgjc1dgtb4qi5di8dmv.dnssec-parent.com. 3600 IN NSEC3 1 [flags] 1 abcd 1SCAQA30LQ0DO5EIRNE4KPJFBEBFGR54 +1 u97st412oa8b4bgjc1dgtb4qi5di8dmv.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +2 . 32768 IN OPT +Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='secure-delegated1.dnssec-parent.com.', qtype=A diff --git a/regression-tests/tests/nsec-at-delegation/expected_result.nsec3-optout b/regression-tests/tests/nsec-at-delegation/expected_result.nsec3-optout new file mode 100644 index 000000000000..aee66ded27be --- /dev/null +++ b/regression-tests/tests/nsec-at-delegation/expected_result.nsec3-optout @@ -0,0 +1,9 @@ +0 secure-delegated.dnssec-parent.com. 3600 IN A 9.9.9.9 +0 secure-delegated.dnssec-parent.com. 3600 IN RRSIG A 8 3 3600 [expiry] [inception] [keytag] secure-delegated.dnssec-parent.com. ... +0 secure-delegated1.dnssec-parent.com. 3600 IN CNAME secure-delegated.dnssec-parent.com. +0 secure-delegated1.dnssec-parent.com. 3600 IN RRSIG CNAME 13 2 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +1 qoqsriqrvi1g1ql3tpph2248q9ldpepf.dnssec-parent.com. 3600 IN NSEC3 1 [flags] 1 abcd 1SCAQA30LQ0DO5EIRNE4KPJFBEBFGR54 A RRSIG +1 qoqsriqrvi1g1ql3tpph2248q9ldpepf.dnssec-parent.com. 3600 IN RRSIG NSEC3 13 3 3600 [expiry] [inception] [keytag] dnssec-parent.com. ... +2 . 32768 IN OPT +Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='secure-delegated1.dnssec-parent.com.', qtype=A diff --git a/regression-tests/tests/nsec-at-delegation/skip.nodnssec b/regression-tests/tests/nsec-at-delegation/skip.nodnssec new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/regression-tests/zones/dnssec-parent.com b/regression-tests/zones/dnssec-parent.com index 0800ccf1eba5..f32469bbf744 100644 --- a/regression-tests/zones/dnssec-parent.com +++ b/regression-tests/zones/dnssec-parent.com @@ -25,3 +25,4 @@ insecure-delegated.ent.ent.auth-ent IN NS ns.example.com. something1.auth-ent IN A 1.1.2.3 insecure IN NS ns.example.com. www IN CNAME www.insecure +* IN CNAME secure-delegated From 385a22085d5ddb119dad293c617716ab64fd7bad Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Thu, 13 Apr 2023 09:32:16 +0200 Subject: [PATCH 074/909] make getCommonLabels() root aware --- pdns/dnsname.cc | 6 +++++- pdns/dnssecsigner.cc | 3 --- pdns/test-dnsname_cc.cc | 12 ++++++++---- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/pdns/dnsname.cc b/pdns/dnsname.cc index 3bfbf3007fbd..25a90078a890 100644 --- a/pdns/dnsname.cc +++ b/pdns/dnsname.cc @@ -296,7 +296,11 @@ void DNSName::makeUsRelative(const DNSName& zone) DNSName DNSName::getCommonLabels(const DNSName& other) const { - DNSName result; + if (empty() || other.empty()) { + return DNSName(); + } + + DNSName result(g_rootdnsname); const std::vector ours = getRawLabels(); const std::vector others = other.getRawLabels(); diff --git a/pdns/dnssecsigner.cc b/pdns/dnssecsigner.cc index 7fd7d532532b..74dc882ab012 100644 --- a/pdns/dnssecsigner.cc +++ b/pdns/dnssecsigner.cc @@ -226,9 +226,6 @@ void addRRSigs(DNSSECKeeper& dk, UeberBackend& db, const set& authSet, signQName = pos->dr.d_name.makeLowerCase(); if (pos->dr.d_type == QType::NSEC) { authQName = signQName.getCommonLabels(getRR(pos->dr)->d_next); - if (authQName.empty()) { - authQName = g_rootdnsname; - } } else { authQName = signQName; diff --git a/pdns/test-dnsname_cc.cc b/pdns/test-dnsname_cc.cc index 0001d1ee04f6..43c1b900ddf6 100644 --- a/pdns/test-dnsname_cc.cc +++ b/pdns/test-dnsname_cc.cc @@ -1019,14 +1019,18 @@ BOOST_AUTO_TEST_CASE(test_getcommonlabels) { BOOST_CHECK_EQUAL(name2.getCommonLabels(name1), DNSName("powerdns.com")); const DNSName name3("www.powerdns.org"); - BOOST_CHECK_EQUAL(name1.getCommonLabels(name3), DNSName()); - BOOST_CHECK_EQUAL(name2.getCommonLabels(name3), DNSName()); - BOOST_CHECK_EQUAL(name3.getCommonLabels(name1), DNSName()); - BOOST_CHECK_EQUAL(name3.getCommonLabels(name2), DNSName()); + BOOST_CHECK_EQUAL(name1.getCommonLabels(name3), g_rootdnsname); + BOOST_CHECK_EQUAL(name2.getCommonLabels(name3), g_rootdnsname); + BOOST_CHECK_EQUAL(name3.getCommonLabels(name1), g_rootdnsname); + BOOST_CHECK_EQUAL(name3.getCommonLabels(name2), g_rootdnsname); const DNSName name4("WWw.PowErDnS.org"); BOOST_CHECK_EQUAL(name3.getCommonLabels(name4), name3); BOOST_CHECK_EQUAL(name4.getCommonLabels(name3), name4); + + const DNSName(name5); + BOOST_CHECK_EQUAL(name1.getCommonLabels(name5), DNSName()); + BOOST_CHECK_EQUAL(name5.getCommonLabels(name1), DNSName()); } BOOST_AUTO_TEST_SUITE_END() From a60758291b0caf997003e59eccbc1aa47f92f8cf Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Wed, 5 Apr 2023 09:52:09 +0200 Subject: [PATCH 075/909] auth: calm down the communicator loop --- pdns/auth-main.cc | 5 ++++- pdns/communicator.cc | 23 +++++++++++------------ pdns/mastercommunicator.cc | 1 - 3 files changed, 15 insertions(+), 14 deletions(-) diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index 0eb9bfb1ec01..5f46624b62a0 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -210,7 +210,7 @@ static void declareArguments() ::arg().set("only-notify", "Only send AXFR NOTIFY to these IP addresses or netmasks") = "0.0.0.0/0,::/0"; ::arg().set("also-notify", "When notifying a zone, also notify these nameservers") = ""; ::arg().set("allow-notify-from", "Allow AXFR NOTIFY from these IP ranges. If empty, drop all incoming notifies.") = "0.0.0.0/0,::/0"; - ::arg().set("slave-cycle-interval", "Schedule slave freshness checks once every .. seconds") = "60"; + ::arg().set("slave-cycle-interval", "Schedule slave freshness checks once every .. seconds") = ""; ::arg().set("xfr-cycle-interval", "Schedule primary/secondary SOA freshness checks once every .. seconds") = "60"; ::arg().set("secondary-check-signature-freshness", "Check signatures in SOA freshness check. Sets DO flag on SOA queries. Outside some very problematic scenarios, say yes here.") = "yes"; @@ -1241,6 +1241,8 @@ int main(int argc, char** argv) ::arg().set("allow-unsigned-autoprimary") = "yes"; if (!::arg().isEmpty("domain-metadata-cache-ttl")) ::arg().set("zone-metadata-cache-ttl") = ::arg()["domain-metadata-cache-ttl"]; + if (!::arg().isEmpty("slave-cycle-interval")) + ::arg().set("xfr-cycle-interval") = ::arg()["slave-cycle-interval"]; // this mirroring back is on purpose, so that config dumps reflect the actual setting on both names if (::arg().mustDo("primary")) @@ -1254,6 +1256,7 @@ int main(int argc, char** argv) if (::arg().mustDo("allow-unsigned-autoprimary")) ::arg().set("allow-unsigned-supermaster") = "yes"; ::arg().set("domain-metadata-cache-ttl") = ::arg()["zone-metadata-cache-ttl"]; + ::arg().set("slave-cycle-interval") = ::arg()["xfr-cycle-interval"]; g_log.setLoglevel((Logger::Urgency)(::arg().asNum("loglevel"))); g_log.disableSyslog(::arg().mustDo("disable-syslog")); diff --git a/pdns/communicator.cc b/pdns/communicator.cc index fd44af19fe92..bbe23eef6a3a 100644 --- a/pdns/communicator.cc +++ b/pdns/communicator.cc @@ -118,22 +118,22 @@ void CommunicatorClass::mainloop() try { setThreadName("pdns/comm-main"); signal(SIGPIPE,SIG_IGN); - g_log< Date: Tue, 28 Mar 2023 10:20:04 +0200 Subject: [PATCH 076/909] dnsdist: Add ChangeLog and secpoll update for dnsdist 1.7.4 --- docs/secpoll.zone | 3 +- pdns/dnsdistdist/docs/changelog.rst | 112 ++++++++++++++++++++++++++++ 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index abd2209fe278..94d25f493fff 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023041201 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023041400 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -498,6 +498,7 @@ dnsdist-1.7.0.security-status 60 IN TXT "1 OK" dnsdist-1.7.1.security-status 60 IN TXT "1 OK" dnsdist-1.7.2.security-status 60 IN TXT "1 OK" dnsdist-1.7.3.security-status 60 IN TXT "1 OK" +dnsdist-1.7.4.security-status 60 IN TXT "1 OK" dnsdist-1.8.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" dnsdist-1.8.0-rc2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" dnsdist-1.8.0-rc3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index e3a4123ed48f..a54a942a503d 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -1,6 +1,118 @@ Changelog ========= +.. changelog:: + :version: 1.7.4 + :released: 14th of April 2023 + + .. change:: + :tags: Bug Fixes + :pullreq: 12183 + :tickets: 12177 + + Fix building with boost < 1.56 + + .. change:: + :tags: Bug Fixes + :pullreq: 12460 + :tickets: 12453 + + lock.hh: include + + .. change:: + :tags: Bug Fixes + :pullreq: 12569 + + dnsdist-protocols.hh: include (Sander Hoentjen) + + .. change:: + :tags: New Features + :pullreq: 12621 + :tickets: 12074 + + Add getPoolNames() function, returning a list of pool names (Christof Chen) + + .. change:: + :tags: Bug Fixes + :pullreq: 12535 + + Fix the formatting of 'showServers' + + .. change:: + :tags: Bug Fixes + :pullreq: 12529 + :tickets: 11905 + + Properly record the incoming flags on a timeout + + .. change:: + :tags: Bug Fixes, Metrics + :pullreq: 12484 + :tickets: 11498 + + Properly update rcode-related metrics on RCodeAction hits + + .. change:: + :tags: Bug Fixes, DNS over TLS, DNS over HTTPS + :pullreq: 12421 + :tickets: 12341 + + Skip invalid OCSP files after issuing a warning + + .. change:: + :tags: Bug Fixes + :pullreq: 12365 + :tickets: 12357 + + Prevent an underflow of the TCP d_queued counter + + .. change:: + :tags: Bug Fixes, DNS over HTTPS + :pullreq: 12327 + + Fix the health-check timeout computation for DoH backend + + .. change:: + :tags: Bug Fixes, Webserver + :pullreq: 12260 + :tickets: 9349 + + Properly encode json strings containing binary data + + .. change:: + :tags: Bug Fixes, DNS over TLS + :pullreq: 12237 + :tickets: 12236 + + Ignore unclean TLS session shutdown + + .. change:: + :tags: Bug Fixes + :pullreq: 12100 + :tickets: 12099 + + Properly handle single-SOA XFR responses + + .. change:: + :tags: Bug Fixes + :pullreq: 11830 + :tickets: 4155 + + Also reconnect on ENETUNREACH. (Asgeir Storesund Nilsen) + + .. change:: + :tags: Bug Fixes + :pullreq: 11729 + :tickets: 11728 + + Fix a bug in SetEDNSOptionAction + + .. change:: + :tags: Bug Fixes + :pullreq: 11718 + + Fix the number of concurrent queries on a backend TCP conn + .. changelog:: :version: 1.8.0 :released: 30th of March 2023 From 5a77a59ce1aa63cc68ebaf44dba272b57b74233b Mon Sep 17 00:00:00 2001 From: Walter Doekes Date: Fri, 14 Apr 2023 11:18:01 +0200 Subject: [PATCH 077/909] document bind-supermaster-destdir --- docs/backends/bind.rst | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/backends/bind.rst b/docs/backends/bind.rst index 16a8f19b529d..7b3da21e39ab 100644 --- a/docs/backends/bind.rst +++ b/docs/backends/bind.rst @@ -117,7 +117,6 @@ The file must contain one IP and account per line, separated by whitespace. BIND backend can only read this file, not write it. - .. _setting-bind-supermaster-config: ``bind-supermaster-config`` @@ -127,6 +126,14 @@ When a new zone is configured via the autosecondary mechanism, bindbackend *writ Your ``bind-config`` file should have an ``include`` statement to make sure this file is read on startup. +.. _setting-bind-supermaster-destdir: + +``bind-supermaster-destdir`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Each new zone configured via the autosecondary mechanism gets a zone file in this directory. +This directory must be writable. + .. _bind-operation: Operation From bd34dbb6d4e17eb95b3a72f93285069231815c13 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 14 Apr 2023 14:03:22 +0200 Subject: [PATCH 078/909] Log if the answer was marked variable by SyncRes and if it was stored into the packet cache (if !quiet) --- pdns/recursordist/pdns_recursor.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index f6e0c6bb0303..a52d3289a5b8 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -1802,7 +1802,9 @@ void startDoResolve(void* p) "tcpout", Logging::Loggable(sr.d_tcpoutqueries), "dotout", Logging::Loggable(sr.d_dotoutqueries), "rcode", Logging::Loggable(res), - "validationState", Logging::Loggable(sr.getValidationState())); + "validationState", Logging::Loggable(sr.getValidationState()), + "answer-is-variable", Logging::Loggable(sr.wasVariable()), + "into-packetcache", Logging::Loggable(g_packetCache && !variableAnswer && !sr.wasVariable())); } } From 73937b16d5a8ae0320309e6695cc69cee85c12de Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Mon, 17 Apr 2023 09:35:46 +0300 Subject: [PATCH 079/909] docs: lmdb - Add blank line after explicit markup --- docs/backends/lmdb.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/backends/lmdb.rst b/docs/backends/lmdb.rst index 64570538cf06..b3c48f83c240 100644 --- a/docs/backends/lmdb.rst +++ b/docs/backends/lmdb.rst @@ -112,6 +112,7 @@ This number can be increased later, but never decreased. Defaults to 100 on 32 bit systems, and 16000 on 64 bit systems. .. _settings-lmdb-flag-deleted: + ``lmdb-flag-deleted`` ^^^^^^^^^^^^^^^^^^^^^ From a2a29d0aa2dd2f2fd6762e13650ec064d8eb2d87 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 13 Apr 2023 16:22:20 +0200 Subject: [PATCH 080/909] auth 4.7.4: secpoll and docs --- docs/changelog/4.7.rst | 73 ++++++++++++++++++++++++++++++++++++++++++ docs/secpoll.zone | 3 +- 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/docs/changelog/4.7.rst b/docs/changelog/4.7.rst index 0c3f88d8b59d..341f0e18e35f 100644 --- a/docs/changelog/4.7.rst +++ b/docs/changelog/4.7.rst @@ -1,6 +1,79 @@ Changelogs for 4.7.x ==================== +.. changelog:: + :version: 4.7.4 + :released: 17th of April 2023 + + This is release 4.7.4 of the Authoritative Server. + It contains various bug fixes, some performance improvements, and one new feature (``pdnsutil list-member-zones``). + + .. change:: + :tags: Bug Fixes + :pullreq: 12742 + + Properly encode json string containing binary data + + .. change:: + :tags: Bug Fixes + :pullreq: 12741 + + Prevent a race during the processing of SVC auto-hints + + .. change:: + :tags: New Features + :pullreq: 12676 + + pdnsutil, implement list-member-zones (Kees Monshouwer) + + .. change:: + :tags: Bug Fixes + :pullreq: 12675 + + lmdb delete fixes and tests (Kees Monshouwer) + + .. change:: + :tags: Bug Fixes + :pullreq: 12429 + + minicurl: stop leaking hostlist memory + + .. change:: + :tags: Bug Fixes + :pullreq: 12521 + + ixfrdist fixes and improvements + + .. change:: + :tags: Improvements + :pullreq: 12458 + + lock.hh: include + + .. change:: + :tags: Bug Fixes + :pullreq: 12746 + + Pick the right signer name when a NSEC name is also a delegation point + + .. change:: + :tags: Improvements + :pullreq: 12745 + + calm down the communicator loop + + .. change:: + :tags: Bug Fixes + :pullreq: 12744 + + Fix multiple-version IXFR request handling in ixfrdist + + .. change:: + :tags: Improvements + :pullreq: 12743 + + timeout handling for IXFRs as a client + .. changelog:: :version: 4.7.3 :released: 9th of December 2022 diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 94d25f493fff..9ba2dde0734b 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023041400 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023041700 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -117,6 +117,7 @@ auth-4.7.0.security-status 60 IN TXT "1 OK" auth-4.7.1.security-status 60 IN TXT "1 OK" auth-4.7.2.security-status 60 IN TXT "1 OK" auth-4.7.3.security-status 60 IN TXT "1 OK" +auth-4.7.4.security-status 60 IN TXT "1 OK" auth-4.8.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release" ; Auth Debian From 2e7fc57427cc94033f088e528dd8d563ff713317 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Mon, 17 Apr 2023 22:06:08 +0200 Subject: [PATCH 081/909] api tests: avoid default pipe size limit Causes tests to freeze at a more or less random point. --- regression-tests.api/runtests.py | 35 ++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/regression-tests.api/runtests.py b/regression-tests.api/runtests.py index d0472e77f4c7..515439d7bb57 100755 --- a/regression-tests.api/runtests.py +++ b/regression-tests.api/runtests.py @@ -237,7 +237,26 @@ def run_check_call(cmd, *args, **kwargs): # Now run pdns and the tests. print("Launching server...") print(format_call_args(servercmd)) -serverproc = subprocess.Popen(servercmd, close_fds=True, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) +server_stdout = tempfile.TemporaryFile() +server_stderr = tempfile.TemporaryFile() +serverproc = subprocess.Popen(servercmd, close_fds=True, text=True, stdout=server_stdout, stderr=server_stderr) + +def finalize_server(): + serverproc.terminate() + serverproc.wait() + + print("==STDOUT==") + server_stdout.seek(0, 0) + sys.stdout.flush() + sys.stdout.buffer.write(server_stdout.read()) + server_stdout.close() + + print("==STDERR==") + server_stderr.seek(0, 0) + sys.stdout.flush() + sys.stdout.buffer.write(server_stderr.read()) + server_stderr.close() + print("Waiting for webserver port to become available...") available = False @@ -255,12 +274,7 @@ def run_check_call(cmd, *args, **kwargs): if not available: print("Webserver port not reachable after 10 tries, giving up.") - serverproc.terminate() - serverproc.wait() - print("==STDOUT===") - print(serverproc.stdout.read()) - print("==STDERRR===") - print(serverproc.stderr.read()) + finalize_server() sys.exit(2) print("Query for example.com/A to create statistic data...") @@ -297,11 +311,6 @@ def run_check_call(cmd, *args, **kwargs): if wait: print("Waiting as requested, press ENTER to stop.") raw_input() - serverproc.terminate() - serverproc.wait() - print("==STDOUT===") - print(serverproc.stdout.read()) - print("==STDERRR===") - print(serverproc.stderr.read()) + finalize_server() sys.exit(returncode) From 75cbb0499340ba4b6c30953633a18704cae8423c Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Tue, 18 Apr 2023 02:15:40 +0200 Subject: [PATCH 082/909] auth: remove unused var in tcpreceiver.cc tcpreceiver.cc:1005:7: warning: variable 'records' set but not used [-Wunused-but-set-variable] int records=0; --- pdns/tcpreceiver.cc | 2 -- 1 file changed, 2 deletions(-) diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 7e7765241edf..3341b1139261 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -993,9 +993,7 @@ int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr& q, unsigned int udiff; DTime dt; dt.set(); - int records=0; for(DNSZoneRecord &loopZRR : zrrs) { - records++; if(securedZone && (loopZRR.auth || loopZRR.dr.d_type == QType::NS)) { if (NSEC3Zone || loopZRR.dr.d_type) { if (presignedZone && NSEC3Zone && loopZRR.dr.d_type == QType::RRSIG && getRR(loopZRR.dr)->d_type == QType::NSEC3) { From d2362a55b17492d4302c052f1066ab4bffc5a558 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Tue, 18 Apr 2023 02:28:46 +0200 Subject: [PATCH 083/909] lmdb-safe: remove leftover debug variable In file included from ../../ext/lmdb-safe/lmdb-typed.cc:1: ../../ext/lmdb-safe/lmdb-typed.hh:656:11: warning: variable 'scanned' set but not used [-Wunused-but-set-variable] int scanned = 0; ^ --- ext/lmdb-safe/lmdb-typed.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index bfaffa76effc..a0e2cefb0d8d 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -653,9 +653,7 @@ public: int rc = cursor.get(out, id, MDB_SET_RANGE); - int scanned = 0; while (rc == 0) { - scanned++; auto sout = out.getNoStripHeader(); // FIXME: this (and many others) could probably be string_view auto thiskey = getKeyFromCombinedKey(out); auto sthiskey = thiskey.getNoStripHeader(); @@ -673,7 +671,6 @@ public: rc = cursor.get(out, id, MDB_NEXT); } - // std::cerr<<"get_multi scanned="< Date: Fri, 10 Mar 2023 09:56:41 +0100 Subject: [PATCH 084/909] Gitignore verify-dnssec-zone/allow-missing --- regression-tests/tests/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/regression-tests/tests/.gitignore b/regression-tests/tests/.gitignore index 0bb54176b7f5..048b3b17db7f 100644 --- a/regression-tests/tests/.gitignore +++ b/regression-tests/tests/.gitignore @@ -3,3 +3,4 @@ real_result *.out start step.* +verify-dnssec-zone/allow-missing From 5d9b131b48debef08c573143c0ee5faa48f0a74d Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 28 Feb 2023 15:49:26 +0100 Subject: [PATCH 085/909] Cleanup the ci_docs_upload_master pyinvoke task --- tasks.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tasks.py b/tasks.py index e9b5809c3011..fee0b6b646bd 100644 --- a/tasks.py +++ b/tasks.py @@ -302,9 +302,18 @@ def ci_docs_build_pdf(c): @task def ci_docs_upload_master(c, docs_host, pdf, username, product, directory=""): - c.run(f"rsync -crv --delete --no-p --chmod=g=rwX --exclude '*~' ./docs/_build/{product}-html-docs/ {username}@{docs_host}:{directory}") - c.run(f"rsync -crv --no-p --chmod=g=rwX --exclude '*~' ./docs/_build/{product}-html-docs.tar.bz2 {username}@{docs_host}:{directory}/html-docs.tar.bz2") - c.run(f"rsync -crv --no-p --chmod=g=rwX --exclude '*~' ./docs/_build/latex/{pdf} {username}@{docs_host}:{directory}") + rsync_cmd = " ".join([ + "rsync", + "--checksum", + "--recursive", + "--verbose", + "--no-p", + "--chmod=g=rwX", + "--exclude '*~'", + ]) + c.run(f"{rsync_cmd} --delete ./docs/_build/{product}-html-docs/ {username}@{docs_host}:{directory}") + c.run(f"{rsync_cmd} ./docs/_build/{product}-html-docs.tar.bz2 {username}@{docs_host}:{directory}/html-docs.tar.bz2") + c.run(f"{rsync_cmd} ./docs/_build/latex/{pdf} {username}@{docs_host}:{directory}") @task def ci_docs_add_ssh(c, ssh_key, host_key): From 8804bc1d1326fc796d709b78ad41980fdec2c98c Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Fri, 10 Mar 2023 10:20:11 +0100 Subject: [PATCH 086/909] Cleanup ci_auth/rec_configure pyinvoke tasks --- tasks.py | 147 +++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 42 deletions(-) diff --git a/tasks.py b/tasks.py index fee0b6b646bd..8cc8e55b387e 100644 --- a/tasks.py +++ b/tasks.py @@ -322,59 +322,122 @@ def ci_docs_add_ssh(c, ssh_key, host_key): c.run('chmod 600 ~/.ssh/id_ed25519') c.run(f'echo "{host_key}" > ~/.ssh/known_hosts') + +def get_sanitizers(): + sanitizers = os.getenv('SANITIZERS') + if sanitizers != '': + sanitizers = sanitizers.split('+') + sanitizers = ['--enable-' + sanitizer for sanitizer in sanitizers] + sanitizers = ' '.join(sanitizers) + return sanitizers + + +def get_cflags(): + return " ".join([ + "-O1", + "-Werror=vla", + "-Werror=shadow", + "-Wformat=2", + "-Werror=format-security", + "-Werror=string-plus-int", + ]) + + +def get_cxxflags(): + return " ".join([ + get_cflags(), + "-Wp,-D_GLIBCXX_ASSERTIONS", + ]) + + +def get_base_configure_cmd(): + return " ".join([ + f'CFLAGS="{get_cflags()}"', + f'CXXFLAGS="{get_cxxflags()}"', + './configure', + "CC='clang-12'", + "CXX='clang++-12'", + "--enable-option-checking=fatal", + "--enable-systemd", + "--with-libsodium", + "--enable-fortify-source=auto", + "--enable-auto-var-init=pattern", + ]) + + @task def ci_auth_configure(c): - sanitizers = ' '.join('--enable-'+x for x in os.getenv('SANITIZERS').split('+')) if os.getenv('SANITIZERS') != '' else '' - unittests = ' --enable-unit-tests --enable-backend-unit-tests' if os.getenv('UNIT_TESTS') == 'yes' else '' - fuzzingtargets = ' --enable-fuzz-targets' if os.getenv('FUZZING_TARGETS') == 'yes' else '' - res = c.run('''CFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int" \ - CXXFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int -Wp,-D_GLIBCXX_ASSERTIONS" \ - ./configure \ - CC='clang-12' \ - CXX='clang++-12' \ - LDFLAGS='-L/usr/local/lib -Wl,-rpath,/usr/local/lib' \ - --enable-option-checking=fatal \ - --with-modules='bind geoip gmysql godbc gpgsql gsqlite3 ldap lmdb lua2 pipe remote tinydns' \ - --enable-systemd \ - --enable-tools \ - --enable-fuzz-targets \ - --enable-experimental-pkcs11 \ - --enable-experimental-gss-tsig \ - --enable-remotebackend-zeromq \ - --with-lmdb=/usr \ - --with-libsodium \ - --with-libdecaf \ - --prefix=/opt/pdns-auth \ - --enable-ixfrdist \ - --enable-fortify-source=auto \ - --enable-auto-var-init=pattern ''' + sanitizers + unittests + fuzzingtargets, warn=True) + sanitizers = get_sanitizers() + + unittests = os.getenv('UNIT_TESTS') + if unittests == 'yes': + unittests = '--enable-unit-tests --enable-backend-unit-tests' + else: + unittests = '' + + fuzz_targets = os.getenv('FUZZING_TARGETS') + fuzz_targets = '--enable-fuzz-targets' if fuzz_targets == 'yes' else '' + + modules = " ".join([ + "bind", + "geoip", + "gmysql", + "godbc", + "gpgsql", + "gsqlite3", + "ldap", + "lmdb", + "lua2", + "pipe", + "remote", + "tinydns", + ]) + configure_cmd = " ".join([ + get_base_configure_cmd(), + "LDFLAGS='-L/usr/local/lib -Wl,-rpath,/usr/local/lib'", + f"--with-modules='{modules}'", + "--enable-tools", + "--enable-experimental-pkcs11", + "--enable-experimental-gss-tsig", + "--enable-remotebackend-zeromq", + "--with-lmdb=/usr", + "--with-libdecaf", + "--prefix=/opt/pdns-auth", + "--enable-ixfrdist", + sanitizers, + unittests, + fuzz_targets, + ]) + res = c.run(configure_cmd, warn=True) if res.exited != 0: c.run('cat config.log') raise UnexpectedExit(res) + + @task def ci_rec_configure(c): - sanitizers = ' '.join('--enable-'+x for x in os.getenv('SANITIZERS').split('+')) if os.getenv('SANITIZERS') != '' else '' - unittests = ' --enable-unit-tests' if os.getenv('UNIT_TESTS') == 'yes' else '' - res = c.run(''' CFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int" \ - CXXFLAGS="-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int -Wp,-D_GLIBCXX_ASSERTIONS" \ - ./configure \ - CC='clang-12' \ - CXX='clang++-12' \ - --enable-option-checking=fatal \ - --enable-nod \ - --enable-systemd \ - --prefix=/opt/pdns-recursor \ - --with-libsodium \ - --with-lua=luajit \ - --with-libcap \ - --with-net-snmp \ - --enable-fortify-source=auto \ - --enable-auto-var-init=pattern \ - --enable-dns-over-tls ''' + sanitizers + unittests, warn=True) + sanitizers = get_sanitizers() + + unittests = os.getenv('UNIT_TESTS') + unittests = '--enable-unit-tests' if unittests == 'yes' else '' + + configure_cmd = " ".join([ + get_base_configure_cmd(), + "--enable-nod", + "--prefix=/opt/pdns-recursor", + "--with-lua=luajit", + "--with-libcap", + "--with-net-snmp", + "--enable-dns-over-tls", + sanitizers, + unittests, + ]) + res = c.run(configure_cmd, warn=True) if res.exited != 0: c.run('cat config.log') raise UnexpectedExit(res) + @task def ci_dnsdist_configure(c, features): additional_flags = '' From 26cf02ca0cabf42cb6a3f2711c515dddd0bae988 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Wed, 5 Apr 2023 18:06:13 +0200 Subject: [PATCH 087/909] Add cmake to auth build deps (needed for libdecaf) --- tasks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks.py b/tasks.py index 8cc8e55b387e..d6b0c670fbd8 100644 --- a/tasks.py +++ b/tasks.py @@ -46,6 +46,7 @@ 'ruby-dev', 'sqlite3', 'unixodbc-dev', + 'cmake', ] rec_build_deps = [ 'libcap-dev', From 9466b8e64ef346dace97f823ce22ae8d29907f1b Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Wed, 5 Apr 2023 18:06:27 +0200 Subject: [PATCH 088/909] Tell the libdecaf cmake build to use clang-12 --- tasks.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks.py b/tasks.py index d6b0c670fbd8..4608c6dd3c64 100644 --- a/tasks.py +++ b/tasks.py @@ -166,7 +166,8 @@ def install_libdecaf(c, product): c.run('git clone https://git.code.sf.net/p/ed448goldilocks/code /tmp/libdecaf') with c.cd('/tmp/libdecaf'): c.run('git checkout 41f349') - c.run('cmake -B build ' + c.run('CC=clang-12 CXX=clang-12 ' + 'cmake -B build ' '-DCMAKE_INSTALL_PREFIX=/usr/local ' '-DCMAKE_INSTALL_LIBDIR=lib ' '-DENABLE_STATIC=OFF ' From 7d6cbd0823d2ebdede600dc034d852ba2c5f39c6 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Fri, 21 Apr 2023 10:58:14 +0200 Subject: [PATCH 089/909] Pin pyasn1 to 0.4.8 because 0.5.0 broke the API with 0.5.0 https://github.com/pyasn1/pyasn1/issues/28 On 20230420: https://pypi.org/project/pyasn1/#history --- regression-tests.dnsdist/requirements.txt | 1 + regression-tests.recursor-dnssec/requirements.txt | 1 + 2 files changed, 2 insertions(+) diff --git a/regression-tests.dnsdist/requirements.txt b/regression-tests.dnsdist/requirements.txt index 7fd3da7a79ad..edfdb669ed32 100644 --- a/regression-tests.dnsdist/requirements.txt +++ b/regression-tests.dnsdist/requirements.txt @@ -3,6 +3,7 @@ nose>=1.3.7 libnacl>=1.4.3,<1.7 requests>=2.1.0 protobuf>=3.0 +pyasn1==0.4.8 pysnmp>=4.3.4 future>=0.17.1 pycurl>=7.43.0 diff --git a/regression-tests.recursor-dnssec/requirements.txt b/regression-tests.recursor-dnssec/requirements.txt index 4f5afe9d8589..3c15fe9ada80 100644 --- a/regression-tests.recursor-dnssec/requirements.txt +++ b/regression-tests.recursor-dnssec/requirements.txt @@ -2,6 +2,7 @@ dnspython>=1.11 nose>=1.3.7 protobuf>=2.5; sys_platform != 'darwin' protobuf>=3.0; sys_platform == 'darwin' +pyasn1==0.4.8 pysnmp>=4.3.4 requests>=2.1.0 Twisted>0.15.0 From fae3e64ca693ba54f36972dfd8e7c20f5fcf9117 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 28 Feb 2023 15:49:40 +0100 Subject: [PATCH 090/909] Github action to run clang-tidy on auth PRs --- .github/scripts/clang-tidy.py | 100 ++++++++++++++++++ .github/scripts/helpers.py | 48 +++++++++ .github/workflows/clang-tidy.yml | 58 ++++++++++ build-scripts/gh-actions-setup-inv | 2 + .../gh-actions-setup-inv-no-dist-upgrade | 2 + tasks.py | 10 ++ 6 files changed, 220 insertions(+) create mode 100755 .github/scripts/clang-tidy.py create mode 100644 .github/scripts/helpers.py create mode 100644 .github/workflows/clang-tidy.yml diff --git a/.github/scripts/clang-tidy.py b/.github/scripts/clang-tidy.py new file mode 100755 index 000000000000..85982e207906 --- /dev/null +++ b/.github/scripts/clang-tidy.py @@ -0,0 +1,100 @@ +#!/usr/bin/env python3 + +"""Clang-tidy to Github Actions annotations converter. + +Convert the YAML file produced by clang-tidy-diff containing warnings and +suggested fixes to Github Actions annotations. + +""" + +import argparse +import os +import sys +from pathlib import Path + +import helpers + + +def create_argument_parser(): + """Create command-line argument parser.""" + parser = argparse.ArgumentParser( + description="Convert clang-tidy output to Github Actions" + ) + parser.add_argument( + "--fixes-file", + type=str, + required=True, + help="Path to the clang-tidy fixes YAML", + ) + return parser.parse_args() + + +def main(): + """Start the script.""" + args = create_argument_parser() + + fixes_path = Path(args.fixes_file) + compdb_filename = os.path.join(fixes_path.parent, "compile_commands.json") + compdb = helpers.load_compdb(compdb_filename) + compdb = helpers.index_compdb(compdb) + + fixes = helpers.load_fixes_file(args.fixes_file) + fixes = fixes["Diagnostics"] + have_warnings = False + for fix in fixes: + name = fix["DiagnosticName"] + level = fix["Level"] + directory = fix["BuildDirectory"] + diagnostic = fix["DiagnosticMessage"] + offset = diagnostic["FileOffset"] + filename = diagnostic["FilePath"] + message = diagnostic["Message"] + + if filename == "": + print(f"Meta error message from `{directory}`: {message}") + continue + + full_filename = filename + full_filename = Path(full_filename) + full_filename = ( + full_filename.as_posix() + if full_filename.is_absolute() + else os.path.join(directory, filename) + ) + + if full_filename not in compdb: + print( + f"Skipping `{full_filename}`" + " because it is not found" + " in the compilation database" + ) + continue + + try: + file_contents = helpers.load_file(full_filename) + except OSError: + # Skip in case the file can't be found. This is usually one of + # those "too many errors emitted, stopping now" clang messages. + print(f"Skipping `{full_filename}` because it is not found") + continue + + line = helpers.get_line_from_offset(file_contents, offset) + + annotation = "".join( + [ + f"::warning file={full_filename},line={line}", + f"::{message} ({name} - Level={level})", + ] + ) + print(annotation) + + # User-friendly printout + print(f"{level}: {full_filename}:{line}: {message} ({name})") + + have_warnings = True + + return 1 if have_warnings else 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.github/scripts/helpers.py b/.github/scripts/helpers.py new file mode 100644 index 000000000000..cc170d1eed5c --- /dev/null +++ b/.github/scripts/helpers.py @@ -0,0 +1,48 @@ +"""Helpers for dealing with git, compilation databases, etc.""" + +import json +import os + +import git +import yaml + + +def load_file(filename): + """Load the entire contents of a file.""" + with open(filename, encoding="utf-8") as file: + contents = file.read() + return contents + + +def get_line_from_offset(file_contents, offset): + """Calculate line number from byte offset in source file.""" + return file_contents[:offset].count("\n") + 1 + + +def get_repo_root(): + """Get the git repo's root directory.""" + cwd = os.getcwd() + repo = git.Repo(cwd, search_parent_directories=True) + root = repo.git.rev_parse("--show-toplevel") + return root + + +def load_fixes_file(filename): + """Load the clang-tidy YAML fixes file.""" + with open(filename, encoding="utf_8") as file: + return yaml.safe_load(file) + + +def load_compdb(filename): + """Load the compilation database.""" + with open(filename, encoding="utf_8") as file: + return json.load(file) + + +def index_compdb(file_contents): + """Index the compilation database.""" + result = set() + for item in file_contents: + filename = os.path.join(item["directory"], item["file"]) + result.add(filename) + return result diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml new file mode 100644 index 000000000000..f4c8c7a13094 --- /dev/null +++ b/.github/workflows/clang-tidy.yml @@ -0,0 +1,58 @@ +--- +name: 'clang-tidy' + +on: + pull_request: + branches: [master] + +permissions: + contents: read + +jobs: + clang-tidy: + name: auth clang-tidy + runs-on: ubuntu-20.04 + env: + UNIT_TESTS: yes + SANITIZERS: + steps: + - uses: PowerDNS/pdns/set-ubuntu-mirror@meta + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: get timestamp for cache + id: get-stamp + shell: bash + run: | + echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" + - name: let GitHub cache our ccache data + uses: actions/cache@v3 + with: + path: ~/.ccache + key: auth-ccache-${{ steps.get-stamp.outputs.stamp }} + restore-keys: auth-ccache- + - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade + - run: inv install-clang + - run: inv install-clang-tidy-tools + - run: inv install-auth-build-deps + - run: inv ci-autoconf + - run: inv ci-auth-configure + - run: inv ci-auth-make-bear + - run: ccache -s + - run: mkdir clang-tidy-results + - run: ln -s .clang-tidy.full .clang-tidy + - name: Run clang-tidy + working-directory: pdns + run: git diff -U0 HEAD^ | python /usr/bin/clang-tidy-diff-12.py -p2 -export-fixes ../clang-tidy-results/auth-fixes.yml + - name: Print clang-tidy fixes YAML + shell: bash + run: | + if [ -f clang-tidy-results/auth-fixes.yml ]; then + cat clang-tidy-results/auth-fixes.yml + fi + - name: Result annotations + shell: bash + run: | + if [ -f clang-tidy-results/auth-fixes.yml ]; then + python .github/scripts/clang-tidy.py --fixes-file clang-tidy-results/auth-fixes.yml + fi diff --git a/build-scripts/gh-actions-setup-inv b/build-scripts/gh-actions-setup-inv index 53239df53b7e..0cd64feb5b7f 100755 --- a/build-scripts/gh-actions-setup-inv +++ b/build-scripts/gh-actions-setup-inv @@ -12,3 +12,5 @@ sudo apt-get autoremove sudo apt-get -qq -y --allow-downgrades dist-upgrade sudo apt-get -qq -y --no-install-recommends install python3-pip sudo pip3 install git+https://github.com/pyinvoke/invoke@faa5728a6f76199a3da1750ed952e7efee17c1da +sudo pip3 install gitpython +sudo pip3 install unidiff diff --git a/build-scripts/gh-actions-setup-inv-no-dist-upgrade b/build-scripts/gh-actions-setup-inv-no-dist-upgrade index be3eb520eb10..e2e18aa60f2b 100755 --- a/build-scripts/gh-actions-setup-inv-no-dist-upgrade +++ b/build-scripts/gh-actions-setup-inv-no-dist-upgrade @@ -8,3 +8,5 @@ sudo chmod 755 /usr/sbin/policy-rc.d sudo apt-get update sudo apt-get -qq -y --no-install-recommends install python3-pip sudo pip3 install git+https://github.com/pyinvoke/invoke@faa5728a6f76199a3da1750ed952e7efee17c1da +sudo pip3 install gitpython +sudo pip3 install unidiff diff --git a/tasks.py b/tasks.py index 4608c6dd3c64..23dc8be7211b 100644 --- a/tasks.py +++ b/tasks.py @@ -157,6 +157,10 @@ def install_clang(c): """ c.sudo('apt-get -qq -y --no-install-recommends install clang-12 llvm-12') +@task +def install_clang_tidy_tools(c): + c.sudo('apt-get -qq -y --no-install-recommends install clang-tidy-12 clang-tools-12 bear python-yaml') + @task def install_clang_runtime(c): # this gives us the symbolizer, for symbols in asan/ubsan traces @@ -525,6 +529,12 @@ def ci_dnsdist_configure(c, features): def ci_auth_make(c): c.run('make -j8 -k V=1') +@task +def ci_auth_make_bear(c): + # Needed for clang-tidy -line-filter vs project structure shenanigans + with c.cd('pdns'): + c.run('bear --append make -j8 -k V=1 -C ..') + @task def ci_rec_make(c): c.run('make -j8 -k V=1') From f01e3a4a10b60f171ecfb17667ee767766f62803 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Mon, 13 Mar 2023 13:53:20 +0100 Subject: [PATCH 091/909] Github action to run clang-tidy on rec PRs --- .github/workflows/clang-tidy.yml | 54 +++++++++++++++++++++++++++++++- tasks.py | 5 +++ 2 files changed, 58 insertions(+), 1 deletion(-) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index f4c8c7a13094..88cf73b443f5 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -9,7 +9,7 @@ permissions: contents: read jobs: - clang-tidy: + clang-tidy-auth: name: auth clang-tidy runs-on: ubuntu-20.04 env: @@ -56,3 +56,55 @@ jobs: if [ -f clang-tidy-results/auth-fixes.yml ]; then python .github/scripts/clang-tidy.py --fixes-file clang-tidy-results/auth-fixes.yml fi + + clang-tidy-rec: + name: rec clang-tidy + runs-on: ubuntu-20.04 + env: + UNIT_TESTS: yes + SANITIZERS: + steps: + - uses: PowerDNS/pdns/set-ubuntu-mirror@meta + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: get timestamp for cache + id: get-stamp + shell: bash + run: | + echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" + - name: let GitHub cache our ccache data + uses: actions/cache@v3 + with: + path: ~/.ccache + key: recursor-ccache-${{ steps.get-stamp.outputs.stamp }} + restore-keys: recursor-ccache- + - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade + - run: inv apt-fresh + - run: inv install-clang + - run: inv install-clang-tidy-tools + - run: inv install-rec-build-deps + - run: inv ci-autoconf + working-directory: pdns/recursordist/ + - run: inv ci-rec-configure + working-directory: pdns/recursordist/ + - run: inv ci-rec-make-bear + working-directory: pdns/recursordist/ + - run: ccache -s + - run: mkdir clang-tidy-results + - run: ln -s .clang-tidy.full .clang-tidy + - name: Run clang-tidy + working-directory: pdns/recursordist/ + run: git diff -U0 HEAD^ | python /usr/bin/clang-tidy-diff-12.py -p3 -export-fixes ../../clang-tidy-results/rec-fixes.yml + - name: Print clang-tidy fixes YAML + shell: bash + run: | + if [ -f clang-tidy-results/rec-fixes.yml ]; then + cat clang-tidy-results/rec-fixes.yml + fi + - name: Result annotations + shell: bash + run: | + if [ -f clang-tidy-results/rec-fixes.yml ]; then + python .github/scripts/clang-tidy.py --fixes-file clang-tidy-results/rec-fixes.yml + fi diff --git a/tasks.py b/tasks.py index 23dc8be7211b..f776ba3d0a0f 100644 --- a/tasks.py +++ b/tasks.py @@ -539,6 +539,11 @@ def ci_auth_make_bear(c): def ci_rec_make(c): c.run('make -j8 -k V=1') +@task +def ci_rec_make_bear(c): + # Assumed to be running under ./pdns/recursordist/ + c.run('bear --append make -j8 -k V=1') + @task def ci_dnsdist_make(c): c.run('make -j4 -k V=1') From 97145bb44b5b4b7e6a97ffaca623bb249debe6fe Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 14 Mar 2023 12:28:17 +0100 Subject: [PATCH 092/909] Github action to run clang-tidy on dnsdist PRs --- .github/workflows/clang-tidy.yml | 52 ++++++++++++++++++++++++++++++++ tasks.py | 5 +++ 2 files changed, 57 insertions(+) diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 88cf73b443f5..3e6ef3e68d0f 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -108,3 +108,55 @@ jobs: if [ -f clang-tidy-results/rec-fixes.yml ]; then python .github/scripts/clang-tidy.py --fixes-file clang-tidy-results/rec-fixes.yml fi + + clang-tidy-dnsdist: + name: dnsdist clang-tidy + runs-on: ubuntu-20.04 + env: + UNIT_TESTS: yes + SANITIZERS: + steps: + - uses: PowerDNS/pdns/set-ubuntu-mirror@meta + - uses: actions/checkout@v3 + with: + fetch-depth: 2 + - name: get timestamp for cache + id: get-stamp + shell: bash + run: | + echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" + - name: let GitHub cache our ccache data + uses: actions/cache@v3 + with: + path: ~/.ccache + key: dnsdist-full-ccache-${{ steps.get-stamp.outputs.stamp }} + restore-keys: dnsdist-full-ccache- + - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade + - run: inv apt-fresh + - run: inv install-clang + - run: inv install-clang-tidy-tools + - run: inv install-dnsdist-build-deps + - run: inv ci-autoconf + working-directory: pdns/dnsdistdist/ + - run: inv ci-dnsdist-configure full + working-directory: pdns/dnsdistdist/ + - run: inv ci-dnsdist-make-bear + working-directory: pdns/dnsdistdist/ + - run: ccache -s + - run: mkdir clang-tidy-results + - run: ln -s .clang-tidy.full .clang-tidy + - name: Run clang-tidy + working-directory: pdns/dnsdistdist/ + run: git diff -U0 HEAD^ | python /usr/bin/clang-tidy-diff-12.py -p3 -export-fixes ../../clang-tidy-results/dnsdist-fixes.yml + - name: Print clang-tidy fixes YAML + shell: bash + run: | + if [ -f clang-tidy-results/dnsdist-fixes.yml ]; then + cat clang-tidy-results/dnsdist-fixes.yml + fi + - name: Result annotations + shell: bash + run: | + if [ -f clang-tidy-results/dnsdist-fixes.yml ]; then + python .github/scripts/clang-tidy.py --fixes-file clang-tidy-results/dnsdist-fixes.yml + fi diff --git a/tasks.py b/tasks.py index f776ba3d0a0f..96f22089744b 100644 --- a/tasks.py +++ b/tasks.py @@ -548,6 +548,11 @@ def ci_rec_make_bear(c): def ci_dnsdist_make(c): c.run('make -j4 -k V=1') +@task +def ci_dnsdist_make_bear(c): + # Assumed to be running under ./pdns/dnsdistdist/ + c.run('bear --append make -j4 -k V=1') + @task def ci_auth_install_remotebackend_test_deps(c): with c.cd('modules/remotebackend'): From 2ff9fc59aae2611dd5bde42980c93213241faa9e Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Wed, 15 Mar 2023 14:26:28 +0100 Subject: [PATCH 093/909] Move clang-tidy-auth to build-and-test-all workflow --- .github/workflows/build-and-test-all.yml | 21 ++++++++++- .github/workflows/clang-tidy.yml | 48 ------------------------ 2 files changed, 20 insertions(+), 49 deletions(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 642e34c11e57..6ad18040e795 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -40,10 +40,29 @@ jobs: restore-keys: auth-ccache- - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - run: inv install-clang + - run: inv install-clang-tidy-tools - run: inv install-auth-build-deps - run: inv ci-autoconf - run: inv ci-auth-configure - - run: inv ci-auth-make + - run: inv ci-auth-make-bear # This runs under pdns/ + - run: ln -s .clang-tidy.full .clang-tidy + - name: Run clang-tidy + working-directory: pdns + run: git diff -U0 HEAD^..HEAD | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p2 -export-fixes clang-tidy-auth.yml + - name: Print clang-tidy fixes YAML + working-directory: pdns + shell: bash + run: | + if [ -f clang-tidy-auth.yml ]; then + cat clang-tidy-auth.yml + fi + - name: Result annotations + shell: bash + working-directory: pdns + run: | + if [ -f clang-tidy-auth.yml ]; then + python3 ../.github/scripts/clang-tidy.py --fixes-file clang-tidy-auth.yml + fi - run: inv ci-auth-install-remotebackend-test-deps - run: inv ci-auth-run-unit-tests - run: inv ci-make-install diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml index 3e6ef3e68d0f..18f8ad932266 100644 --- a/.github/workflows/clang-tidy.yml +++ b/.github/workflows/clang-tidy.yml @@ -9,54 +9,6 @@ permissions: contents: read jobs: - clang-tidy-auth: - name: auth clang-tidy - runs-on: ubuntu-20.04 - env: - UNIT_TESTS: yes - SANITIZERS: - steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - - uses: actions/checkout@v3 - with: - fetch-depth: 2 - - name: get timestamp for cache - id: get-stamp - shell: bash - run: | - echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" - - name: let GitHub cache our ccache data - uses: actions/cache@v3 - with: - path: ~/.ccache - key: auth-ccache-${{ steps.get-stamp.outputs.stamp }} - restore-keys: auth-ccache- - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - - run: inv install-clang - - run: inv install-clang-tidy-tools - - run: inv install-auth-build-deps - - run: inv ci-autoconf - - run: inv ci-auth-configure - - run: inv ci-auth-make-bear - - run: ccache -s - - run: mkdir clang-tidy-results - - run: ln -s .clang-tidy.full .clang-tidy - - name: Run clang-tidy - working-directory: pdns - run: git diff -U0 HEAD^ | python /usr/bin/clang-tidy-diff-12.py -p2 -export-fixes ../clang-tidy-results/auth-fixes.yml - - name: Print clang-tidy fixes YAML - shell: bash - run: | - if [ -f clang-tidy-results/auth-fixes.yml ]; then - cat clang-tidy-results/auth-fixes.yml - fi - - name: Result annotations - shell: bash - run: | - if [ -f clang-tidy-results/auth-fixes.yml ]; then - python .github/scripts/clang-tidy.py --fixes-file clang-tidy-results/auth-fixes.yml - fi - clang-tidy-rec: name: rec clang-tidy runs-on: ubuntu-20.04 From 490bc2522fc0653130599a2c06df63adad4a8b35 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 16 Mar 2023 14:16:10 +0100 Subject: [PATCH 094/909] Move clang-tidy-rec to build-and-test-all workflow --- .github/workflows/build-and-test-all.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 6ad18040e795..3ed360679c4e 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -109,10 +109,26 @@ jobs: - run: ../../build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - run: inv apt-fresh - run: inv install-clang + - run: inv install-clang-tidy-tools - run: inv install-rec-build-deps - run: inv ci-autoconf - run: inv ci-rec-configure - - run: inv ci-rec-make + - run: inv ci-rec-make-bear + - run: ln -s ../../.clang-tidy.full .clang-tidy + - name: Run clang-tidy + run: git diff -U0 HEAD^..HEAD | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-rec.yml + - name: Print clang-tidy fixes YAML + shell: bash + run: | + if [ -f clang-tidy-rec.yml ]; then + cat clang-tidy-rec.yml + fi + - name: Result annotations + shell: bash + run: | + if [ -f clang-tidy-rec.yml ]; then + python ../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-rec.yml + fi - run: inv ci-rec-run-unit-tests - run: inv ci-make-install - run: ccache -s From 3f1a58d163bfc52fe4a4dda659d6e93eee67e6d2 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 16 Mar 2023 14:16:23 +0100 Subject: [PATCH 095/909] Move clang-tidy-dnsdist to build-and-test-all workflow --- .github/workflows/build-and-test-all.yml | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 3ed360679c4e..e739236c8622 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -178,10 +178,26 @@ jobs: - run: ../../build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - run: inv apt-fresh - run: inv install-clang + - run: inv install-clang-tidy-tools - run: inv install-dnsdist-build-deps - run: inv ci-autoconf - run: inv ci-dnsdist-configure ${{ matrix.features }} - - run: inv ci-dnsdist-make + - run: inv ci-dnsdist-make-bear + - run: ln -s ../../.clang-tidy.full .clang-tidy + - name: Run clang-tidy + run: git diff -U0 HEAD^..HEAD | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-dnsdist.yml + - name: Print clang-tidy fixes YAML + shell: bash + run: | + if [ -f clang-tidy-dnsdist.yml ]; then + cat clang-tidy-dnsdist.yml + fi + - name: Result annotations + shell: bash + run: | + if [ -f clang-tidy-dnsdist.yml ]; then + python ../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-dnsdist.yml + fi - run: inv ci-dnsdist-run-unit-tests - run: inv ci-make-install - run: ccache -s From a2d9c159af60202b14ccd5e937c297c5515e6600 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 16 Mar 2023 14:16:36 +0100 Subject: [PATCH 096/909] Delete old clang-tidy workflow --- .github/workflows/clang-tidy.yml | 114 ------------------------------- 1 file changed, 114 deletions(-) delete mode 100644 .github/workflows/clang-tidy.yml diff --git a/.github/workflows/clang-tidy.yml b/.github/workflows/clang-tidy.yml deleted file mode 100644 index 18f8ad932266..000000000000 --- a/.github/workflows/clang-tidy.yml +++ /dev/null @@ -1,114 +0,0 @@ ---- -name: 'clang-tidy' - -on: - pull_request: - branches: [master] - -permissions: - contents: read - -jobs: - clang-tidy-rec: - name: rec clang-tidy - runs-on: ubuntu-20.04 - env: - UNIT_TESTS: yes - SANITIZERS: - steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - - uses: actions/checkout@v3 - with: - fetch-depth: 2 - - name: get timestamp for cache - id: get-stamp - shell: bash - run: | - echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" - - name: let GitHub cache our ccache data - uses: actions/cache@v3 - with: - path: ~/.ccache - key: recursor-ccache-${{ steps.get-stamp.outputs.stamp }} - restore-keys: recursor-ccache- - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - - run: inv apt-fresh - - run: inv install-clang - - run: inv install-clang-tidy-tools - - run: inv install-rec-build-deps - - run: inv ci-autoconf - working-directory: pdns/recursordist/ - - run: inv ci-rec-configure - working-directory: pdns/recursordist/ - - run: inv ci-rec-make-bear - working-directory: pdns/recursordist/ - - run: ccache -s - - run: mkdir clang-tidy-results - - run: ln -s .clang-tidy.full .clang-tidy - - name: Run clang-tidy - working-directory: pdns/recursordist/ - run: git diff -U0 HEAD^ | python /usr/bin/clang-tidy-diff-12.py -p3 -export-fixes ../../clang-tidy-results/rec-fixes.yml - - name: Print clang-tidy fixes YAML - shell: bash - run: | - if [ -f clang-tidy-results/rec-fixes.yml ]; then - cat clang-tidy-results/rec-fixes.yml - fi - - name: Result annotations - shell: bash - run: | - if [ -f clang-tidy-results/rec-fixes.yml ]; then - python .github/scripts/clang-tidy.py --fixes-file clang-tidy-results/rec-fixes.yml - fi - - clang-tidy-dnsdist: - name: dnsdist clang-tidy - runs-on: ubuntu-20.04 - env: - UNIT_TESTS: yes - SANITIZERS: - steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - - uses: actions/checkout@v3 - with: - fetch-depth: 2 - - name: get timestamp for cache - id: get-stamp - shell: bash - run: | - echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" - - name: let GitHub cache our ccache data - uses: actions/cache@v3 - with: - path: ~/.ccache - key: dnsdist-full-ccache-${{ steps.get-stamp.outputs.stamp }} - restore-keys: dnsdist-full-ccache- - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - - run: inv apt-fresh - - run: inv install-clang - - run: inv install-clang-tidy-tools - - run: inv install-dnsdist-build-deps - - run: inv ci-autoconf - working-directory: pdns/dnsdistdist/ - - run: inv ci-dnsdist-configure full - working-directory: pdns/dnsdistdist/ - - run: inv ci-dnsdist-make-bear - working-directory: pdns/dnsdistdist/ - - run: ccache -s - - run: mkdir clang-tidy-results - - run: ln -s .clang-tidy.full .clang-tidy - - name: Run clang-tidy - working-directory: pdns/dnsdistdist/ - run: git diff -U0 HEAD^ | python /usr/bin/clang-tidy-diff-12.py -p3 -export-fixes ../../clang-tidy-results/dnsdist-fixes.yml - - name: Print clang-tidy fixes YAML - shell: bash - run: | - if [ -f clang-tidy-results/dnsdist-fixes.yml ]; then - cat clang-tidy-results/dnsdist-fixes.yml - fi - - name: Result annotations - shell: bash - run: | - if [ -f clang-tidy-results/dnsdist-fixes.yml ]; then - python .github/scripts/clang-tidy.py --fixes-file clang-tidy-results/dnsdist-fixes.yml - fi From 3121aac576721cba60f05315d994f5ee146b642f Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 20 Apr 2023 22:31:54 +0200 Subject: [PATCH 097/909] Filter file diffs that are not in the current project --- .github/scripts/git-filter.py | 35 ++++++++++++++++++++++++ .github/workflows/build-and-test-all.yml | 6 ++-- 2 files changed, 38 insertions(+), 3 deletions(-) create mode 100755 .github/scripts/git-filter.py diff --git a/.github/scripts/git-filter.py b/.github/scripts/git-filter.py new file mode 100755 index 000000000000..533111606d04 --- /dev/null +++ b/.github/scripts/git-filter.py @@ -0,0 +1,35 @@ +#!/usr/bin/env python3 + +"""Filter git diff files that are not in the product. + +Filter files out of a git diff output that are not part of the product found in +the current directory. + +""" + +import os +import sys + +import helpers +import unidiff + + +def main(): + """Start the script.""" + compdb = helpers.load_compdb("compile_commands.json") + compdb = helpers.index_compdb(compdb) + + root = helpers.get_repo_root() + + diff = sys.stdin.read() + patch_set = unidiff.PatchSet(diff) + for patch in patch_set: + path = os.path.join(root, patch.path) + if path in compdb: + print(patch) + + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index e739236c8622..bad2c65e62e8 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -48,7 +48,7 @@ jobs: - run: ln -s .clang-tidy.full .clang-tidy - name: Run clang-tidy working-directory: pdns - run: git diff -U0 HEAD^..HEAD | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p2 -export-fixes clang-tidy-auth.yml + run: git diff -U0 HEAD^..HEAD | python3 ../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p2 -export-fixes clang-tidy-auth.yml - name: Print clang-tidy fixes YAML working-directory: pdns shell: bash @@ -116,7 +116,7 @@ jobs: - run: inv ci-rec-make-bear - run: ln -s ../../.clang-tidy.full .clang-tidy - name: Run clang-tidy - run: git diff -U0 HEAD^..HEAD | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-rec.yml + run: git diff -U0 HEAD^..HEAD | python3 ../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-rec.yml - name: Print clang-tidy fixes YAML shell: bash run: | @@ -185,7 +185,7 @@ jobs: - run: inv ci-dnsdist-make-bear - run: ln -s ../../.clang-tidy.full .clang-tidy - name: Run clang-tidy - run: git diff -U0 HEAD^..HEAD | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-dnsdist.yml + run: git diff -U0 HEAD^..HEAD | python3 ../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-dnsdist.yml - name: Print clang-tidy fixes YAML shell: bash run: | From ef0ad88a34442bcc79273eab38238268609e91d2 Mon Sep 17 00:00:00 2001 From: phonedph1 <20867105+phonedph1@users.noreply.github.com> Date: Fri, 21 Apr 2023 18:20:06 -0600 Subject: [PATCH 098/909] Update config.rst --- pdns/dnsdistdist/docs/reference/config.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 22839b6369a0..c9faac2ca092 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -1156,7 +1156,7 @@ Status, Statistics and More :param str selector: Select queries based on this property. :param {str} selectors: A lua table of selectors. Only queries matching all selectors are shown - :param int num: Show a maximum of ``num`` recent queries+responses, default is 10. + :param int num: Show a maximum of ``num`` recent queries+responses. :param table options: A table with key: value pairs with options described below. Options: From f58f871b72e928c0aa26ba212b4d7e035077291f Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Mon, 24 Apr 2023 16:13:35 +0200 Subject: [PATCH 099/909] ixfrdist: add a per domain max-soa-refresh option to optionaly cap the refresh interval --- docs/manpages/ixfrdist.yml.5.rst | 3 +++ pdns/ixfrdist.cc | 23 +++++++++++++++++++++-- pdns/ixfrdist.example.yml | 4 ++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/manpages/ixfrdist.yml.5.rst b/docs/manpages/ixfrdist.yml.5.rst index 277084432837..387d4515076a 100644 --- a/docs/manpages/ixfrdist.yml.5.rst +++ b/docs/manpages/ixfrdist.yml.5.rst @@ -37,6 +37,7 @@ Example domains: - domain: example.com master: 192.0.2.18:5301 + max-soa-refresh: 1800 - domain: example.net master: 2001:DB8:ABCD::2 @@ -103,6 +104,8 @@ Options Mandatory. :master: IP address of the server to transfer this domain from. Mandatory. + :max-soa-refresh: Cap the refresh time to the given maximum (in seconds). + Optional. :webserver-address: IP address to listen on for the built-in webserver. diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index 9207a346242a..6c1193f5fca7 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -142,6 +142,7 @@ struct ixfrinfo_t { // Why a struct? This way we can add more options to a domain in the future struct ixfrdistdomain_t { set masters; // A set so we can do multiple master addresses in the future + uint32_t maxSOARefresh{0}; // Cap SOA refresh value to the given value in seconds }; // This contains the configuration for each domain @@ -337,8 +338,16 @@ static void updateThread(const string& workdir, const uint16_t& keep, const uint } auto& zoneLastCheck = lastCheck[domain]; - if ((current_soa != nullptr && now - zoneLastCheck < current_soa->d_st.refresh) || // Only check if we have waited `refresh` seconds - (current_soa == nullptr && now - zoneLastCheck < soaRetry)) { // Or if we could not get an update at all still, every 30 seconds + uint32_t refresh = soaRetry; // default if we don't get an update at all + if (current_soa != nullptr) { + // Check every `refresh` seconds as advertised in the SOA record + refresh = current_soa->d_st.refresh; + if (domainConfig.second.maxSOARefresh > 0) { + // Cap refresh value to the configured one if any + refresh = std::min(refresh, domainConfig.second.maxSOARefresh); + } + } + if (now - zoneLastCheck < refresh) { continue; } @@ -1111,6 +1120,13 @@ static bool parseAndCheckConfig(const string& configpath, YAML::Node& config) { g_log<()<<"' master address: "<(); + } catch (const runtime_error &e) { + g_log<()<<"': "< s; s.insert(domain["master"].as()); g_domainConfigs[domain["domain"].as()].masters = s; + if (domain["max-soa-refresh"]) { + g_domainConfigs[domain["domain"].as()].maxSOARefresh = domain["max-soa-refresh"].as(); + } g_stats.registerDomain(domain["domain"].as()); } diff --git a/pdns/ixfrdist.example.yml b/pdns/ixfrdist.example.yml index 976b7f23c622..08bf96bd698f 100644 --- a/pdns/ixfrdist.example.yml +++ b/pdns/ixfrdist.example.yml @@ -98,9 +98,13 @@ webserver-loglevel: normal # When no port is specified, 53 is used. When specifying ports for IPv6, use the # "bracket" notation: # +# You can optionally cap the refresh time of the SOA using 'max-soa-refresh' (seconds) +# Otherwise, or if set to 0, the retreived SOA refresh time will be used +# # domains: # - domain: example.com # master: 192.0.2.15 +# max-soa-refresh: 180 # - domain: rpz.example # master: [2001:DB8:a34:543::53]:5353 # From 0c4dfc36cbe4a1943b0afc87047a3e461d3c0117 Mon Sep 17 00:00:00 2001 From: Neil Cook Date: Mon, 24 Apr 2023 16:25:28 +0100 Subject: [PATCH 100/909] Make Additionals documentation more accurate --- pdns/recursordist/docs/lua-config/additionals.rst | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/docs/lua-config/additionals.rst b/pdns/recursordist/docs/lua-config/additionals.rst index 7d1395ce01f8..39d046538198 100644 --- a/pdns/recursordist/docs/lua-config/additionals.rst +++ b/pdns/recursordist/docs/lua-config/additionals.rst @@ -33,11 +33,21 @@ An example of a configuration: The first line specifies that additional records should be added to the results of ``MX`` queries using the default mode. The qtype of the records to be added are ``A`` and ``AAAA``. -The default mode is ``pdns.AdditionalMode.CacheOnlyRequireAuth``, this mode will only look in the record cache. +The default mode is ``pdns.AdditionalMode.CacheOnlyRequireAuth``; this mode will only look in the record cache. The second line specifies that three record types should be added to ``NAPTR`` answers. If needed, the Recursor will do an active resolve to retrieve these records. +Note that with record types such as ``NAPTR`` which can return records such as ``SRV``, which may themselves return additional +``A`` or ``AAAA`` records, the above example would not be sufficient to return those additional ``A`` and/or ``AAAA`` records. +In such a case, you would need to add an additional line to tell the recursor to fetch the additional records for the ``SRV`` +qtype as well. An example configuration for this case is shown below: + +.. code-block:: Lua + + addAllowedAdditionalQType(pdns.NAPTR, {pdns.A, pdns.AAAA, pdns.SRV}, {mode=pdns.AdditionalMode.ResolveImmediately}) + addAllowedAdditionalQType(pdns.SRV, {pdns.A, pdns.AAAA}, {mode=pdns.AdditionalMode.ResolveImmediately}) + The modes available are: ``pdns.AdditionalMode.Ignore`` From 000f2219b6a0d58a59278f49c4f21151be226f2d Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 26 Apr 2023 14:06:11 +0200 Subject: [PATCH 101/909] move loop into getAllDomainsFiltered --- modules/lmdbbackend/lmdbbackend.cc | 25 +++++++++++++++++-------- modules/lmdbbackend/lmdbbackend.hh | 2 ++ 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index c9a47a613a62..4006e813f563 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1651,22 +1651,31 @@ bool LMDBBackend::createDomain(const DNSName& domain, const DomainInfo::DomainKi return true; } -void LMDBBackend::getAllDomains(vector* domains, bool /* doSerial */, bool include_disabled) -{ - domains->clear(); +void LMDBBackend::getAllDomainsFiltered(vector* domains, const std::function& allow) { auto txn = d_tdomains->getROTransaction(); for (auto iter = txn.begin(); iter != txn.end(); ++iter) { - // cerr<<"iter"<push_back(di); + } + } +} +void LMDBBackend::getAllDomains(vector* domains, bool /* doSerial */, bool include_disabled) +{ + domains->clear(); + + getAllDomainsFiltered(domains, [this, include_disabled](DomainInfo& di) { if (!getSerial(di) && !include_disabled) { - continue; + return false; } - di.backend = this; - domains->push_back(di); - } + return true; + }); + } void LMDBBackend::getUnfreshSlaveInfos(vector* domains) diff --git a/modules/lmdbbackend/lmdbbackend.hh b/modules/lmdbbackend/lmdbbackend.hh index 062e0d497656..3b69451ec65f 100644 --- a/modules/lmdbbackend/lmdbbackend.hh +++ b/modules/lmdbbackend/lmdbbackend.hh @@ -309,6 +309,8 @@ private: int genChangeDomain(uint32_t id, std::function func); void deleteDomainRecords(RecordsRWTransaction& txn, uint32_t domain_id, uint16_t qtype = QType::ANY); + void getAllDomainsFiltered(vector* domains, const std::function& allow); + bool getSerial(DomainInfo& di); bool upgradeToSchemav3(); From f35fc244ccc46a5569712e5d64658fbfa8f2feee Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 26 Apr 2023 14:24:01 +0200 Subject: [PATCH 102/909] refactor getUnfreshSlaveInfos --- modules/lmdbbackend/lmdbbackend.cc | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 4006e813f563..cdc2baa421fd 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1685,20 +1685,19 @@ void LMDBBackend::getUnfreshSlaveInfos(vector* domains) LMDBResourceRecord lrr; soatimes st; - auto txn = d_tdomains->getROTransaction(); - for (auto iter = txn.begin(); iter != txn.end(); ++iter) { - if (!iter->isSecondaryType()) { - continue; + getAllDomainsFiltered(domains, [this, &lrr, &st, &now, &serial](DomainInfo& di) { + if (!di.isSecondaryType()) { + return false; } - auto txn2 = getRecordsROTransaction(iter.getID()); + auto txn2 = getRecordsROTransaction(di.id); compoundOrdername co; MDBOutVal val; - if (!txn2->txn->get(txn2->db->dbi, co(iter.getID(), g_rootdnsname, QType::SOA), val)) { + if (!txn2->txn->get(txn2->db->dbi, co(di.id, g_rootdnsname, QType::SOA), val)) { serFromString(val.get(), lrr); memcpy(&st, &lrr.content[lrr.content.size() - sizeof(soatimes)], sizeof(soatimes)); - if ((time_t)(iter->last_check + ntohl(st.refresh)) > now) { // still fresh - continue; + if ((time_t)(di.last_check + ntohl(st.refresh)) > now) { // still fresh + return false; } serial = ntohl(st.serial); } @@ -1706,13 +1705,8 @@ void LMDBBackend::getUnfreshSlaveInfos(vector* domains) serial = 0; } - DomainInfo di(*iter); - di.id = iter.getID(); - di.serial = serial; - di.backend = this; - - domains->emplace_back(di); - } + return true; + }); } void LMDBBackend::setStale(uint32_t domain_id) From ec6988eb3109b85a54256d084f09676d11819a9f Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 26 Apr 2023 16:07:30 +0200 Subject: [PATCH 103/909] refactor getUpdatedMasters --- modules/lmdbbackend/lmdbbackend.cc | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index cdc2baa421fd..4b127bb6cb79 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1725,35 +1725,29 @@ void LMDBBackend::setFresh(uint32_t domain_id) void LMDBBackend::getUpdatedMasters(vector& updatedDomains, std::unordered_set& catalogs, CatalogHashMap& catalogHashes) { - DomainInfo di; CatalogInfo ci; - - auto txn = d_tdomains->getROTransaction(); - for (auto iter = txn.begin(); iter != txn.end(); ++iter) { - - if (!iter->isPrimaryType()) { - continue; + + getAllDomainsFiltered(&(updatedDomains), [this, &catalogs, &catalogHashes, &ci](DomainInfo& di) { + if (!di.isPrimaryType()) { + return false; } - if (iter->kind == DomainInfo::Producer) { - catalogs.insert(iter->zone); - catalogHashes[iter->zone].process("\0"); - continue; // Producer fresness check is performed elsewhere + if (di.kind == DomainInfo::Producer) { + catalogs.insert(di.zone); + catalogHashes[di.zone].process("\0"); + return false; // Producer fresness check is performed elsewhere } - di = *iter; - di.id = iter.getID(); - - if (!iter->catalog.empty()) { - ci.fromJson(iter->options, CatalogInfo::CatalogType::Producer); + if (!di.catalog.empty()) { + ci.fromJson(di.options, CatalogInfo::CatalogType::Producer); ci.updateHash(catalogHashes, di); } if (getSerial(di) && di.serial != di.notified_serial) { di.backend = this; - updatedDomains.emplace_back(di); + return true; } - } + }); } void LMDBBackend::setNotified(uint32_t domain_id, uint32_t serial) From bdf49371abd31b5aa80271cd5b4a838cc17b177d Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 26 Apr 2023 19:05:21 +0200 Subject: [PATCH 104/909] refactor getCatalogMembers --- modules/lmdbbackend/lmdbbackend.cc | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 4b127bb6cb79..749b4acb2baf 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1759,26 +1759,29 @@ void LMDBBackend::setNotified(uint32_t domain_id, uint32_t serial) bool LMDBBackend::getCatalogMembers(const DNSName& catalog, vector& members, CatalogInfo::CatalogType type) { - auto txn = d_tdomains->getROTransaction(); - for (auto iter = txn.begin(); iter != txn.end(); ++iter) { - if ((type == CatalogInfo::CatalogType::Producer && iter->kind != DomainInfo::Master) || (type == CatalogInfo::CatalogType::Consumer && iter->kind != DomainInfo::Slave) || iter->catalog != catalog) { - continue; + vector scratch; + + getAllDomainsFiltered(&scratch, [this, &catalog, &members, &type](DomainInfo& di) { + if ((type == CatalogInfo::CatalogType::Producer && di.kind != DomainInfo::Master) || (type == CatalogInfo::CatalogType::Consumer && di.kind != DomainInfo::Slave) || di.catalog != catalog) { + return false; } CatalogInfo ci; - ci.d_id = iter->id; - ci.d_zone = iter->zone; - ci.d_primaries = iter->masters; + ci.d_id = di.id; + ci.d_zone = di.zone; + ci.d_primaries = di.masters; try { - ci.fromJson(iter->options, type); + ci.fromJson(di.options, type); } catch (const std::runtime_error& e) { - g_log << Logger::Warning << __PRETTY_FUNCTION__ << " options '" << iter->options << "' for zone '" << iter->zone << "' is no valid JSON: " << e.what() << endl; + g_log << Logger::Warning << __PRETTY_FUNCTION__ << " options '" << di.options << "' for zone '" << di.zone << "' is no valid JSON: " << e.what() << endl; members.clear(); return false; } members.emplace_back(ci); - } + + return false; + }); return true; } From cea7c50cc70174f20022ca7381dbd8c0579d536c Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 28 Apr 2023 13:40:27 +0200 Subject: [PATCH 105/909] add lmdb-lightning-stream option --- docs/backends/lmdb.rst | 11 +++++++++++ ext/lmdb-safe/lmdb-safe.cc | 1 + ext/lmdb-safe/lmdb-safe.hh | 1 + modules/lmdbbackend/lmdbbackend.cc | 9 +++++++++ 4 files changed, 22 insertions(+) diff --git a/docs/backends/lmdb.rst b/docs/backends/lmdb.rst index b3c48f83c240..df52719cf19b 100644 --- a/docs/backends/lmdb.rst +++ b/docs/backends/lmdb.rst @@ -121,6 +121,17 @@ Defaults to 100 on 32 bit systems, and 16000 on 64 bit systems. Instead of deleting items from the database, flag them as deleted in the item's `Lightning Stream `_ header. Only enable this if you are using Lightning Stream. +``lmdb-lightning-stream`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + + .. versionadded:: 4.8.0 + +Run in Lightning Stream compatible mode. This: + +* forces ``flag-deleted`` on +* forces ``random-ids`` on +* handles duplicate entries in databases that can result from domains being added on two Lightning Stream nodes at the same time + LMDB Structure -------------- diff --git a/ext/lmdb-safe/lmdb-safe.cc b/ext/lmdb-safe/lmdb-safe.cc index 33c3d4568acd..4aa6d313a7d8 100644 --- a/ext/lmdb-safe/lmdb-safe.cc +++ b/ext/lmdb-safe/lmdb-safe.cc @@ -69,6 +69,7 @@ namespace LMDBLS { } bool s_flag_deleted{false}; + bool s_handle_dups{false}; } #endif /* #ifndef DNSDIST */ diff --git a/ext/lmdb-safe/lmdb-safe.hh b/ext/lmdb-safe/lmdb-safe.hh index 2d5983be6761..79c3c82dd338 100644 --- a/ext/lmdb-safe/lmdb-safe.hh +++ b/ext/lmdb-safe/lmdb-safe.hh @@ -156,6 +156,7 @@ namespace LMDBLS { bool LSisDeleted(std::string_view val); extern bool s_flag_deleted; + extern bool s_handle_dups; } #undef _LMDB_SAFE_BSWAP64MAYBE diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 749b4acb2baf..05a64a230f30 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "ext/lmdb-safe/lmdb-safe.hh" #include #include #ifdef HAVE_CONFIG_H @@ -665,6 +666,13 @@ LMDBBackend::LMDBBackend(const std::string& suffix) } LMDBLS::s_flag_deleted = mustDo("flag-deleted"); + LMDBLS::s_handle_dups = false; + + if (mustDo("lightning-stream")) { + d_random_ids = true; + LMDBLS::s_flag_deleted = true; + LMDBLS::s_handle_dups = true; + } bool opened = false; @@ -2562,6 +2570,7 @@ class LMDBFactory : public BackendFactory declare(suffix, "random-ids", "Numeric IDs inside the database are generated randomly instead of sequentially", "no"); declare(suffix, "map-size", "LMDB map size in megabytes", (sizeof(void*) == 4) ? "100" : "16000"); declare(suffix, "flag-deleted", "Flag entries on deletion instead of deleting them", "no"); + declare(suffix, "lightning-stream", "Run in Lightning Stream compatible mode", "no"); } DNSBackend* make(const string& suffix = "") override { From 0d1182e9dfa13060d3759745f6c0ce7a115d9b42 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 28 Apr 2023 13:42:52 +0200 Subject: [PATCH 106/909] add missing defaults to doc --- docs/backends/lmdb.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/backends/lmdb.rst b/docs/backends/lmdb.rst index df52719cf19b..c4a4f939ac43 100644 --- a/docs/backends/lmdb.rst +++ b/docs/backends/lmdb.rst @@ -118,6 +118,9 @@ Defaults to 100 on 32 bit systems, and 16000 on 64 bit systems. .. versionadded:: 4.8.0 +- Boolean +- Default: no + Instead of deleting items from the database, flag them as deleted in the item's `Lightning Stream `_ header. Only enable this if you are using Lightning Stream. @@ -126,6 +129,9 @@ Only enable this if you are using Lightning Stream. .. versionadded:: 4.8.0 +- Boolean +- Default: no + Run in Lightning Stream compatible mode. This: * forces ``flag-deleted`` on From 20af815417d406a2a4e21aef1383e5b0c3f1a8d2 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 28 Apr 2023 13:50:11 +0200 Subject: [PATCH 107/909] fix warnings --- modules/lmdbbackend/lmdbbackend.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 05a64a230f30..6259841feaed 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1755,6 +1755,8 @@ void LMDBBackend::getUpdatedMasters(vector& updatedDomains, std::uno di.backend = this; return true; } + + return false; }); } @@ -1769,7 +1771,7 @@ bool LMDBBackend::getCatalogMembers(const DNSName& catalog, vector& { vector scratch; - getAllDomainsFiltered(&scratch, [this, &catalog, &members, &type](DomainInfo& di) { + getAllDomainsFiltered(&scratch, [&catalog, &members, &type](DomainInfo& di) { if ((type == CatalogInfo::CatalogType::Producer && di.kind != DomainInfo::Master) || (type == CatalogInfo::CatalogType::Consumer && di.kind != DomainInfo::Slave) || di.catalog != catalog) { return false; } From 14b68fdb492bfcab47c786e56df511f7453e9b67 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 6 Apr 2023 12:19:59 +0200 Subject: [PATCH 108/909] lmdb indexops: avoid updating timestamp when there is no change --- ext/lmdb-safe/lmdb-typed.hh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index a0e2cefb0d8d..0e837a60913e 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -162,7 +162,11 @@ struct LMDBIndexOps auto scombined = makeCombinedKey(keyConv(d_parent->getMember(t)), id); MDBInVal combined(scombined); - txn->put(d_idx, combined, empty, flags); + MDBOutVal currentvalue; + + if (txn->get(d_idx, combined, currentvalue) == MDB_NOTFOUND) { + txn->put(d_idx, combined, empty, flags); + } } void del(MDBRWTransaction& txn, const Class& t, uint32_t id) From 547e9b51eb77581aadce79a89d9f623d7b223822 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 6 Apr 2023 14:25:50 +0200 Subject: [PATCH 109/909] lmdb: add interface to get timestamp from LS header --- ext/lmdb-safe/lmdb-safe.cc | 5 +++++ ext/lmdb-safe/lmdb-safe.hh | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/ext/lmdb-safe/lmdb-safe.cc b/ext/lmdb-safe/lmdb-safe.cc index 4aa6d313a7d8..d4b820e73749 100644 --- a/ext/lmdb-safe/lmdb-safe.cc +++ b/ext/lmdb-safe/lmdb-safe.cc @@ -68,6 +68,11 @@ namespace LMDBLS { return (lsh->d_flags & LS_FLAG_DELETED) != 0; } + uint64_t LSgetTimestamp(std::string_view val) { + const LSheader* lsh = LSassertFixedHeaderSize(val); + + return lsh->getTimestamp(); + } bool s_flag_deleted{false}; bool s_handle_dups{false}; } diff --git a/ext/lmdb-safe/lmdb-safe.hh b/ext/lmdb-safe/lmdb-safe.hh index 79c3c82dd338..b10b4568ec6b 100644 --- a/ext/lmdb-safe/lmdb-safe.hh +++ b/ext/lmdb-safe/lmdb-safe.hh @@ -140,13 +140,16 @@ namespace LMDBLS { return std::string((char*)this, sizeof(*this)) + std::string(ntohs(d_numextra)*8, '\0'); } - + uint64_t getTimestamp() const { + return _LMDB_SAFE_BSWAP64MAYBE(d_timestamp); + } }; static_assert(sizeof(LSheader)==24, "LSheader size is wrong"); const size_t LS_MIN_HEADER_SIZE = sizeof(LSheader); const size_t LS_BLOCK_SIZE = 8; + const size_t LS_TIMESTAMP_OFFSET = 0; const size_t LS_NUMEXTRA_OFFSET = 22; const uint8_t LS_FLAG_DELETED = 0x01; @@ -154,6 +157,7 @@ namespace LMDBLS { size_t LScheckHeaderAndGetSize(std::string_view val, size_t datasize=0); size_t LScheckHeaderAndGetSize(const MDBOutVal *val, size_t datasize=0); bool LSisDeleted(std::string_view val); + uint64_t LSgetTimestamp(std::string_view val); extern bool s_flag_deleted; extern bool s_handle_dups; From aad38b4c24a5f9214afb38106de647d9f72b2a81 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 28 Apr 2023 13:52:42 +0200 Subject: [PATCH 110/909] add comment --- ext/lmdb-safe/lmdb-typed.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index 0e837a60913e..a0845273b397 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -164,6 +164,7 @@ struct LMDBIndexOps MDBOutVal currentvalue; + // check if the entry already exists, so we don't uselessly bump the timestamp if (txn->get(d_idx, combined, currentvalue) == MDB_NOTFOUND) { txn->put(d_idx, combined, empty, flags); } From 33f44dc6c07ea9ae3c6e245b672ca413af9549e1 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 28 Apr 2023 14:15:11 +0200 Subject: [PATCH 111/909] lmdb-typed: teach get() to optionally fetch just the oldest entry --- ext/lmdb-safe/lmdb-typed.hh | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index a0845273b397..c83ed39859dc 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -310,7 +310,7 @@ public: // auto range = prefix_range(key); LMDBIDvec ids; - get_multi(key, ids); + get_multi(key, ids, true); if (ids.size() == 0) { return 0; @@ -646,7 +646,7 @@ public: }; template - void get_multi(const typename std::tuple_element::type::type& key, LMDBIDvec& ids) + void get_multi(const typename std::tuple_element::type::type& key, LMDBIDvec& ids, bool onlyOldest=false) { // std::cerr<<"in get_multi"<getCursor(std::get(d_parent.d_parent->d_tuple).d_idx); @@ -658,6 +658,9 @@ public: int rc = cursor.get(out, id, MDB_SET_RANGE); + uint64_t oldestts = UINT64_MAX; + uint32_t oldestid = 0; + while (rc == 0) { auto sout = out.getNoStripHeader(); // FIXME: this (and many others) could probably be string_view auto thiskey = getKeyFromCombinedKey(out); @@ -670,7 +673,19 @@ public: if (sthiskey == keyString) { auto _id = getIDFromCombinedKey(out); - ids.push_back(_id.getNoStripHeader()); + uint64_t ts = LMDBLS::LSgetTimestamp(id.getNoStripHeader()); + uint32_t __id = _id.getNoStripHeader(); + + if (ts < oldestts) { + oldestts = ts; + oldestid = __id; + } + ids.push_back(__id); + } + + if (onlyOldest && ids.size() > 1) { + ids.clear(); + ids.push_back(oldestid); } rc = cursor.get(out, id, MDB_NEXT); From 8c11405d6b75a652763248a76c50cc7ed56759c7 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 28 Apr 2023 14:18:15 +0200 Subject: [PATCH 112/909] move handle_dups flag to lmdbbackend --- ext/lmdb-safe/lmdb-safe.cc | 1 - ext/lmdb-safe/lmdb-safe.hh | 1 - modules/lmdbbackend/lmdbbackend.cc | 4 ++-- modules/lmdbbackend/lmdbbackend.hh | 1 + 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/ext/lmdb-safe/lmdb-safe.cc b/ext/lmdb-safe/lmdb-safe.cc index d4b820e73749..6b93b3b7cfaf 100644 --- a/ext/lmdb-safe/lmdb-safe.cc +++ b/ext/lmdb-safe/lmdb-safe.cc @@ -74,7 +74,6 @@ namespace LMDBLS { return lsh->getTimestamp(); } bool s_flag_deleted{false}; - bool s_handle_dups{false}; } #endif /* #ifndef DNSDIST */ diff --git a/ext/lmdb-safe/lmdb-safe.hh b/ext/lmdb-safe/lmdb-safe.hh index b10b4568ec6b..af1c87fcb6d3 100644 --- a/ext/lmdb-safe/lmdb-safe.hh +++ b/ext/lmdb-safe/lmdb-safe.hh @@ -160,7 +160,6 @@ namespace LMDBLS { uint64_t LSgetTimestamp(std::string_view val); extern bool s_flag_deleted; - extern bool s_handle_dups; } #undef _LMDB_SAFE_BSWAP64MAYBE diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 6259841feaed..23804d367459 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -666,12 +666,12 @@ LMDBBackend::LMDBBackend(const std::string& suffix) } LMDBLS::s_flag_deleted = mustDo("flag-deleted"); - LMDBLS::s_handle_dups = false; + d_handle_dups = false; if (mustDo("lightning-stream")) { d_random_ids = true; + d_handle_dups = true; LMDBLS::s_flag_deleted = true; - LMDBLS::s_handle_dups = true; } bool opened = false; diff --git a/modules/lmdbbackend/lmdbbackend.hh b/modules/lmdbbackend/lmdbbackend.hh index 3b69451ec65f..d684a37b91cb 100644 --- a/modules/lmdbbackend/lmdbbackend.hh +++ b/modules/lmdbbackend/lmdbbackend.hh @@ -330,5 +330,6 @@ private: uint32_t d_transactiondomainid; bool d_dolog; bool d_random_ids; + bool d_handle_dups; DTime d_dtime; // used only for logging }; From b5cb63baeeb52b03348de1ec3798fc3c143aa726 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 28 Apr 2023 14:37:22 +0200 Subject: [PATCH 113/909] filter duplicate domain entries --- modules/lmdbbackend/lmdbbackend.cc | 53 ++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 23804d367459..5da5503b4574 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1660,14 +1660,53 @@ bool LMDBBackend::createDomain(const DNSName& domain, const DomainInfo::DomainKi } void LMDBBackend::getAllDomainsFiltered(vector* domains, const std::function& allow) { - auto txn = d_tdomains->getROTransaction(); - for (auto iter = txn.begin(); iter != txn.end(); ++iter) { - DomainInfo di = *iter; - di.id = iter.getID(); - di.backend = this; + if (d_handle_dups) { + cerr<<"handling dups"<getROTransaction(); + + map zonemap; + set dups; - if (allow (di)) { - domains->push_back(di); + for (auto iter = txn.begin(); iter != txn.end(); ++iter) { + DomainInfo di = *iter; + di.id = iter.getID(); + di.backend = this; + + if (zonemap.count(di.zone) == 1) { + dups.insert(di.zone); + } + else { + zonemap[di.zone] = di; + } + } + + for (const auto& zone : dups) { + DomainInfo di; + + if (!(di.id = txn.get<0>(zone, di))) { + continue; + } + + di.backend = this; + zonemap[di.zone] = di; + } + + for (auto [k,v] : zonemap) { + if (allow (v)) { + domains->push_back(v); + } + } + } + else { + auto txn = d_tdomains->getROTransaction(); + for (auto iter = txn.begin(); iter != txn.end(); ++iter) { + DomainInfo di = *iter; + di.id = iter.getID(); + di.backend = this; + + if (allow (di)) { + domains->push_back(di); + } } } } From cc3f7f0a4365b4c52cac7c50ebba4bbd6f9a1917 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 28 Apr 2023 14:43:08 +0200 Subject: [PATCH 114/909] remove debug print --- modules/lmdbbackend/lmdbbackend.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 5da5503b4574..45f3d7d2f2f3 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1661,7 +1661,6 @@ bool LMDBBackend::createDomain(const DNSName& domain, const DomainInfo::DomainKi void LMDBBackend::getAllDomainsFiltered(vector* domains, const std::function& allow) { if (d_handle_dups) { - cerr<<"handling dups"<getROTransaction(); map zonemap; From a180309a91f0123468862e27154d003cc3eb9b1b Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 28 Apr 2023 14:44:08 +0200 Subject: [PATCH 115/909] format --- modules/lmdbbackend/lmdbbackend.cc | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 45f3d7d2f2f3..6cc027a42ed7 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1659,7 +1659,8 @@ bool LMDBBackend::createDomain(const DNSName& domain, const DomainInfo::DomainKi return true; } -void LMDBBackend::getAllDomainsFiltered(vector* domains, const std::function& allow) { +void LMDBBackend::getAllDomainsFiltered(vector* domains, const std::function& allow) +{ if (d_handle_dups) { auto txn = d_tdomains->getROTransaction(); @@ -1683,15 +1684,15 @@ void LMDBBackend::getAllDomainsFiltered(vector* domains, const std:: DomainInfo di; if (!(di.id = txn.get<0>(zone, di))) { - continue; + continue; } di.backend = this; zonemap[di.zone] = di; } - for (auto [k,v] : zonemap) { - if (allow (v)) { + for (auto [k, v] : zonemap) { + if (allow(v)) { domains->push_back(v); } } @@ -1703,7 +1704,7 @@ void LMDBBackend::getAllDomainsFiltered(vector* domains, const std:: di.id = iter.getID(); di.backend = this; - if (allow (di)) { + if (allow(di)) { domains->push_back(di); } } @@ -1721,7 +1722,6 @@ void LMDBBackend::getAllDomains(vector* domains, bool /* doSerial */ return true; }); - } void LMDBBackend::getUnfreshSlaveInfos(vector* domains) @@ -1732,7 +1732,7 @@ void LMDBBackend::getUnfreshSlaveInfos(vector* domains) soatimes st; getAllDomainsFiltered(domains, [this, &lrr, &st, &now, &serial](DomainInfo& di) { - if (!di.isSecondaryType()) { + if (!di.isSecondaryType()) { return false; } @@ -1772,7 +1772,7 @@ void LMDBBackend::setFresh(uint32_t domain_id) void LMDBBackend::getUpdatedMasters(vector& updatedDomains, std::unordered_set& catalogs, CatalogHashMap& catalogHashes) { CatalogInfo ci; - + getAllDomainsFiltered(&(updatedDomains), [this, &catalogs, &catalogHashes, &ci](DomainInfo& di) { if (!di.isPrimaryType()) { return false; From f38196e3bc40e3cc2ca67dc9cafa8c611d012978 Mon Sep 17 00:00:00 2001 From: Jacob Bunk Nielsen Date: Sat, 29 Apr 2023 14:45:07 +0200 Subject: [PATCH 116/909] Make DNSQType.TSIG available in dnsdist --- pdns/qtype.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/qtype.cc b/pdns/qtype.cc index 459a09d36279..f8069f8696d5 100644 --- a/pdns/qtype.cc +++ b/pdns/qtype.cc @@ -84,7 +84,7 @@ const map QType::names = { {"EUI48", 108}, {"EUI64", 109}, {"TKEY", 249}, - // {"TSIG", 250}, + {"TSIG", 250}, {"IXFR", 251}, {"AXFR", 252}, {"MAILB", 253}, From a5f9a1b8b0c51e2dc57b368fec5a09c87a28b534 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 14 Apr 2023 10:48:05 +0200 Subject: [PATCH 117/909] rec: warning: variable 'total' set but not used [-Wunused-but-set-variable] --- pdns/recursordist/ws-recursor.cc | 4 ---- 1 file changed, 4 deletions(-) diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index ae0cde21e1d5..c25236ed5ab5 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -1267,9 +1267,7 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) typedef map counts_t; counts_t counts; - unsigned int total = 0; for (const query_t& q : queries) { - total++; if (filter) counts[pair(getRegisteredName(q.first), q.second)]++; else @@ -1313,9 +1311,7 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) typedef map counts_t; counts_t counts; - unsigned int total = 0; for (const ComboAddress& q : queries) { - total++; counts[q]++; } From 4c8b2fcf41499419d5325896ce7ad9fe0cd9b86f Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 2 May 2023 13:04:49 +0200 Subject: [PATCH 118/909] drop unused const --- ext/lmdb-safe/lmdb-safe.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/ext/lmdb-safe/lmdb-safe.hh b/ext/lmdb-safe/lmdb-safe.hh index af1c87fcb6d3..1c62d8802964 100644 --- a/ext/lmdb-safe/lmdb-safe.hh +++ b/ext/lmdb-safe/lmdb-safe.hh @@ -149,7 +149,6 @@ namespace LMDBLS { const size_t LS_MIN_HEADER_SIZE = sizeof(LSheader); const size_t LS_BLOCK_SIZE = 8; - const size_t LS_TIMESTAMP_OFFSET = 0; const size_t LS_NUMEXTRA_OFFSET = 22; const uint8_t LS_FLAG_DELETED = 0x01; From 77c525f8cf4d8ecbab0927e8f09e2f65b78bcee2 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 2 May 2023 13:04:58 +0200 Subject: [PATCH 119/909] simplify dup check --- modules/lmdbbackend/lmdbbackend.cc | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 6cc027a42ed7..ec425cc187ab 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1672,12 +1672,9 @@ void LMDBBackend::getAllDomainsFiltered(vector* domains, const std:: di.id = iter.getID(); di.backend = this; - if (zonemap.count(di.zone) == 1) { + if (!zonemap.insert(std::make_pair(di.zone, di)).second) { dups.insert(di.zone); } - else { - zonemap[di.zone] = di; - } } for (const auto& zone : dups) { From ae6198721035b5f4eb61f77391a8bf092b24cca2 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 2 May 2023 13:09:15 +0200 Subject: [PATCH 120/909] move transaction opening outside of both if branches --- modules/lmdbbackend/lmdbbackend.cc | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index ec425cc187ab..88cde13a1e51 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1661,9 +1661,8 @@ bool LMDBBackend::createDomain(const DNSName& domain, const DomainInfo::DomainKi void LMDBBackend::getAllDomainsFiltered(vector* domains, const std::function& allow) { + auto txn = d_tdomains->getROTransaction(); if (d_handle_dups) { - auto txn = d_tdomains->getROTransaction(); - map zonemap; set dups; @@ -1695,7 +1694,6 @@ void LMDBBackend::getAllDomainsFiltered(vector* domains, const std:: } } else { - auto txn = d_tdomains->getROTransaction(); for (auto iter = txn.begin(); iter != txn.end(); ++iter) { DomainInfo di = *iter; di.id = iter.getID(); From 61f7077570c70f5a192ec705123a6237261c4a4a Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 2 May 2023 14:02:33 +0200 Subject: [PATCH 121/909] simplify oldestts checking, optimise hot path for non-LS users --- ext/lmdb-safe/lmdb-typed.hh | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index c83ed39859dc..a48c3af01072 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -676,16 +676,17 @@ public: uint64_t ts = LMDBLS::LSgetTimestamp(id.getNoStripHeader()); uint32_t __id = _id.getNoStripHeader(); - if (ts < oldestts) { - oldestts = ts; - oldestid = __id; + if (onlyOldest) { + if (ts < oldestts) { + oldestts = ts; + oldestid = __id; + + ids.clear(); + ids.push_back(oldestid); + } + } else { + ids.push_back(__id); } - ids.push_back(__id); - } - - if (onlyOldest && ids.size() > 1) { - ids.clear(); - ids.push_back(oldestid); } rc = cursor.get(out, id, MDB_NEXT); From d6c032385b7325795fc0a584991018d4017c69fc Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 2 May 2023 14:13:16 +0200 Subject: [PATCH 122/909] add comments --- ext/lmdb-safe/lmdb-typed.hh | 1 + modules/lmdbbackend/lmdbbackend.cc | 1 + 2 files changed, 2 insertions(+) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index a48c3af01072..ad5bb07c8a78 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -310,6 +310,7 @@ public: // auto range = prefix_range(key); LMDBIDvec ids; + // because we know we only want one item, pass onlyOldest=true to consistently get the same one out of a set of duplicates get_multi(key, ids, true); if (ids.size() == 0) { diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 88cde13a1e51..219521978f3c 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1679,6 +1679,7 @@ void LMDBBackend::getAllDomainsFiltered(vector* domains, const std:: for (const auto& zone : dups) { DomainInfo di; + // this get grabs the oldest item if there are duplicates if (!(di.id = txn.get<0>(zone, di))) { continue; } From a747fb49be395e9d70818d2ffc16b61796539af4 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 2 May 2023 14:16:44 +0200 Subject: [PATCH 123/909] move assignment outside of condition --- modules/lmdbbackend/lmdbbackend.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 219521978f3c..55f3d6baa120 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1680,7 +1680,10 @@ void LMDBBackend::getAllDomainsFiltered(vector* domains, const std:: DomainInfo di; // this get grabs the oldest item if there are duplicates - if (!(di.id = txn.get<0>(zone, di))) { + di.id = txn.get<0>(zone, di); + + if (di.id == 0) { + // .get actually found nothing for us continue; } From df640ba37837e44fc4c3610391c798ea8eab77c6 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 2 May 2023 14:41:17 +0200 Subject: [PATCH 124/909] Ignore macros when calculating cognitive complexity of functions --- .clang-tidy.full | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index e37dd0e627c5..7f1aae9c4613 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -253,7 +253,7 @@ CheckOptions: - key: modernize-pass-by-value.ValuesOnly value: 'false' - key: readability-function-cognitive-complexity.IgnoreMacros - value: 'false' + value: 'true' - key: modernize-loop-convert.IncludeStyle value: llvm - key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons From 15501d199276edd0fe404d556f2dd44e7e88c7b2 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 2 May 2023 15:17:51 +0200 Subject: [PATCH 125/909] Improve clang-format documentation --- CONTRIBUTING.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d085eabb31bf..548f408a787f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -77,18 +77,18 @@ plus various other directories with `regression-tests.*` names. ## `clang-format` -We have `clang-format` in place, but not for all files yet. -This is an incremental process. -If you're adding new code, adhering to the formatting config is appreciated. -Formatting breakage in already formatted files will be caught by the CI. -To format all files that are supposed to be formatted, run `make format-code` in the root of the tree. +We have `clang-format` in place, but not for all files yet. We are working towards a fully formatted codebase in an incremental fashion. + +If you're adding new code, adhering to the formatting configuration available in `.clang-format` is appreciated. If you are touching code that is not yet formatted, it would also be very appreciated to format it in a separate commit first. + +Any formatting breakage in already formatted files will be caught by the CI. To format all files that are supposed to be formatted, run `make format-code` in the root of the tree. ## Additional guidelines -* Don't have end-of-line whitespace -* Use spaces instead of tabs -* Although the codebase does not consistently have them, [docblock](https://www.doxygen.nl/manual/docblocks.html)s on functions and classes are appreciated -* Never hesitate to write comments on anything that might not be immediately clear just from reading the code +* Don't have end-of-line whitespace. +* Use spaces instead of tabs. +* Although the codebase does not consistently have them, [docblock](https://www.doxygen.nl/manual/docblocks.html)s on functions and classes are appreciated. +* Never hesitate to write comments on anything that might not be immediately clear just from reading the code. * When adding whole new things, consider putting them in a `pdns::X` namespace. Look for `namespace pdns` in the codebase for examples. ## Code Checkers From 1215b18c207bd130ba8f5adc1df43144fb9eab65 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 2 May 2023 15:17:56 +0200 Subject: [PATCH 126/909] Document the process to disable specific clang-tidy lints --- CONTRIBUTING.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 548f408a787f..36bdab399df8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -111,6 +111,23 @@ We provide two configuration files for `clang-tidy`: 2. A more complete [.clang-tidy.full](.clang-tidy.full) which enables almost all available checks. This configuration can be enabled using `ln -sf .clang-tidy.full .clang-tidy` and is recommended for all new code. +### `clang-tidy` and CI + +We run `clang-tidy` using the `.clang-tidy.full` configuration as part of our CI. `clang-tidy` warnings will show up on a pull request if any are introduced. + +However, it may happen that existing code could produce warnings and can show up too due to being part of the pull request. In such a case there are two options: + +1. Fix the warnings in a separate commit. +2. If fixing the warning would be too much trouble at this point in time, disabling the specific warning using the `// NOLINTNEXTLINE` or `// NOLINT` directives can be acceptable given the following is adhered to: + +Any added `// NOLINTNEXTLINE` or `// NOLINT` directive or others need to have a Github issue title, issue number and link next to them in the description along with the name or Github nickname of the person that wrote it. The Github issue must have an assignee and an accurate description of what needs to be done. As an example: + +`// NOLINTNEXTLINE() : + a short comment if needed.` + +If the warning cannot be avoided in any way, a good explanation is needed. As an example: + +`// NOLINTNEXTLINE(*-cast): Using the OpenSSL C APIs.` + # Development Environment Information about setting up a development environment using a language server like [`clangd`](https://clangd.llvm.org/) or [`ccls`](https://github.com/MaskRay/ccls) can be found in [DEVELOPMENT.md](DEVELOPMENT.md). From c89fb1f472abe5c0775612d6b442ae07617b1b2d Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 2 May 2023 15:25:05 +0200 Subject: [PATCH 127/909] getCatalogMembers: bubble up full return false --- modules/lmdbbackend/lmdbbackend.cc | 49 +++++++++++++++++++----------- 1 file changed, 31 insertions(+), 18 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 55f3d6baa120..1328d66cb4d0 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -22,6 +22,7 @@ #include "ext/lmdb-safe/lmdb-safe.hh" #include +#include #include #ifdef HAVE_CONFIG_H #include "config.h" @@ -1804,31 +1805,43 @@ void LMDBBackend::setNotified(uint32_t domain_id, uint32_t serial) }); } +class getCatalogMembersReturnFalseException : std::runtime_error +{ +public: + getCatalogMembersReturnFalseException() : + std::runtime_error("getCatalogMembers should return false") {} +}; + bool LMDBBackend::getCatalogMembers(const DNSName& catalog, vector& members, CatalogInfo::CatalogType type) { vector scratch; - getAllDomainsFiltered(&scratch, [&catalog, &members, &type](DomainInfo& di) { - if ((type == CatalogInfo::CatalogType::Producer && di.kind != DomainInfo::Master) || (type == CatalogInfo::CatalogType::Consumer && di.kind != DomainInfo::Slave) || di.catalog != catalog) { - return false; - } + try { + getAllDomainsFiltered(&scratch, [&catalog, &members, &type](DomainInfo& di) { + if ((type == CatalogInfo::CatalogType::Producer && di.kind != DomainInfo::Master) || (type == CatalogInfo::CatalogType::Consumer && di.kind != DomainInfo::Slave) || di.catalog != catalog) { + return false; + } - CatalogInfo ci; - ci.d_id = di.id; - ci.d_zone = di.zone; - ci.d_primaries = di.masters; - try { - ci.fromJson(di.options, type); - } - catch (const std::runtime_error& e) { - g_log << Logger::Warning << __PRETTY_FUNCTION__ << " options '" << di.options << "' for zone '" << di.zone << "' is no valid JSON: " << e.what() << endl; - members.clear(); - return false; - } - members.emplace_back(ci); + CatalogInfo ci; + ci.d_id = di.id; + ci.d_zone = di.zone; + ci.d_primaries = di.masters; + try { + ci.fromJson(di.options, type); + } + catch (const std::runtime_error& e) { + g_log << Logger::Warning << __PRETTY_FUNCTION__ << " options '" << di.options << "' for zone '" << di.zone << "' is no valid JSON: " << e.what() << endl; + members.clear(); + throw getCatalogMembersReturnFalseException(); + } + members.emplace_back(ci); + return false; + }); + } + catch (const getCatalogMembersReturnFalseException& e) { return false; - }); + } return true; } From 90e26e1477a10dbd074ff841b9add3a432c3b80a Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 3 May 2023 12:19:47 +0200 Subject: [PATCH 128/909] auth-4.8.0-beta1: secpoll&docs --- docs/changelog/4.8.rst | 63 ++++++++++++++++++++++++++++++++++++++++++ docs/secpoll.zone | 5 ++-- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/docs/changelog/4.8.rst b/docs/changelog/4.8.rst index 5724d2d60cd9..18943912106a 100644 --- a/docs/changelog/4.8.rst +++ b/docs/changelog/4.8.rst @@ -1,6 +1,69 @@ Changelogs for 4.8.x ==================== +.. changelog:: + :version: 4.8.0-beta1 + :released: 3rd of May 2023 + + This is release 4.8.0-beta1 of the Authoritative Server. + + In 4.8, the LMDB backend gains a new Lightning Stream-compatible schema, which requires a data migration (this is automatic, and there is no migration back to the old schema). + LMDB backend users should pay extra attention to the :doc:`Upgrade Notes <../upgrading>`. + + `Lightning Stream `_ is an `open source `_ data syncer that allows multiple nodes to sync LMDB (Lightning Memory-Mapped Database) data to and from an S3 (compatible) bucket. This has particular advantages in distributed and/or large-scale applications (i.e. ~1 million records), making DNS replication much, much easier to manage. + + We are excited about how Lightning Stream simplifies running multiple distributed PowerDNS Authoritative servers, with full support for keeping record data and DNSSEC keys in sync, from multiple writers. + + 4.8.0-beta1 adds logic to deal with domains existing twice in the database when two Lightning Stream nodes manage to add it at the same time. It also contains a few other fixes, please see the list below. + + .. change:: + :tags: Bug Fixes + :pullreq: 12729 + + LMDB: handle duplicate domain existence consistently + + .. change:: + :tags: New Features + :pullreq: 12768 + + ixfrdist: add a per domain max-soa-refresh option + + .. change:: + :tags: Improvements + :pullreq: 12636 + + lmdb: handle lack of support for RRset comments better + + .. change:: + :tags: Bug Fixes + :pullreq: 12740 + + Pick the right signer name when a NSEC name is also a delegation point (Kees Monshouwer) + + .. change:: + :tags: New Features + :pullreq: 12669 + + LUA records: enhance ifportup() with lists of sets of addresses like ifurlup() + + .. change:: + :tags: Improvements + :pullreq: 12721 + + calm down the communicator loop (Kees Monshouwer) + + .. change:: + :tags: Bug Fixes + :pullreq: 12706 + + Fixes a typo in pdnsutil clear-zone help output (san983) + + .. change:: + :tags: Improvements + :pullreq: 12664 + + DNSRecord: Ensure that the content can be read or replaced, not edited + .. changelog:: :version: 4.8.0-alpha1 :released: 21st of March 2023 diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 9ba2dde0734b..444c48830aae 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023041700 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023050300 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -118,7 +118,8 @@ auth-4.7.1.security-status 60 IN TXT "1 OK" auth-4.7.2.security-status 60 IN TXT "1 OK" auth-4.7.3.security-status 60 IN TXT "1 OK" auth-4.7.4.security-status 60 IN TXT "1 OK" -auth-4.8.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release" +auth-4.8.0-alpha1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" +auth-4.8.0-beta1.security-status 60 IN TXT "1 Unsupported pre-release" ; Auth Debian auth-3.4.1-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2015-02/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-03/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-04/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-05/" From 57af5b7c4cd4c01a1ef26f6451a97414f4cf0e47 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 3 May 2023 13:32:18 +0200 Subject: [PATCH 129/909] github runners can be *very* slow wrt I/O, use a more generous timeout in tests This issue seems to be more prominent when using a TSAN enabled dnsdist. --- regression-tests.dnsdist/test_API.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests.dnsdist/test_API.py b/regression-tests.dnsdist/test_API.py index 60b9e54bc2d6..2a9f9bf3a248 100644 --- a/regression-tests.dnsdist/test_API.py +++ b/regression-tests.dnsdist/test_API.py @@ -10,7 +10,7 @@ class APITestsBase(DNSDistTest): __test__ = False - _webTimeout = 2.0 + _webTimeout = 5.0 _webServerPort = 8083 _webServerBasicAuthPassword = 'secret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' From 0c6e4870cecd40f31b5586d1459d61923fd62470 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 3 May 2023 14:11:20 +0200 Subject: [PATCH 130/909] Init len earlier, as suggested by rgacogne --- pdns/recursordist/pdns_recursor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index e05ac3077636..587821f992c2 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -328,12 +328,12 @@ LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAdd pident->remote = fromaddr; int ret = MT->waitEvent(pident, &packet, g_networkTimeoutMsec, &now); + len = 0; /* -1 means error, 0 means timeout, 1 means a result from handleUDPServerResponse() which might still be an error */ if (ret > 0) { /* handleUDPServerResponse() will close the socket for us no matter what */ if (packet.empty()) { // means "error" - len = 0; return LWResult::Result::PermanentError; } From bc4d98b7cb2ecad488560d1dbef156708a1166af Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 3 May 2023 15:02:34 +0200 Subject: [PATCH 131/909] dnsdist: Fix cache hit and miss metrics with DoH queries Since we do two lookups for DoH queries forwarded over UDP (first TCP then UDP), we need to be careful to only record a cache miss in our last attempt. --- pdns/dnsdist.cc | 6 ++++-- regression-tests.dnsdist/test_Metrics.py | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 06aa910ab68f..e2e123b7927a 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -1347,7 +1347,9 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders forwardedOverUDP = false; } - if (dq.ids.packetCache->get(dq, dq.getHeader()->id, &dq.ids.cacheKey, dq.ids.subnet, dq.ids.dnssecOK, forwardedOverUDP, allowExpired, false, true, true)) { + /* we do not record a miss for queries received over DoH and forwarded over TCP + yet, as we will do a second-lookup */ + if (dq.ids.packetCache->get(dq, dq.getHeader()->id, &dq.ids.cacheKey, dq.ids.subnet, dq.ids.dnssecOK, forwardedOverUDP, allowExpired, false, true, (dq.ids.protocol != dnsdist::Protocol::DoH || forwardedOverUDP) ? true : false)) { restoreFlags(dq.getHeader(), dq.ids.origFlags); @@ -1363,7 +1365,7 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders } else if (dq.ids.protocol == dnsdist::Protocol::DoH && !forwardedOverUDP) { /* do a second-lookup for UDP responses, but we do not want TC=1 answers */ - if (dq.ids.packetCache->get(dq, dq.getHeader()->id, &dq.ids.cacheKeyUDP, dq.ids.subnet, dq.ids.dnssecOK, true, allowExpired, false, false, false)) { + if (dq.ids.packetCache->get(dq, dq.getHeader()->id, &dq.ids.cacheKeyUDP, dq.ids.subnet, dq.ids.dnssecOK, true, allowExpired, false, false, true)) { if (!prepareOutgoingResponse(holders, *dq.ids.cs, dq, true)) { return ProcessQueryResult::Drop; } diff --git a/regression-tests.dnsdist/test_Metrics.py b/regression-tests.dnsdist/test_Metrics.py index d907b1135463..5a70d0d8cefd 100644 --- a/regression-tests.dnsdist/test_Metrics.py +++ b/regression-tests.dnsdist/test_Metrics.py @@ -59,6 +59,18 @@ def getMetric(self, name): self.assertIn(name, stats) return int(stats[name]) + def getPoolMetric(self, poolName, metricName): + headers = {'x-api-key': self._webServerAPIKey} + url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost/pool?name=' + poolName + r = requests.get(url, headers=headers, timeout=self._webTimeout) + self.assertTrue(r) + self.assertEqual(r.status_code, 200) + self.assertTrue(r.json()) + content = r.json() + stats = content['stats'] + self.assertIn(metricName, stats) + return int(stats[metricName]) + def testRCodeIncreaseMetrics(self): """ Metrics: Check that metrics are correctly updated for RCodeAction @@ -93,6 +105,7 @@ def testRCodeIncreaseMetrics(self): # self-generated responses should not increase this metric self.assertEqual(self.getMetric('servfail-responses'), servfailBackendResponses) + def testCacheMetrics(self): """ Metrics: Check that metrics are correctly updated for cache misses and hits @@ -114,6 +127,8 @@ def testCacheMetrics(self): responsesBefore = self.getMetric('responses') cacheHitsBefore = self.getMetric('cache-hits') cacheMissesBefore = self.getMetric('cache-misses') + poolCacheHitsBefore = self.getPoolMetric('cache', 'cacheHits') + poolCacheMissesBefore = self.getPoolMetric('cache', 'cacheMisses') sender = getattr(self, method) # first time, cache miss @@ -128,6 +143,8 @@ def testCacheMetrics(self): self.assertEqual(self.getMetric('responses'), responsesBefore + 2) self.assertEqual(self.getMetric('cache-hits'), cacheHitsBefore + 1) self.assertEqual(self.getMetric('cache-misses'), cacheMissesBefore + 1) + self.assertEqual(self.getPoolMetric('cache', 'cacheHits'), poolCacheHitsBefore + 1) + self.assertEqual(self.getPoolMetric('cache', 'cacheMisses'), poolCacheMissesBefore + 1) def testServFailMetrics(self): """ From 264980313c5edcdc062bb159c757444b95168a9c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 4 May 2023 10:32:09 +0200 Subject: [PATCH 132/909] ci: Add a separate check for clang-tidy failure This way the tests are still run even if clang-tidy reported a warning, instead of stopping everything. --- .github/workflows/build-and-test-all.yml | 26 ++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index bad2c65e62e8..4946006ca26b 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -21,6 +21,8 @@ jobs: SANITIZERS: asan+ubsan UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" UNIT_TESTS: yes + outputs: + clang-tidy-auth-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 @@ -57,11 +59,14 @@ jobs: cat clang-tidy-auth.yml fi - name: Result annotations + id: clang-tidy-annotations shell: bash working-directory: pdns run: | if [ -f clang-tidy-auth.yml ]; then + set +e python3 ../.github/scripts/clang-tidy.py --fixes-file clang-tidy-auth.yml + echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-auth-install-remotebackend-test-deps - run: inv ci-auth-run-unit-tests @@ -89,6 +94,8 @@ jobs: defaults: run: working-directory: ./pdns/recursordist/ + outputs: + clang-tidy-recursor-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 @@ -124,10 +131,13 @@ jobs: cat clang-tidy-rec.yml fi - name: Result annotations + id: clang-tidy-annotations shell: bash run: | if [ -f clang-tidy-rec.yml ]; then + set +e python ../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-rec.yml + echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-rec-run-unit-tests - run: inv ci-make-install @@ -158,6 +168,8 @@ jobs: defaults: run: working-directory: ./pdns/dnsdistdist/ + outputs: + clang-tidy-dnsdist-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 @@ -193,10 +205,13 @@ jobs: cat clang-tidy-dnsdist.yml fi - name: Result annotations + id: clang-tidy-annotations shell: bash run: | if [ -f clang-tidy-dnsdist.yml ]; then + set +e python ../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-dnsdist.yml + echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-dnsdist-run-unit-tests - run: inv ci-make-install @@ -517,6 +532,16 @@ jobs: - run: inv install-swagger-tools - run: inv swagger-syntax-check + check-clang-tidy: + needs: [build-auth, build-dnsdist, build-recursor] + runs-on: ubuntu-20.04 + name: Check whether clang-tidy succeeded + steps: + - run: | + if [ ${{ needs.build-auth.outputs.clang-tidy-auth-failed }} != 0 -o ${{ needs.build-dnsdist.outputs.clang-tidy-dnsdist-failed }} != 0 -o ${{ needs.build-recursor.outputs.clang-tidy-recursor-failed }} != 0 ]; then + exit 1 + fi + collect: needs: - build-auth @@ -530,6 +555,7 @@ jobs: - test-recursor-api - test-recursor-regression - test-recursor-bulk + - check-clang-tidy if: success() || failure() runs-on: ubuntu-20.04 steps: From 27f5ff7d0d68f09eba892fe5379ddfb6788d7acd Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 4 May 2023 12:07:20 +0200 Subject: [PATCH 133/909] bump secpoll serial, adjust release date --- docs/changelog/4.8.rst | 2 +- docs/secpoll.zone | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelog/4.8.rst b/docs/changelog/4.8.rst index 18943912106a..7cca29733864 100644 --- a/docs/changelog/4.8.rst +++ b/docs/changelog/4.8.rst @@ -3,7 +3,7 @@ Changelogs for 4.8.x .. changelog:: :version: 4.8.0-beta1 - :released: 3rd of May 2023 + :released: 4th of May 2023 This is release 4.8.0-beta1 of the Authoritative Server. diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 444c48830aae..470b39aa16a0 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023050300 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023050402 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. From 5069e089f01faf60c41e9695be42d72fec06a94d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 4 May 2023 16:38:53 +0200 Subject: [PATCH 134/909] clang-tidy: Increase the code complexity threshold to 100 for now --- .clang-tidy.full | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index 7f1aae9c4613..d27618a002f1 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -405,7 +405,7 @@ CheckOptions: - key: modernize-use-noexcept.UseNoexceptFalse value: 'true' - key: readability-function-cognitive-complexity.Threshold - value: '25' + value: '100' - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic value: 'true' - key: bugprone-argument-comment.IgnoreSingleArgument From f5467372f2459829df31a0587757e5d08db3d9f2 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 5 May 2023 11:08:48 +0200 Subject: [PATCH 135/909] clang-tidy: Lower the code complexity threshold to 50 Let's see how it goes. --- .clang-tidy.full | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index d27618a002f1..43754f59838a 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -405,7 +405,7 @@ CheckOptions: - key: modernize-use-noexcept.UseNoexceptFalse value: 'true' - key: readability-function-cognitive-complexity.Threshold - value: '100' + value: '50' - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic value: 'true' - key: bugprone-argument-comment.IgnoreSingleArgument From 86035484ba1a4004686851109eacd7ed83a12173 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 8 May 2023 08:58:45 +0200 Subject: [PATCH 136/909] serviceMain: fix all lints except complexity --- pdns/recursordist/rec-main.cc | 124 +++++++++++++++++----------------- 1 file changed, 63 insertions(+), 61 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 36401172383a..b288a7cf47bf 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1362,7 +1362,7 @@ template ThreadTimes broadcastAccFunction(const std::function& f template ProxyMappingStats_t broadcastAccFunction(const std::function& fun); template RemoteLoggerStats_t broadcastAccFunction(const std::function& fun); -static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) +static int serviceMain(Logr::log_t log) { g_log.setName(g_programname); g_log.disableSyslog(::arg().mustDo("disable-syslog")); @@ -1371,9 +1371,9 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) if (!::arg()["logging-facility"].empty()) { int val = logFacilityToLOG(::arg().asNum("logging-facility")); - if (val >= 0) + if (val >= 0) { g_log.setFacility(val); - else { + } else { SLOG(g_log << Logger::Error << "Unknown logging facility " << ::arg().asNum("logging-facility") << endl, log->info(Logr::Error, "Unknown logging facility", "facility", Logging::Loggable(::arg().asNum("logging-facility")))); } @@ -1390,7 +1390,7 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) catch (std::exception& e) { SLOG(g_log << Logger::Error << "Assigning local query addresses: " << e.what(), log->error(Logr::Error, e.what(), "Unable to assign local query address")); - exit(99); + return 99; } if (pdns::isQueryLocalAddressFamilyEnabled(AF_INET)) { @@ -1416,31 +1416,31 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) if (!SyncRes::s_doIPv6 && !SyncRes::s_doIPv4) { SLOG(g_log << Logger::Error << "No outgoing addresses configured! Can not continue" << endl, log->info(Logr::Error, "No outgoing addresses configured! Can not continue")); - exit(99); + return 99; } // keep this ABOVE loadRecursorLuaConfig! - if (::arg()["dnssec"] == "off") + if (::arg()["dnssec"] == "off") { g_dnssecmode = DNSSECMode::Off; - else if (::arg()["dnssec"] == "process-no-validate") + } else if (::arg()["dnssec"] == "process-no-validate") { g_dnssecmode = DNSSECMode::ProcessNoValidate; - else if (::arg()["dnssec"] == "process") + } else if (::arg()["dnssec"] == "process") { g_dnssecmode = DNSSECMode::Process; - else if (::arg()["dnssec"] == "validate") + } else if (::arg()["dnssec"] == "validate") { g_dnssecmode = DNSSECMode::ValidateAll; - else if (::arg()["dnssec"] == "log-fail") + } else if (::arg()["dnssec"] == "log-fail {") { g_dnssecmode = DNSSECMode::ValidateForLog; - else { + } else { SLOG(g_log << Logger::Error << "Unknown DNSSEC mode " << ::arg()["dnssec"] << endl, log->info(Logr::Error, "Unknown DNSSEC mode", "dnssec", Logging::Loggable(::arg()["dnssec"]))); - exit(1); + return 1; } g_signatureInceptionSkew = ::arg().asNum("signature-inception-skew"); if (g_signatureInceptionSkew < 0) { SLOG(g_log << Logger::Error << "A negative value for 'signature-inception-skew' is not allowed" << endl, log->info(Logr::Error, "A negative value for 'signature-inception-skew' is not allowed")); - exit(1); + return 1; } g_dnssecLogBogus = ::arg().mustDo("dnssec-log-bogus"); @@ -1458,7 +1458,7 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) catch (PDNSException& e) { SLOG(g_log << Logger::Error << "Cannot load Lua configuration: " << e.reason << endl, log->error(Logr::Error, e.reason, "Cannot load Lua configuration")); - exit(1); + return 1; } parseACLs(); @@ -1467,17 +1467,18 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) if (!::arg()["dont-query"].empty()) { vector ips; stringtok(ips, ::arg()["dont-query"], ", "); - ips.push_back("0.0.0.0"); - ips.push_back("::"); + ips.emplace_back("0.0.0.0"); + ips.emplace_back("::"); - for (const auto& ip : ips) { - SyncRes::addDontQuery(ip); + for (const auto& anIP : ips) { + SyncRes::addDontQuery(anIP); } if (!g_slogStructured) { g_log << Logger::Warning << "Will not send queries to: "; - for (vector::const_iterator i = ips.begin(); i != ips.end(); ++i) { - if (i != ips.begin()) + for (auto i = ips.begin(); i != ips.end(); ++i) { + if (i != ips.begin()) { g_log << Logger::Warning << ", "; + } g_log << Logger::Warning << *i; } g_log << Logger::Warning << endl; @@ -1547,7 +1548,7 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) if (sse > std::numeric_limits::max()) { SLOG(g_log << Logger::Error << "Illegal serve-stale-extensions value: " << sse << "; range = 0..65536" << endl, log->info(Logr::Error, "Illegal serve-stale-extensions value; range = 0..65536", "value", Logging::Loggable(sse))); - exit(1); + return 1; } MemRecursorCache::s_maxServedStaleExtensions = sse; NegCache::s_maxServedStaleExtensions = sse; @@ -1590,7 +1591,7 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) else if (value != "dnssec") { SLOG(g_log << Logger::Error << "Unknown nothing-below-nxdomain mode: " << value << endl, log->info(Logr::Error, "Unknown nothing-below-nxdomain mode", "mode", Logging::Loggable(value))); - exit(1); + return 1; } if (!::arg().isEmpty("ecs-scope-zero-address")) { @@ -1598,25 +1599,25 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) SyncRes::setECSScopeZeroAddress(Netmask(scopeZero, scopeZero.isIPv4() ? 32 : 128)); } else { - Netmask nm; + Netmask netmask; bool done = false; auto addr = pdns::getNonAnyQueryLocalAddress(AF_INET); - if (addr.sin4.sin_family != 0) { - nm = Netmask(addr, 32); + if (addr.sin4.sin_family != 0) { // NOLINT: union access + netmask = Netmask(addr, 32); done = true; } if (!done) { addr = pdns::getNonAnyQueryLocalAddress(AF_INET6); - if (addr.sin4.sin_family != 0) { - nm = Netmask(addr, 128); + if (addr.sin4.sin_family != 0) { // NOLINT: union access + netmask = Netmask(addr, 128); done = true; } } if (!done) { - nm = Netmask(ComboAddress("127.0.0.1"), 32); + netmask = Netmask(ComboAddress("127.0.0.1"), 32); } - SyncRes::setECSScopeZeroAddress(nm); + SyncRes::setECSScopeZeroAddress(netmask); } SyncRes::parseEDNSSubnetAllowlist(::arg()["edns-subnet-whitelist"]); @@ -1633,7 +1634,7 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) if (dns64Prefix.getBits() != 96) { SLOG(g_log << Logger::Error << "Invalid prefix for 'dns64-prefix', the current implementation only supports /96 prefixes: " << ::arg()["dns64-prefix"] << endl, log->info(Logr::Error, "Invalid prefix for 'dns64-prefix', the current implementation only supports /96 prefixes", "prefix", Logging::Loggable(::arg()["dns64-prefix"]))); - exit(1); + return 1; } g_dns64Prefix = dns64Prefix.getNetwork(); g_dns64PrefixReverse = reverseNameFromIP(*g_dns64Prefix); @@ -1645,7 +1646,7 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) catch (const NetmaskException& ne) { SLOG(g_log << Logger::Error << "Invalid prefix '" << ::arg()["dns64-prefix"] << "' for 'dns64-prefix': " << ne.reason << endl, log->info(Logr::Error, "Invalid prefix", "dns64-prefix", Logging::Loggable(::arg()["dns64-prefix"]))); - exit(1); + return 1; } } @@ -1673,7 +1674,7 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) else { SLOG(g_log << Logger::Error << "Unknown edns-padding-mode: " << ::arg()["edns-padding-mode"] << endl, log->info(Logr::Error, "Unknown edns-padding-mode", "edns-padding-mode", Logging::Loggable(::arg()["edns-padding-mode"]))); - exit(1); + return 1; } g_paddingTag = ::arg().asNum("edns-padding-tag"); g_paddingOutgoing = ::arg().mustDo("edns-padding-out"); @@ -1728,16 +1729,16 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) SuffixMatchNode dontThrottleNames; vector parts; stringtok(parts, ::arg()["dont-throttle-names"], " ,"); - for (const auto& p : parts) { - dontThrottleNames.add(DNSName(p)); + for (const auto& part : parts) { + dontThrottleNames.add(DNSName(part)); } g_dontThrottleNames.setState(std::move(dontThrottleNames)); parts.clear(); NetmaskGroup dontThrottleNetmasks; stringtok(parts, ::arg()["dont-throttle-netmasks"], " ,"); - for (const auto& p : parts) { - dontThrottleNetmasks.addMask(Netmask(p)); + for (const auto& part : parts) { + dontThrottleNetmasks.addMask(Netmask(part)); } g_dontThrottleNetmasks.setState(std::move(dontThrottleNetmasks)); } @@ -1746,8 +1747,8 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) SuffixMatchNode xdnssecNames; vector parts; stringtok(parts, ::arg()["x-dnssec-names"], " ,"); - for (const auto& p : parts) { - xdnssecNames.add(DNSName(p)); + for (const auto& part : parts) { + xdnssecNames.add(DNSName(part)); } g_xdnssec.setState(std::move(xdnssecNames)); } @@ -1762,8 +1763,8 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) log->info(Logr::Error, "dot-to-auth-names setting contains names, but Recursor was built without DNS over TLS support. Setting will be ignored")); } #endif - for (const auto& p : parts) { - dotauthNames.add(DNSName(p)); + for (const auto& part : parts) { + dotauthNames.add(DNSName(part)); } g_DoTToAuthNames.setState(std::move(dotauthNames)); } @@ -1840,9 +1841,9 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) setupNODGlobal(); #endif /* NOD_ENABLED */ - int forks; - for (forks = 0; forks < ::arg().asNum("processes") - 1; ++forks) { - if (!fork()) // we are child + int forks = 0; + for (; forks < ::arg().asNum("processes") - 1; ++forks) { + if (fork() == 0) // we are child break; } @@ -1872,7 +1873,7 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) signal(SIGUSR1, usr1Handler); signal(SIGUSR2, usr2Handler); - signal(SIGPIPE, SIG_IGN); + signal(SIGPIPE, SIG_IGN); // NOLINT: Posix API checkOrFixFDS(log); @@ -1880,7 +1881,7 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) if (sodium_init() == -1) { SLOG(g_log << Logger::Error << "Unable to initialize sodium crypto library" << endl, log->info(Logr::Error, "Unable to initialize sodium crypto library")); - exit(99); + return 99; } #endif @@ -1893,12 +1894,14 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) ::arg().set("server-id") = myHostname.has_value() ? *myHostname : ""; } - int newgid = 0; - if (!::arg()["setgid"].empty()) + gid_t newgid = 0; + if (!::arg()["setgid"].empty()) { newgid = strToGID(::arg()["setgid"]); - int newuid = 0; - if (!::arg()["setuid"].empty()) + } + uid_t newuid = 0; + if (!::arg()["setuid"].empty()) { newuid = strToUID(::arg()["setuid"]); + } Utility::dropGroupPrivs(newuid, newgid); @@ -1909,26 +1912,25 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) if (ns != nullptr) { SLOG(g_log << Logger::Error << "Unable to chroot when running from systemd. Please disable chroot= or set the 'Type' for this service to 'simple'" << endl, log->info(Logr::Error, "Unable to chroot when running from systemd. Please disable chroot= or set the 'Type' for this service to 'simple'")); - exit(1); + return 1; } #endif if (chroot(::arg()["chroot"].c_str()) < 0 || chdir("/") < 0) { int err = errno; - SLOG(g_log << Logger::Error << "Unable to chroot to '" + ::arg()["chroot"] + "': " << strerror(err) << ", exiting" << endl, + SLOG(g_log << Logger::Error << "Unable to chroot to '" + ::arg()["chroot"] + "': " << stringerror(err) << ", exiting" << endl, log->error(Logr::Error, err, "Unable to chroot", "chroot", Logging::Loggable(::arg()["chroot"]))); - exit(1); - } - else { - SLOG(g_log << Logger::Info << "Chrooted to '" << ::arg()["chroot"] << "'" << endl, - log->info(Logr::Info, "Chrooted", "chroot", Logging::Loggable(::arg()["chroot"]))); + return 1; } + SLOG(g_log << Logger::Info << "Chrooted to '" << ::arg()["chroot"] << "'" << endl, + log->info(Logr::Info, "Chrooted", "chroot", Logging::Loggable(::arg()["chroot"]))); } checkSocketDir(log); g_pidfname = ::arg()["socket-dir"] + "/" + g_programname + ".pid"; - if (!g_pidfname.empty()) + if (!g_pidfname.empty()) { unlink(g_pidfname.c_str()); // remove possible old pid file + } writePid(log); makeControlChannelSocket(::arg().asNum("processes") > 1 ? forks : -1); @@ -1990,14 +1992,14 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) if (port < 1024 || port > 65535) { SLOG(g_log << Logger::Error << "Unable to launch, udp-source-port-min is not a valid port number" << endl, log->info(Logr::Error, "Unable to launch, udp-source-port-min is not a valid port number")); - exit(99); // this isn't going to fix itself either + return 99; // this isn't going to fix itself either } g_minUdpSourcePort = port; port = ::arg().asNum("udp-source-port-max"); if (port < 1024 || port > 65535 || port < g_minUdpSourcePort) { SLOG(g_log << Logger::Error << "Unable to launch, udp-source-port-max is not a valid port number or is smaller than udp-source-port-min" << endl, log->info(Logr::Error, "Unable to launch, udp-source-port-max is not a valid port number or is smaller than udp-source-port-min")); - exit(99); // this isn't going to fix itself either + return 99; // this isn't going to fix itself either } g_maxUdpSourcePort = port; std::vector parts{}; @@ -2007,7 +2009,7 @@ static int serviceMain(int /* argc */, char* /* argv */[], Logr::log_t log) if (port < 1024 || port > 65535) { SLOG(g_log << Logger::Error << "Unable to launch, udp-source-port-avoid contains an invalid port number: " << part << endl, log->info(Logr::Error, "Unable to launch, udp-source-port-avoid contains an invalid port number", "port", Logging::Loggable(part))); - exit(99); // this isn't going to fix itself either + return 99; // this isn't going to fix itself either } g_avoidUdpSourcePorts.insert(port); } @@ -3044,7 +3046,7 @@ int main(int argc, char** argv) g_packetCache = std::make_unique(g_maxPacketCacheEntries, ::arg().asNum("packetcache-shards")); } - ret = serviceMain(argc, argv, startupLog); + ret = serviceMain(startupLog); } catch (const PDNSException& ae) { SLOG(g_log << Logger::Error << "Exception: " << ae.reason << endl, From 63189aaf3421a79cb1507a49f12d36944be1b08f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 8 May 2023 09:51:19 +0200 Subject: [PATCH 137/909] Split serviceMain() to reduce cognitive complexity --- pdns/recursordist/rec-main.cc | 648 +++++++++++++++++++--------------- 1 file changed, 364 insertions(+), 284 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index b288a7cf47bf..dff35ea1a518 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1362,27 +1362,8 @@ template ThreadTimes broadcastAccFunction(const std::function& f template ProxyMappingStats_t broadcastAccFunction(const std::function& fun); template RemoteLoggerStats_t broadcastAccFunction(const std::function& fun); -static int serviceMain(Logr::log_t log) +static int initNet(Logr::log_t log) { - g_log.setName(g_programname); - g_log.disableSyslog(::arg().mustDo("disable-syslog")); - g_log.setTimestamps(::arg().mustDo("log-timestamp")); - g_regressionTestMode = ::arg().mustDo("devonly-regression-test-mode"); - - if (!::arg()["logging-facility"].empty()) { - int val = logFacilityToLOG(::arg().asNum("logging-facility")); - if (val >= 0) { - g_log.setFacility(val); - } else { - SLOG(g_log << Logger::Error << "Unknown logging facility " << ::arg().asNum("logging-facility") << endl, - log->info(Logr::Error, "Unknown logging facility", "facility", Logging::Loggable(::arg().asNum("logging-facility")))); - } - } - - showProductVersion(); - - g_disthashseed = dns_random(0xffffffff); - checkLinuxIPv6Limits(log); try { pdns::parseQueryLocalAddress(::arg()["query-local-address"]); @@ -1418,8 +1399,11 @@ static int serviceMain(Logr::log_t log) log->info(Logr::Error, "No outgoing addresses configured! Can not continue")); return 99; } + return 0; +} - // keep this ABOVE loadRecursorLuaConfig! +static int initDNSSEC(Logr::log_t log) +{ if (::arg()["dnssec"] == "off") { g_dnssecmode = DNSSECMode::Off; } else if (::arg()["dnssec"] == "process-no-validate") { @@ -1445,25 +1429,11 @@ static int serviceMain(Logr::log_t log) g_dnssecLogBogus = ::arg().mustDo("dnssec-log-bogus"); g_maxNSEC3Iterations = ::arg().asNum("nsec3-max-iterations"); + return 0; +} - g_maxCacheEntries = ::arg().asNum("max-cache-entries"); - - luaConfigDelayedThreads delayedLuaThreads; - try { - ProxyMapping proxyMapping; - loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads, proxyMapping); - // Initial proxy mapping - g_proxyMapping = proxyMapping.empty() ? nullptr : std::make_unique(proxyMapping); - } - catch (PDNSException& e) { - SLOG(g_log << Logger::Error << "Cannot load Lua configuration: " << e.reason << endl, - log->error(Logr::Error, e.reason, "Cannot load Lua configuration")); - return 1; - } - - parseACLs(); - initPublicSuffixList(::arg()["public-suffix-list-file"]); - +static void initDontQuery(Logr::log_t log) +{ if (!::arg()["dont-query"].empty()) { vector ips; stringtok(ips, ::arg()["dont-query"], ", "); @@ -1487,30 +1457,10 @@ static int serviceMain(Logr::log_t log) log->info(Logr::Notice, "Will not send queries to", "addresses", Logging::IterLoggable(ips.begin(), ips.end())); } } +} - /* this needs to be done before parseACLs(), which call broadcastFunction() */ - RecThreadInfo::setWeDistributeQueries(::arg().mustDo("pdns-distributes-queries")); - if (RecThreadInfo::weDistributeQueries()) { - SLOG(g_log << Logger::Warning << "PowerDNS Recursor itself will distribute queries over threads" << endl, - log->info(Logr::Notice, "PowerDNS Recursor itself will distribute queries over threads")); - } - - g_outgoingEDNSBufsize = ::arg().asNum("edns-outgoing-bufsize"); - - if (::arg()["trace"] == "fail") { - SyncRes::setDefaultLogMode(SyncRes::Store); - } - else if (::arg().mustDo("trace")) { - SyncRes::setDefaultLogMode(SyncRes::Log); - ::arg().set("quiet") = "no"; - g_quiet = false; - } - auto myHostname = getHostname(); - if (!myHostname.has_value()) { - SLOG(g_log << Logger::Warning << "Unable to get the hostname, NSID and id.server values will be empty" << endl, - log->info(Logr::Warning, "Unable to get the hostname, NSID and id.server values will be empty")); - } - +static int initSyncRes(Logr::log_t log, const std::optional& myHostname) +{ SyncRes::s_minimumTTL = ::arg().asNum("minimum-ttl-override"); SyncRes::s_minimumECSTTL = ::arg().asNum("ecs-minimum-ttl-override"); SyncRes::s_maxnegttl = ::arg().asNum("max-negative-ttl"); @@ -1624,160 +1574,11 @@ static int serviceMain(Logr::log_t log) SyncRes::parseEDNSSubnetAllowlist(::arg()["edns-subnet-allow-list"]); SyncRes::parseEDNSSubnetAddFor(::arg()["ecs-add-for"]); g_useIncomingECS = ::arg().mustDo("use-incoming-edns-subnet"); + return 0; +} - g_proxyProtocolACL.toMasks(::arg()["proxy-protocol-from"]); - g_proxyProtocolMaximumSize = ::arg().asNum("proxy-protocol-maximum-size"); - - if (!::arg()["dns64-prefix"].empty()) { - try { - auto dns64Prefix = Netmask(::arg()["dns64-prefix"]); - if (dns64Prefix.getBits() != 96) { - SLOG(g_log << Logger::Error << "Invalid prefix for 'dns64-prefix', the current implementation only supports /96 prefixes: " << ::arg()["dns64-prefix"] << endl, - log->info(Logr::Error, "Invalid prefix for 'dns64-prefix', the current implementation only supports /96 prefixes", "prefix", Logging::Loggable(::arg()["dns64-prefix"]))); - return 1; - } - g_dns64Prefix = dns64Prefix.getNetwork(); - g_dns64PrefixReverse = reverseNameFromIP(*g_dns64Prefix); - /* /96 is 24 nibbles + 2 for "ip6.arpa." */ - while (g_dns64PrefixReverse.countLabels() > 26) { - g_dns64PrefixReverse.chopOff(); - } - } - catch (const NetmaskException& ne) { - SLOG(g_log << Logger::Error << "Invalid prefix '" << ::arg()["dns64-prefix"] << "' for 'dns64-prefix': " << ne.reason << endl, - log->info(Logr::Error, "Invalid prefix", "dns64-prefix", Logging::Loggable(::arg()["dns64-prefix"]))); - return 1; - } - } - - g_networkTimeoutMsec = ::arg().asNum("network-timeout"); - - std::tie(g_initialDomainMap, g_initialAllowNotifyFor) = parseZoneConfiguration(); - - g_latencyStatSize = ::arg().asNum("latency-statistic-size"); - - g_logCommonErrors = ::arg().mustDo("log-common-errors"); - g_logRPZChanges = ::arg().mustDo("log-rpz-changes"); - - g_anyToTcp = ::arg().mustDo("any-to-tcp"); - g_udpTruncationThreshold = ::arg().asNum("udp-truncation-threshold"); - - g_lowercaseOutgoing = ::arg().mustDo("lowercase-outgoing"); - - g_paddingFrom.toMasks(::arg()["edns-padding-from"]); - if (::arg()["edns-padding-mode"] == "always") { - g_paddingMode = PaddingMode::Always; - } - else if (::arg()["edns-padding-mode"] == "padded-queries-only") { - g_paddingMode = PaddingMode::PaddedQueries; - } - else { - SLOG(g_log << Logger::Error << "Unknown edns-padding-mode: " << ::arg()["edns-padding-mode"] << endl, - log->info(Logr::Error, "Unknown edns-padding-mode", "edns-padding-mode", Logging::Loggable(::arg()["edns-padding-mode"]))); - return 1; - } - g_paddingTag = ::arg().asNum("edns-padding-tag"); - g_paddingOutgoing = ::arg().mustDo("edns-padding-out"); - - RecThreadInfo::setNumDistributorThreads(::arg().asNum("distributor-threads")); - RecThreadInfo::setNumWorkerThreads(::arg().asNum("threads")); - if (RecThreadInfo::numWorkers() < 1) { - SLOG(g_log << Logger::Warning << "Asked to run with 0 threads, raising to 1 instead" << endl, - log->info(Logr::Warning, "Asked to run with 0 threads, raising to 1 instead")); - RecThreadInfo::setNumWorkerThreads(1); - } - - g_maxMThreads = ::arg().asNum("max-mthreads"); - - int64_t maxInFlight = ::arg().asNum("max-concurrent-requests-per-tcp-connection"); - if (maxInFlight < 1 || maxInFlight > USHRT_MAX || maxInFlight >= g_maxMThreads) { - SLOG(g_log << Logger::Warning << "Asked to run with illegal max-concurrent-requests-per-tcp-connection, setting to default (10)" << endl, - log->info(Logr::Warning, "Asked to run with illegal max-concurrent-requests-per-tcp-connection, setting to default (10)")); - TCPConnection::s_maxInFlight = 10; - } - else { - TCPConnection::s_maxInFlight = maxInFlight; - } - - int64_t millis = ::arg().asNum("tcp-out-max-idle-ms"); - TCPOutConnectionManager::s_maxIdleTime = timeval{millis / 1000, (static_cast(millis) % 1000) * 1000}; - TCPOutConnectionManager::s_maxIdlePerAuth = ::arg().asNum("tcp-out-max-idle-per-auth"); - TCPOutConnectionManager::s_maxQueries = ::arg().asNum("tcp-out-max-queries"); - TCPOutConnectionManager::s_maxIdlePerThread = ::arg().asNum("tcp-out-max-idle-per-thread"); - - g_gettagNeedsEDNSOptions = ::arg().mustDo("gettag-needs-edns-options"); - - s_statisticsInterval = ::arg().asNum("statistics-interval"); - - SyncRes::s_addExtendedResolutionDNSErrors = ::arg().mustDo("extended-resolution-errors"); - - if (::arg().asNum("aggressive-nsec-cache-size") > 0) { - if (g_dnssecmode == DNSSECMode::ValidateAll || g_dnssecmode == DNSSECMode::ValidateForLog || g_dnssecmode == DNSSECMode::Process) { - g_aggressiveNSECCache = make_unique(::arg().asNum("aggressive-nsec-cache-size")); - } - else { - SLOG(g_log << Logger::Warning << "Aggressive NSEC/NSEC3 caching is enabled but DNSSEC validation is not set to 'validate', 'log-fail' or 'process', ignoring" << endl, - log->info(Logr::Warning, "Aggressive NSEC/NSEC3 caching is enabled but DNSSEC validation is not set to 'validate', 'log-fail' or 'process', ignoring")); - } - } - - AggressiveNSECCache::s_maxNSEC3CommonPrefix = static_cast(std::round(std::log2(::arg().asNum("aggressive-cache-min-nsec3-hit-ratio")))); - SLOG(g_log << Logger::Debug << "NSEC3 aggressive cache tuning: aggressive-cache-min-nsec3-hit-ratio: " << ::arg().asNum("aggressive-cache-min-nsec3-hit-ratio") << " max common prefix bits: " << std::to_string(AggressiveNSECCache::s_maxNSEC3CommonPrefix) << endl, - log->info(Logr::Debug, "NSEC3 aggressive cache tuning", "aggressive-cache-min-nsec3-hit-ratio", Logging::Loggable(::arg().asNum("aggressive-cache-min-nsec3-hit-ratio")), "maxCommonPrefixBits", Logging::Loggable(AggressiveNSECCache::s_maxNSEC3CommonPrefix))); - - { - SuffixMatchNode dontThrottleNames; - vector parts; - stringtok(parts, ::arg()["dont-throttle-names"], " ,"); - for (const auto& part : parts) { - dontThrottleNames.add(DNSName(part)); - } - g_dontThrottleNames.setState(std::move(dontThrottleNames)); - - parts.clear(); - NetmaskGroup dontThrottleNetmasks; - stringtok(parts, ::arg()["dont-throttle-netmasks"], " ,"); - for (const auto& part : parts) { - dontThrottleNetmasks.addMask(Netmask(part)); - } - g_dontThrottleNetmasks.setState(std::move(dontThrottleNetmasks)); - } - - { - SuffixMatchNode xdnssecNames; - vector parts; - stringtok(parts, ::arg()["x-dnssec-names"], " ,"); - for (const auto& part : parts) { - xdnssecNames.add(DNSName(part)); - } - g_xdnssec.setState(std::move(xdnssecNames)); - } - - { - SuffixMatchNode dotauthNames; - vector parts; - stringtok(parts, ::arg()["dot-to-auth-names"], " ,"); -#ifndef HAVE_DNS_OVER_TLS - if (parts.size()) { - SLOG(g_log << Logger::Error << "dot-to-auth-names setting contains names, but Recursor was built without DNS over TLS support. Setting will be ignored." << endl, - log->info(Logr::Error, "dot-to-auth-names setting contains names, but Recursor was built without DNS over TLS support. Setting will be ignored")); - } -#endif - for (const auto& part : parts) { - dotauthNames.add(DNSName(part)); - } - g_DoTToAuthNames.setState(std::move(dotauthNames)); - } - - { - CarbonConfig config; - stringtok(config.servers, arg()["carbon-server"], ", "); - config.hostname = arg()["carbon-ourname"]; - config.instance_name = arg()["carbon-instance"]; - config.namespace_name = arg()["carbon-namespace"]; - g_carbonConfig.setState(std::move(config)); - } - +static void initDistribution(Logr::log_t log) +{ g_balancingFactor = ::arg().asDouble("distribution-load-factor"); if (g_balancingFactor != 0.0 && g_balancingFactor < 1.0) { g_balancingFactor = 0.0; @@ -1835,16 +1636,15 @@ static int serviceMain(Logr::log_t log) } } } +} -#ifdef NOD_ENABLED - // Setup newly observed domain globals - setupNODGlobal(); -#endif /* NOD_ENABLED */ - +static int initForks(Logr::log_t log) +{ int forks = 0; for (; forks < ::arg().asNum("processes") - 1; ++forks) { - if (fork() == 0) // we are child + if (fork() == 0) { // we are child break; + } } if (::arg().mustDo("daemon")) { @@ -1853,6 +1653,7 @@ static int serviceMain(Logr::log_t log) g_log.toConsole(Logger::Critical); daemonize(log); } + if (Utility::getpid() == 1) { /* We are running as pid 1, register sigterm and sigint handler @@ -1874,37 +1675,59 @@ static int serviceMain(Logr::log_t log) signal(SIGUSR1, usr1Handler); signal(SIGUSR2, usr2Handler); signal(SIGPIPE, SIG_IGN); // NOLINT: Posix API + return forks; +} - checkOrFixFDS(log); - -#ifdef HAVE_LIBSODIUM - if (sodium_init() == -1) { - SLOG(g_log << Logger::Error << "Unable to initialize sodium crypto library" << endl, - log->info(Logr::Error, "Unable to initialize sodium crypto library")); - return 99; +static int initPorts(Logr::log_t log) +{ + int port = ::arg().asNum("udp-source-port-min"); + if (port < 1024 || port > 65535) { + SLOG(g_log << Logger::Error << "Unable to launch, udp-source-port-min is not a valid port number" << endl, + log->info(Logr::Error, "Unable to launch, udp-source-port-min is not a valid port number")); + return 99; // this isn't going to fix itself either } -#endif - - openssl_thread_setup(); - openssl_seed(); - /* setup rng before chroot */ - dns_random_init(); - - if (::arg()["server-id"].empty()) { - ::arg().set("server-id") = myHostname.has_value() ? *myHostname : ""; + g_minUdpSourcePort = port; + port = ::arg().asNum("udp-source-port-max"); + if (port < 1024 || port > 65535 || port < g_minUdpSourcePort) { + SLOG(g_log << Logger::Error << "Unable to launch, udp-source-port-max is not a valid port number or is smaller than udp-source-port-min" << endl, + log->info(Logr::Error, "Unable to launch, udp-source-port-max is not a valid port number or is smaller than udp-source-port-min")); + return 99; // this isn't going to fix itself either } - - gid_t newgid = 0; - if (!::arg()["setgid"].empty()) { - newgid = strToGID(::arg()["setgid"]); - } - uid_t newuid = 0; - if (!::arg()["setuid"].empty()) { - newuid = strToUID(::arg()["setuid"]); + g_maxUdpSourcePort = port; + std::vector parts{}; + stringtok(parts, ::arg()["udp-source-port-avoid"], ", "); + for (const auto& part : parts) { + port = std::stoi(part); + if (port < 1024 || port > 65535) { + SLOG(g_log << Logger::Error << "Unable to launch, udp-source-port-avoid contains an invalid port number: " << part << endl, + log->info(Logr::Error, "Unable to launch, udp-source-port-avoid contains an invalid port number", "port", Logging::Loggable(part))); + return 99; // this isn't going to fix itself either + } + g_avoidUdpSourcePorts.insert(port); } + return 0; +} - Utility::dropGroupPrivs(newuid, newgid); +static void initSNMP([[maybe_unused]] Logr::log_t log) +{ + if (::arg().mustDo("snmp-agent")) { +#ifdef HAVE_NET_SNMP + string setting = ::arg()["snmp-daemon-socket"]; + if (setting.empty()) { + setting = ::arg()["snmp-master-socket"]; + } + g_snmpAgent = std::make_shared("recursor", setting); + g_snmpAgent->run(); +#else + const std::string msg = "snmp-agent set but SNMP support not compiled in"; + SLOG(g_log << Logger::Error << msg << endl, + log->info(Logr::Error, msg)); +#endif // HAVE_NET_SNMP + } +} +static int initControl(Logr::log_t log, uid_t newuid, int forks) // NOLINT(bugprone-easily-swappable-parameter*) +{ if (!::arg()["chroot"].empty()) { #ifdef HAVE_SYSTEMD char* ns; @@ -1947,6 +1770,297 @@ static int serviceMain(Logr::log_t log) SLOG(g_log << Logger::Warning << e.what() << endl, log->error(Logr::Warning, e.what(), "Could not drop capabilities")); } + return 0; +} + +static void initSuffixMatchNodes() +{ + { + SuffixMatchNode dontThrottleNames; + vector parts; + stringtok(parts, ::arg()["dont-throttle-names"], " ,"); + for (const auto& part : parts) { + dontThrottleNames.add(DNSName(part)); + } + g_dontThrottleNames.setState(std::move(dontThrottleNames)); + + parts.clear(); + NetmaskGroup dontThrottleNetmasks; + stringtok(parts, ::arg()["dont-throttle-netmasks"], " ,"); + for (const auto& part : parts) { + dontThrottleNetmasks.addMask(Netmask(part)); + } + g_dontThrottleNetmasks.setState(std::move(dontThrottleNetmasks)); + } + + { + SuffixMatchNode xdnssecNames; + vector parts; + stringtok(parts, ::arg()["x-dnssec-names"], " ,"); + for (const auto& part : parts) { + xdnssecNames.add(DNSName(part)); + } + g_xdnssec.setState(std::move(xdnssecNames)); + } + + { + SuffixMatchNode dotauthNames; + vector parts; + stringtok(parts, ::arg()["dot-to-auth-names"], " ,"); +#ifndef HAVE_DNS_OVER_TLS + if (parts.size()) { + SLOG(g_log << Logger::Error << "dot-to-auth-names setting contains names, but Recursor was built without DNS over TLS support. Setting will be ignored." << endl, + log->info(Logr::Error, "dot-to-auth-names setting contains names, but Recursor was built without DNS over TLS support. Setting will be ignored")); + } +#endif + for (const auto& part : parts) { + dotauthNames.add(DNSName(part)); + } + g_DoTToAuthNames.setState(std::move(dotauthNames)); + } +} + +static void initCarbon() +{ + CarbonConfig config; + stringtok(config.servers, arg()["carbon-server"], ", "); + config.hostname = arg()["carbon-ourname"]; + config.instance_name = arg()["carbon-instance"]; + config.namespace_name = arg()["carbon-namespace"]; + g_carbonConfig.setState(std::move(config)); +} + +static int initDNS64(Logr::log_t log) +{ + if (!::arg()["dns64-prefix"].empty()) { + try { + auto dns64Prefix = Netmask(::arg()["dns64-prefix"]); + if (dns64Prefix.getBits() != 96) { + SLOG(g_log << Logger::Error << "Invalid prefix for 'dns64-prefix', the current implementation only supports /96 prefixes: " << ::arg()["dns64-prefix"] << endl, + log->info(Logr::Error, "Invalid prefix for 'dns64-prefix', the current implementation only supports /96 prefixes", "prefix", Logging::Loggable(::arg()["dns64-prefix"]))); + return 1; + } + g_dns64Prefix = dns64Prefix.getNetwork(); + g_dns64PrefixReverse = reverseNameFromIP(*g_dns64Prefix); + /* /96 is 24 nibbles + 2 for "ip6.arpa." */ + while (g_dns64PrefixReverse.countLabels() > 26) { + g_dns64PrefixReverse.chopOff(); + } + } + catch (const NetmaskException& ne) { + SLOG(g_log << Logger::Error << "Invalid prefix '" << ::arg()["dns64-prefix"] << "' for 'dns64-prefix': " << ne.reason << endl, + log->info(Logr::Error, "Invalid prefix", "dns64-prefix", Logging::Loggable(::arg()["dns64-prefix"]))); + return 1; + } + } + return 0; +} + +static int serviceMain(Logr::log_t log) +{ + g_log.setName(g_programname); + g_log.disableSyslog(::arg().mustDo("disable-syslog")); + g_log.setTimestamps(::arg().mustDo("log-timestamp")); + g_regressionTestMode = ::arg().mustDo("devonly-regression-test-mode"); + + if (!::arg()["logging-facility"].empty()) { + int val = logFacilityToLOG(::arg().asNum("logging-facility")); + if (val >= 0) { + g_log.setFacility(val); + } else { + SLOG(g_log << Logger::Error << "Unknown logging facility " << ::arg().asNum("logging-facility") << endl, + log->info(Logr::Error, "Unknown logging facility", "facility", Logging::Loggable(::arg().asNum("logging-facility")))); + } + } + + showProductVersion(); + + g_disthashseed = dns_random(0xffffffff); + + int ret = initNet(log); + if (ret != 0) { + return ret; + } + // keep this ABOVE loadRecursorLuaConfig! + ret = initDNSSEC(log); + if (ret != 0) { + return ret; + } + g_maxCacheEntries = ::arg().asNum("max-cache-entries"); + + luaConfigDelayedThreads delayedLuaThreads; + try { + ProxyMapping proxyMapping; + loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads, proxyMapping); + // Initial proxy mapping + g_proxyMapping = proxyMapping.empty() ? nullptr : std::make_unique(proxyMapping); + } + catch (PDNSException& e) { + SLOG(g_log << Logger::Error << "Cannot load Lua configuration: " << e.reason << endl, + log->error(Logr::Error, e.reason, "Cannot load Lua configuration")); + return 1; + } + + parseACLs(); + initPublicSuffixList(::arg()["public-suffix-list-file"]); + + initDontQuery(log); + + /* this needs to be done before parseACLs(), which call broadcastFunction() */ + RecThreadInfo::setWeDistributeQueries(::arg().mustDo("pdns-distributes-queries")); + if (RecThreadInfo::weDistributeQueries()) { + SLOG(g_log << Logger::Warning << "PowerDNS Recursor itself will distribute queries over threads" << endl, + log->info(Logr::Notice, "PowerDNS Recursor itself will distribute queries over threads")); + } + + g_outgoingEDNSBufsize = ::arg().asNum("edns-outgoing-bufsize"); + + if (::arg()["trace"] == "fail") { + SyncRes::setDefaultLogMode(SyncRes::Store); + } + else if (::arg().mustDo("trace")) { + SyncRes::setDefaultLogMode(SyncRes::Log); + ::arg().set("quiet") = "no"; + g_quiet = false; + } + auto myHostname = getHostname(); + if (!myHostname.has_value()) { + SLOG(g_log << Logger::Warning << "Unable to get the hostname, NSID and id.server values will be empty" << endl, + log->info(Logr::Warning, "Unable to get the hostname, NSID and id.server values will be empty")); + } + + ret = initSyncRes(log, myHostname); + if (ret != 0) { + return ret; + } + + g_proxyProtocolACL.toMasks(::arg()["proxy-protocol-from"]); + g_proxyProtocolMaximumSize = ::arg().asNum("proxy-protocol-maximum-size"); + + ret = initDNS64(log); + if (ret != 0) { + return ret; + } + g_networkTimeoutMsec = ::arg().asNum("network-timeout"); + + std::tie(g_initialDomainMap, g_initialAllowNotifyFor) = parseZoneConfiguration(); + + g_latencyStatSize = ::arg().asNum("latency-statistic-size"); + + g_logCommonErrors = ::arg().mustDo("log-common-errors"); + g_logRPZChanges = ::arg().mustDo("log-rpz-changes"); + + g_anyToTcp = ::arg().mustDo("any-to-tcp"); + g_udpTruncationThreshold = ::arg().asNum("udp-truncation-threshold"); + + g_lowercaseOutgoing = ::arg().mustDo("lowercase-outgoing"); + + g_paddingFrom.toMasks(::arg()["edns-padding-from"]); + if (::arg()["edns-padding-mode"] == "always") { + g_paddingMode = PaddingMode::Always; + } + else if (::arg()["edns-padding-mode"] == "padded-queries-only") { + g_paddingMode = PaddingMode::PaddedQueries; + } + else { + SLOG(g_log << Logger::Error << "Unknown edns-padding-mode: " << ::arg()["edns-padding-mode"] << endl, + log->info(Logr::Error, "Unknown edns-padding-mode", "edns-padding-mode", Logging::Loggable(::arg()["edns-padding-mode"]))); + return 1; + } + g_paddingTag = ::arg().asNum("edns-padding-tag"); + g_paddingOutgoing = ::arg().mustDo("edns-padding-out"); + + RecThreadInfo::setNumDistributorThreads(::arg().asNum("distributor-threads")); + RecThreadInfo::setNumWorkerThreads(::arg().asNum("threads")); + if (RecThreadInfo::numWorkers() < 1) { + SLOG(g_log << Logger::Warning << "Asked to run with 0 threads, raising to 1 instead" << endl, + log->info(Logr::Warning, "Asked to run with 0 threads, raising to 1 instead")); + RecThreadInfo::setNumWorkerThreads(1); + } + + g_maxMThreads = ::arg().asNum("max-mthreads"); + + int64_t maxInFlight = ::arg().asNum("max-concurrent-requests-per-tcp-connection"); + if (maxInFlight < 1 || maxInFlight > USHRT_MAX || maxInFlight >= g_maxMThreads) { + SLOG(g_log << Logger::Warning << "Asked to run with illegal max-concurrent-requests-per-tcp-connection, setting to default (10)" << endl, + log->info(Logr::Warning, "Asked to run with illegal max-concurrent-requests-per-tcp-connection, setting to default (10)")); + TCPConnection::s_maxInFlight = 10; + } + else { + TCPConnection::s_maxInFlight = maxInFlight; + } + + int64_t millis = ::arg().asNum("tcp-out-max-idle-ms"); + TCPOutConnectionManager::s_maxIdleTime = timeval{millis / 1000, (static_cast(millis) % 1000) * 1000}; + TCPOutConnectionManager::s_maxIdlePerAuth = ::arg().asNum("tcp-out-max-idle-per-auth"); + TCPOutConnectionManager::s_maxQueries = ::arg().asNum("tcp-out-max-queries"); + TCPOutConnectionManager::s_maxIdlePerThread = ::arg().asNum("tcp-out-max-idle-per-thread"); + + g_gettagNeedsEDNSOptions = ::arg().mustDo("gettag-needs-edns-options"); + + s_statisticsInterval = ::arg().asNum("statistics-interval"); + + SyncRes::s_addExtendedResolutionDNSErrors = ::arg().mustDo("extended-resolution-errors"); + + if (::arg().asNum("aggressive-nsec-cache-size") > 0) { + if (g_dnssecmode == DNSSECMode::ValidateAll || g_dnssecmode == DNSSECMode::ValidateForLog || g_dnssecmode == DNSSECMode::Process) { + g_aggressiveNSECCache = make_unique(::arg().asNum("aggressive-nsec-cache-size")); + } + else { + SLOG(g_log << Logger::Warning << "Aggressive NSEC/NSEC3 caching is enabled but DNSSEC validation is not set to 'validate', 'log-fail' or 'process', ignoring" << endl, + log->info(Logr::Warning, "Aggressive NSEC/NSEC3 caching is enabled but DNSSEC validation is not set to 'validate', 'log-fail' or 'process', ignoring")); + } + } + + AggressiveNSECCache::s_maxNSEC3CommonPrefix = static_cast(std::round(std::log2(::arg().asNum("aggressive-cache-min-nsec3-hit-ratio")))); + SLOG(g_log << Logger::Debug << "NSEC3 aggressive cache tuning: aggressive-cache-min-nsec3-hit-ratio: " << ::arg().asNum("aggressive-cache-min-nsec3-hit-ratio") << " max common prefix bits: " << std::to_string(AggressiveNSECCache::s_maxNSEC3CommonPrefix) << endl, + log->info(Logr::Debug, "NSEC3 aggressive cache tuning", "aggressive-cache-min-nsec3-hit-ratio", Logging::Loggable(::arg().asNum("aggressive-cache-min-nsec3-hit-ratio")), "maxCommonPrefixBits", Logging::Loggable(AggressiveNSECCache::s_maxNSEC3CommonPrefix))); + + initSuffixMatchNodes(); + initCarbon(); + initDistribution(log); + +#ifdef NOD_ENABLED + // Setup newly observed domain globals + setupNODGlobal(); +#endif /* NOD_ENABLED */ + + auto forks = initForks(log); + + checkOrFixFDS(log); + +#ifdef HAVE_LIBSODIUM + if (sodium_init() == -1) { + SLOG(g_log << Logger::Error << "Unable to initialize sodium crypto library" << endl, + log->info(Logr::Error, "Unable to initialize sodium crypto library")); + return 99; + } +#endif + + openssl_thread_setup(); + openssl_seed(); + /* setup rng before chroot */ + dns_random_init(); + + if (::arg()["server-id"].empty()) { + ::arg().set("server-id") = myHostname.has_value() ? *myHostname : ""; + } + + gid_t newgid = 0; + if (!::arg()["setgid"].empty()) { + newgid = strToGID(::arg()["setgid"]); + } + uid_t newuid = 0; + if (!::arg()["setuid"].empty()) { + newuid = strToUID(::arg()["setuid"]); + } + + Utility::dropGroupPrivs(newuid, newgid); + + ret = initControl(log, newuid, forks); + if (ret != 0) { + return ret; + } startLuaConfigDelayedThreads(delayedLuaThreads, g_luaconfs.getCopy().generation); delayedLuaThreads.rpzPrimaryThreads.clear(); // no longer needed @@ -1973,45 +2087,11 @@ static int serviceMain(Logr::log_t log) // Run before any thread doing stats related things registerAllStats(); - if (::arg().mustDo("snmp-agent")) { -#ifdef HAVE_NET_SNMP - string setting = ::arg()["snmp-daemon-socket"]; - if (setting.empty()) { - setting = ::arg()["snmp-master-socket"]; - } - g_snmpAgent = std::make_shared("recursor", setting); - g_snmpAgent->run(); -#else - const std::string msg = "snmp-agent set but SNMP support not compiled in"; - SLOG(g_log << Logger::Error << msg << endl, - log->info(Logr::Error, msg)); -#endif // HAVE_NET_SNMP - } + initSNMP(log); - int port = ::arg().asNum("udp-source-port-min"); - if (port < 1024 || port > 65535) { - SLOG(g_log << Logger::Error << "Unable to launch, udp-source-port-min is not a valid port number" << endl, - log->info(Logr::Error, "Unable to launch, udp-source-port-min is not a valid port number")); - return 99; // this isn't going to fix itself either - } - g_minUdpSourcePort = port; - port = ::arg().asNum("udp-source-port-max"); - if (port < 1024 || port > 65535 || port < g_minUdpSourcePort) { - SLOG(g_log << Logger::Error << "Unable to launch, udp-source-port-max is not a valid port number or is smaller than udp-source-port-min" << endl, - log->info(Logr::Error, "Unable to launch, udp-source-port-max is not a valid port number or is smaller than udp-source-port-min")); - return 99; // this isn't going to fix itself either - } - g_maxUdpSourcePort = port; - std::vector parts{}; - stringtok(parts, ::arg()["udp-source-port-avoid"], ", "); - for (const auto& part : parts) { - port = std::stoi(part); - if (port < 1024 || port > 65535) { - SLOG(g_log << Logger::Error << "Unable to launch, udp-source-port-avoid contains an invalid port number: " << part << endl, - log->info(Logr::Error, "Unable to launch, udp-source-port-avoid contains an invalid port number", "port", Logging::Loggable(part))); - return 99; // this isn't going to fix itself either - } - g_avoidUdpSourcePorts.insert(port); + ret = initPorts(log); + if (ret != 0) { + return ret; } return RecThreadInfo::runThreads(log); From 259011025d5d2823c07b5e0def8d7e4880a41dbe Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 8 May 2023 10:20:06 +0200 Subject: [PATCH 138/909] split main() to reduce complexity --- pdns/recursordist/rec-main.cc | 136 +++++++++++++++++++--------------- 1 file changed, 76 insertions(+), 60 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index dff35ea1a518..e6ca920a42a6 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2667,19 +2667,9 @@ static void recursorThread() } } -int main(int argc, char** argv) +static void initArgs() { - g_argc = argc; - g_argv = argv; - Utility::srandom(); - versionSetProduct(ProductRecursor); - reportBasicTypes(); - reportOtherTypes(); - - int ret = EXIT_SUCCESS; - - try { -#if HAVE_FIBER_SANITIZER + #if HAVE_FIBER_SANITIZER // Asan needs more stack ::arg().set("stack-size", "stack size per mthread") = "600000"; #else @@ -2947,18 +2937,79 @@ int main(int argc, char** argv) ::arg().setCmd("config", "Output blank configuration. You can use --config=check to test the config file and command line arguments."); ::arg().setDefaults(); g_log.toConsole(Logger::Info); +} + +static pair doConfig(Logr::log_t startupLog, const string& configname, int argc, char *argv[]) // NOLINT: Posix API +{ + if (::arg().mustDo("config")) { + string config = ::arg()["config"]; + if (config == "check") { + try { + if (!::arg().file(configname.c_str())) { + SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, + startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); + return {1, true}; + } + ::arg().parse(argc, argv); + return {0, true}; + } + catch (const ArgException& argException) { + SLOG(g_log << Logger::Warning << "Unable to parse configuration file '" << configname << "': " << argException.reason << endl, + startupLog->error("Cannot parse configuration", "Unable to parse configuration file", "config_file", Logging::Loggable(configname), "reason", Logging::Loggable(argException.reason))); + return {1, true}; + } + } + else if (config == "default" || config.empty()) { + cout << ::arg().configstring(false, true); + } + else if (config == "diff") { + if (!::arg().laxFile(configname.c_str())) { + SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, + startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); + return {1, true}; + } + ::arg().laxParse(argc, argv); + cout << ::arg().configstring(true, false); + } + else { + if (!::arg().laxFile(configname.c_str())) { + SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, + startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); + return {1, true}; + } + ::arg().laxParse(argc, argv); + cout << ::arg().configstring(true, true); + } + return {0, true}; + } + return {0, false}; +} + +int main(int argc, char** argv) +{ + g_argc = argc; + g_argv = argv; + Utility::srandom(); + versionSetProduct(ProductRecursor); + reportBasicTypes(); + reportOtherTypes(); + + int ret = EXIT_SUCCESS; + + try { + initArgs(); ::arg().laxParse(argc, argv); // do a lax parse if (::arg().mustDo("version")) { showProductVersion(); showBuildConfiguration(); - exit(0); + return 0; } if (::arg().mustDo("help")) { cout << "syntax:" << endl << endl; cout << ::arg().helpstring(::arg()["help"]) << endl; - exit(0); + return 0; } // Pick up options given on command line to setup logging asap. @@ -2990,15 +3041,15 @@ int main(int argc, char** argv) } cerr << " ("; bool first = true; - for (const auto& c : ::arg().getCommands()) { + for (const auto& command : ::arg().getCommands()) { if (!first) { cerr << ", "; } first = false; - cerr << c; + cerr << command; } cerr << ") on the command line, perhaps a '--setting=123' statement missed the '='?" << endl; - exit(99); + return 99; } if (s_structured_logger_backend == "systemd-journal") { @@ -3025,46 +3076,10 @@ int main(int argc, char** argv) ::arg().setSLog(startupLog); - if (::arg().mustDo("config")) { - string config = ::arg()["config"]; - if (config == "check") { - try { - if (!::arg().file(configname.c_str())) { - SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, - startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); - exit(1); - } - ::arg().parse(argc, argv); - exit(0); - } - catch (const ArgException& argException) { - SLOG(g_log << Logger::Warning << "Unable to parse configuration file '" << configname << "': " << argException.reason << endl, - startupLog->error("Cannot parse configuration", "Unable to parse configuration file", "config_file", Logging::Loggable(configname), "reason", Logging::Loggable(argException.reason))); - exit(1); - } - } - else if (config == "default" || config.empty()) { - cout << ::arg().configstring(false, true); - } - else if (config == "diff") { - if (!::arg().laxFile(configname.c_str())) { - SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, - startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); - exit(1); - } - ::arg().laxParse(argc, argv); - cout << ::arg().configstring(true, false); - } - else { - if (!::arg().laxFile(configname.c_str())) { - SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, - startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); - exit(1); - } - ::arg().laxParse(argc, argv); - cout << ::arg().configstring(true, true); - } - exit(0); + bool mustExit = false; + std::tie(ret, mustExit) = doConfig(startupLog, configname, argc, argv); + if (ret != 0 || mustExit) { + return ret; } if (!::arg().file(configname.c_str())) { @@ -3091,14 +3106,15 @@ int main(int argc, char** argv) if (!::arg()["chroot"].empty() && !::arg()["api-config-dir"].empty()) { SLOG(g_log << Logger::Error << "Using chroot and enabling the API is not possible" << endl, startupLog->info(Logr::Error, "Cannot use chroot and enable the API at the same time")); - exit(EXIT_FAILURE); + return EXIT_FAILURE; } if (::arg()["socket-dir"].empty()) { - if (::arg()["chroot"].empty()) + if (::arg()["chroot"].empty()) { ::arg().set("socket-dir") = std::string(LOCALSTATEDIR) + "/pdns-recursor"; - else + } else { ::arg().set("socket-dir") = "/"; + } } if (::arg().asNum("threads") == 1) { From cc8f9a7990567921a22924cc54c8ae3dd9bfb84f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 8 May 2023 10:21:04 +0200 Subject: [PATCH 139/909] Reformat --- pdns/recursordist/rec-main.cc | 487 +++++++++++++++++----------------- 1 file changed, 247 insertions(+), 240 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index e6ca920a42a6..c43e633a2dc6 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1406,15 +1406,20 @@ static int initDNSSEC(Logr::log_t log) { if (::arg()["dnssec"] == "off") { g_dnssecmode = DNSSECMode::Off; - } else if (::arg()["dnssec"] == "process-no-validate") { + } + else if (::arg()["dnssec"] == "process-no-validate") { g_dnssecmode = DNSSECMode::ProcessNoValidate; - } else if (::arg()["dnssec"] == "process") { + } + else if (::arg()["dnssec"] == "process") { g_dnssecmode = DNSSECMode::Process; - } else if (::arg()["dnssec"] == "validate") { + } + else if (::arg()["dnssec"] == "validate") { g_dnssecmode = DNSSECMode::ValidateAll; - } else if (::arg()["dnssec"] == "log-fail {") { + } + else if (::arg()["dnssec"] == "log-fail {") { g_dnssecmode = DNSSECMode::ValidateForLog; - } else { + } + else { SLOG(g_log << Logger::Error << "Unknown DNSSEC mode " << ::arg()["dnssec"] << endl, log->info(Logr::Error, "Unknown DNSSEC mode", "dnssec", Logging::Loggable(::arg()["dnssec"]))); return 1; @@ -1867,7 +1872,8 @@ static int serviceMain(Logr::log_t log) int val = logFacilityToLOG(::arg().asNum("logging-facility")); if (val >= 0) { g_log.setFacility(val); - } else { + } + else { SLOG(g_log << Logger::Error << "Unknown logging facility " << ::arg().asNum("logging-facility") << endl, log->info(Logr::Error, "Unknown logging facility", "facility", Logging::Loggable(::arg().asNum("logging-facility")))); } @@ -2669,277 +2675,277 @@ static void recursorThread() static void initArgs() { - #if HAVE_FIBER_SANITIZER - // Asan needs more stack - ::arg().set("stack-size", "stack size per mthread") = "600000"; +#if HAVE_FIBER_SANITIZER + // Asan needs more stack + ::arg().set("stack-size", "stack size per mthread") = "600000"; #else - ::arg().set("stack-size", "stack size per mthread") = "200000"; + ::arg().set("stack-size", "stack size per mthread") = "200000"; #endif - ::arg().set("stack-cache-size", "Size of the stack cache, per mthread") = "100"; - // This mode forces metrics snap updates and disable root-refresh, to get consistent counters - ::arg().setSwitch("devonly-regression-test-mode", "internal use only") = "no"; - ::arg().set("soa-minimum-ttl", "Don't change") = "0"; - ::arg().set("no-shuffle", "Don't change") = "off"; - ::arg().set("local-port", "port to listen on") = "53"; - ::arg().set("local-address", "IP addresses to listen on, separated by spaces or commas. Also accepts ports.") = "127.0.0.1"; - ::arg().setSwitch("non-local-bind", "Enable binding to non-local addresses by using FREEBIND / BINDANY socket options") = "no"; - ::arg().set("trace", "if we should output heaps of logging. set to 'fail' to only log failing domains") = "off"; - ::arg().set("dnssec", "DNSSEC mode: off/process-no-validate/process (default)/log-fail/validate") = "process"; - ::arg().set("dnssec-log-bogus", "Log DNSSEC bogus validations") = "no"; - ::arg().set("signature-inception-skew", "Allow the signature inception to be off by this number of seconds") = "60"; - ::arg().set("daemon", "Operate as a daemon") = "no"; - ::arg().setSwitch("write-pid", "Write a PID file") = "yes"; - ::arg().set("loglevel", "Amount of logging. Higher is more. Do not set below 3") = "6"; - ::arg().set("disable-syslog", "Disable logging to syslog, useful when running inside a supervisor that logs stdout") = "no"; - ::arg().set("log-timestamp", "Print timestamps in log lines, useful to disable when running with a tool that timestamps stdout already") = "yes"; - ::arg().set("log-common-errors", "If we should log rather common errors") = "no"; - ::arg().set("chroot", "switch to chroot jail") = ""; - ::arg().set("setgid", "If set, change group id to this gid for more security" + ::arg().set("stack-cache-size", "Size of the stack cache, per mthread") = "100"; + // This mode forces metrics snap updates and disable root-refresh, to get consistent counters + ::arg().setSwitch("devonly-regression-test-mode", "internal use only") = "no"; + ::arg().set("soa-minimum-ttl", "Don't change") = "0"; + ::arg().set("no-shuffle", "Don't change") = "off"; + ::arg().set("local-port", "port to listen on") = "53"; + ::arg().set("local-address", "IP addresses to listen on, separated by spaces or commas. Also accepts ports.") = "127.0.0.1"; + ::arg().setSwitch("non-local-bind", "Enable binding to non-local addresses by using FREEBIND / BINDANY socket options") = "no"; + ::arg().set("trace", "if we should output heaps of logging. set to 'fail' to only log failing domains") = "off"; + ::arg().set("dnssec", "DNSSEC mode: off/process-no-validate/process (default)/log-fail/validate") = "process"; + ::arg().set("dnssec-log-bogus", "Log DNSSEC bogus validations") = "no"; + ::arg().set("signature-inception-skew", "Allow the signature inception to be off by this number of seconds") = "60"; + ::arg().set("daemon", "Operate as a daemon") = "no"; + ::arg().setSwitch("write-pid", "Write a PID file") = "yes"; + ::arg().set("loglevel", "Amount of logging. Higher is more. Do not set below 3") = "6"; + ::arg().set("disable-syslog", "Disable logging to syslog, useful when running inside a supervisor that logs stdout") = "no"; + ::arg().set("log-timestamp", "Print timestamps in log lines, useful to disable when running with a tool that timestamps stdout already") = "yes"; + ::arg().set("log-common-errors", "If we should log rather common errors") = "no"; + ::arg().set("chroot", "switch to chroot jail") = ""; + ::arg().set("setgid", "If set, change group id to this gid for more security" #ifdef HAVE_SYSTEMD #define SYSTEMD_SETID_MSG ". When running inside systemd, use the User and Group settings in the unit-file!" - SYSTEMD_SETID_MSG + SYSTEMD_SETID_MSG #endif - ) - = ""; - ::arg().set("setuid", "If set, change user id to this uid for more security" + ) + = ""; + ::arg().set("setuid", "If set, change user id to this uid for more security" #ifdef HAVE_SYSTEMD - SYSTEMD_SETID_MSG + SYSTEMD_SETID_MSG #endif - ) - = ""; - ::arg().set("network-timeout", "Wait this number of milliseconds for network i/o") = "1500"; - ::arg().set("threads", "Launch this number of threads") = "2"; - ::arg().set("distributor-threads", "Launch this number of distributor threads, distributing queries to other threads") = "0"; - ::arg().set("processes", "Launch this number of processes (EXPERIMENTAL, DO NOT CHANGE)") = "1"; // if we un-experimental this, need to fix openssl rand seeding for multiple PIDs! - ::arg().set("config-name", "Name of this virtual configuration - will rename the binary image") = ""; - ::arg().set("api-config-dir", "Directory where REST API stores config and zones") = ""; - ::arg().set("api-key", "Static pre-shared authentication key for access to the REST API") = ""; - ::arg().setSwitch("webserver", "Start a webserver (for REST API)") = "no"; - ::arg().set("webserver-address", "IP Address of webserver to listen on") = "127.0.0.1"; - ::arg().set("webserver-port", "Port of webserver to listen on") = "8082"; - ::arg().set("webserver-password", "Password required for accessing the webserver") = ""; - ::arg().set("webserver-allow-from", "Webserver access is only allowed from these subnets") = "127.0.0.1,::1"; - ::arg().set("webserver-loglevel", "Amount of logging in the webserver (none, normal, detailed)") = "normal"; - ::arg().setSwitch("webserver-hash-plaintext-credentials", "Whether to hash passwords and api keys supplied in plaintext, to prevent keeping the plaintext version in memory at runtime") = "no"; - ::arg().set("carbon-ourname", "If set, overrides our reported hostname for carbon stats") = ""; - ::arg().set("carbon-server", "If set, send metrics in carbon (graphite) format to this server IP address") = ""; - ::arg().set("carbon-interval", "Number of seconds between carbon (graphite) updates") = "30"; - ::arg().set("carbon-namespace", "If set overwrites the first part of the carbon string") = "pdns"; - ::arg().set("carbon-instance", "If set overwrites the instance name default") = "recursor"; - - ::arg().set("statistics-interval", "Number of seconds between printing of recursor statistics, 0 to disable") = "1800"; - ::arg().set("quiet", "Suppress logging of questions and answers") = ""; - ::arg().set("logging-facility", "Facility to log messages as. 0 corresponds to local0") = ""; - ::arg().set("config-dir", "Location of configuration directory (recursor.conf)") = SYSCONFDIR; - ::arg().set("socket-owner", "Owner of socket") = ""; - ::arg().set("socket-group", "Group of socket") = ""; - ::arg().set("socket-mode", "Permissions for socket") = ""; - - ::arg().set("socket-dir", string("Where the controlsocket will live, ") + LOCALSTATEDIR + "/pdns-recursor when unset and not chrooted" + ) + = ""; + ::arg().set("network-timeout", "Wait this number of milliseconds for network i/o") = "1500"; + ::arg().set("threads", "Launch this number of threads") = "2"; + ::arg().set("distributor-threads", "Launch this number of distributor threads, distributing queries to other threads") = "0"; + ::arg().set("processes", "Launch this number of processes (EXPERIMENTAL, DO NOT CHANGE)") = "1"; // if we un-experimental this, need to fix openssl rand seeding for multiple PIDs! + ::arg().set("config-name", "Name of this virtual configuration - will rename the binary image") = ""; + ::arg().set("api-config-dir", "Directory where REST API stores config and zones") = ""; + ::arg().set("api-key", "Static pre-shared authentication key for access to the REST API") = ""; + ::arg().setSwitch("webserver", "Start a webserver (for REST API)") = "no"; + ::arg().set("webserver-address", "IP Address of webserver to listen on") = "127.0.0.1"; + ::arg().set("webserver-port", "Port of webserver to listen on") = "8082"; + ::arg().set("webserver-password", "Password required for accessing the webserver") = ""; + ::arg().set("webserver-allow-from", "Webserver access is only allowed from these subnets") = "127.0.0.1,::1"; + ::arg().set("webserver-loglevel", "Amount of logging in the webserver (none, normal, detailed)") = "normal"; + ::arg().setSwitch("webserver-hash-plaintext-credentials", "Whether to hash passwords and api keys supplied in plaintext, to prevent keeping the plaintext version in memory at runtime") = "no"; + ::arg().set("carbon-ourname", "If set, overrides our reported hostname for carbon stats") = ""; + ::arg().set("carbon-server", "If set, send metrics in carbon (graphite) format to this server IP address") = ""; + ::arg().set("carbon-interval", "Number of seconds between carbon (graphite) updates") = "30"; + ::arg().set("carbon-namespace", "If set overwrites the first part of the carbon string") = "pdns"; + ::arg().set("carbon-instance", "If set overwrites the instance name default") = "recursor"; + + ::arg().set("statistics-interval", "Number of seconds between printing of recursor statistics, 0 to disable") = "1800"; + ::arg().set("quiet", "Suppress logging of questions and answers") = ""; + ::arg().set("logging-facility", "Facility to log messages as. 0 corresponds to local0") = ""; + ::arg().set("config-dir", "Location of configuration directory (recursor.conf)") = SYSCONFDIR; + ::arg().set("socket-owner", "Owner of socket") = ""; + ::arg().set("socket-group", "Group of socket") = ""; + ::arg().set("socket-mode", "Permissions for socket") = ""; + + ::arg().set("socket-dir", string("Where the controlsocket will live, ") + LOCALSTATEDIR + "/pdns-recursor when unset and not chrooted" #ifdef HAVE_SYSTEMD - + ". Set to the RUNTIME_DIRECTORY environment variable when that variable has a value (e.g. under systemd).") - = ""; - auto runtimeDir = getenv("RUNTIME_DIRECTORY"); - if (runtimeDir != nullptr) { - ::arg().set("socket-dir") = runtimeDir; - } + + ". Set to the RUNTIME_DIRECTORY environment variable when that variable has a value (e.g. under systemd).") + = ""; + auto runtimeDir = getenv("RUNTIME_DIRECTORY"); + if (runtimeDir != nullptr) { + ::arg().set("socket-dir") = runtimeDir; + } #else - ) - = ""; + ) + = ""; #endif - ::arg().set("query-local-address", "Source IP address for sending queries") = "0.0.0.0"; - ::arg().set("client-tcp-timeout", "Timeout in seconds when talking to TCP clients") = "2"; - ::arg().set("max-mthreads", "Maximum number of simultaneous Mtasker threads") = "2048"; - ::arg().set("max-tcp-clients", "Maximum number of simultaneous TCP clients") = "128"; - ::arg().set("max-concurrent-requests-per-tcp-connection", "Maximum number of requests handled concurrently per TCP connection") = "10"; - ::arg().set("server-down-max-fails", "Maximum number of consecutive timeouts (and unreachables) to mark a server as down ( 0 => disabled )") = "64"; - ::arg().set("server-down-throttle-time", "Number of seconds to throttle all queries to a server after being marked as down") = "60"; - ::arg().set("dont-throttle-names", "Do not throttle nameservers with this name or suffix") = ""; - ::arg().set("dont-throttle-netmasks", "Do not throttle nameservers with this IP netmask") = ""; - ::arg().set("non-resolving-ns-max-fails", "Number of failed address resolves of a nameserver to start throttling it, 0 is disabled") = "5"; - ::arg().set("non-resolving-ns-throttle-time", "Number of seconds to throttle a nameserver with a name failing to resolve") = "60"; - - ::arg().set("hint-file", "If set, load root hints from this file") = ""; - ::arg().set("max-cache-entries", "If set, maximum number of entries in the main cache") = "1000000"; - ::arg().set("max-negative-ttl", "maximum number of seconds to keep a negative cached entry in memory") = "3600"; - ::arg().set("max-cache-bogus-ttl", "maximum number of seconds to keep a Bogus (positive or negative) cached entry in memory") = "3600"; - ::arg().set("max-cache-ttl", "maximum number of seconds to keep a cached entry in memory") = "86400"; - ::arg().set("packetcache-ttl", "maximum number of seconds to keep a cached entry in packetcache") = "86400"; - ::arg().set("max-packetcache-entries", "maximum number of entries to keep in the packetcache") = "500000"; - ::arg().set("packetcache-servfail-ttl", "maximum number of seconds to keep a cached servfail entry in packetcache") = "60"; - ::arg().set("packetcache-negative-ttl", "maximum number of seconds to keep a cached NxDomain or NoData entry in packetcache") = "60"; - ::arg().set("server-id", "Returned when queried for 'id.server' TXT or NSID, defaults to hostname, set custom or 'disabled'") = ""; - ::arg().set("stats-ringbuffer-entries", "maximum number of packets to store statistics for") = "10000"; - ::arg().set("version-string", "string reported on version.pdns or version.bind") = fullVersionString(); - ::arg().set("allow-from", "If set, only allow these comma separated netmasks to recurse") = LOCAL_NETS; - ::arg().set("allow-from-file", "If set, load allowed netmasks from this file") = ""; - ::arg().set("allow-notify-for", "If set, NOTIFY requests for these zones will be allowed") = ""; - ::arg().set("allow-notify-for-file", "If set, load NOTIFY-allowed zones from this file") = ""; - ::arg().set("allow-notify-from", "If set, NOTIFY requests from these comma separated netmasks will be allowed") = ""; - ::arg().set("allow-notify-from-file", "If set, load NOTIFY-allowed netmasks from this file") = ""; - ::arg().set("entropy-source", "If set, read entropy from this file") = "/dev/urandom"; - ::arg().set("dont-query", "If set, do not query these netmasks for DNS data") = DONT_QUERY; - ::arg().set("max-tcp-per-client", "If set, maximum number of TCP sessions per client (IP address)") = "0"; - ::arg().set("max-tcp-queries-per-connection", "If set, maximum number of TCP queries in a TCP connection") = "0"; - ::arg().set("spoof-nearmiss-max", "If non-zero, assume spoofing after this many near misses") = "1"; - ::arg().set("single-socket", "If set, only use a single socket for outgoing queries") = "off"; - ::arg().set("auth-zones", "Zones for which we have authoritative data, comma separated domain=file pairs ") = ""; - ::arg().set("lua-config-file", "More powerful configuration options") = ""; - ::arg().setSwitch("allow-trust-anchor-query", "Allow queries for trustanchor.server CH TXT and negativetrustanchor.server CH TXT") = "no"; - - ::arg().set("forward-zones", "Zones for which we forward queries, comma separated domain=ip pairs") = ""; - ::arg().set("forward-zones-recurse", "Zones for which we forward queries with recursion bit, comma separated domain=ip pairs") = ""; - ::arg().set("forward-zones-file", "File with (+)domain=ip pairs for forwarding") = ""; - ::arg().set("export-etc-hosts", "If we should serve up contents from /etc/hosts") = "off"; - ::arg().set("export-etc-hosts-search-suffix", "Also serve up the contents of /etc/hosts with this suffix") = ""; - ::arg().set("etc-hosts-file", "Path to 'hosts' file") = "/etc/hosts"; - ::arg().set("serve-rfc1918", "If we should be authoritative for RFC 1918 private IP space") = "yes"; - ::arg().set("lua-dns-script", "Filename containing an optional 'lua' script that will be used to modify dns answers") = ""; - ::arg().set("lua-maintenance-interval", "Number of seconds between calls to the lua user defined maintenance() function") = "1"; - ::arg().set("latency-statistic-size", "Number of latency values to calculate the qa-latency average") = "10000"; - ::arg().setSwitch("disable-packetcache", "Disable packetcache") = "no"; - ::arg().set("ecs-ipv4-bits", "Number of bits of IPv4 address to pass for EDNS Client Subnet") = "24"; - ::arg().set("ecs-ipv4-cache-bits", "Maximum number of bits of IPv4 mask to cache ECS response") = "24"; - ::arg().set("ecs-ipv6-bits", "Number of bits of IPv6 address to pass for EDNS Client Subnet") = "56"; - ::arg().set("ecs-ipv6-cache-bits", "Maximum number of bits of IPv6 mask to cache ECS response") = "56"; - ::arg().setSwitch("ecs-ipv4-never-cache", "If we should never cache IPv4 ECS responses") = "no"; - ::arg().setSwitch("ecs-ipv6-never-cache", "If we should never cache IPv6 ECS responses") = "no"; - ::arg().set("ecs-minimum-ttl-override", "The minimum TTL for records in ECS-specific answers") = "1"; - ::arg().set("ecs-cache-limit-ttl", "Minimum TTL to cache ECS response") = "0"; - ::arg().set("edns-subnet-whitelist", "List of netmasks and domains that we should enable EDNS subnet for (deprecated)") = ""; - ::arg().set("edns-subnet-allow-list", "List of netmasks and domains that we should enable EDNS subnet for") = ""; - ::arg().set("ecs-add-for", "List of client netmasks for which EDNS Client Subnet will be added") = "0.0.0.0/0, ::/0, " LOCAL_NETS_INVERSE; - ::arg().set("ecs-scope-zero-address", "Address to send to allow-listed authoritative servers for incoming queries with ECS prefix-length source of 0") = ""; - ::arg().setSwitch("use-incoming-edns-subnet", "Pass along received EDNS Client Subnet information") = "no"; - ::arg().setSwitch("pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads") = "no"; - ::arg().setSwitch("root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist") = "yes"; - ::arg().setSwitch("any-to-tcp", "Answer ANY queries with tc=1, shunting to TCP") = "no"; - ::arg().setSwitch("lowercase-outgoing", "Force outgoing questions to lowercase") = "no"; - ::arg().setSwitch("gettag-needs-edns-options", "If EDNS Options should be extracted before calling the gettag() hook") = "no"; - ::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate") = "1232"; - ::arg().set("edns-outgoing-bufsize", "Outgoing EDNS buffer size") = "1232"; - ::arg().set("minimum-ttl-override", "The minimum TTL") = "1"; - ::arg().set("max-qperq", "Maximum outgoing queries per query") = "60"; - ::arg().set("max-ns-per-resolve", "Maximum number of NS records to consider to resolve a name, 0 is no limit") = "13"; - ::arg().set("max-ns-address-qperq", "Maximum outgoing NS address queries per query") = "10"; - ::arg().set("max-total-msec", "Maximum total wall-clock time per query in milliseconds, 0 for unlimited") = "7000"; - ::arg().set("max-recursion-depth", "Maximum number of internal recursion calls per query, 0 for unlimited") = "40"; - ::arg().set("max-udp-queries-per-round", "Maximum number of UDP queries processed per recvmsg() round, before returning back to normal processing") = "10000"; - ::arg().set("protobuf-use-kernel-timestamp", "Compute the latency of queries in protobuf messages by using the timestamp set by the kernel when the query was received (when available)") = ""; - ::arg().set("distribution-pipe-buffer-size", "Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread") = "0"; - - ::arg().set("include-dir", "Include *.conf files from this directory") = ""; - ::arg().set("security-poll-suffix", "Domain name from which to query security update notifications") = "secpoll.powerdns.com."; + ::arg().set("query-local-address", "Source IP address for sending queries") = "0.0.0.0"; + ::arg().set("client-tcp-timeout", "Timeout in seconds when talking to TCP clients") = "2"; + ::arg().set("max-mthreads", "Maximum number of simultaneous Mtasker threads") = "2048"; + ::arg().set("max-tcp-clients", "Maximum number of simultaneous TCP clients") = "128"; + ::arg().set("max-concurrent-requests-per-tcp-connection", "Maximum number of requests handled concurrently per TCP connection") = "10"; + ::arg().set("server-down-max-fails", "Maximum number of consecutive timeouts (and unreachables) to mark a server as down ( 0 => disabled )") = "64"; + ::arg().set("server-down-throttle-time", "Number of seconds to throttle all queries to a server after being marked as down") = "60"; + ::arg().set("dont-throttle-names", "Do not throttle nameservers with this name or suffix") = ""; + ::arg().set("dont-throttle-netmasks", "Do not throttle nameservers with this IP netmask") = ""; + ::arg().set("non-resolving-ns-max-fails", "Number of failed address resolves of a nameserver to start throttling it, 0 is disabled") = "5"; + ::arg().set("non-resolving-ns-throttle-time", "Number of seconds to throttle a nameserver with a name failing to resolve") = "60"; + + ::arg().set("hint-file", "If set, load root hints from this file") = ""; + ::arg().set("max-cache-entries", "If set, maximum number of entries in the main cache") = "1000000"; + ::arg().set("max-negative-ttl", "maximum number of seconds to keep a negative cached entry in memory") = "3600"; + ::arg().set("max-cache-bogus-ttl", "maximum number of seconds to keep a Bogus (positive or negative) cached entry in memory") = "3600"; + ::arg().set("max-cache-ttl", "maximum number of seconds to keep a cached entry in memory") = "86400"; + ::arg().set("packetcache-ttl", "maximum number of seconds to keep a cached entry in packetcache") = "86400"; + ::arg().set("max-packetcache-entries", "maximum number of entries to keep in the packetcache") = "500000"; + ::arg().set("packetcache-servfail-ttl", "maximum number of seconds to keep a cached servfail entry in packetcache") = "60"; + ::arg().set("packetcache-negative-ttl", "maximum number of seconds to keep a cached NxDomain or NoData entry in packetcache") = "60"; + ::arg().set("server-id", "Returned when queried for 'id.server' TXT or NSID, defaults to hostname, set custom or 'disabled'") = ""; + ::arg().set("stats-ringbuffer-entries", "maximum number of packets to store statistics for") = "10000"; + ::arg().set("version-string", "string reported on version.pdns or version.bind") = fullVersionString(); + ::arg().set("allow-from", "If set, only allow these comma separated netmasks to recurse") = LOCAL_NETS; + ::arg().set("allow-from-file", "If set, load allowed netmasks from this file") = ""; + ::arg().set("allow-notify-for", "If set, NOTIFY requests for these zones will be allowed") = ""; + ::arg().set("allow-notify-for-file", "If set, load NOTIFY-allowed zones from this file") = ""; + ::arg().set("allow-notify-from", "If set, NOTIFY requests from these comma separated netmasks will be allowed") = ""; + ::arg().set("allow-notify-from-file", "If set, load NOTIFY-allowed netmasks from this file") = ""; + ::arg().set("entropy-source", "If set, read entropy from this file") = "/dev/urandom"; + ::arg().set("dont-query", "If set, do not query these netmasks for DNS data") = DONT_QUERY; + ::arg().set("max-tcp-per-client", "If set, maximum number of TCP sessions per client (IP address)") = "0"; + ::arg().set("max-tcp-queries-per-connection", "If set, maximum number of TCP queries in a TCP connection") = "0"; + ::arg().set("spoof-nearmiss-max", "If non-zero, assume spoofing after this many near misses") = "1"; + ::arg().set("single-socket", "If set, only use a single socket for outgoing queries") = "off"; + ::arg().set("auth-zones", "Zones for which we have authoritative data, comma separated domain=file pairs ") = ""; + ::arg().set("lua-config-file", "More powerful configuration options") = ""; + ::arg().setSwitch("allow-trust-anchor-query", "Allow queries for trustanchor.server CH TXT and negativetrustanchor.server CH TXT") = "no"; + + ::arg().set("forward-zones", "Zones for which we forward queries, comma separated domain=ip pairs") = ""; + ::arg().set("forward-zones-recurse", "Zones for which we forward queries with recursion bit, comma separated domain=ip pairs") = ""; + ::arg().set("forward-zones-file", "File with (+)domain=ip pairs for forwarding") = ""; + ::arg().set("export-etc-hosts", "If we should serve up contents from /etc/hosts") = "off"; + ::arg().set("export-etc-hosts-search-suffix", "Also serve up the contents of /etc/hosts with this suffix") = ""; + ::arg().set("etc-hosts-file", "Path to 'hosts' file") = "/etc/hosts"; + ::arg().set("serve-rfc1918", "If we should be authoritative for RFC 1918 private IP space") = "yes"; + ::arg().set("lua-dns-script", "Filename containing an optional 'lua' script that will be used to modify dns answers") = ""; + ::arg().set("lua-maintenance-interval", "Number of seconds between calls to the lua user defined maintenance() function") = "1"; + ::arg().set("latency-statistic-size", "Number of latency values to calculate the qa-latency average") = "10000"; + ::arg().setSwitch("disable-packetcache", "Disable packetcache") = "no"; + ::arg().set("ecs-ipv4-bits", "Number of bits of IPv4 address to pass for EDNS Client Subnet") = "24"; + ::arg().set("ecs-ipv4-cache-bits", "Maximum number of bits of IPv4 mask to cache ECS response") = "24"; + ::arg().set("ecs-ipv6-bits", "Number of bits of IPv6 address to pass for EDNS Client Subnet") = "56"; + ::arg().set("ecs-ipv6-cache-bits", "Maximum number of bits of IPv6 mask to cache ECS response") = "56"; + ::arg().setSwitch("ecs-ipv4-never-cache", "If we should never cache IPv4 ECS responses") = "no"; + ::arg().setSwitch("ecs-ipv6-never-cache", "If we should never cache IPv6 ECS responses") = "no"; + ::arg().set("ecs-minimum-ttl-override", "The minimum TTL for records in ECS-specific answers") = "1"; + ::arg().set("ecs-cache-limit-ttl", "Minimum TTL to cache ECS response") = "0"; + ::arg().set("edns-subnet-whitelist", "List of netmasks and domains that we should enable EDNS subnet for (deprecated)") = ""; + ::arg().set("edns-subnet-allow-list", "List of netmasks and domains that we should enable EDNS subnet for") = ""; + ::arg().set("ecs-add-for", "List of client netmasks for which EDNS Client Subnet will be added") = "0.0.0.0/0, ::/0, " LOCAL_NETS_INVERSE; + ::arg().set("ecs-scope-zero-address", "Address to send to allow-listed authoritative servers for incoming queries with ECS prefix-length source of 0") = ""; + ::arg().setSwitch("use-incoming-edns-subnet", "Pass along received EDNS Client Subnet information") = "no"; + ::arg().setSwitch("pdns-distributes-queries", "If PowerDNS itself should distribute queries over threads") = "no"; + ::arg().setSwitch("root-nx-trust", "If set, believe that an NXDOMAIN from the root means the TLD does not exist") = "yes"; + ::arg().setSwitch("any-to-tcp", "Answer ANY queries with tc=1, shunting to TCP") = "no"; + ::arg().setSwitch("lowercase-outgoing", "Force outgoing questions to lowercase") = "no"; + ::arg().setSwitch("gettag-needs-edns-options", "If EDNS Options should be extracted before calling the gettag() hook") = "no"; + ::arg().set("udp-truncation-threshold", "Maximum UDP response size before we truncate") = "1232"; + ::arg().set("edns-outgoing-bufsize", "Outgoing EDNS buffer size") = "1232"; + ::arg().set("minimum-ttl-override", "The minimum TTL") = "1"; + ::arg().set("max-qperq", "Maximum outgoing queries per query") = "60"; + ::arg().set("max-ns-per-resolve", "Maximum number of NS records to consider to resolve a name, 0 is no limit") = "13"; + ::arg().set("max-ns-address-qperq", "Maximum outgoing NS address queries per query") = "10"; + ::arg().set("max-total-msec", "Maximum total wall-clock time per query in milliseconds, 0 for unlimited") = "7000"; + ::arg().set("max-recursion-depth", "Maximum number of internal recursion calls per query, 0 for unlimited") = "40"; + ::arg().set("max-udp-queries-per-round", "Maximum number of UDP queries processed per recvmsg() round, before returning back to normal processing") = "10000"; + ::arg().set("protobuf-use-kernel-timestamp", "Compute the latency of queries in protobuf messages by using the timestamp set by the kernel when the query was received (when available)") = ""; + ::arg().set("distribution-pipe-buffer-size", "Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread") = "0"; + + ::arg().set("include-dir", "Include *.conf files from this directory") = ""; + ::arg().set("security-poll-suffix", "Domain name from which to query security update notifications") = "secpoll.powerdns.com."; #ifdef SO_REUSEPORT - ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "yes"; + ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "yes"; #else - ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "no"; + ::arg().setSwitch("reuseport", "Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address") = "no"; #endif - ::arg().setSwitch("snmp-agent", "If set, register as an SNMP agent") = "no"; - ::arg().set("snmp-master-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon (deprecated)") = ""; - ::arg().set("snmp-daemon-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon") = ""; + ::arg().setSwitch("snmp-agent", "If set, register as an SNMP agent") = "no"; + ::arg().set("snmp-master-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon (deprecated)") = ""; + ::arg().set("snmp-daemon-socket", "If set and snmp-agent is set, the socket to use to register to the SNMP daemon") = ""; - std::string defaultAPIDisabledStats = "cache-bytes, packetcache-bytes, special-memory-usage"; - for (size_t idx = 0; idx < 32; idx++) { - defaultAPIDisabledStats += ", ecs-v4-response-bits-" + std::to_string(idx + 1); - } - for (size_t idx = 0; idx < 128; idx++) { - defaultAPIDisabledStats += ", ecs-v6-response-bits-" + std::to_string(idx + 1); - } - std::string defaultDisabledStats = defaultAPIDisabledStats + ", cumul-clientanswers, cumul-authanswers, policy-hits, proxy-mapping-total, remote-logger-count"; + std::string defaultAPIDisabledStats = "cache-bytes, packetcache-bytes, special-memory-usage"; + for (size_t idx = 0; idx < 32; idx++) { + defaultAPIDisabledStats += ", ecs-v4-response-bits-" + std::to_string(idx + 1); + } + for (size_t idx = 0; idx < 128; idx++) { + defaultAPIDisabledStats += ", ecs-v6-response-bits-" + std::to_string(idx + 1); + } + std::string defaultDisabledStats = defaultAPIDisabledStats + ", cumul-clientanswers, cumul-authanswers, policy-hits, proxy-mapping-total, remote-logger-count"; - ::arg().set("stats-api-blacklist", "List of statistics that are disabled when retrieving the complete list of statistics via the API (deprecated)") = defaultAPIDisabledStats; - ::arg().set("stats-carbon-blacklist", "List of statistics that are prevented from being exported via Carbon (deprecated)") = defaultDisabledStats; - ::arg().set("stats-rec-control-blacklist", "List of statistics that are prevented from being exported via rec_control get-all (deprecated)") = defaultDisabledStats; - ::arg().set("stats-snmp-blacklist", "List of statistics that are prevented from being exported via SNMP (deprecated)") = defaultDisabledStats; + ::arg().set("stats-api-blacklist", "List of statistics that are disabled when retrieving the complete list of statistics via the API (deprecated)") = defaultAPIDisabledStats; + ::arg().set("stats-carbon-blacklist", "List of statistics that are prevented from being exported via Carbon (deprecated)") = defaultDisabledStats; + ::arg().set("stats-rec-control-blacklist", "List of statistics that are prevented from being exported via rec_control get-all (deprecated)") = defaultDisabledStats; + ::arg().set("stats-snmp-blacklist", "List of statistics that are prevented from being exported via SNMP (deprecated)") = defaultDisabledStats; - ::arg().set("stats-api-disabled-list", "List of statistics that are disabled when retrieving the complete list of statistics via the API") = defaultAPIDisabledStats; - ::arg().set("stats-carbon-disabled-list", "List of statistics that are prevented from being exported via Carbon") = defaultDisabledStats; - ::arg().set("stats-rec-control-disabled-list", "List of statistics that are prevented from being exported via rec_control get-all") = defaultDisabledStats; - ::arg().set("stats-snmp-disabled-list", "List of statistics that are prevented from being exported via SNMP") = defaultDisabledStats; + ::arg().set("stats-api-disabled-list", "List of statistics that are disabled when retrieving the complete list of statistics via the API") = defaultAPIDisabledStats; + ::arg().set("stats-carbon-disabled-list", "List of statistics that are prevented from being exported via Carbon") = defaultDisabledStats; + ::arg().set("stats-rec-control-disabled-list", "List of statistics that are prevented from being exported via rec_control get-all") = defaultDisabledStats; + ::arg().set("stats-snmp-disabled-list", "List of statistics that are prevented from being exported via SNMP") = defaultDisabledStats; - ::arg().set("tcp-fast-open", "Enable TCP Fast Open support on the listening sockets, using the supplied numerical value as the queue size") = "0"; - ::arg().set("tcp-fast-open-connect", "Enable TCP Fast Open support on outgoing sockets") = "no"; - ::arg().set("nsec3-max-iterations", "Maximum number of iterations allowed for an NSEC3 record") = "150"; + ::arg().set("tcp-fast-open", "Enable TCP Fast Open support on the listening sockets, using the supplied numerical value as the queue size") = "0"; + ::arg().set("tcp-fast-open-connect", "Enable TCP Fast Open support on outgoing sockets") = "no"; + ::arg().set("nsec3-max-iterations", "Maximum number of iterations allowed for an NSEC3 record") = "150"; - ::arg().set("cpu-map", "Thread to CPU mapping, space separated thread-id=cpu1,cpu2..cpuN pairs") = ""; + ::arg().set("cpu-map", "Thread to CPU mapping, space separated thread-id=cpu1,cpu2..cpuN pairs") = ""; - ::arg().setSwitch("log-rpz-changes", "Log additions and removals to RPZ zones at Info level") = "no"; + ::arg().setSwitch("log-rpz-changes", "Log additions and removals to RPZ zones at Info level") = "no"; - ::arg().set("proxy-protocol-from", "A Proxy Protocol header is only allowed from these subnets") = ""; - ::arg().set("proxy-protocol-maximum-size", "The maximum size of a proxy protocol payload, including the TLV values") = "512"; + ::arg().set("proxy-protocol-from", "A Proxy Protocol header is only allowed from these subnets") = ""; + ::arg().set("proxy-protocol-maximum-size", "The maximum size of a proxy protocol payload, including the TLV values") = "512"; - ::arg().set("dns64-prefix", "DNS64 prefix") = ""; + ::arg().set("dns64-prefix", "DNS64 prefix") = ""; - ::arg().set("udp-source-port-min", "Minimum UDP port to bind on") = "1024"; - ::arg().set("udp-source-port-max", "Maximum UDP port to bind on") = "65535"; - ::arg().set("udp-source-port-avoid", "List of comma separated UDP port number to avoid") = "11211"; - ::arg().set("rng", "Specify random number generator to use. Valid values are auto,sodium,openssl,getrandom,arc4random,urandom.") = "auto"; - ::arg().set("public-suffix-list-file", "Path to the Public Suffix List file, if any") = ""; - ::arg().set("distribution-load-factor", "The load factor used when PowerDNS is distributing queries to worker threads") = "0.0"; + ::arg().set("udp-source-port-min", "Minimum UDP port to bind on") = "1024"; + ::arg().set("udp-source-port-max", "Maximum UDP port to bind on") = "65535"; + ::arg().set("udp-source-port-avoid", "List of comma separated UDP port number to avoid") = "11211"; + ::arg().set("rng", "Specify random number generator to use. Valid values are auto,sodium,openssl,getrandom,arc4random,urandom.") = "auto"; + ::arg().set("public-suffix-list-file", "Path to the Public Suffix List file, if any") = ""; + ::arg().set("distribution-load-factor", "The load factor used when PowerDNS is distributing queries to worker threads") = "0.0"; - ::arg().setSwitch("qname-minimization", "Use Query Name Minimization") = "yes"; - ::arg().setSwitch("nothing-below-nxdomain", "When an NXDOMAIN exists in cache for a name with fewer labels than the qname, send NXDOMAIN without doing a lookup (see RFC 8020)") = "dnssec"; - ::arg().set("max-generate-steps", "Maximum number of $GENERATE steps when loading a zone from a file") = "0"; - ::arg().set("max-include-depth", "Maximum nested $INCLUDE depth when loading a zone from a file") = "20"; + ::arg().setSwitch("qname-minimization", "Use Query Name Minimization") = "yes"; + ::arg().setSwitch("nothing-below-nxdomain", "When an NXDOMAIN exists in cache for a name with fewer labels than the qname, send NXDOMAIN without doing a lookup (see RFC 8020)") = "dnssec"; + ::arg().set("max-generate-steps", "Maximum number of $GENERATE steps when loading a zone from a file") = "0"; + ::arg().set("max-include-depth", "Maximum nested $INCLUDE depth when loading a zone from a file") = "20"; - ::arg().set("record-cache-shards", "Number of shards in the record cache") = "1024"; - ::arg().set("packetcache-shards", "Number of shards in the packet cache") = "1024"; + ::arg().set("record-cache-shards", "Number of shards in the record cache") = "1024"; + ::arg().set("packetcache-shards", "Number of shards in the packet cache") = "1024"; - ::arg().set("refresh-on-ttl-perc", "If a record is requested from the cache and only this % of original TTL remains, refetch") = "0"; - ::arg().set("record-cache-locked-ttl-perc", "Replace records in record cache only after this % of original TTL has passed") = "0"; + ::arg().set("refresh-on-ttl-perc", "If a record is requested from the cache and only this % of original TTL remains, refetch") = "0"; + ::arg().set("record-cache-locked-ttl-perc", "Replace records in record cache only after this % of original TTL has passed") = "0"; - ::arg().set("x-dnssec-names", "Collect DNSSEC statistics for names or suffixes in this list in separate x-dnssec counters") = ""; + ::arg().set("x-dnssec-names", "Collect DNSSEC statistics for names or suffixes in this list in separate x-dnssec counters") = ""; #ifdef NOD_ENABLED - ::arg().set("new-domain-tracking", "Track newly observed domains (i.e. never seen before).") = "no"; - ::arg().set("new-domain-log", "Log newly observed domains.") = "yes"; - ::arg().set("new-domain-lookup", "Perform a DNS lookup newly observed domains as a subdomain of the configured domain") = ""; - ::arg().set("new-domain-history-dir", "Persist new domain tracking data here to persist between restarts") = string(NODCACHEDIR) + "/nod"; - ::arg().set("new-domain-whitelist", "List of domains (and implicitly all subdomains) which will never be considered a new domain (deprecated)") = ""; - ::arg().set("new-domain-ignore-list", "List of domains (and implicitly all subdomains) which will never be considered a new domain") = ""; - ::arg().set("new-domain-db-size", "Size of the DB used to track new domains in terms of number of cells. Defaults to 67108864") = "67108864"; - ::arg().set("new-domain-pb-tag", "If protobuf is configured, the tag to use for messages containing newly observed domains. Defaults to 'pdns-nod'") = "pdns-nod"; - ::arg().set("unique-response-tracking", "Track unique responses (tuple of query name, type and RR).") = "no"; - ::arg().set("unique-response-log", "Log unique responses") = "yes"; - ::arg().set("unique-response-history-dir", "Persist unique response tracking data here to persist between restarts") = string(NODCACHEDIR) + "/udr"; - ::arg().set("unique-response-db-size", "Size of the DB used to track unique responses in terms of number of cells. Defaults to 67108864") = "67108864"; - ::arg().set("unique-response-pb-tag", "If protobuf is configured, the tag to use for messages containing unique DNS responses. Defaults to 'pdns-udr'") = "pdns-udr"; + ::arg().set("new-domain-tracking", "Track newly observed domains (i.e. never seen before).") = "no"; + ::arg().set("new-domain-log", "Log newly observed domains.") = "yes"; + ::arg().set("new-domain-lookup", "Perform a DNS lookup newly observed domains as a subdomain of the configured domain") = ""; + ::arg().set("new-domain-history-dir", "Persist new domain tracking data here to persist between restarts") = string(NODCACHEDIR) + "/nod"; + ::arg().set("new-domain-whitelist", "List of domains (and implicitly all subdomains) which will never be considered a new domain (deprecated)") = ""; + ::arg().set("new-domain-ignore-list", "List of domains (and implicitly all subdomains) which will never be considered a new domain") = ""; + ::arg().set("new-domain-db-size", "Size of the DB used to track new domains in terms of number of cells. Defaults to 67108864") = "67108864"; + ::arg().set("new-domain-pb-tag", "If protobuf is configured, the tag to use for messages containing newly observed domains. Defaults to 'pdns-nod'") = "pdns-nod"; + ::arg().set("unique-response-tracking", "Track unique responses (tuple of query name, type and RR).") = "no"; + ::arg().set("unique-response-log", "Log unique responses") = "yes"; + ::arg().set("unique-response-history-dir", "Persist unique response tracking data here to persist between restarts") = string(NODCACHEDIR) + "/udr"; + ::arg().set("unique-response-db-size", "Size of the DB used to track unique responses in terms of number of cells. Defaults to 67108864") = "67108864"; + ::arg().set("unique-response-pb-tag", "If protobuf is configured, the tag to use for messages containing unique DNS responses. Defaults to 'pdns-udr'") = "pdns-udr"; #endif /* NOD_ENABLED */ - ::arg().setSwitch("extended-resolution-errors", "If set, send an EDNS Extended Error extension on resolution failures, like DNSSEC validation errors") = "no"; + ::arg().setSwitch("extended-resolution-errors", "If set, send an EDNS Extended Error extension on resolution failures, like DNSSEC validation errors") = "no"; - ::arg().set("aggressive-nsec-cache-size", "The number of records to cache in the aggressive cache. If set to a value greater than 0, and DNSSEC processing or validation is enabled, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in rfc8198") = "100000"; - ::arg().set("aggressive-cache-min-nsec3-hit-ratio", "The minimum expected hit ratio to store NSEC3 records into the aggressive cache") = "2000"; + ::arg().set("aggressive-nsec-cache-size", "The number of records to cache in the aggressive cache. If set to a value greater than 0, and DNSSEC processing or validation is enabled, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in rfc8198") = "100000"; + ::arg().set("aggressive-cache-min-nsec3-hit-ratio", "The minimum expected hit ratio to store NSEC3 records into the aggressive cache") = "2000"; - ::arg().set("edns-padding-from", "List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that 'edns-padding-mode' applies") = ""; - ::arg().set("edns-padding-mode", "Whether to add EDNS padding to all responses ('always') or only to responses for queries containing the EDNS padding option ('padded-queries-only', the default). In both modes, padding will only be added to responses for queries coming from `edns-padding-from`_ sources") = "padded-queries-only"; - ::arg().set("edns-padding-tag", "Packetcache tag associated to responses sent with EDNS padding, to prevent sending these to clients for which padding is not enabled.") = "7830"; - ::arg().setSwitch("edns-padding-out", "Whether to add EDNS padding to outgoing DoT messages") = "yes"; + ::arg().set("edns-padding-from", "List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that 'edns-padding-mode' applies") = ""; + ::arg().set("edns-padding-mode", "Whether to add EDNS padding to all responses ('always') or only to responses for queries containing the EDNS padding option ('padded-queries-only', the default). In both modes, padding will only be added to responses for queries coming from `edns-padding-from`_ sources") = "padded-queries-only"; + ::arg().set("edns-padding-tag", "Packetcache tag associated to responses sent with EDNS padding, to prevent sending these to clients for which padding is not enabled.") = "7830"; + ::arg().setSwitch("edns-padding-out", "Whether to add EDNS padding to outgoing DoT messages") = "yes"; - ::arg().setSwitch("dot-to-port-853", "Force DoT connection to target port 853 if DoT compiled in") = "yes"; - ::arg().set("dot-to-auth-names", "Use DoT to authoritative servers with these names or suffixes") = ""; - ::arg().set("event-trace-enabled", "If set, event traces are collected and send out via protobuf logging (1), logfile (2) or both(3)") = "0"; + ::arg().setSwitch("dot-to-port-853", "Force DoT connection to target port 853 if DoT compiled in") = "yes"; + ::arg().set("dot-to-auth-names", "Use DoT to authoritative servers with these names or suffixes") = ""; + ::arg().set("event-trace-enabled", "If set, event traces are collected and send out via protobuf logging (1), logfile (2) or both(3)") = "0"; - ::arg().set("tcp-out-max-idle-ms", "Time TCP/DoT connections are left idle in milliseconds or 0 if no limit") = "10000"; - ::arg().set("tcp-out-max-idle-per-auth", "Maximum number of idle TCP/DoT connections to a specific IP per thread, 0 means do not keep idle connections open") = "10"; - ::arg().set("tcp-out-max-queries", "Maximum total number of queries per TCP/DoT connection, 0 means no limit") = "0"; - ::arg().set("tcp-out-max-idle-per-thread", "Maximum number of idle TCP/DoT connections per thread") = "100"; - ::arg().setSwitch("structured-logging", "Prefer structured logging") = "yes"; - ::arg().set("structured-logging-backend", "Structured logging backend") = "default"; - ::arg().setSwitch("save-parent-ns-set", "Save parent NS set to be used if child NS set fails") = "yes"; - ::arg().set("max-busy-dot-probes", "Maximum number of concurrent DoT probes") = "0"; - ::arg().set("serve-stale-extensions", "Number of times a record's ttl is extended by 30s to be served stale") = "0"; + ::arg().set("tcp-out-max-idle-ms", "Time TCP/DoT connections are left idle in milliseconds or 0 if no limit") = "10000"; + ::arg().set("tcp-out-max-idle-per-auth", "Maximum number of idle TCP/DoT connections to a specific IP per thread, 0 means do not keep idle connections open") = "10"; + ::arg().set("tcp-out-max-queries", "Maximum total number of queries per TCP/DoT connection, 0 means no limit") = "0"; + ::arg().set("tcp-out-max-idle-per-thread", "Maximum number of idle TCP/DoT connections per thread") = "100"; + ::arg().setSwitch("structured-logging", "Prefer structured logging") = "yes"; + ::arg().set("structured-logging-backend", "Structured logging backend") = "default"; + ::arg().setSwitch("save-parent-ns-set", "Save parent NS set to be used if child NS set fails") = "yes"; + ::arg().set("max-busy-dot-probes", "Maximum number of concurrent DoT probes") = "0"; + ::arg().set("serve-stale-extensions", "Number of times a record's ttl is extended by 30s to be served stale") = "0"; - ::arg().setCmd("help", "Provide a helpful message"); - ::arg().setCmd("version", "Print version string"); - ::arg().setCmd("config", "Output blank configuration. You can use --config=check to test the config file and command line arguments."); - ::arg().setDefaults(); - g_log.toConsole(Logger::Info); + ::arg().setCmd("help", "Provide a helpful message"); + ::arg().setCmd("version", "Print version string"); + ::arg().setCmd("config", "Output blank configuration. You can use --config=check to test the config file and command line arguments."); + ::arg().setDefaults(); + g_log.toConsole(Logger::Info); } -static pair doConfig(Logr::log_t startupLog, const string& configname, int argc, char *argv[]) // NOLINT: Posix API +static pair doConfig(Logr::log_t startupLog, const string& configname, int argc, char* argv[]) // NOLINT: Posix API { if (::arg().mustDo("config")) { string config = ::arg()["config"]; @@ -3112,7 +3118,8 @@ int main(int argc, char** argv) if (::arg()["socket-dir"].empty()) { if (::arg()["chroot"].empty()) { ::arg().set("socket-dir") = std::string(LOCALSTATEDIR) + "/pdns-recursor"; - } else { + } + else { ::arg().set("socket-dir") = "/"; } } From 434c5804208755de253214c3a0046c144e812a6a Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 8 May 2023 10:58:29 +0200 Subject: [PATCH 140/909] Split recursorThread() to reduce complexity --- pdns/recursordist/rec-main.cc | 550 ++++++++++++++++++---------------- 1 file changed, 290 insertions(+), 260 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index c43e633a2dc6..d7243ce21702 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -45,6 +45,8 @@ #ifdef HAVE_LIBSODIUM #include + +#include #endif #ifdef HAVE_SYSTEMD @@ -2216,194 +2218,201 @@ class PeriodicTask const string name; }; -static void houseKeeping(void*) +static void houseKeeping0(Logr::log_t log) { - auto log = g_slog->withName("housekeeping"); - static thread_local bool t_running; // houseKeeping can get suspended in secpoll, and be restarted, which makes us do duplicate work - - try { - if (t_running) { - return; - } - t_running = true; - - struct timeval now; - Utility::gettimeofday(&now); - t_Counters.updateSnap(now, g_regressionTestMode); + struct timeval now + { + }; + Utility::gettimeofday(&now); + t_Counters.updateSnap(now, g_regressionTestMode); - // Below are the tasks that run for every recursorThread, including handler and taskThread + // Below are the tasks that run for every recursorThread, including handler and taskThread - static thread_local PeriodicTask pruneTCPTask{"pruneTCPTask", 5}; - pruneTCPTask.runIfDue(now, [now]() { - t_tcp_manager.cleanup(now); - }); + static thread_local PeriodicTask pruneTCPTask{"pruneTCPTask", 5}; + pruneTCPTask.runIfDue(now, [now]() { + t_tcp_manager.cleanup(now); + }); - const auto& info = RecThreadInfo::self(); + const auto& info = RecThreadInfo::self(); - // Threads handling packets process config changes in the input path, but not all threads process input packets - // distr threads only process TCP, so that may not happenn very often. So do all periodically. - static thread_local PeriodicTask exportConfigTask{"exportConfigTask", 30}; - auto luaconfsLocal = g_luaconfs.getLocal(); - exportConfigTask.runIfDue(now, [&luaconfsLocal]() { - checkProtobufExport(luaconfsLocal); - checkOutgoingProtobufExport(luaconfsLocal); + // Threads handling packets process config changes in the input path, but not all threads process input packets + // distr threads only process TCP, so that may not happenn very often. So do all periodically. + static thread_local PeriodicTask exportConfigTask{"exportConfigTask", 30}; + auto luaconfsLocal = g_luaconfs.getLocal(); + exportConfigTask.runIfDue(now, [&luaconfsLocal]() { + checkProtobufExport(luaconfsLocal); + checkOutgoingProtobufExport(luaconfsLocal); #ifdef HAVE_FSTRM - checkFrameStreamExport(luaconfsLocal, luaconfsLocal->frameStreamExportConfig, t_frameStreamServersInfo); - checkFrameStreamExport(luaconfsLocal, luaconfsLocal->nodFrameStreamExportConfig, t_nodFrameStreamServersInfo); + checkFrameStreamExport(luaconfsLocal, luaconfsLocal->frameStreamExportConfig, t_frameStreamServersInfo); + checkFrameStreamExport(luaconfsLocal, luaconfsLocal->nodFrameStreamExportConfig, t_nodFrameStreamServersInfo); #endif - }); + }); - // Below are the thread specific tasks for the handler and the taskThread - // Likley a few handler tasks could be moved to the taskThread - if (info.isTaskThread()) { - // TaskQueue is run always - runTasks(10, g_logCommonErrors); - - static PeriodicTask ztcTask{"ZTC", 60}; - static map ztcStates; - ztcTask.runIfDue(now, [&luaconfsLocal]() { - RecZoneToCache::maintainStates(luaconfsLocal->ztcConfigs, ztcStates, luaconfsLocal->generation); - for (auto& ztc : luaconfsLocal->ztcConfigs) { - RecZoneToCache::ZoneToCache(ztc.second, ztcStates.at(ztc.first)); - } - }); - } - else if (info.isHandler()) { - if (g_packetCache) { - static PeriodicTask packetCacheTask{"packetCacheTask", 5}; - packetCacheTask.runIfDue(now, []() { - g_packetCache->doPruneTo(g_maxPacketCacheEntries); - }); + // Below are the thread specific tasks for the handler and the taskThread + // Likley a few handler tasks could be moved to the taskThread + if (info.isTaskThread()) { + // TaskQueue is run always + runTasks(10, g_logCommonErrors); + + static PeriodicTask ztcTask{"ZTC", 60}; + static map ztcStates; + ztcTask.runIfDue(now, [&luaconfsLocal]() { + RecZoneToCache::maintainStates(luaconfsLocal->ztcConfigs, ztcStates, luaconfsLocal->generation); + for (const auto& ztc : luaconfsLocal->ztcConfigs) { + RecZoneToCache::ZoneToCache(ztc.second, ztcStates.at(ztc.first)); } - static PeriodicTask recordCachePruneTask{"RecordCachePruneTask", 5}; - recordCachePruneTask.runIfDue(now, []() { - g_recCache->doPrune(g_maxCacheEntries); + }); + } + else if (info.isHandler()) { + if (g_packetCache) { + static PeriodicTask packetCacheTask{"packetCacheTask", 5}; + packetCacheTask.runIfDue(now, []() { + g_packetCache->doPruneTo(g_maxPacketCacheEntries); }); + } + static PeriodicTask recordCachePruneTask{"RecordCachePruneTask", 5}; + recordCachePruneTask.runIfDue(now, []() { + g_recCache->doPrune(g_maxCacheEntries); + }); - static PeriodicTask negCachePruneTask{"NegCachePrunteTask", 5}; - negCachePruneTask.runIfDue(now, []() { - g_negCache->prune(g_maxCacheEntries / 8); - }); + static PeriodicTask negCachePruneTask{"NegCachePrunteTask", 5}; + negCachePruneTask.runIfDue(now, []() { + g_negCache->prune(g_maxCacheEntries / 8); + }); - static PeriodicTask aggrNSECPruneTask{"AggrNSECPruneTask", 5}; - aggrNSECPruneTask.runIfDue(now, [now]() { - if (g_aggressiveNSECCache) { - g_aggressiveNSECCache->prune(now.tv_sec); - } - }); + static PeriodicTask aggrNSECPruneTask{"AggrNSECPruneTask", 5}; + aggrNSECPruneTask.runIfDue(now, [now]() { + if (g_aggressiveNSECCache) { + g_aggressiveNSECCache->prune(now.tv_sec); + } + }); - static PeriodicTask pruneNSpeedTask{"pruneNSSpeedTask", 30}; - pruneNSpeedTask.runIfDue(now, [now]() { - SyncRes::pruneNSSpeeds(now.tv_sec - 300); - }); + static PeriodicTask pruneNSpeedTask{"pruneNSSpeedTask", 30}; + pruneNSpeedTask.runIfDue(now, [now]() { + SyncRes::pruneNSSpeeds(now.tv_sec - 300); + }); + + static PeriodicTask pruneEDNSTask{"pruneEDNSTask", 60}; + pruneEDNSTask.runIfDue(now, [now]() { + SyncRes::pruneEDNSStatuses(now.tv_sec); + }); - static PeriodicTask pruneEDNSTask{"pruneEDNSTask", 60}; - pruneEDNSTask.runIfDue(now, [now]() { - SyncRes::pruneEDNSStatuses(now.tv_sec); + if (SyncRes::s_max_busy_dot_probes > 0) { + static PeriodicTask pruneDoTProbeMap{"pruneDoTProbeMapTask", 60}; + pruneDoTProbeMap.runIfDue(now, [now]() { + SyncRes::pruneDoTProbeMap(now.tv_sec); }); + } - if (SyncRes::s_max_busy_dot_probes > 0) { - static PeriodicTask pruneDoTProbeMap{"pruneDoTProbeMapTask", 60}; - pruneDoTProbeMap.runIfDue(now, [now]() { - SyncRes::pruneDoTProbeMap(now.tv_sec); - }); - } + static PeriodicTask pruneThrottledTask{"pruneThrottledTask", 5}; + pruneThrottledTask.runIfDue(now, [now]() { + SyncRes::pruneThrottledServers(now.tv_sec); + }); - static PeriodicTask pruneThrottledTask{"pruneThrottledTask", 5}; - pruneThrottledTask.runIfDue(now, [now]() { - SyncRes::pruneThrottledServers(now.tv_sec); - }); + static PeriodicTask pruneFailedServersTask{"pruneFailedServerTask", 5}; + pruneFailedServersTask.runIfDue(now, [now]() { + SyncRes::pruneFailedServers(now.tv_sec - static_cast(SyncRes::s_serverdownthrottletime * 10)); + }); - static PeriodicTask pruneFailedServersTask{"pruneFailedServerTask", 5}; - pruneFailedServersTask.runIfDue(now, [now]() { - SyncRes::pruneFailedServers(now.tv_sec - SyncRes::s_serverdownthrottletime * 10); - }); + static PeriodicTask pruneNonResolvingTask{"pruneNonResolvingTask", 5}; + pruneNonResolvingTask.runIfDue(now, [now]() { + SyncRes::pruneNonResolving(now.tv_sec - SyncRes::s_nonresolvingnsthrottletime); + }); - static PeriodicTask pruneNonResolvingTask{"pruneNonResolvingTask", 5}; - pruneNonResolvingTask.runIfDue(now, [now]() { - SyncRes::pruneNonResolving(now.tv_sec - SyncRes::s_nonresolvingnsthrottletime); - }); + static PeriodicTask pruneSaveParentSetTask{"pruneSaveParentSetTask", 60}; + pruneSaveParentSetTask.runIfDue(now, [now]() { + SyncRes::pruneSaveParentsNSSets(now.tv_sec); + }); - static PeriodicTask pruneSaveParentSetTask{"pruneSaveParentSetTask", 60}; - pruneSaveParentSetTask.runIfDue(now, [now]() { - SyncRes::pruneSaveParentsNSSets(now.tv_sec); - }); + // By default, refresh at 80% of max-cache-ttl with a minimum period of 10s + const unsigned int minRootRefreshInterval = 10; + static PeriodicTask rootUpdateTask{"rootUpdateTask", std::max(SyncRes::s_maxcachettl * 8 / 10, minRootRefreshInterval)}; + rootUpdateTask.runIfDue(now, [now, &log, minRootRefreshInterval]() { + int res = 0; + if (!g_regressionTestMode) { + res = SyncRes::getRootNS(now, nullptr, 0, log); + } + if (res == 0) { + // Success, go back to the defaut period + rootUpdateTask.setPeriod(std::max(SyncRes::s_maxcachettl * 8 / 10, minRootRefreshInterval)); + } + else { + // On failure, go to the middle of the remaining period (initially 80% / 8 = 10%) and shorten the interval on each + // failure by dividing the existing interval by 8, keeping the minimum interval at 10s. + // So with a 1 day period and failures we'll see a refresh attempt at 69120, 69120+11520, 69120+11520+1440, ... + rootUpdateTask.setPeriod(std::max(rootUpdateTask.getPeriod() / 8, minRootRefreshInterval)); + } + }); - // By default, refresh at 80% of max-cache-ttl with a minimum period of 10s - const unsigned int minRootRefreshInterval = 10; - static PeriodicTask rootUpdateTask{"rootUpdateTask", std::max(SyncRes::s_maxcachettl * 8 / 10, minRootRefreshInterval)}; - rootUpdateTask.runIfDue(now, [now, &log, minRootRefreshInterval]() { - int res = 0; - if (!g_regressionTestMode) { - res = SyncRes::getRootNS(now, nullptr, 0, log); - } - if (res == 0) { - // Success, go back to the defaut period - rootUpdateTask.setPeriod(std::max(SyncRes::s_maxcachettl * 8 / 10, minRootRefreshInterval)); - } - else { - // On failure, go to the middle of the remaining period (initially 80% / 8 = 10%) and shorten the interval on each - // failure by dividing the existing interval by 8, keeping the minimum interval at 10s. - // So with a 1 day period and failures we'll see a refresh attempt at 69120, 69120+11520, 69120+11520+1440, ... - rootUpdateTask.setPeriod(std::max(rootUpdateTask.getPeriod() / 8, minRootRefreshInterval)); - } - }); + static PeriodicTask secpollTask{"secpollTask", 3600}; + static time_t t_last_secpoll; + secpollTask.runIfDue(now, [&log]() { + try { + doSecPoll(&t_last_secpoll, log); + } + catch (const std::exception& e) { + SLOG(g_log << Logger::Error << "Exception while performing security poll: " << e.what() << endl, + log->error(Logr::Error, e.what(), "Exception while performing security poll")); + } + catch (const PDNSException& e) { + SLOG(g_log << Logger::Error << "Exception while performing security poll: " << e.reason << endl, + log->error(Logr::Error, e.reason, "Exception while performing security poll")); + } + catch (const ImmediateServFailException& e) { + SLOG(g_log << Logger::Error << "Exception while performing security poll: " << e.reason << endl, + log->error(Logr::Error, e.reason, "Exception while performing security poll")); + } + catch (const PolicyHitException& e) { + SLOG(g_log << Logger::Error << "Policy hit while performing security poll" << endl, + log->info(Logr::Error, "Policy hit while performing security poll")); + } + catch (...) { + SLOG(g_log << Logger::Error << "Exception while performing security poll" << endl, + log->info(Logr::Error, "Exception while performing security poll")); + } + }); - static PeriodicTask secpollTask{"secpollTask", 3600}; - static time_t t_last_secpoll; - secpollTask.runIfDue(now, [&log]() { + const time_t taInterval = std::max(1, static_cast(luaconfsLocal->trustAnchorFileInfo.interval) * 3600); + static PeriodicTask trustAnchorTask{"trustAnchorTask", taInterval}; + if (!trustAnchorTask.hasRun()) { + // Loading the Lua config file already "refreshed" the TAs + trustAnchorTask.updateLastRun(); + } + // interval might have ben updated + trustAnchorTask.setPeriod(taInterval); + trustAnchorTask.runIfDue(now, [&luaconfsLocal, &log]() { + if (!luaconfsLocal->trustAnchorFileInfo.fname.empty() && luaconfsLocal->trustAnchorFileInfo.interval != 0) { + SLOG(g_log << Logger::Debug << "Refreshing Trust Anchors from file" << endl, + log->info(Logr::Debug, "Refreshing Trust Anchors from file")); try { - doSecPoll(&t_last_secpoll, log); - } - catch (const std::exception& e) { - SLOG(g_log << Logger::Error << "Exception while performing security poll: " << e.what() << endl, - log->error(Logr::Error, e.what(), "Exception while performing security poll")); - } - catch (const PDNSException& e) { - SLOG(g_log << Logger::Error << "Exception while performing security poll: " << e.reason << endl, - log->error(Logr::Error, e.reason, "Exception while performing security poll")); - } - catch (const ImmediateServFailException& e) { - SLOG(g_log << Logger::Error << "Exception while performing security poll: " << e.reason << endl, - log->error(Logr::Error, e.reason, "Exception while performing security poll")); - } - catch (const PolicyHitException& e) { - SLOG(g_log << Logger::Error << "Policy hit while performing security poll" << endl, - log->info(Logr::Error, "Policy hit while performing security poll")); + map dsAnchors; + if (updateTrustAnchorsFromFile(luaconfsLocal->trustAnchorFileInfo.fname, dsAnchors, log)) { + g_luaconfs.modify([&dsAnchors](LuaConfigItems& lci) { + lci.dsAnchors = dsAnchors; + }); + } } - catch (...) { - SLOG(g_log << Logger::Error << "Exception while performing security poll" << endl, - log->info(Logr::Error, "Exception while performing security poll")); + catch (const PDNSException& pe) { + SLOG(g_log << Logger::Error << "Unable to update Trust Anchors: " << pe.reason << endl, + log->error(Logr::Error, pe.reason, "Unable to update Trust Anchors")); } - }); - - static PeriodicTask trustAnchorTask{"trustAnchorTask", std::max(1U, luaconfsLocal->trustAnchorFileInfo.interval) * 3600}; - if (!trustAnchorTask.hasRun()) { - // Loading the Lua config file already "refreshed" the TAs - trustAnchorTask.updateLastRun(); } - // interval might have ben updated - trustAnchorTask.setPeriod(std::max(1U, luaconfsLocal->trustAnchorFileInfo.interval) * 3600); - trustAnchorTask.runIfDue(now, [&luaconfsLocal, &log]() { - if (!luaconfsLocal->trustAnchorFileInfo.fname.empty() && luaconfsLocal->trustAnchorFileInfo.interval != 0) { - SLOG(g_log << Logger::Debug << "Refreshing Trust Anchors from file" << endl, - log->info(Logr::Debug, "Refreshing Trust Anchors from file")); - try { - map dsAnchors; - if (updateTrustAnchorsFromFile(luaconfsLocal->trustAnchorFileInfo.fname, dsAnchors, log)) { - g_luaconfs.modify([&dsAnchors](LuaConfigItems& lci) { - lci.dsAnchors = dsAnchors; - }); - } - } - catch (const PDNSException& pe) { - SLOG(g_log << Logger::Error << "Unable to update Trust Anchors: " << pe.reason << endl, - log->error(Logr::Error, pe.reason, "Unable to update Trust Anchors")); - } - } - }); + }); + } + t_Counters.updateSnap(g_regressionTestMode); +} + +static void houseKeeping(void* /* ignored */) +{ + auto log = g_slog->withName("housekeeping"); + static thread_local bool t_running; // houseKeeping can get suspended in secpoll, and be restarted, which makes us do duplicate work + + try { + if (t_running) { + return; } - t_Counters.updateSnap(g_regressionTestMode); + t_running = true; + houseKeeping0(log); t_running = false; } catch (const PDNSException& ae) { @@ -2420,6 +2429,117 @@ static void houseKeeping(void*) } } +static void runLuaMaintenance(RecThreadInfo& threadInfo, time_t& last_lua_maintenance, time_t luaMaintenanceInterval) +{ + if (t_pdl != nullptr) { + // lua-dns-script directive is present, call the maintenance callback if needed + /* remember that the listener threads handle TCP queries */ + if (threadInfo.isWorker() || threadInfo.isListener()) { + // Only on threads processing queries + if (g_now.tv_sec - last_lua_maintenance >= luaMaintenanceInterval) { + struct timeval start{}; + Utility::gettimeofday(&start); + t_pdl->maintenance(); + last_lua_maintenance = g_now.tv_sec; + struct timeval stop{}; + Utility::gettimeofday(&stop); + t_Counters.at(rec::Counter::maintenanceUsec) += uSec(stop - start); + ++t_Counters.at(rec::Counter::maintenanceCalls); + } + } + } +} + +static void runTCPMaintenance(RecThreadInfo& threadInfo, bool& listenOnTCP, unsigned int maxTcpClients) +{ + if (threadInfo.isListener()) { + if (listenOnTCP) { + if (TCPConnection::getCurrentConnections() > maxTcpClients) { // shutdown, too many connections + for (const auto fileDesc : threadInfo.tcpSockets) { + t_fdm->removeReadFD(fileDesc); + } + listenOnTCP = false; + } + } + else { + if (TCPConnection::getCurrentConnections() <= maxTcpClients) { // reenable + for (const auto fileDesc : threadInfo.tcpSockets) { + t_fdm->addReadFD(fileDesc, handleNewTCPQuestion); + } + listenOnTCP = true; + } + } + } +} + +static void recLoop() +{ + unsigned int maxTcpClients = ::arg().asNum("max-tcp-clients"); + bool listenOnTCP{true}; + time_t last_stat = 0; + time_t last_carbon = 0; + time_t last_lua_maintenance = 0; + time_t carbonInterval = ::arg().asNum("carbon-interval"); + time_t luaMaintenanceInterval = ::arg().asNum("lua-maintenance-interval"); + + auto& threadInfo = RecThreadInfo::self(); + + while (!RecursorControlChannel::stop) { + while (MT->schedule(&g_now)) { + ; // MTasker letting the mthreads do their thing + } + + // Use primes, it avoid not being scheduled in cases where the counter has a regular pattern. + // We want to call handler thread often, it gets scheduled about 2 times per second + if (((threadInfo.isHandler() || threadInfo.isTaskThread()) && s_counter % 11 == 0) || s_counter % 499 == 0) { + struct timeval start{}; + Utility::gettimeofday(&start); + MT->makeThread(houseKeeping, nullptr); + if (!threadInfo.isTaskThread()) { + struct timeval stop{}; + Utility::gettimeofday(&stop); + t_Counters.at(rec::Counter::maintenanceUsec) += uSec(stop - start); + ++t_Counters.at(rec::Counter::maintenanceCalls); + } + } + + if (s_counter % 55 == 0) { + auto expired = t_fdm->getTimeouts(g_now); + + for (const auto & exp : expired) { + auto conn = boost::any_cast>(exp.second); + if (g_logCommonErrors) { + SLOG(g_log << Logger::Warning << "Timeout from remote TCP client " << conn->d_remote.toStringWithPort() << endl, // NOLINT: union access + g_slogtcpin->info(Logr::Warning, "Timeout from remote TCP client", "remote", Logging::Loggable(conn->d_remote))); + } + t_fdm->removeReadFD(exp.first); + } + } + + s_counter++; + + if (threadInfo.isHandler()) { + if (statsWanted || (s_statisticsInterval > 0 && (g_now.tv_sec - last_stat) >= s_statisticsInterval)) { + doStats(); + last_stat = g_now.tv_sec; + } + + Utility::gettimeofday(&g_now, nullptr); + + if ((g_now.tv_sec - last_carbon) >= carbonInterval) { + MT->makeThread(doCarbonDump, nullptr); + last_carbon = g_now.tv_sec; + } + } + runLuaMaintenance(threadInfo, last_lua_maintenance, luaMaintenanceInterval); + + t_fdm->run(&g_now); + // 'run' updates g_now for us + + runTCPMaintenance(threadInfo, listenOnTCP, maxTcpClients); + } +} + static void recursorThread() { auto log = g_slog->withName("runtime"); @@ -2444,7 +2564,7 @@ static void recursorThread() if (threadInfo.isHandler()) { if (!primeHints()) { threadInfo.setExitCode(EXIT_FAILURE); - RecursorControlChannel::stop = 1; + RecursorControlChannel::stop = true; SLOG(g_log << Logger::Critical << "Priming cache failed, stopping" << endl, log->info(Logr::Critical, "Priming cache failed, stopping")); } @@ -2454,8 +2574,9 @@ static void recursorThread() } #ifdef NOD_ENABLED - if (threadInfo.isWorker()) + if (threadInfo.isWorker()) { setupNODThread(log); + } #endif /* NOD_ENABLED */ /* the listener threads handle TCP queries */ @@ -2476,12 +2597,14 @@ static void recursorThread() } unsigned int ringsize = ::arg().asNum("stats-ringbuffer-entries") / RecThreadInfo::numWorkers(); - if (ringsize) { + if (ringsize != 0) { t_remotes = std::make_unique(); - if (RecThreadInfo::weDistributeQueries()) + if (RecThreadInfo::weDistributeQueries()) { t_remotes->set_capacity(::arg().asNum("stats-ringbuffer-entries") / RecThreadInfo::numDistributors()); - else + } + else { t_remotes->set_capacity(ringsize); + } t_servfailremotes = std::make_unique(); t_servfailremotes->set_capacity(ringsize); t_bogusremotes = std::make_unique(); @@ -2555,15 +2678,6 @@ static void recursorThread() t_fdm->addReadFD(g_rcc.d_fd, handleRCC); // control channel } - unsigned int maxTcpClients = ::arg().asNum("max-tcp-clients"); - - bool listenOnTCP{true}; - - time_t last_stat = 0; - time_t last_carbon = 0, last_lua_maintenance = 0; - time_t carbonInterval = ::arg().asNum("carbon-interval"); - time_t luaMaintenanceInterval = ::arg().asNum("lua-maintenance-interval"); - #ifdef HAVE_SYSTEMD if (threadInfo.isHandler()) { // There is a race, as some threads might not be ready yet to do work. @@ -2572,92 +2686,8 @@ static void recursorThread() sd_notify(0, "READY=1"); } #endif - while (!RecursorControlChannel::stop) { - while (MT->schedule(&g_now)) - ; // MTasker letting the mthreads do their thing - - // Use primes, it avoid not being scheduled in cases where the counter has a regular pattern. - // We want to call handler thread often, it gets scheduled about 2 times per second - if (((threadInfo.isHandler() || threadInfo.isTaskThread()) && s_counter % 11 == 0) || s_counter % 499 == 0) { - struct timeval start; - Utility::gettimeofday(&start); - MT->makeThread(houseKeeping, nullptr); - if (!threadInfo.isTaskThread()) { - struct timeval stop; - Utility::gettimeofday(&stop); - t_Counters.at(rec::Counter::maintenanceUsec) += uSec(stop - start); - ++t_Counters.at(rec::Counter::maintenanceCalls); - } - } - - if (!(s_counter % 55)) { - typedef vector> expired_t; - expired_t expired = t_fdm->getTimeouts(g_now); - - for (expired_t::iterator i = expired.begin(); i != expired.end(); ++i) { - shared_ptr conn = boost::any_cast>(i->second); - if (g_logCommonErrors) - SLOG(g_log << Logger::Warning << "Timeout from remote TCP client " << conn->d_remote.toStringWithPort() << endl, - g_slogtcpin->info(Logr::Warning, "Timeout from remote TCP client", "remote", Logging::Loggable(conn->d_remote))); - t_fdm->removeReadFD(i->first); - } - } - - s_counter++; - - if (threadInfo.isHandler()) { - if (statsWanted || (s_statisticsInterval > 0 && (g_now.tv_sec - last_stat) >= s_statisticsInterval)) { - doStats(); - last_stat = g_now.tv_sec; - } - - Utility::gettimeofday(&g_now, nullptr); - if ((g_now.tv_sec - last_carbon) >= carbonInterval) { - MT->makeThread(doCarbonDump, 0); - last_carbon = g_now.tv_sec; - } - } - if (t_pdl != nullptr) { - // lua-dns-script directive is present, call the maintenance callback if needed - /* remember that the listener threads handle TCP queries */ - if (threadInfo.isWorker() || threadInfo.isListener()) { - // Only on threads processing queries - if (g_now.tv_sec - last_lua_maintenance >= luaMaintenanceInterval) { - struct timeval start; - Utility::gettimeofday(&start); - t_pdl->maintenance(); - last_lua_maintenance = g_now.tv_sec; - struct timeval stop; - Utility::gettimeofday(&stop); - t_Counters.at(rec::Counter::maintenanceUsec) += uSec(stop - start); - ++t_Counters.at(rec::Counter::maintenanceCalls); - } - } - } - - t_fdm->run(&g_now); - // 'run' updates g_now for us - - if (threadInfo.isListener()) { - if (listenOnTCP) { - if (TCPConnection::getCurrentConnections() > maxTcpClients) { // shutdown, too many connections - for (const auto fd : threadInfo.tcpSockets) { - t_fdm->removeReadFD(fd); - } - listenOnTCP = false; - } - } - else { - if (TCPConnection::getCurrentConnections() <= maxTcpClients) { // reenable - for (const auto fd : threadInfo.tcpSockets) { - t_fdm->addReadFD(fd, handleNewTCPQuestion); - } - listenOnTCP = true; - } - } - } - } + recLoop(); } catch (PDNSException& ae) { SLOG(g_log << Logger::Error << "Exception: " << ae.reason << endl, From 3273775ce4417b18a597f086a2ff8fcacda6abd0 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 8 May 2023 11:07:10 +0200 Subject: [PATCH 141/909] Some general clang-tidy cleanup --- pdns/recursordist/rec-main.cc | 63 ++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 27 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index d7243ce21702..91fe7d4dd4a2 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1247,28 +1247,29 @@ void broadcastFunction(const pipefunc_t& func) func(); } - unsigned int n = 0; + unsigned int thread = 0; for (const auto& threadInfo : RecThreadInfo::infos()) { - if (n++ == RecThreadInfo::id()) { + if (thread++ == RecThreadInfo::id()) { func(); // don't write to ourselves! continue; } - ThreadMSG* tmsg = new ThreadMSG(); + ThreadMSG* tmsg = new ThreadMSG(); // NOLINT: manual onwership handling tmsg->func = func; tmsg->wantAnswer = true; - if (write(threadInfo.pipes.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { - delete tmsg; + if (write(threadInfo.pipes.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // NOLINT: sizeof correct + delete tmsg; // NOLINT: manual ownership handling unixDie("write to thread pipe returned wrong size or error"); } string* resp = nullptr; - if (read(threadInfo.pipes.readFromThread, &resp, sizeof(resp)) != sizeof(resp)) + if (read(threadInfo.pipes.readFromThread, &resp, sizeof(resp)) != sizeof(resp)) { // NOLINT: sizeof correct unixDie("read from thread pipe returned wrong size or error"); + } - if (resp) { - delete resp; + if (resp != nullptr) { + delete resp; // NOLINT: manual ownership handling resp = nullptr; } // coverity[leaked_storage] @@ -1324,30 +1325,30 @@ T broadcastAccFunction(const std::function& func) _exit(1); } - unsigned int n = 0; + unsigned int thread = 0; T ret = T(); for (const auto& threadInfo : RecThreadInfo::infos()) { - if (n++ == RecThreadInfo::id()) { + if (thread++ == RecThreadInfo::id()) { continue; } const auto& tps = threadInfo.pipes; - ThreadMSG* tmsg = new ThreadMSG(); + ThreadMSG* tmsg = new ThreadMSG(); // NOLINT: manual ownership handling tmsg->func = [func] { return voider(func); }; tmsg->wantAnswer = true; - if (write(tps.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { - delete tmsg; + if (write(tps.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // NOLINT:: sizeof correct + delete tmsg; // NOLINT: manual ownership handling unixDie("write to thread pipe returned wrong size or error"); } T* resp = nullptr; - if (read(tps.readFromThread, &resp, sizeof(resp)) != sizeof(resp)) + if (read(tps.readFromThread, &resp, sizeof(resp)) != sizeof(resp)) // NOLINT: sizeof correct unixDie("read from thread pipe returned wrong size or error"); if (resp) { ret += *resp; - delete resp; + delete resp; // NOLINT: manual ownershipm handling resp = nullptr; } // coverity[leaked_storage] @@ -1780,7 +1781,7 @@ static int initControl(Logr::log_t log, uid_t newuid, int forks) // NOLINT(bugpr return 0; } -static void initSuffixMatchNodes() +static void initSuffixMatchNodes([[maybe_unused]] Logr::log_t log) { { SuffixMatchNode dontThrottleNames; @@ -2024,7 +2025,7 @@ static int serviceMain(Logr::log_t log) SLOG(g_log << Logger::Debug << "NSEC3 aggressive cache tuning: aggressive-cache-min-nsec3-hit-ratio: " << ::arg().asNum("aggressive-cache-min-nsec3-hit-ratio") << " max common prefix bits: " << std::to_string(AggressiveNSECCache::s_maxNSEC3CommonPrefix) << endl, log->info(Logr::Debug, "NSEC3 aggressive cache tuning", "aggressive-cache-min-nsec3-hit-ratio", Logging::Loggable(::arg().asNum("aggressive-cache-min-nsec3-hit-ratio")), "maxCommonPrefixBits", Logging::Loggable(AggressiveNSECCache::s_maxNSEC3CommonPrefix))); - initSuffixMatchNodes(); + initSuffixMatchNodes(log); initCarbon(); initDistribution(log); @@ -2105,15 +2106,15 @@ static int serviceMain(Logr::log_t log) return RecThreadInfo::runThreads(log); } -static void handlePipeRequest(int fd, FDMultiplexer::funcparam_t& /* var */) +static void handlePipeRequest(int fileDesc, FDMultiplexer::funcparam_t& /* var */) { ThreadMSG* tmsg = nullptr; - if (read(fd, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // fd == readToThread || fd == readQueriesToThread + if (read(fileDesc, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // fd == readToThread || fd == readQueriesToThread NOLINT: sizeof correct unixDie("read from thread pipe returned wrong size or error"); } - void* resp = 0; + void* resp = nullptr; try { resp = tmsg->func(); } @@ -2131,12 +2132,12 @@ static void handlePipeRequest(int fd, FDMultiplexer::funcparam_t& /* var */) } if (tmsg->wantAnswer) { if (write(RecThreadInfo::self().pipes.writeFromThread, &resp, sizeof(resp)) != sizeof(resp)) { - delete tmsg; + delete tmsg; // NOLINT: manual ownership handling unixDie("write to thread pipe returned wrong size or error"); } } - delete tmsg; + delete tmsg; // NOLINT: manual ownership handling } static void handleRCC(int fd, FDMultiplexer::funcparam_t& /* var */) @@ -2437,11 +2438,15 @@ static void runLuaMaintenance(RecThreadInfo& threadInfo, time_t& last_lua_mainte if (threadInfo.isWorker() || threadInfo.isListener()) { // Only on threads processing queries if (g_now.tv_sec - last_lua_maintenance >= luaMaintenanceInterval) { - struct timeval start{}; + struct timeval start + { + }; Utility::gettimeofday(&start); t_pdl->maintenance(); last_lua_maintenance = g_now.tv_sec; - struct timeval stop{}; + struct timeval stop + { + }; Utility::gettimeofday(&stop); t_Counters.at(rec::Counter::maintenanceUsec) += uSec(stop - start); ++t_Counters.at(rec::Counter::maintenanceCalls); @@ -2492,11 +2497,15 @@ static void recLoop() // Use primes, it avoid not being scheduled in cases where the counter has a regular pattern. // We want to call handler thread often, it gets scheduled about 2 times per second if (((threadInfo.isHandler() || threadInfo.isTaskThread()) && s_counter % 11 == 0) || s_counter % 499 == 0) { - struct timeval start{}; + struct timeval start + { + }; Utility::gettimeofday(&start); MT->makeThread(houseKeeping, nullptr); if (!threadInfo.isTaskThread()) { - struct timeval stop{}; + struct timeval stop + { + }; Utility::gettimeofday(&stop); t_Counters.at(rec::Counter::maintenanceUsec) += uSec(stop - start); ++t_Counters.at(rec::Counter::maintenanceCalls); @@ -2506,7 +2515,7 @@ static void recLoop() if (s_counter % 55 == 0) { auto expired = t_fdm->getTimeouts(g_now); - for (const auto & exp : expired) { + for (const auto& exp : expired) { auto conn = boost::any_cast>(exp.second); if (g_logCommonErrors) { SLOG(g_log << Logger::Warning << "Timeout from remote TCP client " << conn->d_remote.toStringWithPort() << endl, // NOLINT: union access From ba5af7d1da1c5af3d929e232486a02e3ce161f9d Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 8 May 2023 11:58:54 +0200 Subject: [PATCH 142/909] mark getenv() NOLINT Locally (using clangd) no warning is reported... --- pdns/recursordist/rec-main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 91fe7d4dd4a2..f8708ec21aa6 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2784,7 +2784,7 @@ static void initArgs() #ifdef HAVE_SYSTEMD + ". Set to the RUNTIME_DIRECTORY environment variable when that variable has a value (e.g. under systemd).") = ""; - auto runtimeDir = getenv("RUNTIME_DIRECTORY"); + auto* runtimeDir = getenv("RUNTIME_DIRECTORY"); // NOLINT(concurrency-mt-unsafe,cppcoreguidelines-pro-type-vararg) if (runtimeDir != nullptr) { ::arg().set("socket-dir") = runtimeDir; } From 33c76ef0a6c6a08b7da7028c3d209788ff87d4fa Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 8 May 2023 14:01:40 +0200 Subject: [PATCH 143/909] Add // NOLINT(readability-function-cognitive-complexity) Once readability-function-cognitive-complexity.IgnoreMacros works in CI, these annotations can be removed. It currenlty does not work as clang-12 does not support it. --- .clang-tidy.full | 2 +- pdns/recursordist/rec-main.cc | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index 43754f59838a..e4a95882a62d 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -253,7 +253,7 @@ CheckOptions: - key: modernize-pass-by-value.ValuesOnly value: 'false' - key: readability-function-cognitive-complexity.IgnoreMacros - value: 'true' + value: 'false' - key: modernize-loop-convert.IncludeStyle value: llvm - key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index f8708ec21aa6..0746901882d2 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1734,7 +1734,7 @@ static void initSNMP([[maybe_unused]] Logr::log_t log) } } -static int initControl(Logr::log_t log, uid_t newuid, int forks) // NOLINT(bugprone-easily-swappable-parameter*) +static int initControl(Logr::log_t log, uid_t newuid, int forks) // NOLINT(bugprone-easily-swappable-parameter*) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek { if (!::arg()["chroot"].empty()) { #ifdef HAVE_SYSTEMD @@ -1864,7 +1864,7 @@ static int initDNS64(Logr::log_t log) return 0; } -static int serviceMain(Logr::log_t log) +static int serviceMain(Logr::log_t log) // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek { g_log.setName(g_programname); g_log.disableSyslog(::arg().mustDo("disable-syslog")); @@ -2219,7 +2219,7 @@ class PeriodicTask const string name; }; -static void houseKeeping0(Logr::log_t log) +static void houseKeeping0(Logr::log_t log) // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek { struct timeval now { @@ -2549,7 +2549,7 @@ static void recLoop() } } -static void recursorThread() +static void recursorThread() // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek { auto log = g_slog->withName("runtime"); t_Counters.updateSnap(true); @@ -3030,7 +3030,7 @@ static pair doConfig(Logr::log_t startupLog, const string& configname return {0, false}; } -int main(int argc, char** argv) +int main(int argc, char** argv) // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek { g_argc = argc; g_argv = argv; From 098bfe746aaefd6eca6a05fe72ba77a5441f3e9b Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Mon, 8 May 2023 14:24:39 +0200 Subject: [PATCH 144/909] Quote the output vars --- .github/workflows/build-and-test-all.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 4946006ca26b..3a70f76d6a83 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -22,7 +22,7 @@ jobs: UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" UNIT_TESTS: yes outputs: - clang-tidy-auth-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} + clang-tidy-failed: ${{steps.clang-tidy-annotations.outputs.failed}} steps: - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 @@ -95,7 +95,7 @@ jobs: run: working-directory: ./pdns/recursordist/ outputs: - clang-tidy-recursor-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} + clang-tidy-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 @@ -169,7 +169,7 @@ jobs: run: working-directory: ./pdns/dnsdistdist/ outputs: - clang-tidy-dnsdist-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} + clang-tidy-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 @@ -537,10 +537,10 @@ jobs: runs-on: ubuntu-20.04 name: Check whether clang-tidy succeeded steps: - - run: | - if [ ${{ needs.build-auth.outputs.clang-tidy-auth-failed }} != 0 -o ${{ needs.build-dnsdist.outputs.clang-tidy-dnsdist-failed }} != 0 -o ${{ needs.build-recursor.outputs.clang-tidy-recursor-failed }} != 0 ]; then - exit 1 - fi + - run: | + if [ "${{needs.build-auth.outputs.clang-tidy-failed}}" != "0" -o "${{needs.build-dnsdist.outputs.clang-tidy-failed}}" != "0" -o "${{needs.build-recursor.outputs.clang-tidy-failed}}" != "0" ]; then + exit 1 + fi collect: needs: From 28deb0e583d75e6d740effec8e360c27f5c55af9 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Mon, 8 May 2023 14:30:48 +0200 Subject: [PATCH 145/909] Don't fail when there are no warnings produced by clang-tidy --- .github/scripts/clang-tidy.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/scripts/clang-tidy.py b/.github/scripts/clang-tidy.py index 85982e207906..856be887f67c 100755 --- a/.github/scripts/clang-tidy.py +++ b/.github/scripts/clang-tidy.py @@ -39,6 +39,11 @@ def main(): compdb = helpers.index_compdb(compdb) fixes = helpers.load_fixes_file(args.fixes_file) + + if not fixes: + print("No diagnostics or warnings produced by clang-tidy") + return 0 + fixes = fixes["Diagnostics"] have_warnings = False for fix in fixes: From 17b4faeecdb345b104c641f56461ccc24364041a Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 24 Mar 2023 10:40:28 +0100 Subject: [PATCH 146/909] remove ubuntu bionic target, as 18.04 will EOL soon --- .github/workflows/builder-dispatch.yml | 1 - .github/workflows/builder.yml | 1 - .../Dockerfile.target.ubuntu-bionic | 35 ------------------- .../Dockerfile.target.ubuntu-bionic-amd64 | 1 - .../Dockerfile.target.ubuntu-bionic-arm64 | 1 - 5 files changed, 39 deletions(-) delete mode 100644 builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic delete mode 120000 builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic-amd64 delete mode 120000 builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic-arm64 diff --git a/.github/workflows/builder-dispatch.yml b/.github/workflows/builder-dispatch.yml index ca000c31fdc9..a8eb5e19689c 100644 --- a/.github/workflows/builder-dispatch.yml +++ b/.github/workflows/builder-dispatch.yml @@ -20,7 +20,6 @@ on: el-9 debian-buster debian-bullseye - ubuntu-bionic ubuntu-focal ubuntu-jammy ref: diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index 8823b25c22db..f0edb1afc0d5 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -19,7 +19,6 @@ jobs: product: ['authoritative', 'recursor', 'dnsdist'] os: - centos-7 - - ubuntu-bionic - el-8 - centos-8-stream - centos-9-stream diff --git a/builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic b/builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic deleted file mode 100644 index fe38051feda3..000000000000 --- a/builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic +++ /dev/null @@ -1,35 +0,0 @@ -# First do the source builds -@INCLUDE Dockerfile.target.sdist - -@IF [ ${BUILDER_TARGET} = ubuntu-bionic ] -FROM ubuntu:bionic as dist-base -@ENDIF -@IF [ ${BUILDER_TARGET} = ubuntu-bionic-amd64 ] -FROM amd64/ubuntu:bionic as dist-base -@ENDIF -@IF [ ${BUILDER_TARGET} = ubuntu-bionic-arm64 ] -FROM arm64v8/ubuntu:bionic as dist-base -@ENDIF -ARG BUILDER_CACHE_BUSTER= -ARG APT_URL -RUN apt-get update && apt-get -y dist-upgrade - -@INCLUDE Dockerfile.debbuild-prepare - -@IF [ -n "$M_authoritative$M_all" ] -ADD builder-support/debian/authoritative/debian-buster/ pdns-${BUILDER_VERSION}/debian/ -@ENDIF - -@IF [ -n "$M_recursor$M_all" ] -ADD builder-support/debian/recursor/debian-buster/ pdns-recursor-${BUILDER_VERSION}/debian/ -@ENDIF - -@IF [ -n "$M_dnsdist$M_all" ] -ADD builder-support/debian/dnsdist/debian-buster/ dnsdist-${BUILDER_VERSION}/debian/ -@ENDIF - -@INCLUDE Dockerfile.debbuild - -# Do a test install and verify -# Can be skipped with skiptests=1 in the environment -# @EXEC [ "$skiptests" = "" ] && include Dockerfile.debtest diff --git a/builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic-amd64 b/builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic-amd64 deleted file mode 120000 index 003426b39616..000000000000 --- a/builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic-amd64 +++ /dev/null @@ -1 +0,0 @@ -Dockerfile.target.ubuntu-bionic \ No newline at end of file diff --git a/builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic-arm64 b/builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic-arm64 deleted file mode 120000 index 003426b39616..000000000000 --- a/builder-support/dockerfiles/Dockerfile.target.ubuntu-bionic-arm64 +++ /dev/null @@ -1 +0,0 @@ -Dockerfile.target.ubuntu-bionic \ No newline at end of file From 37285a568a91542909394013d7619d4b9f17b512 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 24 Mar 2023 11:12:18 +0100 Subject: [PATCH 147/909] switch builder docs target to ubuntu jammy --- builder-support/dockerfiles/Dockerfile.target.docs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/builder-support/dockerfiles/Dockerfile.target.docs b/builder-support/dockerfiles/Dockerfile.target.docs index bf7432818f48..b7dd82a5dc3f 100644 --- a/builder-support/dockerfiles/Dockerfile.target.docs +++ b/builder-support/dockerfiles/Dockerfile.target.docs @@ -1,12 +1,11 @@ # Sphinx -FROM ubuntu:bionic as pdns-docs +FROM ubuntu:jammy as pdns-docs RUN apt-get update && apt-get -y dist-upgrade && apt-get -y --no-install-recommends install \ ghostscript \ git \ latexmk \ make \ - python-minimal \ - python2.7 \ + python3-minimal \ texlive \ texlive-font-utils \ texlive-fonts-extra \ From 87405a08cc7965badbab35c6a36674179a11a01c Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 9 May 2023 11:31:27 +0200 Subject: [PATCH 148/909] Consistent formatting Co-authored-by: Remi Gacogne --- .github/workflows/build-and-test-all.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 3a70f76d6a83..880566ec85dc 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -22,7 +22,7 @@ jobs: UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" UNIT_TESTS: yes outputs: - clang-tidy-failed: ${{steps.clang-tidy-annotations.outputs.failed}} + clang-tidy-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 From 666391b19885096feca543ccd3bcc9b3b81b9ebd Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 9 May 2023 12:02:51 +0200 Subject: [PATCH 149/909] Handle the case where none of the products produce any warnings Co-authored-by: Remi Gacogne --- .github/workflows/build-and-test-all.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 880566ec85dc..668c9bf77c0f 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -538,7 +538,13 @@ jobs: name: Check whether clang-tidy succeeded steps: - run: | - if [ "${{needs.build-auth.outputs.clang-tidy-failed}}" != "0" -o "${{needs.build-dnsdist.outputs.clang-tidy-failed}}" != "0" -o "${{needs.build-recursor.outputs.clang-tidy-failed}}" != "0" ]; then + if [ "x${{ needs.build-auth.outputs.clang-tidy-failed }}" != "x" -a "${{ needs.build-auth.outputs.clang-tidy-failed }}" != "0" ]; then + exit 1 + fi + if [ "x${{ needs.build-dnsdist.outputs.clang-tidy-failed }}" != "x" -a "${{ needs.build-dnsdist.outputs.clang-tidy-failed }}" != "0" ]; then + exit 1 + fi + if [ "x${{needs.build-recursor.outputs.clang-tidy-failed}}" != "" -a "${{needs.build-recursor.outputs.clang-tidy-failed}}" != "0" ]; then exit 1 fi From b6fcd0b9563d6fe25562fe8cd4076364123dd6c6 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 9 May 2023 12:31:23 +0200 Subject: [PATCH 150/909] Fix check for recursor clang-tidy output Co-authored-by: Remi Gacogne --- .github/workflows/build-and-test-all.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 668c9bf77c0f..0c9c731b0368 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -544,7 +544,7 @@ jobs: if [ "x${{ needs.build-dnsdist.outputs.clang-tidy-failed }}" != "x" -a "${{ needs.build-dnsdist.outputs.clang-tidy-failed }}" != "0" ]; then exit 1 fi - if [ "x${{needs.build-recursor.outputs.clang-tidy-failed}}" != "" -a "${{needs.build-recursor.outputs.clang-tidy-failed}}" != "0" ]; then + if [ "x${{needs.build-recursor.outputs.clang-tidy-failed}}" != "x" -a "${{needs.build-recursor.outputs.clang-tidy-failed}}" != "0" ]; then exit 1 fi From 0a18d0349145ae0c49b6dfef0be58bde925c4806 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 9 May 2023 15:15:06 +0200 Subject: [PATCH 151/909] libssl: Fix a memory leak when processing TLS tickets w/ OpenSSL 3.x --- pdns/libssl.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pdns/libssl.cc b/pdns/libssl.cc index 24fd774a73a8..ea05a0278222 100644 --- a/pdns/libssl.cc +++ b/pdns/libssl.cc @@ -762,6 +762,7 @@ int OpenSSLTLSTicketKey::encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE #if OPENSSL_VERSION_MAJOR >= 3 using ParamsBuilder = std::unique_ptr; + using Params = std::unique_ptr; auto params_build = ParamsBuilder(OSSL_PARAM_BLD_new(), OSSL_PARAM_BLD_free); if (params_build == nullptr) { @@ -772,12 +773,12 @@ int OpenSSLTLSTicketKey::encrypt(unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE return -1; } - auto* params = OSSL_PARAM_BLD_to_param(params_build.get()); + auto params = Params(OSSL_PARAM_BLD_to_param(params_build.get()), OSSL_PARAM_free); if (params == nullptr) { return -1; } - if (EVP_MAC_CTX_set_params(hctx, params) == 0) { + if (EVP_MAC_CTX_set_params(hctx, params.get()) == 0) { return -1; } @@ -801,6 +802,7 @@ bool OpenSSLTLSTicketKey::decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, { #if OPENSSL_VERSION_MAJOR >= 3 using ParamsBuilder = std::unique_ptr; + using Params = std::unique_ptr; auto params_build = ParamsBuilder(OSSL_PARAM_BLD_new(), OSSL_PARAM_BLD_free); if (params_build == nullptr) { @@ -811,12 +813,12 @@ bool OpenSSLTLSTicketKey::decrypt(const unsigned char* iv, EVP_CIPHER_CTX* ectx, return false; } - auto* params = OSSL_PARAM_BLD_to_param(params_build.get()); + auto params = Params(OSSL_PARAM_BLD_to_param(params_build.get()), OSSL_PARAM_free); if (params == nullptr) { return false; } - if (EVP_MAC_CTX_set_params(hctx, params) == 0) { + if (EVP_MAC_CTX_set_params(hctx, params.get()) == 0) { return false; } From bd95b65ea01f50b0442819b022bc9735f4c640e0 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 9 May 2023 15:47:43 +0200 Subject: [PATCH 152/909] Fix indentation --- .github/workflows/build-and-test-all.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 0c9c731b0368..94e8db2e0993 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -544,7 +544,7 @@ jobs: if [ "x${{ needs.build-dnsdist.outputs.clang-tidy-failed }}" != "x" -a "${{ needs.build-dnsdist.outputs.clang-tidy-failed }}" != "0" ]; then exit 1 fi - if [ "x${{needs.build-recursor.outputs.clang-tidy-failed}}" != "x" -a "${{needs.build-recursor.outputs.clang-tidy-failed}}" != "0" ]; then + if [ "x${{needs.build-recursor.outputs.clang-tidy-failed}}" != "x" -a "${{needs.build-recursor.outputs.clang-tidy-failed}}" != "0" ]; then exit 1 fi From 87f63fd0177e7c4b96ae7e4756aa1c91804b1fd9 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 10 May 2023 13:08:08 +0200 Subject: [PATCH 153/909] Name housekeeping0 better --- pdns/recursordist/rec-main.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 0746901882d2..cf09ccbb8afa 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2219,7 +2219,7 @@ class PeriodicTask const string name; }; -static void houseKeeping0(Logr::log_t log) // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek +static void houseKeepingWork(Logr::log_t log) // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek { struct timeval now { @@ -2413,7 +2413,7 @@ static void houseKeeping(void* /* ignored */) return; } t_running = true; - houseKeeping0(log); + houseKeepingWork(log); t_running = false; } catch (const PDNSException& ae) { From ad949cc46b4162d45497c406ca5f971d96affb2e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 10 May 2023 14:47:44 +0200 Subject: [PATCH 154/909] dnsdist: Suppress a race warning when setting a backend health-check mode There is an actual race when one thread, likely the console, changes the health-check mode of a given backend just when the health-check thread is determining whether it should send a health-check probe. We are fine with getting a wrong value in the health-check thread, as long as we eventually get the new one, so let's not worry about it and add a TSAN suppression. The TSAN report was: ``` WARNING: ThreadSanitizer: data race (pid=5301) Read of size 1 at 0x7b78000002ae by thread T11: #0 DownstreamState::healthCheckRequired(std::optional) /__w/pdns/pdns/pdns/dnsdistdist/dnsdist-backend.cc:555:16 (dnsdist+0x18f003) #1 healthChecksThread() /__w/pdns/pdns/pdns/dnsdistdist/dnsdist.cc:2046:17 (dnsdist+0x811ea9) #2 void std::__invoke_impl(std::__invoke_other, void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:60:14 (dnsdist+0x1dfe39) #3 std::__invoke_result::type std::__invoke(void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95:14 (dnsdist+0x1dfe39) #4 void std::thread::_Invoker >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:264:13 (dnsdist+0x1dfe39) #5 std::thread::_Invoker >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:271:11 (dnsdist+0x1dfe39) #6 std::thread::_State_impl > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:215:13 (dnsdist+0x1dfe39) #7 (libstdc++.so.6+0xceecf) Previous write of size 1 at 0x7b78000002ae by thread T21 (mutexes: write M189): #0 std::enable_if::value, setupLuaBindings(LuaContext&, bool)::$_15>::type LuaContext::readIntoFunction >(std::__cxx11::basic_string, std::allocator > const&, setupLuaBindings(LuaContext&, bool)::$_15, LuaContext::tag, LuaContext::tag)>)::'lambda'(std::shared_ptr const&, boost::optional)&, std::shared_ptr const&>&, boost::optional >(lua_State*, LuaContext::tag, void&&, int, LuaContext::tag, LuaContext::tag >) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp (dnsdist+0x4b6ab2) #1 std::enable_if::value), setupLuaBindings(LuaContext&, bool)::$_15>::type LuaContext::readIntoFunction >(std::__cxx11::basic_string, std::allocator > const&, setupLuaBindings(LuaContext&, bool)::$_15, LuaContext::tag, LuaContext::tag)>)::'lambda'(std::shared_ptr const&, boost::optional)&, std::shared_ptr, boost::optional >(lua_State*, LuaContext::tag, void&&, int, LuaContext::tag, LuaContext::tag >) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:1803:16 (dnsdist+0x4b6ab2) #2 std::enable_if<(std::integral_constant::value) && (!(std::is_void::value)), LuaContext::PushedObject>::type LuaContext::Pusher, boost::optional), void>::callback2 >(std::__cxx11::basic_string, std::allocator > const&, setupLuaBindings(LuaContext&, bool)::$_15, LuaContext::tag, LuaContext::tag)>)::'lambda'(std::shared_ptr const&, boost::optional)&>(lua_State*, setupLuaBindings(LuaContext&, bool)::$_15&&, int) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:2443:9 (dnsdist+0x4b6ab2) #3 LuaContext::PushedObject LuaContext::Pusher, boost::optional), void>::callback >(std::__cxx11::basic_string, std::allocator > const&, setupLuaBindings(LuaContext&, bool)::$_15, LuaContext::tag, LuaContext::tag)>)::'lambda'(std::shared_ptr const&, boost::optional)>(lua_State*, setupLuaBindings(LuaContext&, bool)::$_15*, int) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:2405:20 (dnsdist+0x4b6ab2) #4 std::enable_if::value, LuaContext::PushedObject>::type LuaContext::Pusher, boost::optional), void>::push >(std::__cxx11::basic_string, std::allocator > const&, setupLuaBindings(LuaContext&, bool)::$_15, LuaContext::tag, LuaContext::tag)>)::'lambda'(std::shared_ptr const&, boost::optional)>(lua_State*, setupLuaBindings(LuaContext&, bool)::$_15)::'lambda'(lua_State*)::operator()(lua_State*) const /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:2334:20 (dnsdist+0x4b6ab2) #5 std::enable_if::value, LuaContext::PushedObject>::type LuaContext::Pusher, boost::optional), void>::push >(std::__cxx11::basic_string, std::allocator > const&, setupLuaBindings(LuaContext&, bool)::$_15, LuaContext::tag, LuaContext::tag)>)::'lambda'(std::shared_ptr const&, boost::optional)>(lua_State*, setupLuaBindings(LuaContext&, bool)::$_15)::'lambda'(lua_State*)::__invoke(lua_State*) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:2330:31 (dnsdist+0x4b6ab2) #6 (libluajit-5.1.so.2+0xa5e6) #7 boost::optional, std::allocator >, std::shared_ptr, ClientState*, std::unordered_map, std::allocator >, double, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, double> > > > > LuaContext::call, std::allocator >, std::shared_ptr, ClientState*, std::unordered_map, std::allocator >, double, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, double> > > > > >(lua_State*, LuaContext::PushedObject) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:1413:29 (dnsdist+0x1c2b4b) #8 boost::optional, std::allocator >, std::shared_ptr, ClientState*, std::unordered_map, std::allocator >, double, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, double> > > > > LuaContext::executeCode, std::allocator >, std::shared_ptr, ClientState*, std::unordered_map, std::allocator >, double, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, double> > > > > >(char const*) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:324:16 (dnsdist+0x1c2b4b) #9 boost::optional, std::allocator >, std::shared_ptr, ClientState*, std::unordered_map, std::allocator >, double, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, double> > > > > LuaContext::executeCode, std::allocator >, std::shared_ptr, ClientState*, std::unordered_map, std::allocator >, double, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, double> > > > > >(std::__cxx11::basic_string, std::allocator > const&) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:301:16 (dnsdist+0x1bf450) #10 controlClientThread(ConsoleConnection&&) /__w/pdns/pdns/pdns/dnsdistdist/dnsdist-console.cc:897:27 (dnsdist+0x1bf450) #11 boost::optional, std::allocator >, std::shared_ptr, ClientState*, std::unordered_map, std::allocator >, double, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, double> > > > > LuaContext::executeCode, std::allocator >, std::shared_ptr, ClientState*, std::unordered_map, std::allocator >, double, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, double> > > > > >(std::__cxx11::basic_string, std::allocator > const&) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:301:16 (dnsdist+0x1bf450) #12 controlClientThread(ConsoleConnection&&) /__w/pdns/pdns/pdns/dnsdistdist/dnsdist-console.cc:897:27 (dnsdist+0x1bf450) #13 void std::__invoke_impl(std::__invoke_other, void (*&&)(ConsoleConnection&&), ConsoleConnection&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:60:14 (dnsdist+0x1c76f3) #14 std::__invoke_result::type std::__invoke(void (*&&)(ConsoleConnection&&), ConsoleConnection&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95:14 (dnsdist+0x1c76f3) #15 void std::thread::_Invoker >::_M_invoke<0ul, 1ul>(std::_Index_tuple<0ul, 1ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:264:13 (dnsdist+0x1c76f3) #16 std::thread::_Invoker >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:271:11 (dnsdist+0x1c76f3) #17 std::thread::_State_impl > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:215:13 (dnsdist+0x1c76f3) #18 (libstdc++.so.6+0xceecf) As if synchronized via sleep: #0 healthChecksThread() /__w/pdns/pdns/pdns/dnsdistdist/dnsdist.cc:2034:5 (dnsdist+0xc77e8) #1 void std::__invoke_impl(std::__invoke_other, void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:60:14 (dnsdist+0x811b8e) #2 std::__invoke_result::type std::__invoke(void (*&&)()) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95:14 (dnsdist+0x811b8e) #3 void std::thread::_Invoker >::_M_invoke<0ul>(std::_Index_tuple<0ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:264:13 (dnsdist+0x811b8e) #4 std::thread::_Invoker >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:271:11 (dnsdist+0x811b8e) #5 std::thread::_State_impl > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:215:13 (dnsdist+0x811b8e) #6 (dnsdist+0x1dfe39) #7 operator new(unsigned long, std::align_val_t) (libstdc++.so.6+0xceecf) Location is heap block of size 2880 at 0x7b7800000000 allocated by main thread: #0 __gnu_cxx::new_allocator, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/ext/new_allocator.h:112:31 (dnsdist+0x13f29c) #1 std::allocator_traits, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::allocator, (__gnu_cxx::_Lock_policy)2> >&, unsigned long) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/alloc_traits.h:460:20 (dnsdist+0x13f29c) #2 std::__allocated_ptr, (__gnu_cxx::_Lock_policy)2> > > std::__allocate_guarded, (__gnu_cxx::_Lock_policy)2> > >(std::allocator, (__gnu_cxx::_Lock_policy)2> >&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/allocated_ptr.h:97:21 (dnsdist+0x13f29c) #3 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count, DownstreamState::Config, std::shared_ptr, bool>(DownstreamState*&, std::_Sp_alloc_shared_tag >, DownstreamState::Config&&, std::shared_ptr&&, bool&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h:680:19 (dnsdist+0x13f29c) #4 std::__shared_ptr::__shared_ptr, DownstreamState::Config, std::shared_ptr, bool>(std::_Sp_alloc_shared_tag >, DownstreamState::Config&&, std::shared_ptr&&, bool&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h:1371:14 (dnsdist+0x13f29c) #5 std::shared_ptr::shared_ptr, DownstreamState::Config, std::shared_ptr, bool>(std::_Sp_alloc_shared_tag >, DownstreamState::Config&&, std::shared_ptr&&, bool&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:408:4 (dnsdist+0x1db3be) #6 std::shared_ptr std::allocate_shared, DownstreamState::Config, std::shared_ptr, bool>(std::allocator const&, DownstreamState::Config&&, std::shared_ptr&&, bool&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:859:14 (dnsdist+0x1db3be) #7 std::shared_ptr std::make_shared, bool>(DownstreamState::Config&&, std::shared_ptr&&, bool&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:875:14 (dnsdist+0x1db3be) #8 setupLuaConfig(LuaContext&, bool, bool)::$_3::operator()(boost::variant, std::allocator >, std::unordered_map, std::allocator >, boost::variant, std::allocator >, std::vector, std::allocator > >, std::allocator, std::allocator > > > >, std::function (DNSName const&, unsigned short, unsigned short, dnsheader*)> >, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, boost::variant, std::allocator >, std::vector, std::allocator > >, std::allocator, std::allocator > > > >, std::function (DNSName const&, unsigned short, unsigned short, dnsheader*)> > > > > >, boost::optional) const /__w/pdns/pdns/pdns/dnsdistdist/dnsdist-lua.cc:619:37 (dnsdist+0x1db3be) #9 tor > > > >, std::function (DNSName const&, unsigned short, unsigned short, dnsheader*)> > > > > >, boost::optional), void>::callback2(lua_State*, setupLuaConfig(LuaContext&, bool, bool)::$_3&, int) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:2436:31 (dnsdist+0x69065d) #10 LuaContext::PushedObject LuaContext::Pusher (boost::variant, std::allocator >, std::unordered_map, std::allocator >, boost::variant, std::allocator >, std::vector, std::allocator > >, std::allocator, std::allocator > > > >, std::function (DNSName const&, unsigned short, unsigned short, dnsheader*)> >, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, boost::variant, std::allocator >, std::vector, std::allocator > >, std::allocator, std::allocator > > > >, std::function (DNSName const&, unsigned short, unsigned short, dnsheader*)> > > > > >, boost::optional), void>::callback(lua_State*, setupLuaConfig(LuaContext&, bool, bool)::$_3*, int) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:2405:20 (dnsdist+0x69065d) #11 std::enable_if::value, LuaContext::PushedObject>::type LuaContext::Pusher (boost::variant, std::allocator >, std::unordered_map, std::allocator >, boost::variant, std::allocator >, std::vector, std::allocator > >, std::allocator, std::allocator > > > >, std::function (DNSName const&, unsigned short, unsigned short, dnsheader*)> >, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, boost::variant, std::allocator >, std::vector, std::allocator > >, std::allocator, std::allocator > > > >, std::function (DNSName const&, unsigned short, unsigned short, dnsheader*)> > > > > >, boost::optional), void>::push(lua_State*, setupLuaConfig(LuaContext&, bool, bool)::$_3)::'lambda'(lua_State*)::operator()(lua_State*) const /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:2334:20 (dnsdist+0x69065d) #12 std::enable_if::value, LuaContext::PushedObject>::type LuaContext::Pusher (boost::variant, std::allocator >, std::unordered_map, std::allocator >, boost::variant, std::allocator >, std::vector, std::allocator > >, std::allocator, std::allocator > > > >, std::function (DNSName const&, unsigned short, unsigned short, dnsheader*)> >, std::hash, std::allocator > >, std::equal_to, std::allocator > >, std::allocator, std::allocator > const, boost::variant, std::allocator >, std::vector, std::allocator > >, std::allocator, std::allocator > > > >, std::function (DNSName const&, unsigned short, unsigned short, dnsheader*)> > > > > >, boost::optional), void>::push(lua_State*, setupLuaConfig(LuaContext&, bool, bool)::$_3)::'lambda'(lua_State*)::__invoke(lua_State*) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:2330:31 (dnsdist+0x69065d) #13 (dnsdist+0x687942) #14 (libluajit-5.1.so.2+0xa5e6) #15 std::tuple<> LuaContext::call >(lua_State*, LuaContext::PushedObject) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:1413:29 (dnsdist+0x577e85) #16 LuaContext::executeCode(std::istream&) /__w/pdns/pdns/pdns/dnsdistdist/./ext/luawrapper/include/LuaContext.hpp:267:9 (dnsdist+0x685db6) #17 setupLua(LuaContext&, bool, bool, std::__cxx11::basic_string, std::allocator > const&) /__w/pdns/pdns/pdns/dnsdistdist/dnsdist-lua.cc:3025:10 (dnsdist+0x67b759) #18 main /__w/pdns/pdns/pdns/dnsdistdist/dnsdist.cc:2668:17 (dnsdist+0x809d2c) Mutex M189 (0x55801da4cdf0) created at: #0 pthread_mutex_lock (dnsdist+0xe74f8) #1 __gthread_mutex_lock(pthread_mutex_t*) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10/bits/gthr-default.h:749:12 (dnsdist+0x80c177) #2 std::mutex::lock() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/std_mutex.h:100:17 (dnsdist+0x80c177) #3 std::lock_guard::lock_guard(std::mutex&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/std_mutex.h:159:19 (dnsdist+0x80c177) #4 LockGuardedHolder::LockGuardedHolder(LuaContext&, std::mutex&) /__w/pdns/pdns/pdns/dnsdistdist/./lock.hh:209:60 (dnsdist+0x80c177) #5 LockGuarded::lock() /__w/pdns/pdns/pdns/dnsdistdist/./lock.hh:289:12 (dnsdist+0x80c177) #6 main /__w/pdns/pdns/pdns/dnsdistdist/dnsdist.cc:2668:34 (dnsdist+0x809d0c) Thread T11 'dnsdist/healthC' (tid=5313, running) created by main thread at: #0 pthread_create (dnsdist+0xca21d) #1 std::thread::_M_start_thread(std::unique_ptr >, void (*)()) (libstdc++.so.6+0xcf144) #2 main /__w/pdns/pdns/pdns/dnsdistdist/dnsdist.cc:2938:12 (dnsdist+0x80b06e) Thread T21 'dnsdist/conscli' (tid=5325, finished) created by thread T5 at: #0 pthread_create (dnsdist+0xca21d) #1 std::thread::_M_start_thread(std::unique_ptr >, void (*)()) (libstdc++.so.6+0xcf144) #2 void std::__invoke_impl(std::__invoke_other, void (*&&)(int, ComboAddress), int&&, ComboAddress&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:60:14 (dnsdist+0x6c0435) #3 std::__invoke_result::type std::__invoke(void (*&&)(int, ComboAddress), int&&, ComboAddress&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/invoke.h:95:14 (dnsdist+0x6c0435) #4 void std::thread::_Invoker >::_M_invoke<0ul, 1ul, 2ul>(std::_Index_tuple<0ul, 1ul, 2ul>) /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:264:13 (dnsdist+0x6c0435) #5 std::thread::_Invoker >::operator()() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:271:11 (dnsdist+0x6c0435) #6 std::thread::_State_impl > >::_M_run() /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/thread:215:13 (dnsdist+0x6c0435) #7 (libstdc++.so.6+0xceecf) ``` --- pdns/dnsdistdist/dnsdist-tsan.supp | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/dnsdistdist/dnsdist-tsan.supp b/pdns/dnsdistdist/dnsdist-tsan.supp index f9c1d984d642..d597a72af721 100644 --- a/pdns/dnsdistdist/dnsdist-tsan.supp +++ b/pdns/dnsdistdist/dnsdist-tsan.supp @@ -15,4 +15,5 @@ race:DownstreamState::setAuto # eventual consistency is fine race:DownstreamState::stop race:DownstreamState::submitHealthCheckResult +race:DownstreamState::healthCheckRequired race:carbonDumpThread From bf22f0fdc1b9fe5f5d4e1d96333751542c432fe6 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 11 May 2023 10:15:44 +0200 Subject: [PATCH 155/909] dnsdist: Print the received, invalid health-check response ID --- pdns/dnsdistdist/dnsdist-healthchecks.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index 4a5205227626..1addf7583de3 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -69,7 +69,7 @@ static bool handleResponse(std::shared_ptr& data) const dnsheader * responseHeader = reinterpret_cast(data->d_buffer.data()); if (responseHeader->id != data->d_queryID) { if (g_verboseHealthChecks) { - infolog("Invalid health check response id %d from backend %s, expecting %d", data->d_queryID, ds->getNameWithAddr(), data->d_queryID); + infolog("Invalid health check response id %d from backend %s, expecting %d", responseHeader->id, ds->getNameWithAddr(), data->d_queryID); } return false; } From 5b48dd1425dabbba7ab6758fe3ccf2b1410faef7 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 11 May 2023 15:07:01 +0200 Subject: [PATCH 156/909] dnsdist: Account for the health-check run time between two runs We used to wait one full second between every run, which only makes sense if the runs are not taking a long time. But as soon as we have at least one check timing out, the run is taking roughly the time of the longest timeout configured, so after this commit we: - do not wait at all if the last run took more than a full second - wait one second minus the elapsed time of the last run otherwise --- pdns/dnsdist.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 06aa910ab68f..e786041e6857 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -2027,11 +2027,24 @@ static void healthChecksThread() { setThreadName("dnsdist/healthC"); - constexpr int interval = 1; + constexpr int intervalUsec = 1000 * 1000; + struct timeval lastRound{ + .tv_sec = 0, + .tv_usec = 0 + }; auto states = g_dstates.getLocal(); // this points to the actual shared_ptrs! for (;;) { - sleep(interval); + struct timeval now; + gettimeofday(&now, nullptr); + auto elapsedTimeUsec = uSec(now - lastRound); + if (elapsedTimeUsec < intervalUsec) { + usleep(intervalUsec - elapsedTimeUsec); + gettimeofday(&lastRound, nullptr); + } + else { + lastRound = now; + } std::unique_ptr mplexer{nullptr}; for (auto& dss : *states) { From 6a04912e36e32104434d2b1b0625a0de0e0c002d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 11 May 2023 15:27:07 +0200 Subject: [PATCH 157/909] dnsdist: Properly set the size of the UDP health-check response We forgot to resize the response buffer to what we actually got, so the initial buffer size (512) was mistakenly used later on. Technically this should not be an issue as the buffer is large enough, but that prevents us from reporting that the response was broken if it not large enough for a DNS header, for example. --- pdns/dnsdistdist/dnsdist-healthchecks.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index 1addf7583de3..631f9ef9493f 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -177,6 +177,7 @@ static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) data->d_ds->submitHealthCheckResult(data->d_initial, false); return; } + data->d_buffer.resize(static_cast(got)); /* we are using a connected socket but hey.. */ if (from != data->d_ds->d_config.remote) { From e053d2cece486c06a0fda877094a04ce32abbf68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A5kan=20Lindqvist?= Date: Thu, 11 May 2023 14:25:35 +0000 Subject: [PATCH 158/909] Clarify log message for NODATA/NXDOMAIN without AA The old log message did not indicate the specific reason why the record was considered irrelevant, logging only information about a SOA record that quite likely is both normal and relevant. This somewhat helps explaining what the actual problem is. --- pdns/recursordist/syncres.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index f7270474f106..3195b4095be8 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -4163,7 +4163,7 @@ void SyncRes::sanitizeRecords(const std::string& prefix, LWResult& lwr, const DN } if (!(lwr.d_aabit || wasForwardRecurse)) { - LOG(prefix << qname << ": Removing irrelevant record '" << rec->d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->getContent()->getZoneRepresentation() << "' in the AUTHORITY section received from " << auth << endl); + LOG(prefix << qname << ": Removing irrelevant record (AA not set) '" << rec->d_name << "|" << DNSRecordContent::NumberToType(rec->d_type) << "|" << rec->getContent()->getZoneRepresentation() << "' in the AUTHORITY section received from " << auth << endl); rec = lwr.d_records.erase(rec); continue; } From 6bb404b627442d64b829edcffcc9f5fbc4987eb4 Mon Sep 17 00:00:00 2001 From: Christof Chen Date: Thu, 11 May 2023 20:00:01 +0200 Subject: [PATCH 159/909] fix #12801 + regression test --- pdns/dnsdist-lua-actions.cc | 4 +++- regression-tests.dnsdist/test_Spoofing.py | 27 +++++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdist-lua-actions.cc b/pdns/dnsdist-lua-actions.cc index 905cf3d08f9d..a7ec4aea1aba 100644 --- a/pdns/dnsdist-lua-actions.cc +++ b/pdns/dnsdist-lua-actions.cc @@ -880,12 +880,14 @@ DNSAction::Action SpoofAction::operator()(DNSQuestion* dq, std::string* ruleresu dq->getHeader()->arcount = 0; // for now, forget about your EDNS, we're marching over it uint32_t ttl = htonl(d_responseConfig.ttl); + uint16_t qclass = htons(dq->ids.qclass); unsigned char recordstart[] = {0xc0, 0x0c, // compressed name 0, 0, // QTYPE - 0, QClass::IN, + 0, 0, // QCLASS 0, 0, 0, 0, // TTL 0, 0 }; // rdata length static_assert(sizeof(recordstart) == 12, "sizeof(recordstart) must be equal to 12, otherwise the above check is invalid"); + memcpy(&recordstart[4], &qclass, sizeof(qclass)); memcpy(&recordstart[6], &ttl, sizeof(ttl)); bool raw = false; diff --git a/regression-tests.dnsdist/test_Spoofing.py b/regression-tests.dnsdist/test_Spoofing.py index ff89f406e004..d40c13ca5e75 100644 --- a/regression-tests.dnsdist/test_Spoofing.py +++ b/regression-tests.dnsdist/test_Spoofing.py @@ -16,6 +16,7 @@ class TestSpoofingSpoof(DNSDistTest): addAction(AndRule{makeRule("raw.spoofing.tests.powerdns.com"), QTypeRule(DNSQType.A)}, SpoofRawAction("\\192\\000\\002\\001")) addAction(AndRule{makeRule("raw.spoofing.tests.powerdns.com"), QTypeRule(DNSQType.TXT)}, SpoofRawAction("\\003aaa\\004bbbb\\011ccccccccccc")) addAction(AndRule{makeRule("raw.spoofing.tests.powerdns.com"), QTypeRule(DNSQType.SRV)}, SpoofRawAction("\\000\\000\\000\\000\\255\\255\\003srv\\008powerdns\\003com\\000", { aa=true, ttl=3600 })) + addAction(AndRule{makeRule("rawchaos.spoofing.tests.powerdns.com"), QTypeRule(DNSQType.TXT), QClassRule(DNSClass.CHAOS)}, SpoofRawAction("\\005chaos")) addAction(AndRule{makeRule("multiraw.spoofing.tests.powerdns.com"), QTypeRule(DNSQType.TXT)}, SpoofRawAction({"\\003aaa\\004bbbb", "\\011ccccccccccc"})) addAction(AndRule{makeRule("multiraw.spoofing.tests.powerdns.com"), QTypeRule(DNSQType.A)}, SpoofRawAction({"\\192\\000\\002\\001", "\\192\\000\\002\\002"})) newServer{address="127.0.0.1:%s"} @@ -359,6 +360,32 @@ def testSpoofRawAction(self): self.assertEqual(expectedResponse, receivedResponse) self.assertEqual(receivedResponse.answer[0].ttl, 3600) + def testSpoofRawChaosAction(self): + """ + Spoofing: Spoof a response from several raw bytes in QCLass CH + """ + name = 'rawchaos.spoofing.tests.powerdns.com.' + + # TXT CH + query = dns.message.make_query(name, 'TXT', 'CH') + query.flags &= ~dns.flags.RD + expectedResponse = dns.message.make_response(query) + expectedResponse.flags &= ~dns.flags.AA + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.CH, + dns.rdatatype.TXT, + '"chaos"') + expectedResponse.answer.append(rrset) + + for method in ("sendUDPQuery", "sendTCPQuery"): + sender = getattr(self, method) + (_, receivedResponse) = sender(query, response=None, useQueue=False) + self.assertTrue(receivedResponse) + self.assertEqual(expectedResponse, receivedResponse) + self.assertEqual(receivedResponse.answer[0].ttl, 60) + + def testSpoofRawActionMulti(self): """ Spoofing: Spoof a response from several raw bytes From 3af419da4c52fe7f9ba19f78b0349cc5eda9e1f2 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 26 Apr 2023 15:52:25 +0200 Subject: [PATCH 160/909] auth: add setting workaround-11804 Workaround for https://github.com/PowerDNS/pdns/issues/11804. Defaults to no, implying the previously hard-coded value of 100. --- docs/settings.rst | 14 ++++++++++++++ pdns/auth-main.cc | 1 + pdns/pdnsutil.cc | 2 +- pdns/signingpipe.cc | 4 ++-- pdns/signingpipe.hh | 2 +- pdns/tcpreceiver.cc | 2 +- 6 files changed, 20 insertions(+), 5 deletions(-) diff --git a/docs/settings.rst b/docs/settings.rst index 899e1e47e3fa..ed39a436397f 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -1982,6 +1982,20 @@ If the webserver should print arguments. If a PID file should be written. +.. _setting-workaround-11804: + +``workaround-11804`` +------------------- + +- Boolean +- Default: no + +Workaround for issue https://github.com/PowerDNS/pdns/issues/11804. + +Default of no implies the pre-4.8 behaviour of up to 100 RRs per AXFR chunk. + +If enabled, only a single RR will be put into each AXFR chunk, making some zones transferable when they were not. + .. _setting-xfr-cycle-interval: ``xfr-cycle-interval`` diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index 5f46624b62a0..5bf5e1ccf622 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -196,6 +196,7 @@ static void declareArguments() ::arg().set("log-timestamp", "Print timestamps in log lines") = "yes"; ::arg().set("distributor-threads", "Default number of Distributor (backend) threads to start") = "3"; ::arg().set("signing-threads", "Default number of signer threads to start") = "3"; + ::arg().setSwitch("workaround-11804", "Workaround for issue 11804: send single RR per AXFR chunk") = "no"; ::arg().set("receiver-threads", "Default number of receiver threads to start") = "1"; ::arg().set("queue-limit", "Maximum number of milliseconds to queue a query") = "1500"; ::arg().set("resolver", "Use this resolver for ALIAS and the internal stub resolver") = "no"; diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index cea44001b8fc..18b10c24bfe2 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -1842,7 +1842,7 @@ static void testSpeed(const DNSName& zone, const string& /* remote */, int cores throw runtime_error("No backends available for DNSSEC key storage"); } - ChunkedSigningPipe csp(DNSName(zone), true, cores); + ChunkedSigningPipe csp(DNSName(zone), true, cores, 100); vector signatures; uint32_t rnd; diff --git a/pdns/signingpipe.cc b/pdns/signingpipe.cc index f740ae8bb7a8..2da3db7a24b6 100644 --- a/pdns/signingpipe.cc +++ b/pdns/signingpipe.cc @@ -57,9 +57,9 @@ catch(...) { return nullptr; } -ChunkedSigningPipe::ChunkedSigningPipe(DNSName signerName, bool mustSign, unsigned int workers) +ChunkedSigningPipe::ChunkedSigningPipe(DNSName signerName, bool mustSign, unsigned int workers, unsigned int maxChunkRecords) : d_signed(0), d_queued(0), d_outstanding(0), d_numworkers(workers), d_submitted(0), d_signer(std::move(signerName)), - d_maxchunkrecords(100), d_threads(d_numworkers), d_mustSign(mustSign), d_final(false) + d_maxchunkrecords(maxChunkRecords), d_threads(d_numworkers), d_mustSign(mustSign), d_final(false) { d_rrsetToSign = make_unique(); d_chunks.push_back(vector()); // load an empty chunk diff --git a/pdns/signingpipe.hh b/pdns/signingpipe.hh index 4c6443342fa8..c72b54178641 100644 --- a/pdns/signingpipe.hh +++ b/pdns/signingpipe.hh @@ -42,7 +42,7 @@ public: ChunkedSigningPipe(const ChunkedSigningPipe&) = delete; void operator=(const ChunkedSigningPipe&) = delete; - ChunkedSigningPipe(DNSName signerName, bool mustSign, unsigned int numWorkers=3); + ChunkedSigningPipe(DNSName signerName, bool mustSign, unsigned int numWorkers, unsigned int maxChunkRecords); ~ChunkedSigningPipe(); bool submit(const DNSZoneRecord& rr); chunk_t getChunk(bool final=false); diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 3341b1139261..12db956bb758 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -987,7 +987,7 @@ int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr& q, typedef map nsecxrepo_t; nsecxrepo_t nsecxrepo; - ChunkedSigningPipe csp(target, (securedZone && !presignedZone), ::arg().asNum("signing-threads", 1)); + ChunkedSigningPipe csp(target, (securedZone && !presignedZone), ::arg().asNum("signing-threads", 1), ::arg().mustDo("workaround-11804") ? 1 : 100); DNSName keyname; unsigned int udiff; From 4c6dd7970397f2220c015ab2403cc9f1977c1d19 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 12 May 2023 15:29:37 +0200 Subject: [PATCH 161/909] clang-tidy: Disable cppcoreguidelines-special-member-functions We will need to re-enable it once https://github.com/PowerDNS/pdns/issues/12809 has been fixed. --- .clang-tidy.full | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index 43754f59838a..d6fd67347192 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -1,5 +1,5 @@ --- -Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,bugprone-*,concurrency-*,modernize-*,performance-*,portability-*,readability-*,-modernize-use-trailing-return-type,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers' +Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,bugprone-*,concurrency-*,modernize-*,performance-*,portability-*,readability-*,-modernize-use-trailing-return-type,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-union-access' WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false From 541b8df1fc0773549a76c8de13fb1123baba8bda Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 5 Apr 2023 22:17:23 +0200 Subject: [PATCH 162/909] dnsdist: Properly handle reconnection failure for backend UDP sockets We try to reconnect our UDP sockets toward backends on some kind of network errors that indicate a topology change, but we need to be careful to handle the case where we actually fail to reconnect, as we end up with no remaining sockets to use. This commit properly deals with this case by pausing the thread handling UDP responses from the backend, instead of having it enter a busy loop, and by attempting to reconnect if we get a `bad file number` error when trying to send a UDP datagram to the backend. --- pdns/dnsdist.cc | 20 ++++++++++++++++++-- pdns/dnsdist.hh | 3 +++ pdns/dnsdistdist/dnsdist-backend.cc | 21 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 06aa910ab68f..0c85289e2ab4 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -722,9 +722,25 @@ void responderThread(std::shared_ptr dss) std::vector sockets; sockets.reserve(dss->sockets.size()); - for(;;) { + for (;;) { try { + if (dss->isStopped()) { + break; + } + + if (!dss->connected) { + /* the sockets are not connected yet, likely because we detected a problem, + tried to reconnect and it failed. We will try to reconnect after the next + successful health-check (unless reconnectOnUp is false), or when trying + to send in the UDP listener thread, but until then we simply need to wait. */ + dss->waitUntilConnected(); + continue; + } + dss->pickSocketsReadyForReceiving(sockets); + + /* check a second time here because we might have waited quite a bit + since the first check */ if (dss->isStopped()) { break; } @@ -1117,7 +1133,7 @@ ssize_t udpClientSendRequestToBackend(const std::shared_ptr& ss We don't want to reconnect the real socket if the healthcheck failed, because it's not using the same socket. */ - if (!healthCheck && (savederrno == EINVAL || savederrno == ENODEV || savederrno == ENETUNREACH)) { + if (!healthCheck && (savederrno == EINVAL || savederrno == ENODEV || savederrno == ENETUNREACH || savederrno == EBADF)) { ss->reconnect(); } } diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 472a729ba170..a26adeba9e75 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -23,6 +23,7 @@ #include "config.h" #include "ext/luawrapper/include/LuaContext.hpp" +#include #include #include #include @@ -903,6 +904,7 @@ private: std::thread tid; std::mutex connectLock; + std::condition_variable d_connectedWait; std::atomic_flag threadStarted; bool d_stopped{false}; public: @@ -975,6 +977,7 @@ public: } bool reconnect(); + void waitUntilConnected(); void hash(); void setId(const boost::uuids::uuid& newId); void setWeight(int newWeight); diff --git a/pdns/dnsdistdist/dnsdist-backend.cc b/pdns/dnsdistdist/dnsdist-backend.cc index 9113183c83f3..8ffa1fba61c2 100644 --- a/pdns/dnsdistdist/dnsdist-backend.cc +++ b/pdns/dnsdistdist/dnsdist-backend.cc @@ -116,9 +116,30 @@ bool DownstreamState::reconnect() } } + if (connected) { + tl.unlock(); + d_connectedWait.notify_all(); + } + return connected; } +void DownstreamState::waitUntilConnected() +{ + if (d_stopped) { + return; + } + if (connected) { + return; + } + { + std::unique_lock lock(connectLock); + d_connectedWait.wait(lock, [this]{ + return connected.load(); + }); + } +} + void DownstreamState::stop() { if (d_stopped) { From 3de50c36895bc12a8555066f376e70320166c73e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 3 May 2023 16:36:29 +0200 Subject: [PATCH 163/909] dnsdist: Only log failed backend connection attempt at info on first try --- pdns/dnsdist.hh | 2 +- pdns/dnsdistdist/dnsdist-backend.cc | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index a26adeba9e75..e55205599fb2 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -976,7 +976,7 @@ public: return status; } - bool reconnect(); + bool reconnect(bool initialAttempt = false); void waitUntilConnected(); void hash(); void setId(const boost::uuids::uuid& newId); diff --git a/pdns/dnsdistdist/dnsdist-backend.cc b/pdns/dnsdistdist/dnsdist-backend.cc index 8ffa1fba61c2..cc49a7d42f0e 100644 --- a/pdns/dnsdistdist/dnsdist-backend.cc +++ b/pdns/dnsdistdist/dnsdist-backend.cc @@ -37,7 +37,7 @@ bool DownstreamState::passCrossProtocolQuery(std::unique_ptr } } -bool DownstreamState::reconnect() +bool DownstreamState::reconnect(bool initialAttempt) { std::unique_lock tl(connectLock, std::try_to_lock); if (!tl.owns_lock() || isStopped()) { @@ -89,7 +89,9 @@ bool DownstreamState::reconnect() connected = true; } catch (const std::runtime_error& error) { - infolog("Error connecting to new server with address %s: %s", d_config.remote.toStringWithPort(), error.what()); + if (initialAttempt || g_verbose) { + infolog("Error connecting to new server with address %s: %s", d_config.remote.toStringWithPort(), error.what()); + } connected = false; break; } @@ -287,7 +289,7 @@ void DownstreamState::connectUDPSockets() fd = -1; } - reconnect(); + reconnect(true); } DownstreamState::~DownstreamState() From bb1ace1fedca0f6bdd2a962514cd5a6491f3c703 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 3 May 2023 16:37:36 +0200 Subject: [PATCH 164/909] dnsdist: check that the UDP responder thread is running after reconnecting --- pdns/dnsdistdist/dnsdist-backend.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-backend.cc b/pdns/dnsdistdist/dnsdist-backend.cc index cc49a7d42f0e..8426cdd2566b 100644 --- a/pdns/dnsdistdist/dnsdist-backend.cc +++ b/pdns/dnsdistdist/dnsdist-backend.cc @@ -121,6 +121,12 @@ bool DownstreamState::reconnect(bool initialAttempt) if (connected) { tl.unlock(); d_connectedWait.notify_all(); + if (!initialAttempt) { + /* we need to be careful not to start this + thread too soon, as the creation should only + happen after the configuration has been parsed */ + start(); + } } return connected; @@ -775,7 +781,6 @@ void DownstreamState::submitHealthCheckResult(bool initial, bool newResult) if (newState && !isTCPOnly() && (!connected || d_config.reconnectOnUp)) { newState = reconnect(); - start(); } setUpStatus(newState); From 0d199b6529f5c410d6014bf3058c717b57625553 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 3 May 2023 17:55:34 +0200 Subject: [PATCH 165/909] dnsdist: Add a TSAN suppression for the backend re-connection code --- pdns/dnsdistdist/dnsdist-tsan.supp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pdns/dnsdistdist/dnsdist-tsan.supp b/pdns/dnsdistdist/dnsdist-tsan.supp index d597a72af721..8443ab5319f3 100644 --- a/pdns/dnsdistdist/dnsdist-tsan.supp +++ b/pdns/dnsdistdist/dnsdist-tsan.supp @@ -17,3 +17,8 @@ race:DownstreamState::stop race:DownstreamState::submitHealthCheckResult race:DownstreamState::healthCheckRequired race:carbonDumpThread +# There is a slight race when we detect an error and +# re-connect a backend, where the UDP responder thread +# can still be looking at the existing socket descriptors. +# Actually writing to these is protected by a mutex, though. +race:DownstreamState::reconnect From c0a71561d71bd7a8bf7107be3d8f5414262a026b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 12 May 2023 17:57:02 +0200 Subject: [PATCH 166/909] clang-tidy: Disable cppcoreguidelines-avoid-non-const-global-variables While I agree that we should try to avoid non-const global vars as much as possible, this rule kills the boost testing framework so we cannot keep it. --- .clang-tidy.full | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index d6fd67347192..3d678e379e25 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -1,5 +1,5 @@ --- -Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,bugprone-*,concurrency-*,modernize-*,performance-*,portability-*,readability-*,-modernize-use-trailing-return-type,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-union-access' +Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,bugprone-*,concurrency-*,modernize-*,performance-*,portability-*,readability-*,-modernize-use-trailing-return-type,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-avoid-non-const-global-variables' WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false From f5d4cf70dd112cc26c01f097d10984098375d69a Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Fri, 12 May 2023 22:37:13 +0200 Subject: [PATCH 167/909] Apply changes for doc nits --- docs/settings.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/settings.rst b/docs/settings.rst index ed39a436397f..782435ef5f9f 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -1985,12 +1985,12 @@ If a PID file should be written. .. _setting-workaround-11804: ``workaround-11804`` -------------------- +-------------------- - Boolean - Default: no -Workaround for issue https://github.com/PowerDNS/pdns/issues/11804. +Workaround for `issue #11804 (outgoing AXFR may try to overfill a chunk and fail) `_. Default of no implies the pre-4.8 behaviour of up to 100 RRs per AXFR chunk. From 1463e0417a11bb97017662d7e4adf2abac846d19 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 15 May 2023 10:57:53 +0200 Subject: [PATCH 168/909] clang-tidy: Increase the cognitive complexity threshold to 75 The current level of 50 is too low for a function like 'handleQueuedHealthChecks' which is quite simple. --- .clang-tidy.full | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index 3d678e379e25..db601de54806 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -405,7 +405,7 @@ CheckOptions: - key: modernize-use-noexcept.UseNoexceptFalse value: 'true' - key: readability-function-cognitive-complexity.Threshold - value: '50' + value: '75' - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic value: 'true' - key: bugprone-argument-comment.IgnoreSingleArgument From 568a800b36d1fe03f6f28382a3a89c8d5fa6a758 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 15 May 2023 12:00:58 +0200 Subject: [PATCH 169/909] Process review comments --- .clang-tidy.full | 2 +- pdns/recursordist/rec-main.cc | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index e4a95882a62d..43754f59838a 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -253,7 +253,7 @@ CheckOptions: - key: modernize-pass-by-value.ValuesOnly value: 'false' - key: readability-function-cognitive-complexity.IgnoreMacros - value: 'false' + value: 'true' - key: modernize-loop-convert.IncludeStyle value: llvm - key: cert-str34-c.DiagnoseSignedUnsignedCharComparisons diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index cf09ccbb8afa..d5f310811314 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1254,7 +1254,7 @@ void broadcastFunction(const pipefunc_t& func) continue; } - ThreadMSG* tmsg = new ThreadMSG(); // NOLINT: manual onwership handling + ThreadMSG* tmsg = new ThreadMSG(); // NOLINT: manual ownership handling tmsg->func = func; tmsg->wantAnswer = true; if (write(threadInfo.pipes.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // NOLINT: sizeof correct @@ -1348,7 +1348,7 @@ T broadcastAccFunction(const std::function& func) if (resp) { ret += *resp; - delete resp; // NOLINT: manual ownershipm handling + delete resp; // NOLINT: manual ownership handling resp = nullptr; } // coverity[leaked_storage] @@ -1915,7 +1915,6 @@ static int serviceMain(Logr::log_t log) // NOLINT(readability-function-cognitive initDontQuery(log); - /* this needs to be done before parseACLs(), which call broadcastFunction() */ RecThreadInfo::setWeDistributeQueries(::arg().mustDo("pdns-distributes-queries")); if (RecThreadInfo::weDistributeQueries()) { SLOG(g_log << Logger::Warning << "PowerDNS Recursor itself will distribute queries over threads" << endl, From 2d46fe5d99755427dc11a8ea37e72656e9af0173 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 15 May 2023 11:49:17 +0200 Subject: [PATCH 170/909] Also log in the non-structured logging case --- pdns/recursordist/pdns_recursor.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index a52d3289a5b8..7f8a91a17967 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -893,7 +893,7 @@ static uint32_t capPacketCacheTTL(const struct dnsheader& hdr, uint32_t ttl, boo return ttl; } -void startDoResolve(void* p) +void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 { auto dc = std::unique_ptr(reinterpret_cast(p)); SyncRes sr(dc->d_now); @@ -1673,7 +1673,8 @@ void startDoResolve(void* p) #endif } - if (g_packetCache && !variableAnswer && !sr.wasVariable()) { + const bool intoPC = g_packetCache && !variableAnswer && !sr.wasVariable(); + if (intoPC) { minTTL = capPacketCacheTTL(*pw.getHeader(), minTTL, seenAuthSOA); g_packetCache->insertResponsePacket(dc->d_tag, dc->d_qhash, std::move(dc->d_query), dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass, @@ -1788,6 +1789,7 @@ void startDoResolve(void* p) if (!shouldNotValidate && sr.isDNSSECValidationRequested()) { g_log << ", dnssec=" << sr.getValidationState(); } + g_log << " answer-is-variable=" << sr.wasVariable() << ", into-packetcache=" << intoPC; g_log << endl; } else { @@ -1804,7 +1806,7 @@ void startDoResolve(void* p) "rcode", Logging::Loggable(res), "validationState", Logging::Loggable(sr.getValidationState()), "answer-is-variable", Logging::Loggable(sr.wasVariable()), - "into-packetcache", Logging::Loggable(g_packetCache && !variableAnswer && !sr.wasVariable())); + "into-packetcache", Logging::Loggable(intoPC)); } } From 475718662b06927e54a379dcf311b2623830f7da Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 14 Apr 2023 10:43:23 +0200 Subject: [PATCH 171/909] rec: Distinguish between recursion depth and cname length, they are not the same --- pdns/recursordist/syncres.cc | 50 ++++++++++----------- pdns/recursordist/syncres.hh | 1 + pdns/recursordist/test-syncres_cc1.cc | 65 +++++++++++++++++++++++---- 3 files changed, 82 insertions(+), 34 deletions(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index f7270474f106..72ec1d0caab3 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -468,6 +468,7 @@ bool SyncRes::s_dot_to_port_853; int SyncRes::s_event_trace_enabled; bool SyncRes::s_save_parent_ns_set; unsigned int SyncRes::s_max_busy_dot_probes; +unsigned int SyncRes::s_max_CNAMES_followed = 10; bool SyncRes::s_addExtendedResolutionDNSErrors; #define LOG(x) \ @@ -1825,7 +1826,8 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName& qname, const QType qtyp if (s_maxdepth > 0) { auto bound = getAdjustedRecursionBound(); - if (depth > bound) { + // Use a stricter bound if throttling + if (depth > bound || (d_outqueries > 10 && d_throttledqueries > 5 && depth > bound * 2 / 3)) { string msg = "More than " + std::to_string(bound) + " (adjusted max-recursion-depth) levels of recursion needed while resolving " + qname.toLogString(); LOG(prefix << qname << ": " << msg << endl); throw ImmediateServFailException(msg); @@ -2403,30 +2405,22 @@ void SyncRes::updateValidationStatusInCache(const DNSName& qname, const QType qt } } -static bool scanForCNAMELoop(const DNSName& name, const vector& records) +static pair scanForCNAMELoop(const DNSName& name, const vector& records) { + unsigned int numCNames = 0; for (const auto& record : records) { if (record.d_type == QType::CNAME && record.d_place == DNSResourceRecord::ANSWER) { + ++numCNames; if (name == record.d_name) { - return true; + return {true, numCNames}; } } } - return false; + return {false, numCNames}; } bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse) { - // Even if s_maxdepth is zero, we want to have this check - auto bound = std::max(40U, getAdjustedRecursionBound()); - // Bounds were > 9 and > 15 originally, now they are derived from s_maxdepth (default 40) - // Apply more strict bound if we see throttling - if ((depth >= bound / 4 && d_outqueries > 10 && d_throttledqueries > 5) || depth > bound * 3 / 8) { - LOG(prefix << qname << ": Recursing (CNAME or other indirection) too deep, depth=" << depth << endl); - res = RCode::ServFail; - return true; - } - vector cset; vector> signatures; vector> authorityRecs; @@ -2599,12 +2593,18 @@ bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector< return true; } - // Check to see if we already have seen the new target as a previous target - if (scanForCNAMELoop(newTarget, ret)) { + // Check to see if we already have seen the new target as a previous target or that we have a very long CNAME chain + const auto [CNAMELoop, numCNAMEs] = scanForCNAMELoop(newTarget, ret); + if (CNAMELoop) { string msg = "got a CNAME referral (from cache) that causes a loop"; LOG(prefix << qname << ": Status=" << msg << endl); throw ImmediateServFailException(msg); } + if (numCNAMEs > s_max_CNAMES_followed) { + string msg = "max number of CNAMEs exceeded"; + LOG(prefix << qname << ": Status=" << msg << endl); + throw ImmediateServFailException(msg); + } set beenthere; Context cnameContext; @@ -5327,26 +5327,24 @@ void SyncRes::handleNewTarget(const std::string& prefix, const DNSName& qname, c setQNameMinimization(false); } - // Was 10 originally, default s_maxdepth is 40, but even if it is zero we want to apply a bound - auto bound = std::max(40U, getAdjustedRecursionBound()) / 4; - if (depth > bound) { - LOG(prefix << qname << ": Status=got a CNAME referral, but recursing too deep, returning SERVFAIL" << endl); - rcode = RCode::ServFail; - return; - } - if (!d_followCNAME) { rcode = RCode::NoError; return; } - // Check to see if we already have seen the new target as a previous target - if (scanForCNAMELoop(newtarget, ret)) { + // Check to see if we already have seen the new target as a previous target or that the chain is too long + const auto [CNAMELoop, numCNAMEs] = scanForCNAMELoop(newtarget, ret); + if (CNAMELoop) { LOG(prefix << qname << ": Status=got a CNAME referral that causes a loop, returning SERVFAIL" << endl); ret.clear(); rcode = RCode::ServFail; return; } + if (numCNAMEs > s_max_CNAMES_followed) { + LOG(prefix << qname << ": Status=got a CNAME referral, but chain too long, returning SERVFAIL" << endl); + rcode = RCode::ServFail; + return; + } if (qtype == QType::DS || qtype == QType::DNSKEY) { LOG(prefix << qname << ": Status=got a CNAME referral, but we are looking for a DS or DNSKEY" << endl); diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index b271acfbfaf6..445482b95265 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -545,6 +545,7 @@ public: static bool s_tcp_fast_open_connect; static bool s_dot_to_port_853; static unsigned int s_max_busy_dot_probes; + static unsigned int s_max_CNAMES_followed; static const int event_trace_to_pb = 1; static const int event_trace_to_log = 2; diff --git a/pdns/recursordist/test-syncres_cc1.cc b/pdns/recursordist/test-syncres_cc1.cc index 9d1c19d420c8..e265fa1042c0 100644 --- a/pdns/recursordist/test-syncres_cc1.cc +++ b/pdns/recursordist/test-syncres_cc1.cc @@ -1002,6 +1002,56 @@ BOOST_AUTO_TEST_CASE(test_glueless_referral) BOOST_CHECK_EQUAL(ret[0].d_name, target); } +BOOST_AUTO_TEST_CASE(test_endless_glueless_referral) +{ + std::unique_ptr sr; + initSR(sr); + + primeHints(); + + const DNSName target("powerdns.com."); + + size_t count = 0; + sr->setAsyncCallback([target, &count](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { + if (isRootServer(ip)) { + setLWResult(res, 0, false, false, true); + + if (domain.isPartOf(DNSName("com."))) { + addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); + } + else if (domain.isPartOf(DNSName("org."))) { + addRecordToLW(res, "org.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); + } + else { + setLWResult(res, RCode::NXDomain, false, false, true); + return LWResult::Result::Success; + } + + addRecordToLW(res, "a.gtld-servers.net.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600); + addRecordToLW(res, "a.gtld-servers.net.", QType::AAAA, "2001:DB8::1", DNSResourceRecord::ADDITIONAL, 3600); + return LWResult::Result::Success; + } + if (domain == target) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, "powerdns.com.", QType::NS, "ns1.powerdns.org.", DNSResourceRecord::AUTHORITY, 172800); + addRecordToLW(res, "powerdns.com.", QType::NS, "ns2.powerdns.org.", DNSResourceRecord::AUTHORITY, 172800); + return LWResult::Result::Success; + } + setLWResult(res, 0, false, false, true); + addRecordToLW(res, domain, QType::NS, std::to_string(count) + ".ns1.powerdns.org", DNSResourceRecord::AUTHORITY, 172800); + addRecordToLW(res, domain, QType::NS, std::to_string(count) + ".ns2.powerdns.org", DNSResourceRecord::AUTHORITY, 172800); + count++; + return LWResult::Result::Success; + }); + + vector ret; + BOOST_CHECK_EXCEPTION(sr->beginResolve(target, QType(QType::A), QClass::IN, ret), + ImmediateServFailException, + [](const ImmediateServFailException& isfe) { + return isfe.reason.substr(0, 9) == "More than"; + }); +} + BOOST_AUTO_TEST_CASE(test_glueless_referral_aaaa_task) { std::unique_ptr sr; @@ -1647,17 +1697,17 @@ BOOST_AUTO_TEST_CASE(test_cname_long_loop) } } -BOOST_AUTO_TEST_CASE(test_cname_depth) +BOOST_AUTO_TEST_CASE(test_cname_length) { std::unique_ptr sr; initSR(sr); primeHints(); - size_t depth = 0; + size_t length = 0; const DNSName target("cname.powerdns.com."); - sr->setAsyncCallback([target, &depth](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { + sr->setAsyncCallback([target, &length](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -1668,8 +1718,8 @@ BOOST_AUTO_TEST_CASE(test_cname_depth) else if (ip == ComboAddress("192.0.2.1:53")) { setLWResult(res, 0, true, false, false); - addRecordToLW(res, domain, QType::CNAME, std::to_string(depth) + "-cname.powerdns.com"); - depth++; + addRecordToLW(res, domain, QType::CNAME, std::to_string(length) + "-cname.powerdns.com"); + length++; return LWResult::Result::Success; } @@ -1679,9 +1729,8 @@ BOOST_AUTO_TEST_CASE(test_cname_depth) vector ret; int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); BOOST_CHECK_EQUAL(res, RCode::ServFail); - BOOST_CHECK_EQUAL(ret.size(), depth); - /* we have an arbitrary limit at 10 when following a CNAME chain */ - BOOST_CHECK_EQUAL(depth, 10U + 2U); + BOOST_CHECK_EQUAL(ret.size(), length); + BOOST_CHECK_EQUAL(length, SyncRes::s_max_CNAMES_followed + 1); } BOOST_AUTO_TEST_CASE(test_time_limit) From c5fe87a227e8f11993e48ed04471432132b79644 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 15 May 2023 13:23:55 +0200 Subject: [PATCH 172/909] As an experiment, just fix the two reported cases of performance-unnecessary-value-param --- pdns/recursordist/test-syncres_cc1.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/test-syncres_cc1.cc b/pdns/recursordist/test-syncres_cc1.cc index e265fa1042c0..4f8471c7b00e 100644 --- a/pdns/recursordist/test-syncres_cc1.cc +++ b/pdns/recursordist/test-syncres_cc1.cc @@ -1012,7 +1012,7 @@ BOOST_AUTO_TEST_CASE(test_endless_glueless_referral) const DNSName target("powerdns.com."); size_t count = 0; - sr->setAsyncCallback([target, &count](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { + sr->setAsyncCallback([target, &count](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, const boost::optional& /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); @@ -1642,7 +1642,7 @@ BOOST_AUTO_TEST_CASE(test_cname_long_loop) const DNSName target3("cname3.powerdns.com."); const DNSName target4("cname4.powerdns.com."); - sr->setAsyncCallback([target1, target2, target3, target4, &count](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { + sr->setAsyncCallback([target1, target2, target3, target4, &count](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, const boost::optional& /* context */, LWResult* res, bool* /* chained */) { count++; if (isRootServer(ip)) { From 714b494ea4d3b177972b4522281a89cf78ae8f18 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 15 May 2023 13:38:10 +0200 Subject: [PATCH 173/909] NOLINT(readability-function-cognitive-complexity) markers --- .clang-tidy.full | 2 +- pdns/recursordist/syncres.cc | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index 3d678e379e25..baae11e15790 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -1,5 +1,5 @@ --- -Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,bugprone-*,concurrency-*,modernize-*,performance-*,portability-*,readability-*,-modernize-use-trailing-return-type,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-avoid-non-const-global-variables' +Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,bugprone-*,concurrency-*,modernize-*,performance-*,portability-*,readability-*,-modernize-use-trailing-return-type,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-avoid-non-const-global-variables,--cppcoreguidelines-pro-type-vararg' WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 72ec1d0caab3..6119a325e991 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1817,7 +1817,7 @@ unsigned int SyncRes::getAdjustedRecursionBound() const * \param stopAtDelegation if non-nullptr and pointed-to value is Stop requests the callee to stop at a delegation, if so pointed-to value is set to Stopped * \return DNS RCODE or -1 (Error) */ -int SyncRes::doResolveNoQNameMinimization(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, set& beenthere, Context& context, bool* fromCache, StopAtDelegation* stopAtDelegation) +int SyncRes::doResolveNoQNameMinimization(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, set& beenthere, Context& context, bool* fromCache, StopAtDelegation* stopAtDelegation) // NOLINT(readability-function-cognitive-complexity) { context.extendedError.reset(); auto prefix = getPrefix(depth); @@ -2419,7 +2419,7 @@ static pair scanForCNAMELoop(const DNSName& name, const vect return {false, numCNames}; } -bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse) +bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse) // NOLINT(readability-function-cognitive-complexity) { vector cset; vector> signatures; From 6bf7d9e319d4c06323a8454415e5a91270965209 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 15 May 2023 13:40:06 +0200 Subject: [PATCH 174/909] -cppcoreguidelines-avoid-non-const-global-variables --- .clang-tidy.full | 2 +- pdns/recursordist/test-syncres_cc1.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index baae11e15790..4b10cf3989f6 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -1,5 +1,5 @@ --- -Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,bugprone-*,concurrency-*,modernize-*,performance-*,portability-*,readability-*,-modernize-use-trailing-return-type,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-avoid-non-const-global-variables,--cppcoreguidelines-pro-type-vararg' +Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,bugprone-*,concurrency-*,modernize-*,performance-*,portability-*,readability-*,-modernize-use-trailing-return-type,-readability-magic-numbers,-cppcoreguidelines-avoid-magic-numbers,-cppcoreguidelines-pro-type-union-access,-cppcoreguidelines-avoid-non-const-global-variables,-cppcoreguidelines-pro-type-vararg' WarningsAsErrors: '' HeaderFilterRegex: '' AnalyzeTemporaryDtors: false diff --git a/pdns/recursordist/test-syncres_cc1.cc b/pdns/recursordist/test-syncres_cc1.cc index 4f8471c7b00e..3d642a17240c 100644 --- a/pdns/recursordist/test-syncres_cc1.cc +++ b/pdns/recursordist/test-syncres_cc1.cc @@ -1707,7 +1707,7 @@ BOOST_AUTO_TEST_CASE(test_cname_length) size_t length = 0; const DNSName target("cname.powerdns.com."); - sr->setAsyncCallback([target, &length](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { + sr->setAsyncCallback([target, &length](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, const boost::optional& /* context */, LWResult* res, bool* /* chained */) { if (isRootServer(ip)) { setLWResult(res, 0, false, false, true); From b33f09f1989e938c503142a38c556df94254443a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 15 May 2023 14:10:55 +0200 Subject: [PATCH 175/909] dnsdist: Stop setting SO_REUSEADDR on outgoing UDP client sockets `SO_REUSEADDR` is useful on TCP server sockets to allow binding quickly after restarting the process without waiting `TIME_WAIT` seconds, or to allow some port reuse on BSD. It also allows reusing a port more quickly for TCP client sockets. For UDP sockets, however, Linux allows two sockets to be bound to the same address and port, and will distribute all packets to the most recent socket, which is very unexpected, to say the least. --- pdns/dnsdistdist/dnsdist-backend.cc | 1 - pdns/dnsdistdist/dnsdist-healthchecks.cc | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-backend.cc b/pdns/dnsdistdist/dnsdist-backend.cc index 9113183c83f3..cfa6e5c7b653 100644 --- a/pdns/dnsdistdist/dnsdist-backend.cc +++ b/pdns/dnsdistdist/dnsdist-backend.cc @@ -72,7 +72,6 @@ bool DownstreamState::reconnect() #endif if (!IsAnyAddress(d_config.sourceAddr)) { - SSetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, 1); #ifdef IP_BIND_ADDRESS_NO_PORT if (d_config.ipBindAddrNoPort) { SSetsockopt(fd, SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1); diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index 1addf7583de3..9ec50e3a5a17 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -319,7 +319,9 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared #endif if (!IsAnyAddress(ds->d_config.sourceAddr)) { - sock.setReuseAddr(); + if (ds->doHealthcheckOverTCP()) { + sock.setReuseAddr(); + } #ifdef IP_BIND_ADDRESS_NO_PORT if (ds->d_config.ipBindAddrNoPort) { SSetsockopt(sock.getHandle(), SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1); From 20f67fee9447069d4586a41254468ac060b2d65e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 15 May 2023 15:32:27 +0200 Subject: [PATCH 176/909] dnsdist: Really disable REUSEADDR on outgoing UDP client sockets It turns out that our `Socket::bind()` will _helpfully_ enable this by default. --- pdns/dnsdistdist/dnsdist-healthchecks.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index 9ec50e3a5a17..213374020f15 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -327,7 +327,7 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared SSetsockopt(sock.getHandle(), SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1); } #endif - sock.bind(ds->d_config.sourceAddr); + sock.bind(ds->d_config.sourceAddr, false); } auto data = std::make_shared(*mplexer, ds, std::move(checkName), checkType, checkClass, queryID); From 769c36cc4d2d6deed97be78a799ca611cf10ede0 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 15 May 2023 15:09:04 +0200 Subject: [PATCH 177/909] Fix DoT test to no use www.powerdns.com, as it changed --- regression-tests.recursor-dnssec/test_SimpleDoT.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/regression-tests.recursor-dnssec/test_SimpleDoT.py b/regression-tests.recursor-dnssec/test_SimpleDoT.py index 1026001d9ecc..fcc915ab53d1 100644 --- a/regression-tests.recursor-dnssec/test_SimpleDoT.py +++ b/regression-tests.recursor-dnssec/test_SimpleDoT.py @@ -30,9 +30,9 @@ def setUpClass(cls): cls.generateRecursorConfig(confdir) cls.startRecursor(confdir, cls._recursorPort) - def testA(self): - expected = dns.rrset.from_text('www.powerdns.com.', 0, dns.rdataclass.IN, 'A', '188.166.104.92') - query = dns.message.make_query('www.powerdns.com', 'A', want_dnssec=True) + def testTXT(self): + expected = dns.rrset.from_text('dot-test-target.powerdns.org.', 0, dns.rdataclass.IN, 'TXT', 'https://github.com/PowerDNS/pdns/pull/12825') + query = dns.message.make_query('dot-test-target.powerdns.org', 'TXT', want_dnssec=True) query.flags |= dns.flags.AD res = self.sendUDPQuery(query) From 56871b9bca8e3958ebec1fe0683c08d618d53b39 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 16 May 2023 08:23:51 +0200 Subject: [PATCH 178/909] rec: fix clang-tidy botch wrt spelling of "log-fail" Followup to #12790 --- pdns/recursordist/rec-main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index d5f310811314..0e7e3fceb382 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1419,7 +1419,7 @@ static int initDNSSEC(Logr::log_t log) else if (::arg()["dnssec"] == "validate") { g_dnssecmode = DNSSECMode::ValidateAll; } - else if (::arg()["dnssec"] == "log-fail {") { + else if (::arg()["dnssec"] == "log-fail") { g_dnssecmode = DNSSECMode::ValidateForLog; } else { From 3fb0ebf1e9dea4063aabd735319600fa4273466a Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 16 May 2023 09:18:00 +0200 Subject: [PATCH 179/909] apt no qq --- tasks.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tasks.py b/tasks.py index 96f22089744b..62880a5c9fc8 100644 --- a/tasks.py +++ b/tasks.py @@ -221,7 +221,7 @@ def install_auth_test_deps(c, backend): # FIXME: rename this, we do way more tha extra=[] for b in backend: extra.extend(auth_backend_test_deps[b]) - c.sudo('apt-get -y -qq install ' + ' '.join(extra+auth_test_deps)) + c.sudo('apt-get -y install ' + ' '.join(extra+auth_test_deps)) c.run('chmod +x /opt/pdns-auth/bin/* /opt/pdns-auth/sbin/*') # c.run('''if [ ! -e $HOME/bin/jdnssec-verifyzone ]; then From 699d088acc89a1417c922a6c7026063f81fd28bd Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 16 May 2023 09:30:54 +0200 Subject: [PATCH 180/909] more apt no -qq --- tasks.py | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tasks.py b/tasks.py index 62880a5c9fc8..33bdfc70a294 100644 --- a/tasks.py +++ b/tasks.py @@ -148,23 +148,23 @@ def apt_fresh(c): c.sudo('sed -i \'s/azure\.//\' /etc/apt/sources.list') c.sudo('apt-get update') - c.sudo('apt-get -qq -y --allow-downgrades dist-upgrade') + c.sudo('apt-get -y --allow-downgrades dist-upgrade') @task def install_clang(c): """ install clang-12 and llvm-12 """ - c.sudo('apt-get -qq -y --no-install-recommends install clang-12 llvm-12') + c.sudo('apt-get -y --no-install-recommends install clang-12 llvm-12') @task def install_clang_tidy_tools(c): - c.sudo('apt-get -qq -y --no-install-recommends install clang-tidy-12 clang-tools-12 bear python-yaml') + c.sudo('apt-get -y --no-install-recommends install clang-tidy-12 clang-tools-12 bear python-yaml') @task def install_clang_runtime(c): # this gives us the symbolizer, for symbols in asan/ubsan traces - c.sudo('apt-get -qq -y --no-install-recommends install clang-12') + c.sudo('apt-get -y --no-install-recommends install clang-12') def install_libdecaf(c, product): c.run('git clone https://git.code.sf.net/p/ed448goldilocks/code /tmp/libdecaf') @@ -184,15 +184,15 @@ def install_libdecaf(c, product): @task def install_doc_deps(c): - c.sudo('apt-get install -qq -y ' + ' '.join(doc_deps)) + c.sudo('apt-get install -y ' + ' '.join(doc_deps)) @task def install_doc_deps_pdf(c): - c.sudo('apt-get install -qq -y ' + ' '.join(doc_deps_pdf)) + c.sudo('apt-get install -y ' + ' '.join(doc_deps_pdf)) @task def install_auth_build_deps(c): - c.sudo('apt-get install -qq -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + auth_build_deps)) + c.sudo('apt-get install -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + auth_build_deps)) install_libdecaf(c, 'pdns-auth') def setup_authbind(c): @@ -240,12 +240,12 @@ def install_auth_test_deps(c, backend): # FIXME: rename this, we do way more tha @task def install_rec_bulk_deps(c): # FIXME: rename this, we do way more than apt-get - c.sudo('apt-get --no-install-recommends -qq -y install ' + ' '.join(rec_bulk_deps)) + c.sudo('apt-get --no-install-recommends -y install ' + ' '.join(rec_bulk_deps)) c.run('chmod +x /opt/pdns-recursor/bin/* /opt/pdns-recursor/sbin/*') @task def install_rec_test_deps(c): # FIXME: rename this, we do way more than apt-get - c.sudo('apt-get --no-install-recommends install -qq -y ' + ' '.join(rec_bulk_deps) + ' \ + c.sudo('apt-get --no-install-recommends install -y ' + ' '.join(rec_bulk_deps) + ' \ pdns-server pdns-backend-bind daemontools \ jq libfaketime lua-posix lua-socket bc authbind \ python3-venv python3-dev default-libmysqlclient-dev libpq-dev \ @@ -262,7 +262,7 @@ def install_rec_test_deps(c): # FIXME: rename this, we do way more than apt-get @task def install_dnsdist_test_deps(c): # FIXME: rename this, we do way more than apt-get - c.sudo('apt-get install -qq -y \ + c.sudo('apt-get install -y \ libluajit-5.1-2 \ libboost-all-dev \ libcap2 \ @@ -288,11 +288,11 @@ def install_dnsdist_test_deps(c): # FIXME: rename this, we do way more than apt- @task def install_rec_build_deps(c): - c.sudo('apt-get install -qq -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + rec_build_deps)) + c.sudo('apt-get install -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + rec_build_deps)) @task def install_dnsdist_build_deps(c): - c.sudo('apt-get install -qq -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + dnsdist_build_deps)) + c.sudo('apt-get install -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + dnsdist_build_deps)) @task def ci_autoconf(c): @@ -558,7 +558,7 @@ def ci_auth_install_remotebackend_test_deps(c): with c.cd('modules/remotebackend'): # c.run('bundle config set path vendor/bundle') c.run('sudo ruby -S bundle install') - c.sudo('apt-get install -qq -y socat') + c.sudo('apt-get install -y socat') @task def ci_auth_run_unit_tests(c): @@ -592,7 +592,7 @@ def add_auth_repo(c): release = 'focal' version = '44' - c.sudo('apt-get install -qq -y curl gnupg2') + c.sudo('apt-get install -y curl gnupg2') if version == 'master': c.sudo('curl -s -o /etc/apt/trusted.gpg.d/pdns-repo.asc https://repo.powerdns.com/CBC8B383-pub.asc') else: @@ -727,7 +727,7 @@ def setup_godbc_sqlite3(c): c.sudo('sed -i "s/libsqlite3odbc.so/\/usr\/lib\/x86_64-linux-gnu\/odbc\/libsqlite3odbc.so/g" /etc/odbcinst.ini') def setup_ldap_client(c): - c.sudo('DEBIAN_FRONTEND=noninteractive apt-get install -qq -y ldap-utils') + c.sudo('DEBIAN_FRONTEND=noninteractive apt-get install -y ldap-utils') c.sudo('sh -c \'echo "127.0.0.1 ldapserver" | tee -a /etc/hosts\'') @task From deb5c828c03696869d073691942dc33f38a90602 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 16 May 2023 09:38:36 +0200 Subject: [PATCH 181/909] get rid of firefox --- build-scripts/gh-actions-setup-inv | 1 + 1 file changed, 1 insertion(+) diff --git a/build-scripts/gh-actions-setup-inv b/build-scripts/gh-actions-setup-inv index 0cd64feb5b7f..50d11f607c77 100755 --- a/build-scripts/gh-actions-setup-inv +++ b/build-scripts/gh-actions-setup-inv @@ -8,6 +8,7 @@ sudo chmod 755 /usr/sbin/policy-rc.d sudo apt-get update # FIXME: Avoid GRUB related errors due to runner image configuration by removing it. sudo dpkg --purge --force-all grub-efi-amd64-signed && sudo dpkg --purge --force-all shim-signed +sudo dpkg --purge --force-all firefox sudo apt-get autoremove sudo apt-get -qq -y --allow-downgrades dist-upgrade sudo apt-get -qq -y --no-install-recommends install python3-pip From fd72b5d152fe60ff2af2cc1ab9ef9fb068e77677 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 16 May 2023 09:33:28 +0200 Subject: [PATCH 182/909] secpoll check: use preferred ubuntu mirror --- .github/workflows/secpoll.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/secpoll.yml b/.github/workflows/secpoll.yml index b7b52ea7a125..e1e4463f9eaa 100644 --- a/.github/workflows/secpoll.yml +++ b/.github/workflows/secpoll.yml @@ -14,6 +14,7 @@ jobs: # on a ubuntu-20.04 VM runs-on: ubuntu-20.04 steps: + - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 From b29a61b140510aa3c40d203e894fb0171dc0b7ab Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 16 Mar 2023 16:08:56 +0100 Subject: [PATCH 183/909] Sanitize d_orig_ttl The computed orig_ttl can be wrong if d_now.tv_sec is more recent than the d_now.tv_sec the ttd was computed from. This can happen if we went out to get e.g. keys and that took time. d_orig_ttl wraps around in that case if the TTL value was smaller than that delay. Work around that and make sure d_orig_ttl is within the legal range. --- pdns/recursordist/recursor_cache.cc | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index 4c95c052c55c..c32364c40d75 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -607,7 +607,19 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, /* Yes, we have altered the d_ttl value by adding time(nullptr) to it prior to calling this function, so the TTL actually holds a TTD. */ ce.d_ttd = min(maxTTD, static_cast(i.d_ttl)); // XXX this does weird things if TTLs differ in the set + ce.d_orig_ttl = ce.d_ttd - now; + + // d_orig_ttl should be between s_minimumTTL and s_maxcachettl, as d_ttd was sanitized wrt those + // bounds. But our reference point (d_now aka now) might be "too new" at this point, if we went + // outside to e.g. get DNSKEYS and that took a while. In that case, if the original TTL was + // smaller than the delay, d_orig_ttl will wrap and become very large. Detect that case and + // make sure d_orig_ttl is fixed. Likewise if there was a delay but that was smaller than the + // original TTL, d_orig_ttl can become smaller than s_minimumTTL. Detect those cases and use a + // small but legal d_orig_ttl in those cases. + if (ce.d_orig_ttl < SyncRes::s_minimumTTL || ce.d_orig_ttl > SyncRes::s_maxcachettl) { + ce.d_orig_ttl = SyncRes::s_minimumTTL; + } ce.d_records.push_back(i.getContent()); } From 86c6bb8a16324dd51bf48ce4554e41f301f90e53 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 22 Mar 2023 14:05:40 +0100 Subject: [PATCH 184/909] Alternate approach: remmeber the actual orig_ttl. A bit harded than you think, as in somce cases TTDs are modified later. --- pdns/recursordist/recursor_cache.cc | 7 ++++--- pdns/recursordist/recursor_cache.hh | 2 +- pdns/recursordist/syncres.cc | 25 ++++++++++++++++++++++--- pdns/recursordist/test-syncres_cc2.cc | 6 +++--- 4 files changed, 30 insertions(+), 10 deletions(-) diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index c32364c40d75..4001df41a870 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -531,7 +531,7 @@ bool MemRecursorCache::CacheEntry::shouldReplace(time_t now, bool auth, vState s return true; } -void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, const DNSName& authZone, boost::optional ednsmask, const OptTag& routingTag, vState state, boost::optional from, bool refresh) +void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, const DNSName& authZone, boost::optional ednsmask, const OptTag& routingTag, vState state, boost::optional from, bool refresh, uint32_t orig_ttl) { auto& shard = getMap(qname); auto lockedShard = shard.lock(); @@ -608,8 +608,8 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, prior to calling this function, so the TTL actually holds a TTD. */ ce.d_ttd = min(maxTTD, static_cast(i.d_ttl)); // XXX this does weird things if TTLs differ in the set - ce.d_orig_ttl = ce.d_ttd - now; - + ce.d_orig_ttl = orig_ttl; +#if 0 // d_orig_ttl should be between s_minimumTTL and s_maxcachettl, as d_ttd was sanitized wrt those // bounds. But our reference point (d_now aka now) might be "too new" at this point, if we went // outside to e.g. get DNSKEYS and that took a while. In that case, if the original TTL was @@ -620,6 +620,7 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, if (ce.d_orig_ttl < SyncRes::s_minimumTTL || ce.d_orig_ttl > SyncRes::s_maxcachettl) { ce.d_orig_ttl = SyncRes::s_minimumTTL; } +#endif ce.d_records.push_back(i.getContent()); } diff --git a/pdns/recursordist/recursor_cache.hh b/pdns/recursordist/recursor_cache.hh index ce37145f003e..638728a27003 100644 --- a/pdns/recursordist/recursor_cache.hh +++ b/pdns/recursordist/recursor_cache.hh @@ -69,7 +69,7 @@ public: time_t get(time_t, const DNSName& qname, const QType qt, Flags flags, vector* res, const ComboAddress& who, const OptTag& routingTag = boost::none, vector>* signatures = nullptr, std::vector>* authorityRecs = nullptr, bool* variable = nullptr, vState* state = nullptr, bool* wasAuth = nullptr, DNSName* fromAuthZone = nullptr, ComboAddress* fromAuthIP = nullptr); - void replace(time_t, const DNSName& qname, const QType qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, const DNSName& authZone, boost::optional ednsmask = boost::none, const OptTag& routingTag = boost::none, vState state = vState::Indeterminate, boost::optional from = boost::none, bool refresh = false); + void replace(time_t, const DNSName& qname, const QType qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, const DNSName& authZone, boost::optional ednsmask = boost::none, const OptTag& routingTag = boost::none, vState state = vState::Indeterminate, boost::optional from = boost::none, bool refresh = false, uint32_t orig_ttl = 0); void doPrune(size_t keep); uint64_t doDump(int fd, size_t maxCacheEntries); diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 6119a325e991..bb19aa9f2152 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -2627,6 +2627,7 @@ struct CacheEntry vector records; vector> signatures; uint32_t signaturesTTL{std::numeric_limits::max()}; + uint32_t d_orig_ttl{0}; }; struct CacheKey { @@ -4410,6 +4411,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& rec.d_ttl = min(s_maxcachettl, rec.d_ttl); DNSRecord dr(rec); + tcache[{rec.d_name, rec.d_type, rec.d_place}].d_orig_ttl = dr.d_ttl; dr.d_ttl += d_now.tv_sec; dr.d_place = DNSResourceRecord::ANSWER; tcache[{rec.d_name, rec.d_type, rec.d_place}].records.push_back(dr); @@ -4424,9 +4426,17 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& if ((entry.second.records.size() + entry.second.signatures.size() + authorityRecs.size()) > 1) { // need to group the ttl to be the minimum of the RRSET (RFC 2181, 5.2) uint32_t lowestTTD = computeLowestTTD(entry.second.records, entry.second.signatures, entry.second.signaturesTTL, authorityRecs); + uint32_t compensation = 0; for (auto& record : entry.second.records) { + compensation = record.d_ttl - lowestTTD; record.d_ttl = lowestTTD; // boom } + entry.second.d_orig_ttl -= compensation; +#if 0 + if (compensation != 0) { + cerr << entry.first.name << '/' << entry.first.type << " compensated " << compensation << endl; + } +#endif } } @@ -4533,10 +4543,19 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& } if (vStateIsBogus(recordState)) { + uint32_t compensation = 0; /* this is a TTD by now, be careful */ for (auto& record : i->second.records) { - record.d_ttl = std::min(record.d_ttl, static_cast(s_maxbogusttl + d_now.tv_sec)); + auto newval = std::min(record.d_ttl, static_cast(s_maxbogusttl + d_now.tv_sec)); + compensation = record.d_ttl - newval; + record.d_ttl = newval; } + i->second.d_orig_ttl -= compensation; +#if 0 + if (compensation != 0) { + cerr << i->first.name << '/' << i->first.type << " compensated by bogus case " << compensation << endl; + } +#endif } /* We don't need to store NSEC3 records in the positive cache because: @@ -4582,7 +4601,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& if (isAA && i->first.type == QType::NS && s_save_parent_ns_set) { rememberParentSetIfNeeded(i->first.name, i->second.records, depth, prefix); } - g_recCache->replace(d_now.tv_sec, i->first.name, i->first.type, i->second.records, i->second.signatures, authorityRecs, i->first.type == QType::DS ? true : isAA, auth, i->first.place == DNSResourceRecord::ANSWER ? ednsmask : boost::none, d_routingTag, recordState, remoteIP, d_refresh); + g_recCache->replace(d_now.tv_sec, i->first.name, i->first.type, i->second.records, i->second.signatures, authorityRecs, i->first.type == QType::DS ? true : isAA, auth, i->first.place == DNSResourceRecord::ANSWER ? ednsmask : boost::none, d_routingTag, recordState, remoteIP, d_refresh, i->second.d_orig_ttl); // Delete potential negcache entry. When a record recovers with serve-stale the negcache entry can cause the wrong entry to // be served, as negcache entries are checked before record cache entries @@ -4606,7 +4625,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& content.push_back(std::move(nonExpandedRecord)); } - g_recCache->replace(d_now.tv_sec, realOwner, QType(i->first.type), content, i->second.signatures, /* no additional records in that case */ {}, i->first.type == QType::DS ? true : isAA, auth, boost::none, boost::none, recordState, remoteIP, d_refresh); + g_recCache->replace(d_now.tv_sec, realOwner, QType(i->first.type), content, i->second.signatures, /* no additional records in that case */ {}, i->first.type == QType::DS ? true : isAA, auth, boost::none, boost::none, recordState, remoteIP, d_refresh, i->second.d_orig_ttl); } } } diff --git a/pdns/recursordist/test-syncres_cc2.cc b/pdns/recursordist/test-syncres_cc2.cc index 8d4bb74b50d1..7c51872db1ec 100644 --- a/pdns/recursordist/test-syncres_cc2.cc +++ b/pdns/recursordist/test-syncres_cc2.cc @@ -1806,12 +1806,12 @@ BOOST_AUTO_TEST_CASE(test_cache_almost_expired_ttl) std::vector> sigs; addRecordToList(records, target, QType::A, "192.0.2.2", DNSResourceRecord::ANSWER, now + 29); - g_recCache->replace(now - 30, target, QType(QType::A), records, sigs, vector>(), true, g_rootdnsname, boost::optional()); + g_recCache->replace(now - 30, target, QType(QType::A), records, sigs, {}, true, g_rootdnsname, boost::optional(), boost::none, vState::Indeterminate, boost::none, false, 60); /* Same for the NS record */ std::vector ns; addRecordToList(ns, target, QType::NS, "pdns-public-ns1.powerdns.com", DNSResourceRecord::ANSWER, now + 29); - g_recCache->replace(now - 30, target, QType::NS, ns, sigs, vector>(), false, target, boost::optional()); + g_recCache->replace(now - 30, target, QType::NS, ns, sigs, {}, false, target, boost::optional(), boost::none, vState::Indeterminate, boost::none, false, 60); vector ret; int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); @@ -1823,7 +1823,7 @@ BOOST_AUTO_TEST_CASE(test_cache_almost_expired_ttl) BOOST_CHECK_EQUAL(ttl, 29U); // One task should be submitted - BOOST_CHECK_EQUAL(getTaskSize(), 1U); + BOOST_REQUIRE_EQUAL(getTaskSize(), 1U); auto task = taskQueuePop(); From 46dcd67bbf8151089f514179840777f51f8ea6a7 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 15 May 2023 15:48:46 +0200 Subject: [PATCH 185/909] Record time the ttd was computed instead of compensating --- pdns/recursordist/recursor_cache.cc | 16 ++-------------- pdns/recursordist/recursor_cache.hh | 2 +- pdns/recursordist/syncres.cc | 27 ++++++--------------------- pdns/recursordist/test-syncres_cc2.cc | 4 ++-- 4 files changed, 11 insertions(+), 38 deletions(-) diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index 4001df41a870..8b5b72f908c6 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -531,7 +531,7 @@ bool MemRecursorCache::CacheEntry::shouldReplace(time_t now, bool auth, vState s return true; } -void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, const DNSName& authZone, boost::optional ednsmask, const OptTag& routingTag, vState state, boost::optional from, bool refresh, uint32_t orig_ttl) +void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, const DNSName& authZone, boost::optional ednsmask, const OptTag& routingTag, vState state, boost::optional from, bool refresh, time_t ttl_time) { auto& shard = getMap(qname); auto lockedShard = shard.lock(); @@ -608,19 +608,7 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, prior to calling this function, so the TTL actually holds a TTD. */ ce.d_ttd = min(maxTTD, static_cast(i.d_ttl)); // XXX this does weird things if TTLs differ in the set - ce.d_orig_ttl = orig_ttl; -#if 0 - // d_orig_ttl should be between s_minimumTTL and s_maxcachettl, as d_ttd was sanitized wrt those - // bounds. But our reference point (d_now aka now) might be "too new" at this point, if we went - // outside to e.g. get DNSKEYS and that took a while. In that case, if the original TTL was - // smaller than the delay, d_orig_ttl will wrap and become very large. Detect that case and - // make sure d_orig_ttl is fixed. Likewise if there was a delay but that was smaller than the - // original TTL, d_orig_ttl can become smaller than s_minimumTTL. Detect those cases and use a - // small but legal d_orig_ttl in those cases. - if (ce.d_orig_ttl < SyncRes::s_minimumTTL || ce.d_orig_ttl > SyncRes::s_maxcachettl) { - ce.d_orig_ttl = SyncRes::s_minimumTTL; - } -#endif + ce.d_orig_ttl = ce.d_ttd - ttl_time; ce.d_records.push_back(i.getContent()); } diff --git a/pdns/recursordist/recursor_cache.hh b/pdns/recursordist/recursor_cache.hh index 638728a27003..379249b61002 100644 --- a/pdns/recursordist/recursor_cache.hh +++ b/pdns/recursordist/recursor_cache.hh @@ -69,7 +69,7 @@ public: time_t get(time_t, const DNSName& qname, const QType qt, Flags flags, vector* res, const ComboAddress& who, const OptTag& routingTag = boost::none, vector>* signatures = nullptr, std::vector>* authorityRecs = nullptr, bool* variable = nullptr, vState* state = nullptr, bool* wasAuth = nullptr, DNSName* fromAuthZone = nullptr, ComboAddress* fromAuthIP = nullptr); - void replace(time_t, const DNSName& qname, const QType qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, const DNSName& authZone, boost::optional ednsmask = boost::none, const OptTag& routingTag = boost::none, vState state = vState::Indeterminate, boost::optional from = boost::none, bool refresh = false, uint32_t orig_ttl = 0); + void replace(time_t, const DNSName& qname, const QType qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, const DNSName& authZone, boost::optional ednsmask = boost::none, const OptTag& routingTag = boost::none, vState state = vState::Indeterminate, boost::optional from = boost::none, bool refresh = false, time_t ttl_time = time(nullptr)); void doPrune(size_t keep); uint64_t doDump(int fd, size_t maxCacheEntries); diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index bb19aa9f2152..e797035f537b 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -2626,8 +2626,8 @@ struct CacheEntry { vector records; vector> signatures; + time_t d_ttl_time{0}; uint32_t signaturesTTL{std::numeric_limits::max()}; - uint32_t d_orig_ttl{0}; }; struct CacheKey { @@ -4269,7 +4269,7 @@ void SyncRes::rememberParentSetIfNeeded(const DNSName& domain, const vector ednsmask, vState& state, bool& needWildcardProof, bool& gatherWildcardProof, unsigned int& wildcardLabelsCount, bool rdQuery, const ComboAddress& remoteIP) +RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& prefix, LWResult& lwr, const DNSName& qname, const QType qtype, const DNSName& auth, bool wasForwarded, const boost::optional ednsmask, vState& state, bool& needWildcardProof, bool& gatherWildcardProof, unsigned int& wildcardLabelsCount, bool rdQuery, const ComboAddress& remoteIP) // NOLINT(readability-function-cognitive-complexity) { bool wasForwardRecurse = wasForwarded && rdQuery; tcache_t tcache; @@ -4411,7 +4411,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& rec.d_ttl = min(s_maxcachettl, rec.d_ttl); DNSRecord dr(rec); - tcache[{rec.d_name, rec.d_type, rec.d_place}].d_orig_ttl = dr.d_ttl; + tcache[{rec.d_name, rec.d_type, rec.d_place}].d_ttl_time = d_now.tv_sec; dr.d_ttl += d_now.tv_sec; dr.d_place = DNSResourceRecord::ANSWER; tcache[{rec.d_name, rec.d_type, rec.d_place}].records.push_back(dr); @@ -4426,17 +4426,9 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& if ((entry.second.records.size() + entry.second.signatures.size() + authorityRecs.size()) > 1) { // need to group the ttl to be the minimum of the RRSET (RFC 2181, 5.2) uint32_t lowestTTD = computeLowestTTD(entry.second.records, entry.second.signatures, entry.second.signaturesTTL, authorityRecs); - uint32_t compensation = 0; for (auto& record : entry.second.records) { - compensation = record.d_ttl - lowestTTD; record.d_ttl = lowestTTD; // boom } - entry.second.d_orig_ttl -= compensation; -#if 0 - if (compensation != 0) { - cerr << entry.first.name << '/' << entry.first.type << " compensated " << compensation << endl; - } -#endif } } @@ -4543,19 +4535,12 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& } if (vStateIsBogus(recordState)) { - uint32_t compensation = 0; /* this is a TTD by now, be careful */ for (auto& record : i->second.records) { auto newval = std::min(record.d_ttl, static_cast(s_maxbogusttl + d_now.tv_sec)); - compensation = record.d_ttl - newval; record.d_ttl = newval; } - i->second.d_orig_ttl -= compensation; -#if 0 - if (compensation != 0) { - cerr << i->first.name << '/' << i->first.type << " compensated by bogus case " << compensation << endl; - } -#endif + i->second.d_ttl_time = d_now.tv_sec; } /* We don't need to store NSEC3 records in the positive cache because: @@ -4601,7 +4586,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& if (isAA && i->first.type == QType::NS && s_save_parent_ns_set) { rememberParentSetIfNeeded(i->first.name, i->second.records, depth, prefix); } - g_recCache->replace(d_now.tv_sec, i->first.name, i->first.type, i->second.records, i->second.signatures, authorityRecs, i->first.type == QType::DS ? true : isAA, auth, i->first.place == DNSResourceRecord::ANSWER ? ednsmask : boost::none, d_routingTag, recordState, remoteIP, d_refresh, i->second.d_orig_ttl); + g_recCache->replace(d_now.tv_sec, i->first.name, i->first.type, i->second.records, i->second.signatures, authorityRecs, i->first.type == QType::DS ? true : isAA, auth, i->first.place == DNSResourceRecord::ANSWER ? ednsmask : boost::none, d_routingTag, recordState, remoteIP, d_refresh, i->second.d_ttl_time); // Delete potential negcache entry. When a record recovers with serve-stale the negcache entry can cause the wrong entry to // be served, as negcache entries are checked before record cache entries @@ -4625,7 +4610,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& content.push_back(std::move(nonExpandedRecord)); } - g_recCache->replace(d_now.tv_sec, realOwner, QType(i->first.type), content, i->second.signatures, /* no additional records in that case */ {}, i->first.type == QType::DS ? true : isAA, auth, boost::none, boost::none, recordState, remoteIP, d_refresh, i->second.d_orig_ttl); + g_recCache->replace(d_now.tv_sec, realOwner, QType(i->first.type), content, i->second.signatures, /* no additional records in that case */ {}, i->first.type == QType::DS ? true : isAA, auth, boost::none, boost::none, recordState, remoteIP, d_refresh, i->second.d_ttl_time); } } } diff --git a/pdns/recursordist/test-syncres_cc2.cc b/pdns/recursordist/test-syncres_cc2.cc index 7c51872db1ec..7f761238f03c 100644 --- a/pdns/recursordist/test-syncres_cc2.cc +++ b/pdns/recursordist/test-syncres_cc2.cc @@ -1806,12 +1806,12 @@ BOOST_AUTO_TEST_CASE(test_cache_almost_expired_ttl) std::vector> sigs; addRecordToList(records, target, QType::A, "192.0.2.2", DNSResourceRecord::ANSWER, now + 29); - g_recCache->replace(now - 30, target, QType(QType::A), records, sigs, {}, true, g_rootdnsname, boost::optional(), boost::none, vState::Indeterminate, boost::none, false, 60); + g_recCache->replace(now - 30, target, QType(QType::A), records, sigs, {}, true, g_rootdnsname, boost::optional(), boost::none, vState::Indeterminate, boost::none, false, now - 31); /* Same for the NS record */ std::vector ns; addRecordToList(ns, target, QType::NS, "pdns-public-ns1.powerdns.com", DNSResourceRecord::ANSWER, now + 29); - g_recCache->replace(now - 30, target, QType::NS, ns, sigs, {}, false, target, boost::optional(), boost::none, vState::Indeterminate, boost::none, false, 60); + g_recCache->replace(now - 30, target, QType::NS, ns, sigs, {}, false, target, boost::optional(), boost::none, vState::Indeterminate, boost::none, false, now - 31); vector ret; int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); From d53850d20a0723662f722ca96b7ff73adb2bf954 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 16 May 2023 13:14:37 +0200 Subject: [PATCH 186/909] delint updateCacheFromRecords --- .clang-tidy.full | 2 +- pdns/recursordist/syncres.cc | 2 +- pdns/recursordist/syncres.hh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index bf8c8c8eca18..f6ba38ee2e97 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -113,7 +113,7 @@ CheckOptions: - key: readability-function-size.LineThreshold value: '4294967295' - key: bugprone-easily-swappable-parameters.MinimumLength - value: '2' + value: '4' - key: portability-simd-intrinsics.Suggest value: 'false' - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index e797035f537b..d8f2bbf34f7b 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -4269,7 +4269,7 @@ void SyncRes::rememberParentSetIfNeeded(const DNSName& domain, const vector ednsmask, vState& state, bool& needWildcardProof, bool& gatherWildcardProof, unsigned int& wildcardLabelsCount, bool rdQuery, const ComboAddress& remoteIP) // NOLINT(readability-function-cognitive-complexity) +RCode::rcodes_ SyncRes::updateCacheFromRecords(unsigned int depth, const string& prefix, LWResult& lwr, const DNSName& qname, const QType qtype, const DNSName& auth, bool wasForwarded, const boost::optional& ednsmask, vState& state, bool& needWildcardProof, bool& gatherWildcardProof, unsigned int& wildcardLabelsCount, bool rdQuery, const ComboAddress& remoteIP) // NOLINT(readability-function-cognitive-complexity) { bool wasForwardRecurse = wasForwarded && rdQuery; tcache_t tcache; diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 445482b95265..8690578e4b73 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -644,7 +644,7 @@ private: This is unfortunately needed to deal with very crappy so-called DNS servers */ void fixupAnswer(const std::string& prefix, LWResult& lwr, const DNSName& qname, const QType qtype, const DNSName& auth, bool wasForwarded, bool rdQuery); void rememberParentSetIfNeeded(const DNSName& domain, const vector& newRecords, unsigned int depth, const string& prefix); - RCode::rcodes_ updateCacheFromRecords(unsigned int depth, const string& prefix, LWResult& lwr, const DNSName& qname, const QType qtype, const DNSName& auth, bool wasForwarded, const boost::optional, vState& state, bool& needWildcardProof, bool& gatherWildcardProof, unsigned int& wildcardLabelsCount, bool sendRDQuery, const ComboAddress& remoteIP); + RCode::rcodes_ updateCacheFromRecords(unsigned int depth, const string& prefix, LWResult& lwr, const DNSName& qname, const QType qtype, const DNSName& auth, bool wasForwarded, const boost::optional&, vState& state, bool& needWildcardProof, bool& gatherWildcardProof, unsigned int& wildcardLabelsCount, bool sendRDQuery, const ComboAddress& remoteIP); bool processRecords(const std::string& prefix, const DNSName& qname, const QType qtype, const DNSName& auth, LWResult& lwr, const bool sendRDQuery, vector& ret, set& nsset, DNSName& newtarget, DNSName& newauth, bool& realreferral, bool& negindic, vState& state, const bool needWildcardProof, const bool gatherwildcardProof, const unsigned int wildcardLabelsCount, int& rcode, bool& negIndicHasSignatures, unsigned int depth); bool doSpecialNamesResolve(const DNSName& qname, QType qtype, const QClass qclass, vector& ret); From 7d862cb38635506af5faaa2b0bae7ab6189e092e Mon Sep 17 00:00:00 2001 From: Alexis Romero Date: Fri, 12 May 2023 11:30:50 +0200 Subject: [PATCH 187/909] Run build-and-test-all.yml on a custom debian container --- .github/workflows/build-and-test-all.yml | 188 +++++++++--------- .../kerberos-client/krb5.conf | 4 +- regression-tests.dnsdist/dnsdisttests.py | 2 +- regression-tests.dnsdist/test_Advanced.py | 3 + regression-tests.nobackend/counters/command | 18 +- .../counters/expected_result.noipv6 | 71 +++++++ .../distributor/command | 8 +- tasks.py | 76 +++---- 8 files changed, 236 insertions(+), 134 deletions(-) create mode 100644 regression-tests.nobackend/counters/expected_result.noipv6 diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 94e8db2e0993..3e0c3fe1be4e 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -10,21 +10,28 @@ on: permissions: # least privileges, see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions contents: read +env: + CLANG_VERSION: '13' + # github.workspace variable points to the Runner home folder. Container home folder defined below. + REPO_HOME: '/__w/pdns/pdns' + jobs: build-auth: name: build auth if: ${{ !github.event.schedule || vars.SCHEDULED_JOBS_BUILD_AND_TEST_ALL }} runs-on: ubuntu-20.04 - env: - ASAN_OPTIONS: detect_leaks=0 - FUZZING_TARGETS: yes - SANITIZERS: asan+ubsan - UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" - UNIT_TESTS: yes + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + env: + ASAN_OPTIONS: detect_leaks=0 + FUZZING_TARGETS: yes + SANITIZERS: asan+ubsan + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" + UNIT_TESTS: yes + PDNS_TEST_NO_IPV6: yes outputs: clang-tidy-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 @@ -34,23 +41,20 @@ jobs: run: | echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" shell: bash + - run: mkdir -p ~/.ccache - name: let GitHub cache our ccache data uses: actions/cache@v3 with: path: ~/.ccache key: auth-ccache-${{ steps.get-stamp.outputs.stamp }} restore-keys: auth-ccache- - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - - run: inv install-clang - - run: inv install-clang-tidy-tools - - run: inv install-auth-build-deps - run: inv ci-autoconf - run: inv ci-auth-configure - run: inv ci-auth-make-bear # This runs under pdns/ - run: ln -s .clang-tidy.full .clang-tidy - name: Run clang-tidy working-directory: pdns - run: git diff -U0 HEAD^..HEAD | python3 ../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p2 -export-fixes clang-tidy-auth.yml + run: git diff -U0 HEAD^..HEAD | python3 ../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p2 -export-fixes clang-tidy-auth.yml - name: Print clang-tidy fixes YAML working-directory: pdns shell: bash @@ -86,18 +90,19 @@ jobs: strategy: matrix: sanitizers: [ubsan+asan, tsan] - env: - ASAN_OPTIONS: detect_leaks=0 - SANITIZERS: ${{ matrix.sanitizers }} - UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" - UNIT_TESTS: yes + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + env: + ASAN_OPTIONS: detect_leaks=0 + SANITIZERS: ${{ matrix.sanitizers }} + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" + UNIT_TESTS: yes defaults: run: working-directory: ./pdns/recursordist/ outputs: clang-tidy-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 @@ -107,23 +112,19 @@ jobs: run: | echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" shell: bash + - run: mkdir -p ~/.ccache - name: let GitHub cache our ccache data uses: actions/cache@v3 with: path: ~/.ccache key: recursor-${{ matrix.sanitizers }}-ccache-${{ steps.get-stamp.outputs.stamp }} restore-keys: recursor-${{ matrix.sanitizers }}-ccache- - - run: ../../build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - - run: inv apt-fresh - - run: inv install-clang - - run: inv install-clang-tidy-tools - - run: inv install-rec-build-deps - run: inv ci-autoconf - run: inv ci-rec-configure - run: inv ci-rec-make-bear - run: ln -s ../../.clang-tidy.full .clang-tidy - name: Run clang-tidy - run: git diff -U0 HEAD^..HEAD | python3 ../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-rec.yml + run: git diff -U0 HEAD^..HEAD | python3 ../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-rec.yml - name: Print clang-tidy fixes YAML shell: bash run: | @@ -160,18 +161,19 @@ jobs: exclude: - sanitizers: tsan features: least - env: - ASAN_OPTIONS: detect_leaks=0 - SANITIZERS: ${{ matrix.sanitizers }} - UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" - UNIT_TESTS: yes + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + env: + ASAN_OPTIONS: detect_leaks=0 + SANITIZERS: ${{ matrix.sanitizers }} + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" + UNIT_TESTS: yes defaults: run: working-directory: ./pdns/dnsdistdist/ outputs: clang-tidy-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 @@ -181,23 +183,19 @@ jobs: run: | echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" shell: bash + - run: mkdir -p ~/.ccache - name: let GitHub cache our ccache data uses: actions/cache@v3 with: path: ~/.ccache key: dnsdist-${{ matrix.features }}-${{ matrix.sanitizers }}-ccache-${{ steps.get-stamp.outputs.stamp }} restore-keys: dnsdist-${{ matrix.features }}-${{ matrix.sanitizers }}-ccache- - - run: ../../build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - - run: inv apt-fresh - - run: inv install-clang - - run: inv install-clang-tidy-tools - - run: inv install-dnsdist-build-deps - run: inv ci-autoconf - run: inv ci-dnsdist-configure ${{ matrix.features }} - run: inv ci-dnsdist-make-bear - run: ln -s ../../.clang-tidy.full .clang-tidy - name: Run clang-tidy - run: git diff -U0 HEAD^..HEAD | python3 ../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-12.py -clang-tidy-binary /usr/bin/clang-tidy-12 -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-dnsdist.yml + run: git diff -U0 HEAD^..HEAD | python3 ../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-dnsdist.yml - name: Print clang-tidy fixes YAML shell: bash run: | @@ -226,10 +224,13 @@ jobs: test-auth-api: needs: build-auth runs-on: ubuntu-20.04 - env: - UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" - ASAN_OPTIONS: detect_leaks=0 - TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ github.workspace }}/pdns/dnsdistdist/dnsdist-tsan.supp" + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + env: + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" + ASAN_OPTIONS: detect_leaks=0 + TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ env.REPO_HOME }}/pdns/dnsdistdist/dnsdist-tsan.supp" + AUTH_BACKEND_IP_ADDR: "172.17.0.1" strategy: matrix: include: @@ -256,7 +257,6 @@ jobs: options: >- --restart always steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 @@ -266,9 +266,7 @@ jobs: with: name: pdns-auth path: /opt/pdns-auth - # - name: Setup upterm session - # uses: lhotari/action-upterm@v1 - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade + - run: inv apt-fresh - run: inv install-clang-runtime - run: inv install-auth-test-deps -b ${{ matrix.backend }} - run: inv test-api auth -b ${{ matrix.backend }} @@ -276,10 +274,15 @@ jobs: test-auth-backend: needs: build-auth runs-on: ubuntu-20.04 - env: - UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" - ASAN_OPTIONS: detect_leaks=0 - LDAPHOST: ldap://ldapserver/ + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + env: + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" + ASAN_OPTIONS: detect_leaks=0 + LDAPHOST: ldap://ldapserver/ + ODBCINI: /github/home/.odbc.ini + AUTH_BACKEND_IP_ADDR: "172.17.0.1" + SKIP_IPV6_TESTS: yes strategy: matrix: include: @@ -366,7 +369,6 @@ jobs: options: >- --restart always steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 @@ -376,10 +378,7 @@ jobs: with: name: pdns-auth path: /opt/pdns-auth - # - name: Setup upterm session - # uses: lhotari/action-upterm@v1 # FIXME: install recursor for backends that have ALIAS - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - run: inv install-clang-runtime - run: inv install-auth-test-deps -b ${{ matrix.backend }} - run: inv test-auth-backend -b ${{ matrix.backend }} @@ -387,11 +386,12 @@ jobs: test-ixfrdist: needs: build-auth runs-on: ubuntu-20.04 - env: - UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" - ASAN_OPTIONS: detect_leaks=0 + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + env: + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" + ASAN_OPTIONS: detect_leaks=0 steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 @@ -401,7 +401,6 @@ jobs: with: name: pdns-auth path: /opt/pdns-auth - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - run: inv install-clang-runtime - run: inv install-auth-test-deps - run: inv test-ixfrdist @@ -412,12 +411,16 @@ jobs: strategy: matrix: sanitizers: [ubsan+asan, tsan] - env: - UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" - ASAN_OPTIONS: detect_leaks=0 - TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ github.workspace }}/pdns/recursordist/recursor-tsan.supp" + dist_name: [debian] + dist_release_name: [bullseye] + pdns_repo_version: ['45'] + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + env: + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" + ASAN_OPTIONS: detect_leaks=0 + TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ env.REPO_HOME }}/pdns/recursordist/recursor-tsan.supp" steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 @@ -427,8 +430,8 @@ jobs: with: name: pdns-recursor-${{ matrix.sanitizers }} path: /opt/pdns-recursor - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - - run: inv add-auth-repo # FIXME: do we need this for rec API testing? + - run: inv apt-fresh + - run: inv add-auth-repo ${{ matrix.dist_name }} ${{ matrix.dist_release_name }} ${{ matrix.pdns_repo_version }} - run: inv install-clang-runtime - run: inv install-rec-test-deps - run: inv test-api recursor @@ -439,13 +442,19 @@ jobs: strategy: matrix: sanitizers: [ubsan+asan, tsan] - env: - UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp' - ASAN_OPTIONS: detect_leaks=0 - TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ github.workspace }}/pdns/recursordist/recursor-tsan.supp" + dist_name: [debian] + dist_release_name: [bullseye] + pdns_repo_version: ['45'] + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + env: + UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp' + ASAN_OPTIONS: detect_leaks=0 + TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ env.REPO_HOME }}/pdns/recursordist/recursor-tsan.supp" + SKIP_IPV6_TESTS: yes steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - - uses: actions/checkout@v3 + # - uses: PowerDNS/pdns/set-ubuntu-mirror@meta + - uses: actions/checkout@v3.1.0 with: fetch-depth: 5 submodules: recursive @@ -454,8 +463,8 @@ jobs: with: name: pdns-recursor-${{ matrix.sanitizers }} path: /opt/pdns-recursor - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - - run: inv add-auth-repo + - run: inv apt-fresh + - run: inv add-auth-repo ${{ matrix.dist_name }} ${{ matrix.dist_release_name }} ${{ matrix.pdns_repo_version }} - run: inv install-clang-runtime - run: inv install-rec-test-deps - run: inv test-regression-recursor @@ -470,12 +479,13 @@ jobs: threads: [1, 2, 3, 4, 8] mthreads: [2048] shards: [1, 2, 1024] - env: - UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp' - ASAN_OPTIONS: detect_leaks=0 - TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ github.workspace }}/pdns/recursordist/recursor-tsan.supp" + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + env: + UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp' + ASAN_OPTIONS: detect_leaks=0 + TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ env.REPO_HOME }}/pdns/recursordist/recursor-tsan.supp" steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 @@ -485,7 +495,6 @@ jobs: with: name: pdns-recursor-${{ matrix.sanitizers }} path: /opt/pdns-recursor - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - run: inv install-clang-runtime - run: inv install-rec-bulk-deps - run: inv test-bulk-recursor ${{ matrix.threads }} ${{ matrix.mthreads }} ${{ matrix.shards }} @@ -496,15 +505,17 @@ jobs: strategy: matrix: sanitizers: [ubsan+asan, tsan] - env: - UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ github.workspace }}/build-scripts/UBSan.supp" - # Disabling (intercept_send=0) the custom send wrappers for ASAN and TSAN because they cause the tools to report a race that doesn't exist on actual implementations of send(), see https://github.com/google/sanitizers/issues/1498 - ASAN_OPTIONS: detect_leaks=0:intercept_send=0 - TSAN_OPTIONS: "halt_on_error=1:intercept_send=0:suppressions=${{ github.workspace }}/pdns/dnsdistdist/dnsdist-tsan.supp" - # IncludeDir tests are disabled because of a weird interaction between TSAN and these tests which ever only happens on GH actions - SKIP_INCLUDEDIR_TESTS: yes + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + env: + UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" + # Disabling (intercept_send=0) the custom send wrappers for ASAN and TSAN because they cause the tools to report a race that doesn't exist on actual implementations of send(), see https://github.com/google/sanitizers/issues/1498 + ASAN_OPTIONS: detect_leaks=0:intercept_send=0 + TSAN_OPTIONS: "halt_on_error=1:intercept_send=0:suppressions=${{ env.REPO_HOME }}/pdns/dnsdistdist/dnsdist-tsan.supp" + # IncludeDir tests are disabled because of a weird interaction between TSAN and these tests which ever only happens on GH actions + SKIP_INCLUDEDIR_TESTS: yes + SKIP_IPV6_TESTS: yes steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 @@ -514,7 +525,6 @@ jobs: with: name: dnsdist-full-${{ matrix.sanitizers }} path: /opt/dnsdist - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - run: inv install-clang-runtime - run: inv install-dnsdist-test-deps - run: inv test-dnsdist @@ -522,13 +532,13 @@ jobs: swagger-syntax-check: if: ${{ !github.event.schedule || vars.SCHEDULED_JOBS_BUILD_AND_TEST_ALL }} runs-on: ubuntu-20.04 + container: + image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master steps: - - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 submodules: recursive - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - run: inv install-swagger-tools - run: inv swagger-syntax-check diff --git a/regression-tests.auth-py/kerberos-client/krb5.conf b/regression-tests.auth-py/kerberos-client/krb5.conf index 1d65c48436ec..287fcc290be8 100755 --- a/regression-tests.auth-py/kerberos-client/krb5.conf +++ b/regression-tests.auth-py/kerberos-client/krb5.conf @@ -3,7 +3,7 @@ [realms] EXAMPLE.COM = { - kdc = 127.0.0.1:1188 - admin_server = 127.0.0.1:1749 + kdc = kerberos-server:1188 + admin_server = kerberos-server:1749 } diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index dfc6ead966b6..ce3e3ccf819d 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -764,7 +764,7 @@ def _decryptConsole(cls, command, nonce): return result.decode('UTF-8') @classmethod - def sendConsoleCommand(cls, command, timeout=1.0): + def sendConsoleCommand(cls, command, timeout=5.0): ourNonce = libnacl.utils.rand_nonce() theirNonce = None sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) diff --git a/regression-tests.dnsdist/test_Advanced.py b/regression-tests.dnsdist/test_Advanced.py index 1a110e483dad..5c3efbb5016d 100644 --- a/regression-tests.dnsdist/test_Advanced.py +++ b/regression-tests.dnsdist/test_Advanced.py @@ -394,6 +394,9 @@ def testAdvancedCheckSourceAddrOnAnyBind(self): self.assertEqual(receivedQuery, query) self.assertEqual(receivedResponse, response) + if 'SKIP_IPV6_TESTS' in os.environ: + return + # a bit more tricky, UDP-only IPv6 sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) sock.settimeout(1.0) diff --git a/regression-tests.nobackend/counters/command b/regression-tests.nobackend/counters/command index a88d4a46e46a..8647f5d9c35b 100755 --- a/regression-tests.nobackend/counters/command +++ b/regression-tests.nobackend/counters/command @@ -4,11 +4,17 @@ if [ "${PDNS_DEBUG}" = "YES" ]; then set -x fi +local_address="127.0.0.1,::1" + +if [ -n "${SKIP_IPV6_TESTS}" ]; then + local_address="127.0.0.1" +fi + port=5600 rm -f pdns*.pid -$PDNS --daemon=no --local-address=127.0.0.1,::1 \ +$PDNS --daemon=no --local-address=$local_address \ --local-port=$port --socket-dir=./ --no-shuffle --launch=bind --no-config \ --module-dir=../regression-tests/modules --bind-config=counters/named.conf & @@ -20,11 +26,13 @@ $SDIG 127.0.0.1 $port test.com SOA >&2 >/dev/null $SDIG 127.0.0.1 $port server1.test.com A tcp >&2 >/dev/null $SDIG 127.0.0.1 $port test.com SOA tcp >&2 >/dev/null -$SDIG ::1 $port server1.test.com A >&2 >/dev/null -$SDIG ::1 $port server1.com A tcp >&2 >/dev/null +if [ -z "${SKIP_IPV6_TESTS}" ]; then + $SDIG ::1 $port server1.test.com A >&2 >/dev/null + $SDIG ::1 $port server1.com A tcp >&2 >/dev/null -$SDIG ::1 $port test.com SOA >&2 >/dev/null -$SDIG ::1 $port test.com SOA tcp >&2 >/dev/null + $SDIG ::1 $port test.com SOA >&2 >/dev/null + $SDIG ::1 $port test.com SOA tcp >&2 >/dev/null +fi # NXDOMAIN $SDIG 127.0.0.1 $port nx.test.com A >&2 >/dev/null diff --git a/regression-tests.nobackend/counters/expected_result.noipv6 b/regression-tests.nobackend/counters/expected_result.noipv6 new file mode 100644 index 000000000000..650b2c96cdda --- /dev/null +++ b/regression-tests.nobackend/counters/expected_result.noipv6 @@ -0,0 +1,71 @@ + +corrupt-packets=0 +deferred-cache-inserts=0 +deferred-cache-lookup=0 +deferred-packetcache-inserts=0 +deferred-packetcache-lookup=0 +dnsupdate-answers=0 +dnsupdate-changes=0 +dnsupdate-queries=0 +dnsupdate-refused=0 +incoming-notifications=0 +key-cache-size=0 +meta-cache-size=1 +noerror-packets=1 +nxdomain-packets=1 +open-tcp-connections=0 +overload-drops=0 +packetcache-size=7 +qsize-q=0 +query-cache-size=4 +rd-queries=0 +recursing-answers=0 +recursing-questions=0 +recursion-unanswered=0 +ring-logmessages-capacity=10000 +ring-logmessages-size=0 +ring-noerror-queries-capacity=10000 +ring-noerror-queries-size=0 +ring-nxdomain-queries-capacity=10000 +ring-nxdomain-queries-size=0 +ring-queries-capacity=10000 +ring-queries-size=0 +ring-remotes-capacity=10000 +ring-remotes-corrupt-capacity=10000 +ring-remotes-corrupt-size=0 +ring-remotes-size=0 +ring-remotes-unauth-capacity=10000 +ring-remotes-unauth-size=0 +ring-servfail-queries-capacity=10000 +ring-servfail-queries-size=0 +ring-unauth-queries-capacity=10000 +ring-unauth-queries-size=0 +security-status=0 +servfail-packets=0 +signature-cache-size=0 +signatures=0 +tcp-answers-bytes=128 +tcp-answers=2 +tcp-cookie-queries=0 +tcp-queries=2 +tcp4-answers-bytes=128 +tcp4-answers=2 +tcp4-queries=2 +tcp6-answers-bytes=0 +tcp6-answers=0 +tcp6-queries=0 +timedout-packets=0 +udp-answers-bytes=321 +udp-answers=5 +udp-cookie-queries=0 +udp-do-queries=0 +udp-queries=5 +udp4-answers-bytes=321 +udp4-answers=5 +udp4-queries=5 +udp6-answers-bytes=0 +udp6-answers=0 +udp6-queries=0 +unauth-packets=1 +xfr-queue=0 +zone-cache-size=1 diff --git a/regression-tests.nobackend/distributor/command b/regression-tests.nobackend/distributor/command index c96f3770b68f..ec37c64da86e 100755 --- a/regression-tests.nobackend/distributor/command +++ b/regression-tests.nobackend/distributor/command @@ -5,11 +5,17 @@ if [ "${PDNS_DEBUG}" = "YES" ]; then set -x fi +local_address="127.0.0.1,::1" + +if [ -n "${SKIP_IPV6_TESTS}" ]; then + local_address="127.0.0.1" +fi + port=5600 rm -f pdns*.pid -$PDNS --daemon=no --local-address=127.0.0.1,::1 \ +$PDNS --daemon=no --local-address=$local_address \ --local-port=$port --socket-dir=./ --no-shuffle --launch=pipe --no-config \ --module-dir=../regression-tests/modules --pipe-command=$(pwd)/distributor/slow.pl \ --pipe-abi-version=5 \ diff --git a/tasks.py b/tasks.py index 33bdfc70a294..426a428f3b2e 100644 --- a/tasks.py +++ b/tasks.py @@ -5,6 +5,10 @@ import sys import time +auth_backend_ip_addr = os.getenv('AUTH_BACKEND_IP_ADDR', '127.0.0.1') + +clang_version = os.getenv('CLANG_VERSION', '13') + all_build_deps = [ 'ccache', 'libboost-all-dev', @@ -59,7 +63,7 @@ 'libcap2', 'libfstrm0', 'libluajit-5.1-2', - 'libsnmp35', + '"libsnmp[1-9]+"', 'libsodium23', 'libssl1.1', 'libsystemd0', @@ -91,7 +95,7 @@ 'gawk', 'krb5-user', 'ldnsutils', - 'libboost-serialization1.71.0', + '"libboost-serialization1.7[1-9]+"', 'libcdb1', 'libcurl4', 'libgeoip1', @@ -153,24 +157,24 @@ def apt_fresh(c): @task def install_clang(c): """ - install clang-12 and llvm-12 + install clang and llvm """ - c.sudo('apt-get -y --no-install-recommends install clang-12 llvm-12') + c.sudo(f'apt-get -y --no-install-recommends install clang-{clang_version} llvm-{clang_version}') @task def install_clang_tidy_tools(c): - c.sudo('apt-get -y --no-install-recommends install clang-tidy-12 clang-tools-12 bear python-yaml') + c.sudo(f'apt-get -y --no-install-recommends install clang-tidy-{clang_version} clang-tools-{clang_version} bear python3-yaml') @task def install_clang_runtime(c): # this gives us the symbolizer, for symbols in asan/ubsan traces - c.sudo('apt-get -y --no-install-recommends install clang-12') + c.sudo(f'apt-get -y --no-install-recommends install clang-{clang_version}') def install_libdecaf(c, product): c.run('git clone https://git.code.sf.net/p/ed448goldilocks/code /tmp/libdecaf') with c.cd('/tmp/libdecaf'): c.run('git checkout 41f349') - c.run('CC=clang-12 CXX=clang-12 ' + c.run(f'CC=clang-{clang_version} CXX=clang-{clang_version} ' 'cmake -B build ' '-DCMAKE_INSTALL_PREFIX=/usr/local ' '-DCMAKE_INSTALL_LIBDIR=lib ' @@ -221,7 +225,7 @@ def install_auth_test_deps(c, backend): # FIXME: rename this, we do way more tha extra=[] for b in backend: extra.extend(auth_backend_test_deps[b]) - c.sudo('apt-get -y install ' + ' '.join(extra+auth_test_deps)) + c.sudo('DEBIAN_FRONTEND=noninteractive apt-get -y install ' + ' '.join(extra+auth_test_deps)) c.run('chmod +x /opt/pdns-auth/bin/* /opt/pdns-auth/sbin/*') # c.run('''if [ ! -e $HOME/bin/jdnssec-verifyzone ]; then @@ -256,7 +260,7 @@ def install_rec_test_deps(c): # FIXME: rename this, we do way more than apt-get setup_authbind(c) c.run('sed "s/agentxperms 0700 0755 recursor/agentxperms 0777 0755/g" regression-tests.recursor-dnssec/snmpd.conf | sudo tee /etc/snmp/snmpd.conf') - c.sudo('systemctl restart snmpd') + c.sudo('/etc/init.d/snmpd restart') time.sleep(5) c.sudo('chmod 755 /var/agentx') @@ -273,7 +277,7 @@ def install_dnsdist_test_deps(c): # FIXME: rename this, we do way more than apt- libh2o-evloop0.13 \ liblmdb0 \ libnghttp2-14 \ - libre2-5 \ + "libre2-[1-9]+" \ libssl-dev \ libsystemd0 \ libsodium23 \ @@ -282,7 +286,7 @@ def install_dnsdist_test_deps(c): # FIXME: rename this, we do way more than apt- protobuf-compiler \ python3-venv snmpd prometheus') c.run('sed "s/agentxperms 0700 0755 dnsdist/agentxperms 0777 0755/g" regression-tests.dnsdist/snmpd.conf | sudo tee /etc/snmp/snmpd.conf') - c.sudo('systemctl restart snmpd') + c.sudo('/etc/init.d/snmpd restart') time.sleep(5) c.sudo('chmod 755 /var/agentx') @@ -361,8 +365,8 @@ def get_base_configure_cmd(): f'CFLAGS="{get_cflags()}"', f'CXXFLAGS="{get_cxxflags()}"', './configure', - "CC='clang-12'", - "CXX='clang++-12'", + f"CC='clang-{clang_version}'", + f"CXX='clang++-{clang_version}'", "--enable-option-checking=fatal", "--enable-systemd", "--with-libsodium", @@ -509,13 +513,13 @@ def ci_dnsdist_configure(c, features): sanitizers = ' '.join('--enable-'+x for x in os.getenv('SANITIZERS').split('+')) if os.getenv('SANITIZERS') != '' else '' cflags = '-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int' cxxflags = cflags + ' -Wp,-D_GLIBCXX_ASSERTIONS ' + additional_flags - res = c.run('''CFLAGS="%s" \ + res = c.run(f'''CFLAGS="%s" \ CXXFLAGS="%s" \ - AR=llvm-ar-12 \ - RANLIB=llvm-ranlib-12 \ + AR=llvm-ar-{clang_version} \ + RANLIB=llvm-ranlib-{clang_version} \ ./configure \ - CC='clang-12' \ - CXX='clang++-12' \ + CC='clang-{clang_version}' \ + CXX='clang++-{clang_version}' \ --enable-option-checking=fatal \ --enable-fortify-source=auto \ --enable-auto-var-init=pattern \ @@ -533,7 +537,7 @@ def ci_auth_make(c): def ci_auth_make_bear(c): # Needed for clang-tidy -line-filter vs project structure shenanigans with c.cd('pdns'): - c.run('bear --append make -j8 -k V=1 -C ..') + c.run('bear --append -- make -j8 -k V=1 -C ..') @task def ci_rec_make(c): @@ -542,7 +546,7 @@ def ci_rec_make(c): @task def ci_rec_make_bear(c): # Assumed to be running under ./pdns/recursordist/ - c.run('bear --append make -j8 -k V=1') + c.run('bear --append -- make -j8 -k V=1') @task def ci_dnsdist_make(c): @@ -551,7 +555,7 @@ def ci_dnsdist_make(c): @task def ci_dnsdist_make_bear(c): # Assumed to be running under ./pdns/dnsdistdist/ - c.run('bear --append make -j4 -k V=1') + c.run('bear --append -- make -j4 -k V=1') @task def ci_auth_install_remotebackend_test_deps(c): @@ -587,17 +591,13 @@ def ci_make_install(c): res = c.run('make install') # FIXME: this builds auth docs - again @task -def add_auth_repo(c): - dist = 'ubuntu' # FIXME take these from the caller? - release = 'focal' - version = '44' - +def add_auth_repo(c, dist_name, dist_release_name, pdns_repo_version): c.sudo('apt-get install -y curl gnupg2') - if version == 'master': + if pdns_repo_version == 'master': c.sudo('curl -s -o /etc/apt/trusted.gpg.d/pdns-repo.asc https://repo.powerdns.com/CBC8B383-pub.asc') else: c.sudo('curl -s -o /etc/apt/trusted.gpg.d/pdns-repo.asc https://repo.powerdns.com/FD380FBB-pub.asc') - c.run(f"echo 'deb [arch=amd64] http://repo.powerdns.com/{dist} {release}-auth-{version} main' | sudo tee /etc/apt/sources.list.d/pdns.list") + c.run(f"echo 'deb [arch=amd64] http://repo.powerdns.com/{dist_name} {dist_release_name}-auth-{pdns_repo_version} main' | sudo tee /etc/apt/sources.list.d/pdns.list") c.run("echo 'Package: pdns-*' | sudo tee /etc/apt/preferences.d/pdns") c.run("echo 'Pin: origin repo.powerdns.com' | sudo tee -a /etc/apt/preferences.d/pdns") c.run("echo 'Pin-Priority: 600' | sudo tee -a /etc/apt/preferences.d/pdns") @@ -610,7 +610,7 @@ def test_api(c, product, backend=''): c.run(f'PDNSRECURSOR=/opt/pdns-recursor/sbin/pdns_recursor ./runtests recursor {backend}') elif product == 'auth': with c.cd('regression-tests.api'): - c.run(f'PDNSSERVER=/opt/pdns-auth/sbin/pdns_server PDNSUTIL=/opt/pdns-auth/bin/pdnsutil SDIG=/opt/pdns-auth/bin/sdig MYSQL_HOST="127.0.0.1" PGHOST="127.0.0.1" PGPORT="5432" ./runtests authoritative {backend}') + c.run(f'PDNSSERVER=/opt/pdns-auth/sbin/pdns_server PDNSUTIL=/opt/pdns-auth/bin/pdnsutil SDIG=/opt/pdns-auth/bin/sdig MYSQL_HOST={auth_backend_ip_addr} PGHOST={auth_backend_ip_addr} PGPORT=5432 ./runtests authoritative {backend}') else: raise Failure('unknown product') @@ -687,11 +687,11 @@ def test_api(c, product, backend=''): godbc_mssql_credentials = {"username": "sa", "password": "SAsa12%%"} -godbc_config = ''' +godbc_config = f''' [pdns-mssql-docker] Driver=FreeTDS Trace=No -Server=127.0.0.1 +Server={auth_backend_ip_addr} Port=1433 Database=pdns TDS_Version=7.1 @@ -699,7 +699,7 @@ def test_api(c, product, backend=''): [pdns-mssql-docker-nodb] Driver=FreeTDS Trace=No -Server=127.0.0.1 +Server={auth_backend_ip_addr} Port=1433 TDS_Version=7.1 @@ -728,16 +728,17 @@ def setup_godbc_sqlite3(c): def setup_ldap_client(c): c.sudo('DEBIAN_FRONTEND=noninteractive apt-get install -y ldap-utils') - c.sudo('sh -c \'echo "127.0.0.1 ldapserver" | tee -a /etc/hosts\'') + c.sudo(f'sh -c \'echo "{auth_backend_ip_addr} ldapserver" | tee -a /etc/hosts\'') @task def test_auth_backend(c, backend): - pdns_auth_env_vars = 'PDNS=/opt/pdns-auth/sbin/pdns_server PDNS2=/opt/pdns-auth/sbin/pdns_server SDIG=/opt/pdns-auth/bin/sdig NOTIFY=/opt/pdns-auth/bin/pdns_notify NSEC3DIG=/opt/pdns-auth/bin/nsec3dig SAXFR=/opt/pdns-auth/bin/saxfr ZONE2SQL=/opt/pdns-auth/bin/zone2sql ZONE2LDAP=/opt/pdns-auth/bin/zone2ldap ZONE2JSON=/opt/pdns-auth/bin/zone2json PDNSUTIL=/opt/pdns-auth/bin/pdnsutil PDNSCONTROL=/opt/pdns-auth/bin/pdns_control PDNSSERVER=/opt/pdns-auth/sbin/pdns_server SDIG=/opt/pdns-auth/bin/sdig GMYSQLHOST=127.0.0.1 GMYSQL2HOST=127.0.0.1 MYSQL_HOST="127.0.0.1" PGHOST="127.0.0.1" PGPORT="5432"' + pdns_auth_env_vars = f'PDNS=/opt/pdns-auth/sbin/pdns_server PDNS2=/opt/pdns-auth/sbin/pdns_server SDIG=/opt/pdns-auth/bin/sdig NOTIFY=/opt/pdns-auth/bin/pdns_notify NSEC3DIG=/opt/pdns-auth/bin/nsec3dig SAXFR=/opt/pdns-auth/bin/saxfr ZONE2SQL=/opt/pdns-auth/bin/zone2sql ZONE2LDAP=/opt/pdns-auth/bin/zone2ldap ZONE2JSON=/opt/pdns-auth/bin/zone2json PDNSUTIL=/opt/pdns-auth/bin/pdnsutil PDNSCONTROL=/opt/pdns-auth/bin/pdns_control PDNSSERVER=/opt/pdns-auth/sbin/pdns_server SDIG=/opt/pdns-auth/bin/sdig GMYSQLHOST={auth_backend_ip_addr} GMYSQL2HOST={auth_backend_ip_addr} MYSQL_HOST={auth_backend_ip_addr} PGHOST={auth_backend_ip_addr} PGPORT=5432' if backend == 'remote': ci_auth_install_remotebackend_test_deps(c) if backend == 'authpy': + c.sudo(f'sh -c \'echo "{auth_backend_ip_addr} kerberos-server" | tee -a /etc/hosts\'') with c.cd('regression-tests.auth-py'): c.run(f'{pdns_auth_env_vars} WITHKERBEROS=YES ./runtests') return @@ -772,7 +773,10 @@ def test_auth_backend(c, backend): c.run(f'{pdns_auth_env_vars} ./start-test-stop 5300 {variant}') if backend == 'gsqlite3': + if os.getenv('SKIP_IPV6_TESTS'): + pdns_auth_env_vars += ' context=noipv6' with c.cd('regression-tests.nobackend'): + c.run(f'echo {pdns_auth_env_vars}') c.run(f'{pdns_auth_env_vars} ./runtests') c.run('/opt/pdns-auth/bin/pdnsutil test-algorithms') return @@ -793,7 +797,7 @@ def test_dnsdist(c): @task def test_regression_recursor(c): c.run('/opt/pdns-recursor/sbin/pdns_recursor --version') - c.run('PDNSRECURSOR=/opt/pdns-recursor/sbin/pdns_recursor RECCONTROL=/opt/pdns-recursor/bin/rec_control SKIP_IPV6_TESTS=y ./build-scripts/test-recursor') + c.run('PDNSRECURSOR=/opt/pdns-recursor/sbin/pdns_recursor RECCONTROL=/opt/pdns-recursor/bin/rec_control ./build-scripts/test-recursor') @task def test_bulk_recursor(c, threads, mthreads, shards): @@ -819,7 +823,7 @@ def install_coverity_tools(c, project): @task def coverity_clang_configure(c): - c.sudo('/usr/local/bin/cov-configure --template --comptype clangcc --compiler clang++-12') + c.sudo(f'/usr/local/bin/cov-configure --template --comptype clangcc --compiler clang++-{clang_version}') @task def coverity_make(c): From 5eb9bb252f7d83bf7a22d735b387a99182fcab05 Mon Sep 17 00:00:00 2001 From: Alexis Romero Date: Tue, 16 May 2023 18:59:06 +0200 Subject: [PATCH 188/909] set apt mirror for cifuzz base builder image --- .github/workflows/fuzz.yml | 5 +++++ Dockerfile-cifuzz | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 Dockerfile-cifuzz diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index c93ed0ef8769..2dbd3a34223f 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -8,6 +8,11 @@ jobs: Fuzzing: runs-on: ubuntu-20.04 steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 5 + submodules: recursive + - run: docker build -t gcr.io/oss-fuzz-base/base-builder:latest -f Dockerfile-cifuzz . - name: Build Fuzzers uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master with: diff --git a/Dockerfile-cifuzz b/Dockerfile-cifuzz new file mode 100644 index 000000000000..61036bbdcafc --- /dev/null +++ b/Dockerfile-cifuzz @@ -0,0 +1,5 @@ +FROM gcr.io/oss-fuzz-base/base-builder:latest + +RUN sed -i 's/[a-z]*\.ubuntu\.com/mirror\.leaseweb\.net/' /etc/apt/sources.list +RUN apt-get update + From 291075fac264b0cc35eb6c51777d4357e0dadfcc Mon Sep 17 00:00:00 2001 From: Jan-Piet Mens Date: Tue, 16 May 2023 20:07:10 +0200 Subject: [PATCH 189/909] Be more specific in describing config-dir I think this more clearly describes the option --- docs/settings.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/settings.rst b/docs/settings.rst index 782435ef5f9f..32c8dde935e8 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -300,7 +300,7 @@ It is strongly recommended to keep this setting enabled (`yes`). - Path -Location of configuration directory (``pdns.conf``). Usually +Location of configuration directory (the directory containing ``pdns.conf``). Usually ``/etc/powerdns``, but this depends on ``SYSCONFDIR`` during compile-time. From 6e974f900ad4e5a7c5957ad9773035a82a86b638 Mon Sep 17 00:00:00 2001 From: Alexis Romero Date: Wed, 17 May 2023 10:28:29 +0200 Subject: [PATCH 190/909] GH actions - misc-dailies: Set clang version for Ubuntu-20 --- .github/workflows/misc-dailies.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/misc-dailies.yml b/.github/workflows/misc-dailies.yml index a7d0db59b655..1b12ce6cf03f 100644 --- a/.github/workflows/misc-dailies.yml +++ b/.github/workflows/misc-dailies.yml @@ -7,6 +7,9 @@ on: permissions: # least privileges, see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions contents: read +env: + CLANG_VERSION: '12' + jobs: el7-devtoolset: if: ${{ vars.SCHEDULED_MISC_DAILIES }} From ebe2aeb802efc969607840b011637835dba52af8 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 17 May 2023 10:44:44 +0200 Subject: [PATCH 191/909] Full delint rec-main.cc --- .clang-tidy.full | 2 +- pdns/recursordist/rec-main.cc | 370 ++++++++++++++++++---------------- pdns/recursordist/rec-main.hh | 4 +- pdns/recursordist/syncres.hh | 2 +- 4 files changed, 197 insertions(+), 181 deletions(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index bf8c8c8eca18..f6ba38ee2e97 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -113,7 +113,7 @@ CheckOptions: - key: readability-function-size.LineThreshold value: '4294967295' - key: bugprone-easily-swappable-parameters.MinimumLength - value: '2' + value: '4' - key: portability-simd-intrinsics.Suggest value: 'false' - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 0e7e3fceb382..c9191137fd13 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -47,6 +47,7 @@ #include #include +#include #endif #ifdef HAVE_SYSTEMD @@ -135,8 +136,9 @@ static std::map> parseCPUMap(Logr::log_t log) stringtok(parts, value, " \t"); for (const auto& part : parts) { - if (part.find('=') == string::npos) + if (part.find('=') == string::npos) { continue; + } try { auto headers = splitField(part, '='); @@ -169,8 +171,8 @@ static void setCPUMap(const std::map>& cpusMap, unsi if (cpuMapping == cpusMap.cend()) { return; } - int rc = mapThreadToCPUList(tid, cpuMapping->second); - if (rc == 0) { + int ret = mapThreadToCPUList(tid, cpuMapping->second); + if (ret == 0) { if (!g_slogStructured) { g_log << Logger::Info << "CPU affinity for thread " << n << " has been set to CPU map:"; for (const auto cpu : cpuMapping->second) { @@ -188,26 +190,26 @@ static void setCPUMap(const std::map>& cpusMap, unsi for (const auto cpu : cpuMapping->second) { g_log << Logger::Info << " " << cpu; } - g_log << Logger::Info << ' ' << strerror(rc) << endl; + g_log << Logger::Info << ' ' << stringerror(ret) << endl; } else { - log->error(Logr::Warning, rc, "Error setting CPU affinity", "thread", Logging::Loggable(n), "cpumap", Logging::IterLoggable(cpuMapping->second.begin(), cpuMapping->second.end())); + log->error(Logr::Warning, ret, "Error setting CPU affinity", "thread", Logging::Loggable(n), "cpumap", Logging::IterLoggable(cpuMapping->second.begin(), cpuMapping->second.end())); } } } static void recursorThread(); -void RecThreadInfo::start(unsigned int id, const string& tname, const std::map>& cpusMap, Logr::log_t log) +void RecThreadInfo::start(unsigned int tid, const string& tname, const std::map>& cpusMap, Logr::log_t log) { name = tname; - thread = std::thread([id, tname] { - t_id = id; + thread = std::thread([tid, tname] { + t_id = tid; const string threadPrefix = "rec/"; setThreadName(threadPrefix + tname); recursorThread(); }); - setCPUMap(cpusMap, id, thread.native_handle(), log); + setCPUMap(cpusMap, tid, thread.native_handle(), log); } int RecThreadInfo::runThreads(Logr::log_t log) @@ -231,7 +233,7 @@ int RecThreadInfo::runThreads(Logr::log_t log) auto& info = RecThreadInfo::info(currentThreadId); info.setListener(); info.setWorker(); - info.setThreadId(currentThreadId++); + RecThreadInfo::setThreadId(currentThreadId++); recursorThread(); handlerInfo.thread.join(); @@ -247,16 +249,16 @@ int RecThreadInfo::runThreads(Logr::log_t log) // Setup RecThreadInfo objects unsigned int tmp = currentThreadId; if (RecThreadInfo::weDistributeQueries()) { - for (unsigned int n = 0; n < RecThreadInfo::numDistributors(); ++n) { + for (unsigned int thread = 0; thread < RecThreadInfo::numDistributors(); ++thread) { RecThreadInfo::info(tmp++).setListener(); } } - for (unsigned int n = 0; n < RecThreadInfo::numWorkers(); ++n) { + for (unsigned int thread = 0; thread < RecThreadInfo::numWorkers(); ++thread) { auto& info = RecThreadInfo::info(tmp++); info.setListener(!RecThreadInfo::weDistributeQueries()); info.setWorker(); } - for (unsigned int n = 0; n < RecThreadInfo::numTaskThreads(); ++n) { + for (unsigned int thread = 0; thread < RecThreadInfo::numTaskThreads(); ++thread) { auto& info = RecThreadInfo::info(tmp++); info.setTaskThread(); } @@ -265,7 +267,7 @@ int RecThreadInfo::runThreads(Logr::log_t log) if (RecThreadInfo::weDistributeQueries()) { SLOG(g_log << Logger::Warning << "Launching " << RecThreadInfo::numDistributors() << " distributor threads" << endl, log->info(Logr::Notice, "Launching distributor threads", "count", Logging::Loggable(RecThreadInfo::numDistributors()))); - for (unsigned int n = 0; n < RecThreadInfo::numDistributors(); ++n) { + for (unsigned int thread = 0; thread < RecThreadInfo::numDistributors(); ++thread) { auto& info = RecThreadInfo::info(currentThreadId); info.start(currentThreadId++, "distr", cpusMap, log); } @@ -273,12 +275,12 @@ int RecThreadInfo::runThreads(Logr::log_t log) SLOG(g_log << Logger::Warning << "Launching " << RecThreadInfo::numWorkers() << " worker threads" << endl, log->info(Logr::Notice, "Launching worker threads", "count", Logging::Loggable(RecThreadInfo::numWorkers()))); - for (unsigned int n = 0; n < RecThreadInfo::numWorkers(); ++n) { + for (unsigned int thread = 0; thread < RecThreadInfo::numWorkers(); ++thread) { auto& info = RecThreadInfo::info(currentThreadId); info.start(currentThreadId++, "worker", cpusMap, log); } - for (unsigned int n = 0; n < RecThreadInfo::numTaskThreads(); ++n) { + for (unsigned int thread = 0; thread < RecThreadInfo::numTaskThreads(); ++thread) { auto& info = RecThreadInfo::info(currentThreadId); info.start(currentThreadId++, "task", cpusMap, log); } @@ -288,10 +290,10 @@ int RecThreadInfo::runThreads(Logr::log_t log) info.setHandler(); info.start(0, "web+stat", cpusMap, log); - for (auto& ti : RecThreadInfo::infos()) { - ti.thread.join(); - if (ti.exitCode != 0) { - ret = ti.exitCode; + for (auto& tInfo : RecThreadInfo::infos()) { + tInfo.thread.join(); + if (tInfo.exitCode != 0) { + ret = tInfo.exitCode; } } } @@ -307,42 +309,45 @@ void RecThreadInfo::makeThreadPipes(Logr::log_t log) } /* thread 0 is the handler / SNMP, worker threads start at 1 */ - for (unsigned int n = 0; n < numRecursorThreads(); ++n) { - auto& threadInfo = info(n); + for (unsigned int thread = 0; thread < numRecursorThreads(); ++thread) { + auto& threadInfo = info(thread); - int fd[2]; - if (pipe(fd) < 0) + std::array fileDesc{}; + if (pipe(fileDesc.data()) < 0) { unixDie("Creating pipe for inter-thread communications"); + } - threadInfo.pipes.readToThread = fd[0]; - threadInfo.pipes.writeToThread = fd[1]; + threadInfo.pipes.readToThread = fileDesc[0]; + threadInfo.pipes.writeToThread = fileDesc[1]; // handler thread only gets first pipe, not the others - if (n == 0) { + if (thread == 0) { continue; } - if (pipe(fd) < 0) + if (pipe(fileDesc.data()) < 0) { unixDie("Creating pipe for inter-thread communications"); + } - threadInfo.pipes.readFromThread = fd[0]; - threadInfo.pipes.writeFromThread = fd[1]; + threadInfo.pipes.readFromThread = fileDesc[0]; + threadInfo.pipes.writeFromThread = fileDesc[1]; - if (pipe(fd) < 0) + if (pipe(fileDesc.data()) < 0) { unixDie("Creating pipe for inter-thread communications"); + } - threadInfo.pipes.readQueriesToThread = fd[0]; - threadInfo.pipes.writeQueriesToThread = fd[1]; + threadInfo.pipes.readQueriesToThread = fileDesc[0]; + threadInfo.pipes.writeQueriesToThread = fileDesc[1]; if (pipeBufferSize > 0) { if (!setPipeBufferSize(threadInfo.pipes.writeQueriesToThread, pipeBufferSize)) { int err = errno; - SLOG(g_log << Logger::Warning << "Error resizing the buffer of the distribution pipe for thread " << n << " to " << pipeBufferSize << ": " << strerror(err) << endl, - log->error(Logr::Warning, err, "Error resizing the buffer of the distribution pipe for thread", "thread", Logging::Loggable(n), "size", Logging::Loggable(pipeBufferSize))); + SLOG(g_log << Logger::Warning << "Error resizing the buffer of the distribution pipe for thread " << thread << " to " << pipeBufferSize << ": " << stringerror(err) << endl, + log->error(Logr::Warning, err, "Error resizing the buffer of the distribution pipe for thread", "thread", Logging::Loggable(thread), "size", Logging::Loggable(pipeBufferSize))); auto existingSize = getPipeBufferSize(threadInfo.pipes.writeQueriesToThread); if (existingSize > 0) { - SLOG(g_log << Logger::Warning << "The current size of the distribution pipe's buffer for thread " << n << " is " << existingSize << endl, - log->info(Logr::Warning, "The current size of the distribution pipe's buffer for thread", "thread", Logging::Loggable(n), "size", Logging::Loggable(existingSize))); + SLOG(g_log << Logger::Warning << "The current size of the distribution pipe's buffer for thread " << thread << " is " << existingSize << endl, + log->info(Logr::Warning, "The current size of the distribution pipe's buffer for thread", "thread", Logging::Loggable(thread), "size", Logging::Loggable(existingSize))); } } } @@ -361,10 +366,10 @@ ArgvMap& arg() static FDMultiplexer* getMultiplexer(Logr::log_t log) { - FDMultiplexer* ret; - for (const auto& i : FDMultiplexer::getMultiplexerMap()) { + FDMultiplexer* ret = nullptr; + for (const auto& mplexer : FDMultiplexer::getMultiplexerMap()) { try { - ret = i.second(FDMultiplexer::s_maxevents); + ret = mplexer.second(FDMultiplexer::s_maxevents); return ret; } catch (FDMultiplexerException& fe) { @@ -459,7 +464,7 @@ bool checkOutgoingProtobufExport(LocalStateHolder& luaconfsLocal return true; } -void protobufLogQuery(LocalStateHolder& luaconfsLocal, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const ComboAddress& mappedRemote, const Netmask& ednssubnet, bool tcp, uint16_t id, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::unordered_set& policyTags, const std::string& requestorId, const std::string& deviceId, const std::string& deviceName, const std::map& meta) +void protobufLogQuery(LocalStateHolder& luaconfsLocal, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const ComboAddress& mappedSource, const Netmask& ednssubnet, bool tcp, uint16_t queryID, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::unordered_set& policyTags, const std::string& requestorId, const std::string& deviceId, const std::string& deviceName, const std::map& meta) { auto log = g_slog->withName("pblq"); @@ -474,30 +479,30 @@ void protobufLogQuery(LocalStateHolder& luaconfsLocal, const boo requestor.setPort(remote.getPort()); } else { - Netmask requestorNM(mappedRemote, mappedRemote.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); + Netmask requestorNM(mappedSource, mappedSource.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); requestor = requestorNM.getMaskedNetwork(); - requestor.setPort(mappedRemote.getPort()); + requestor.setPort(mappedSource.getPort()); } - pdns::ProtoZero::RecMessage m{128, std::string::size_type(policyTags.empty() ? 0 : 64)}; // It's a guess - m.setType(pdns::ProtoZero::Message::MessageType::DNSQueryType); - m.setRequest(uniqueId, requestor, local, qname, qtype, qclass, id, tcp ? pdns::ProtoZero::Message::TransportProtocol::TCP : pdns::ProtoZero::Message::TransportProtocol::UDP, len); - m.setServerIdentity(SyncRes::s_serverID); - m.setEDNSSubnet(ednssubnet, ednssubnet.isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); - m.setRequestorId(requestorId); - m.setDeviceId(deviceId); - m.setDeviceName(deviceName); + pdns::ProtoZero::RecMessage msg{128, std::string::size_type(policyTags.empty() ? 0 : 64)}; // It's a guess + msg.setType(pdns::ProtoZero::Message::MessageType::DNSQueryType); + msg.setRequest(uniqueId, requestor, local, qname, qtype, qclass, queryID, tcp ? pdns::ProtoZero::Message::TransportProtocol::TCP : pdns::ProtoZero::Message::TransportProtocol::UDP, len); + msg.setServerIdentity(SyncRes::s_serverID); + msg.setEDNSSubnet(ednssubnet, ednssubnet.isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); + msg.setRequestorId(requestorId); + msg.setDeviceId(deviceId); + msg.setDeviceName(deviceName); if (!policyTags.empty()) { - m.addPolicyTags(policyTags); + msg.addPolicyTags(policyTags); } for (const auto& mit : meta) { - m.setMeta(mit.first, mit.second.stringVal, mit.second.intVal); + msg.setMeta(mit.first, mit.second.stringVal, mit.second.intVal); } - std::string msg(m.finishAndMoveBuf()); + std::string strMsg(msg.finishAndMoveBuf()); for (auto& server : *t_protobufServers.servers) { - remoteLoggerQueueData(*server, msg); + remoteLoggerQueueData(*server, strMsg); } } @@ -513,8 +518,8 @@ void protobufLogResponse(pdns::ProtoZero::RecMessage& message) } } -void protobufLogResponse(const struct dnsheader* dh, LocalStateHolder& luaconfsLocal, - const RecursorPacketCache::OptPBData& pbData, const struct timeval& tv, +void protobufLogResponse(const struct dnsheader* header, LocalStateHolder& luaconfsLocal, + const RecursorPacketCache::OptPBData& pbData, const struct timeval& tval, bool tcp, const ComboAddress& source, const ComboAddress& destination, const ComboAddress& mappedSource, const EDNSSubnetOpts& ednssubnet, @@ -531,8 +536,8 @@ void protobufLogResponse(const struct dnsheader* dh, LocalStateHolderid); + pbMessage.setId(header->id); pbMessage.setTime(); pbMessage.setEDNSSubnet(ednssubnet.source, ednssubnet.source.isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); @@ -562,15 +567,15 @@ void protobufLogResponse(const struct dnsheader* dh, LocalStateHolder>> startFra options["outputQueueSize"] = config.outputQueueSize; options["queueNotifyThreshold"] = config.queueNotifyThreshold; options["reopenInterval"] = config.reopenInterval; - FrameStreamLogger* fsl = nullptr; + unique_ptr fsl = nullptr; try { ComboAddress address(server); - fsl = new FrameStreamLogger(address.sin4.sin_family, address.toStringWithPort(), true, options); + fsl = make_unique(address.sin4.sin_family, address.toStringWithPort(), true, options); } catch (const PDNSException& e) { - fsl = new FrameStreamLogger(AF_UNIX, server, true, options); + fsl = make_unique(AF_UNIX, server, true, options); } fsl->setLogQueries(config.logQueries); fsl->setLogResponses(config.logResponses); fsl->setLogNODs(config.logNODs); fsl->setLogUDRs(config.logUDRs); - result->emplace_back(fsl); + result->emplace_back(std::move(fsl)); } catch (const std::exception& e) { SLOG(g_log << Logger::Error << "Error while starting dnstap framestream logger to '" << server << ": " << e.what() << endl, @@ -661,18 +666,21 @@ bool checkFrameStreamExport(LocalStateHolder& luaconfsLocal, con static void makeControlChannelSocket(int processNum = -1) { string sockname = ::arg()["socket-dir"] + "/" + g_programname; - if (processNum >= 0) + if (processNum >= 0) { sockname += "." + std::to_string(processNum); + } sockname += ".controlsocket"; g_rcc.listen(sockname); - int sockowner = -1; - int sockgroup = -1; + uid_t sockowner = -1; + gid_t sockgroup = -1; - if (!::arg().isEmpty("socket-group")) + if (!::arg().isEmpty("socket-group")) { sockgroup = ::arg().asGid("socket-group"); - if (!::arg().isEmpty("socket-owner")) + } + if (!::arg().isEmpty("socket-owner")) { sockowner = ::arg().asUid("socket-owner"); + } if (sockgroup > -1 || sockowner > -1) { if (chown(sockname.c_str(), sockowner, sockgroup) < 0) { @@ -691,11 +699,13 @@ static void makeControlChannelSocket(int processNum = -1) static void writePid(Logr::log_t log) { - if (!::arg().mustDo("write-pid")) + if (!::arg().mustDo("write-pid")) { return; - ofstream of(g_pidfname.c_str(), std::ios_base::app); - if (of) - of << Utility::getpid() << endl; + } + ofstream ostr(g_pidfname.c_str(), std::ios_base::app); + if (ostr) { + ostr << Utility::getpid() << endl; + } else { int err = errno; SLOG(g_log << Logger::Error << "Writing pid for " << Utility::getpid() << " to " << g_pidfname << " failed: " << stringerror(err) << endl, @@ -746,8 +756,8 @@ static void setupNODThread(Logr::log_t log) log->info(Logr::Error, "Could not initialize domain tracking")); _exit(1); } - std::thread t(nod::NODDB::startHousekeepingThread, t_nodDBp, std::this_thread::get_id()); - t.detach(); + std::thread thread(nod::NODDB::startHousekeepingThread, t_nodDBp, std::this_thread::get_id()); + thread.detach(); } if (g_udrEnabled) { uint32_t num_cells = ::arg().asNum("unique-response-db-size"); @@ -765,8 +775,8 @@ static void setupNODThread(Logr::log_t log) log->info(Logr::Error, "Could not initialize unique response tracking")); _exit(1); } - std::thread t(nod::UniqueResponseDB::startHousekeepingThread, t_udrDBp, std::this_thread::get_id()); - t.detach(); + std::thread thread(nod::UniqueResponseDB::startHousekeepingThread, t_udrDBp, std::this_thread::get_id()); + thread.detach(); } } @@ -774,8 +784,8 @@ static void parseNODIgnorelist(const std::string& wlist) { vector parts; stringtok(parts, wlist, ",; "); - for (const auto& a : parts) { - g_nodDomainWL.add(DNSName(a)); + for (const auto& part : parts) { + g_nodDomainWL.add(DNSName(part)); } } @@ -798,36 +808,37 @@ static void setupNODGlobal() static void daemonize(Logr::log_t log) { - if (fork()) - exit(0); // bye bye + if (fork() < 0) { + exit(0); // NOLINT(concurrency-mt-unsafe + } setsid(); - int i = open("/dev/null", O_RDWR); /* open stdin */ - if (i < 0) { + int devNull = open("/dev/null", O_RDWR); /* open stdin */ + if (devNull < 0) { int err = errno; SLOG(g_log << Logger::Critical << "Unable to open /dev/null: " << stringerror(err) << endl, log->error(Logr::Critical, err, "Unable to open /dev/null")); } else { - dup2(i, 0); /* stdin */ - dup2(i, 1); /* stderr */ - dup2(i, 2); /* stderr */ - close(i); + dup2(devNull, 0); /* stdin */ + dup2(devNull, 1); /* stderr */ + dup2(devNull, 2); /* stderr */ + close(devNull); } } -static void termIntHandler(int) +static void termIntHandler([[maybe_unused]] int arg) { doExit(); } -static void usr1Handler(int) +static void usr1Handler([[maybe_unused]] int arg) { statsWanted = true; } -static void usr2Handler(int) +static void usr2Handler([[maybe_unused]] int arg) { g_quiet = !g_quiet; SyncRes::setDefaultLogMode(g_quiet ? SyncRes::LogNone : SyncRes::Log); @@ -862,7 +873,7 @@ static void checkOrFixFDS(Logr::log_t log) log->info(Logr::Warning, "Raised soft limit on number of filedescriptors to match max-mthreads and threads settings", "limit", Logging::Loggable(wantFDs))); } else { - int newval = (hardlimit - 25 - TCPOutConnectionManager::s_maxIdlePerThread) / RecThreadInfo::numWorkers(); + auto newval = (hardlimit - 25 - TCPOutConnectionManager::s_maxIdlePerThread) / RecThreadInfo::numWorkers(); SLOG(g_log << Logger::Warning << "Insufficient number of filedescriptors available for max-mthreads*threads setting! (" << hardlimit << " < " << wantFDs << "), reducing max-mthreads to " << newval << endl, log->info(Logr::Warning, "Insufficient number of filedescriptors available for max-mthreads*threads setting! Reducing max-mthreads", "hardlimit", Logging::Loggable(hardlimit), "want", Logging::Loggable(wantFDs), "max-mthreads", Logging::Loggable(newval))); g_maxMThreads = newval; @@ -874,22 +885,24 @@ static void checkOrFixFDS(Logr::log_t log) // static std::string s_timestampFormat = "%m-%dT%H:%M:%S"; static std::string s_timestampFormat = "%s"; -static const char* toTimestampStringMilli(const struct timeval& tv, char* buf, size_t sz) +static const char* toTimestampStringMilli(const struct timeval& tval, std::array& buf) { size_t len = 0; if (s_timestampFormat != "%s") { // strftime is not thread safe, it can access locale information - static std::mutex m; - auto lock = std::lock_guard(m); - struct tm tm; - len = strftime(buf, sz, s_timestampFormat.c_str(), localtime_r(&tv.tv_sec, &tm)); + static std::mutex mutex; + auto lock = std::lock_guard(mutex); + struct tm theTime // clang-format insists on formatting it like this + { + }; + len = strftime(buf.data(), buf.size(), s_timestampFormat.c_str(), localtime_r(&tval.tv_sec, &theTime)); } if (len == 0) { - len = snprintf(buf, sz, "%lld", static_cast(tv.tv_sec)); + len = snprintf(buf.data(), buf.size(), "%lld", static_cast(tval.tv_sec)); } - snprintf(buf + len, sz - len, ".%03ld", static_cast(tv.tv_usec) / 1000); - return buf; + snprintf(&buf.at(len), buf.size() - len, ".%03ld", static_cast(tval.tv_usec) / 1000); + return buf.data(); } #ifdef HAVE_SYSTEMD @@ -916,8 +929,8 @@ static void loggerSDBackend(const Logging::Entry& entry) if (entry.name) { appendKeyAndVal("SUBSYSTEM", entry.name.get()); } - char timebuf[64]; - appendKeyAndVal("TIMESTAMP", toTimestampStringMilli(entry.d_timestamp, timebuf, sizeof(timebuf))); + std::array timebuf{}; + appendKeyAndVal("TIMESTAMP", toTimestampStringMilli(entry.d_timestamp, timebuf)); for (auto const& v : entry.values) { appendKeyAndVal(toUpper(v.first), v.second); } @@ -940,8 +953,8 @@ static void loggerBackend(const Logging::Entry& entry) static thread_local std::stringstream buf; // First map SL priority to syslog's Urgency - Logger::Urgency u = entry.d_priority ? Logger::Urgency(entry.d_priority) : Logger::Info; - if (u > s_logUrgency) { + Logger::Urgency urg = entry.d_priority != 0 ? Logger::Urgency(entry.d_priority) : Logger::Info; + if (urg > s_logUrgency) { // We do not log anything if the Urgency of the message is lower than the requested loglevel. // Not that lower Urgency means higher number. return; @@ -956,20 +969,20 @@ static void loggerBackend(const Logging::Entry& entry) buf << " subsystem=" << std::quoted(entry.name.get()); } buf << " level=" << std::quoted(std::to_string(entry.level)); - if (entry.d_priority) { + if (entry.d_priority != 0) { buf << " prio=" << std::quoted(Logr::Logger::toString(entry.d_priority)); } // Thread id filled in by backend, since the SL code does not know about RecursorThreads // We use the Recursor thread, other threads get id 0. May need to revisit. buf << " tid=" << std::quoted(std::to_string(RecThreadInfo::id())); - char timebuf[64]; - buf << " ts=" << std::quoted(toTimestampStringMilli(entry.d_timestamp, timebuf, sizeof(timebuf))); - for (auto const& v : entry.values) { + std::array timebuf{}; + buf << " ts=" << std::quoted(toTimestampStringMilli(entry.d_timestamp, timebuf)); + for (auto const& value : entry.values) { buf << " "; - buf << v.first << "=" << std::quoted(v.second); + buf << value.first << "=" << std::quoted(value.second); } - g_log << u << buf.str() << endl; + g_log << urg << buf.str() << endl; } static int ratePercentage(uint64_t nom, uint64_t denom) @@ -977,10 +990,10 @@ static int ratePercentage(uint64_t nom, uint64_t denom) if (denom == 0) { return 0; } - return round(100.0 * nom / denom); + return static_cast(round(100.0 * static_cast(nom) / static_cast(denom))); } -static void doStats(void) +static void doStats() { static time_t lastOutputTime; static uint64_t lastQueryCount; @@ -990,8 +1003,8 @@ static void doStats(void) uint64_t cacheSize = g_recCache->size(); auto rc_stats = g_recCache->stats(); auto pc_stats = g_packetCache ? g_packetCache->stats() : std::pair{0, 0}; - double rrc = rc_stats.second == 0 ? 0.0 : (100.0 * rc_stats.first / rc_stats.second); - double rpc = pc_stats.second == 0 ? 0.0 : (100.0 * pc_stats.first / pc_stats.second); + double rrc = ratePercentage(rc_stats.first, rc_stats.second); + double rpc = ratePercentage(pc_stats.first, pc_stats.second); uint64_t negCacheSize = g_negCache->size(); auto taskPushes = getTaskPushes(); auto taskExpired = getTaskExpired(); @@ -1031,8 +1044,8 @@ static void doStats(void) g_log << Logger::Notice << "stats: tasks pushed/expired/queuesize: " << taskPushes << '/' << taskExpired << '/' << taskSize << endl; } else { - const string m = "Periodic statistics report"; - log->info(Logr::Info, m, + const string report = "Periodic statistics report"; + log->info(Logr::Info, report, "questions", Logging::Loggable(qcounter), "cache-entries", Logging::Loggable(cacheSize), "negcache-entries", Logging::Loggable(negCacheSize), @@ -1043,7 +1056,7 @@ static void doStats(void) "packetcache-contended", Logging::Loggable(pc_stats.first), "packetcache-acquired", Logging::Loggable(pc_stats.second), "packetcache-contended-perc", Logging::Loggable(rpc)); - log->info(Logr::Info, m, + log->info(Logr::Info, report, "throttle-entries", Logging::Loggable(SyncRes::getThrottledServersSize()), "nsspeed-entries", Logging::Loggable(SyncRes::getNSSpeedsSize()), "failed-host-entries", Logging::Loggable(SyncRes::getFailedServersSize()), @@ -1051,14 +1064,14 @@ static void doStats(void) "non-resolving-nameserver-entries", Logging::Loggable(SyncRes::getNonResolvingNSSize()), "saved-parent-ns-sets-entries", Logging::Loggable(SyncRes::getSaveParentsNSSetsSize()), "outqueries-per-query", Logging::Loggable(ratePercentage(outqueries, syncresqueries))); - log->info(Logr::Info, m, + log->info(Logr::Info, report, "throttled-queries-perc", Logging::Loggable(ratePercentage(throttledqueries, outqueries + throttledqueries)), "tcp-outqueries", Logging::Loggable(tcpoutqueries), "dot-outqueries", Logging::Loggable(dotoutqueries), "idle-tcpout-connections", Logging::Loggable(getCurrentIdleTCPConnections()), "concurrent-queries", Logging::Loggable(broadcastAccFunction(pleaseGetConcurrentQueries)), "outgoing-timeouts", Logging::Loggable(outgoingtimeouts)); - log->info(Logr::Info, m, + log->info(Logr::Info, report, "packetcache-entries", Logging::Loggable(pcSize), "packetcache-hitratio-perc", Logging::Loggable(ratePercentage(pcHits, qcounter)), "taskqueue-pushed", Logging::Loggable(taskPushes), @@ -1073,8 +1086,8 @@ static void doStats(void) ++idx; } } - time_t now = time(0); - if (lastOutputTime && lastQueryCount && now != lastOutputTime) { + time_t now = time(nullptr); + if (lastOutputTime != 0 && lastQueryCount != 0 && now != lastOutputTime) { SLOG(g_log << Logger::Notice << "stats: " << (qcounter - lastQueryCount) / (now - lastOutputTime) << " qps (average over " << (now - lastOutputTime) << " seconds)" << endl, log->info(Logr::Info, "Periodic QPS report", "qps", Logging::Loggable((qcounter - lastQueryCount) / (now - lastOutputTime)), "averagedOver", Logging::Loggable(now - lastOutputTime))); @@ -1101,14 +1114,15 @@ static std::shared_ptr parseACL(const std::string& aclFile, const throw runtime_error("Could not open '" + ::arg()[aclFile] + "': " + stringerror()); } - string::size_type pos; while (getline(ifs, line)) { - pos = line.find('#'); - if (pos != string::npos) + auto pos = line.find('#'); + if (pos != string::npos) { line.resize(pos); + } boost::trim(line); - if (line.empty()) + if (line.empty()) { continue; + } result->addMask(line); } @@ -1120,14 +1134,15 @@ static std::shared_ptr parseACL(const std::string& aclFile, const vector ips; stringtok(ips, ::arg()[aclSetting], ", "); - for (const auto& i : ips) { - result->addMask(i); + for (const auto& address : ips) { + result->addMask(address); } if (!g_slogStructured) { g_log << Logger::Info << aclSetting << ": "; - for (vector::const_iterator i = ips.begin(); i != ips.end(); ++i) { - if (i != ips.begin()) + for (auto i = ips.begin(); i != ips.end(); ++i) { + if (i != ips.begin()) { g_log << Logger::Info << ", "; + } g_log << Logger::Info << *i; } g_log << Logger::Info << endl; @@ -1140,21 +1155,21 @@ static std::shared_ptr parseACL(const std::string& aclFile, const return result; } -static void* pleaseSupplantAllowFrom(std::shared_ptr ng) +static void* pleaseSupplantAllowFrom(std::shared_ptr nmgroup) { - t_allowFrom = ng; + t_allowFrom = std::move(nmgroup); return nullptr; } -static void* pleaseSupplantAllowNotifyFrom(std::shared_ptr ng) +static void* pleaseSupplantAllowNotifyFrom(std::shared_ptr nmgroup) { - t_allowNotifyFrom = ng; + t_allowNotifyFrom = std::move(nmgroup); return nullptr; } -void* pleaseSupplantAllowNotifyFor(std::shared_ptr ns) +void* pleaseSupplantAllowNotifyFor(std::shared_ptr allowNotifyFor) { - t_allowNotifyFor = ns; + t_allowNotifyFor = std::move(allowNotifyFor); return nullptr; } @@ -1282,33 +1297,33 @@ void* voider(const std::function& func) return func(); } -static vector& operator+=(vector& a, const vector& b) +static vector& operator+=(vector& lhs, const vector& rhs) { - a.insert(a.end(), b.begin(), b.end()); - return a; + lhs.insert(lhs.end(), rhs.begin(), rhs.end()); + return lhs; } -static vector>& operator+=(vector>& a, const vector>& b) +static vector>& operator+=(vector>& lhs, const vector>& rhs) { - a.insert(a.end(), b.begin(), b.end()); - return a; + lhs.insert(lhs.end(), rhs.begin(), rhs.end()); + return lhs; } -static ProxyMappingStats_t& operator+=(ProxyMappingStats_t& a, const ProxyMappingStats_t& b) +static ProxyMappingStats_t& operator+=(ProxyMappingStats_t& lhs, const ProxyMappingStats_t& rhs) { - for (const auto& [key, entry] : b) { - a[key].netmaskMatches += entry.netmaskMatches; - a[key].suffixMatches += entry.suffixMatches; + for (const auto& [key, entry] : rhs) { + lhs[key].netmaskMatches += entry.netmaskMatches; + lhs[key].suffixMatches += entry.suffixMatches; } - return a; + return lhs; } -static RemoteLoggerStats_t& operator+=(RemoteLoggerStats_t& a, const RemoteLoggerStats_t& b) +static RemoteLoggerStats_t& operator+=(RemoteLoggerStats_t& lhs, const RemoteLoggerStats_t& rhs) { - for (const auto& [key, entry] : b) { - a[key] += entry; + for (const auto& [key, entry] : rhs) { + lhs[key] += entry; } - return a; + return lhs; } // This function should only be called by the handler to gather @@ -1561,13 +1576,13 @@ static int initSyncRes(Logr::log_t log, const std::optional& myHost bool done = false; auto addr = pdns::getNonAnyQueryLocalAddress(AF_INET); - if (addr.sin4.sin_family != 0) { // NOLINT: union access + if (addr.sin4.sin_family != 0) { netmask = Netmask(addr, 32); done = true; } if (!done) { addr = pdns::getNonAnyQueryLocalAddress(AF_INET6); - if (addr.sin4.sin_family != 0) { // NOLINT: union access + if (addr.sin4.sin_family != 0) { netmask = Netmask(addr, 128); done = true; } @@ -1734,7 +1749,7 @@ static void initSNMP([[maybe_unused]] Logr::log_t log) } } -static int initControl(Logr::log_t log, uid_t newuid, int forks) // NOLINT(bugprone-easily-swappable-parameter*) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek +static int initControl(Logr::log_t log, uid_t newuid, int forks) { if (!::arg()["chroot"].empty()) { #ifdef HAVE_SYSTEMD @@ -1864,7 +1879,7 @@ static int initDNS64(Logr::log_t log) return 0; } -static int serviceMain(Logr::log_t log) // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek +static int serviceMain(Logr::log_t log) { g_log.setName(g_programname); g_log.disableSyslog(::arg().mustDo("disable-syslog")); @@ -2139,11 +2154,11 @@ static void handlePipeRequest(int fileDesc, FDMultiplexer::funcparam_t& /* var * delete tmsg; // NOLINT: manual ownership handling } -static void handleRCC(int fd, FDMultiplexer::funcparam_t& /* var */) +static void handleRCC(int fileDesc, FDMultiplexer::funcparam_t& /* var */) { auto log = g_slog->withName("control"); try { - FDWrapper clientfd = accept(fd, nullptr, nullptr); + FDWrapper clientfd = accept(fileDesc, nullptr, nullptr); if (clientfd == -1) { throw PDNSException("accept failed"); } @@ -2152,7 +2167,7 @@ static void handleRCC(int fd, FDMultiplexer::funcparam_t& /* var */) log->info(Logr::Info, "Received rec_control command via control socket", "command", Logging::Loggable(msg))); RecursorControlParser rcp; - RecursorControlParser::func_t* command; + RecursorControlParser::func_t* command = nullptr; auto answer = rcp.getAnswer(clientfd, msg, &command); g_rcc.send(clientfd, answer); @@ -2171,32 +2186,32 @@ static void handleRCC(int fd, FDMultiplexer::funcparam_t& /* var */) class PeriodicTask { public: - PeriodicTask(const string& n, time_t p) : - period{p, 0}, name(n) + PeriodicTask(const string& aName, time_t aTime) : + period{aTime, 0}, name(aName) { - if (p <= 0) { - throw PDNSException("Invalid period of periodic task " + n); + if (aTime <= 0) { + throw PDNSException("Invalid period of periodic task " + aName); } } - void runIfDue(struct timeval& now, const std::function& f) + void runIfDue(struct timeval& now, const std::function& function) { if (last_run < now - period) { // cerr << RecThreadInfo::id() << ' ' << name << ' ' << now.tv_sec << '.' << now.tv_usec << " running" << endl; - f(); + function(); Utility::gettimeofday(&last_run); now = last_run; } } - time_t getPeriod() const + [[nodiscard]] time_t getPeriod() const { return period.tv_sec; } - void setPeriod(time_t p) + void setPeriod(time_t newperiod) { - period.tv_sec = p; + period.tv_sec = newperiod; } void updateLastRun() @@ -2204,7 +2219,7 @@ class PeriodicTask Utility::gettimeofday(&last_run); } - bool hasRun() const + [[nodiscard]] bool hasRun() const { return last_run.tv_sec != 0 || last_run.tv_usec != 0; } @@ -2218,7 +2233,7 @@ class PeriodicTask const string name; }; -static void houseKeepingWork(Logr::log_t log) // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek +static void houseKeepingWork(Logr::log_t log) { struct timeval now { @@ -2517,7 +2532,7 @@ static void recLoop() for (const auto& exp : expired) { auto conn = boost::any_cast>(exp.second); if (g_logCommonErrors) { - SLOG(g_log << Logger::Warning << "Timeout from remote TCP client " << conn->d_remote.toStringWithPort() << endl, // NOLINT: union access + SLOG(g_log << Logger::Warning << "Timeout from remote TCP client " << conn->d_remote.toStringWithPort() << endl, g_slogtcpin->info(Logr::Warning, "Timeout from remote TCP client", "remote", Logging::Loggable(conn->d_remote))); } t_fdm->removeReadFD(exp.first); @@ -2548,7 +2563,7 @@ static void recLoop() } } -static void recursorThread() // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek +static void recursorThread() { auto log = g_slog->withName("runtime"); t_Counters.updateSnap(true); @@ -3029,7 +3044,7 @@ static pair doConfig(Logr::log_t startupLog, const string& configname return {0, false}; } -int main(int argc, char** argv) // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek +int main(int argc, char** argv) { g_argc = argc; g_argv = argv; @@ -3244,8 +3259,9 @@ static RecursorControlChannel::Answer* doReloadLuaScript() RecursorControlChannel::Answer doQueueReloadLuaScript(vector::const_iterator begin, vector::const_iterator end) { - if (begin != end) + if (begin != end) { ::arg().set("lua-dns-script") = *begin; + } return broadcastAccFunction(doReloadLuaScript); } @@ -3282,12 +3298,12 @@ struct WipeCacheResult wipeCaches(const DNSName& canon, bool subtree, uint16_t q struct WipeCacheResult res; try { - res.record_count = g_recCache->doWipeCache(canon, subtree, qtype); + res.record_count = static_cast(g_recCache->doWipeCache(canon, subtree, qtype)); // scanbuild complains here about an allocated function object that is being leaked. Needs investigation if (g_packetCache) { - res.packet_count = g_packetCache->doWipePacketCache(canon, qtype, subtree); + res.packet_count = static_cast(g_packetCache->doWipePacketCache(canon, qtype, subtree)); } - res.negative_record_count = g_negCache->wipe(canon, subtree); + res.negative_record_count = static_cast(g_negCache->wipe(canon, subtree)); if (g_aggressiveNSECCache) { g_aggressiveNSECCache->removeZoneInfo(canon, subtree); } diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index 72ded229e7dd..2e515fa5794f 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -524,7 +524,7 @@ bool checkFrameStreamExport(LocalStateHolder& luaconfsLocal, con #endif void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* qtype, uint16_t* qclass, bool& foundECS, EDNSSubnetOpts* ednssubnet, EDNSOptionViewMap* options); -void protobufLogQuery(LocalStateHolder& luaconfsLocal, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const ComboAddress& mappedSource, const Netmask& ednssubnet, bool tcp, uint16_t id, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::unordered_set& policyTags, const std::string& requestorId, const std::string& deviceId, const std::string& deviceName, const std::map& meta); +void protobufLogQuery(LocalStateHolder& luaconfsLocal, const boost::uuids::uuid& uniqueId, const ComboAddress& remote, const ComboAddress& local, const ComboAddress& mappedSource, const Netmask& ednssubnet, bool tcp, uint16_t queryID, size_t len, const DNSName& qname, uint16_t qtype, uint16_t qclass, const std::unordered_set& policyTags, const std::string& requestorId, const std::string& deviceId, const std::string& deviceName, const std::map& meta); bool isAllowNotifyForZone(DNSName qname); bool checkForCacheHit(bool qnameParsed, unsigned int tag, const string& data, DNSName& qname, uint16_t& qtype, uint16_t& qclass, @@ -532,7 +532,7 @@ bool checkForCacheHit(bool qnameParsed, unsigned int tag, const string& data, string& response, uint32_t& qhash, RecursorPacketCache::OptPBData& pbData, bool tcp, const ComboAddress& source, const ComboAddress& mappedSource); void protobufLogResponse(pdns::ProtoZero::RecMessage& message); -void protobufLogResponse(const struct dnsheader* dh, LocalStateHolder& luaconfsLocal, +void protobufLogResponse(const struct dnsheader* header, LocalStateHolder& luaconfsLocal, const RecursorPacketCache::OptPBData& pbData, const struct timeval& tv, bool tcp, const ComboAddress& source, const ComboAddress& destination, const ComboAddress& mappedSource, const EDNSSubnetOpts& ednssubnet, diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 445482b95265..362324405e6a 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -917,7 +917,7 @@ T broadcastAccFunction(const std::function& func); typedef std::unordered_set notifyset_t; std::tuple, std::shared_ptr> parseZoneConfiguration(); -void* pleaseSupplantAllowNotifyFor(std::shared_ptr ns); +void* pleaseSupplantAllowNotifyFor(std::shared_ptr allowNotifyFor); uint64_t* pleaseGetNsSpeedsSize(); uint64_t* pleaseGetFailedServersSize(); From 7ada1188272c520477f6390d4a431371a1793aa5 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 17 May 2023 12:22:18 +0200 Subject: [PATCH 192/909] Delint validate.cc and related files --- .clang-tidy.full | 2 +- pdns/recursordist/validate-recursor.cc | 30 +-- pdns/validate.cc | 319 +++++++++++++------------ pdns/validate.hh | 37 +-- 4 files changed, 201 insertions(+), 187 deletions(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index bf8c8c8eca18..f6ba38ee2e97 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -113,7 +113,7 @@ CheckOptions: - key: readability-function-size.LineThreshold value: '4294967295' - key: bugprone-easily-swappable-parameters.MinimumLength - value: '2' + value: '4' - key: portability-simd-intrinsics.Suggest value: 'false' - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader diff --git a/pdns/recursordist/validate-recursor.cc b/pdns/recursordist/validate-recursor.cc index ba8c2cae219f..1a676792a992 100644 --- a/pdns/recursordist/validate-recursor.cc +++ b/pdns/recursordist/validate-recursor.cc @@ -46,26 +46,26 @@ bool updateTrustAnchorsFromFile(const std::string& fname, map& { map newDSAnchors; try { - auto zp = ZoneParserTNG(fname); - zp.disableGenerate(); - DNSResourceRecord rr; - DNSRecord dr; - while (zp.get(rr)) { - dr = DNSRecord(rr); - if (rr.qtype == QType::DS) { - auto dsr = getRR(dr); + auto zoneParser = ZoneParserTNG(fname); + zoneParser.disableGenerate(); + DNSResourceRecord resourceRecord; + DNSRecord dnsrecord; + while (zoneParser.get(resourceRecord)) { + dnsrecord = DNSRecord(resourceRecord); + if (resourceRecord.qtype == QType::DS) { + auto dsr = getRR(dnsrecord); if (dsr == nullptr) { - throw PDNSException("Unable to parse DS record '" + rr.qname.toString() + " " + rr.getZoneRepresentation() + "'"); + throw PDNSException("Unable to parse DS record '" + resourceRecord.qname.toString() + " " + resourceRecord.getZoneRepresentation() + "'"); } - newDSAnchors[rr.qname].insert(*dsr); + newDSAnchors[resourceRecord.qname].insert(*dsr); } - if (rr.qtype == QType::DNSKEY) { - auto dnskeyr = getRR(dr); + if (resourceRecord.qtype == QType::DNSKEY) { + auto dnskeyr = getRR(dnsrecord); if (dnskeyr == nullptr) { - throw PDNSException("Unable to parse DNSKEY record '" + rr.qname.toString() + " " + rr.getZoneRepresentation() + "'"); + throw PDNSException("Unable to parse DNSKEY record '" + resourceRecord.qname.toString() + " " + resourceRecord.getZoneRepresentation() + "'"); } - auto dsr = makeDSFromDNSKey(rr.qname, *dnskeyr, DNSSECKeeper::DIGEST_SHA256); - newDSAnchors[rr.qname].insert(dsr); + auto dsr = makeDSFromDNSKey(resourceRecord.qname, *dnskeyr, DNSSECKeeper::DIGEST_SHA256); + newDSAnchors[resourceRecord.qname].insert(dsr); } } if (dsAnchors == newDSAnchors) { diff --git a/pdns/validate.cc b/pdns/validate.cc index af4f9d69af54..8306d9aae553 100644 --- a/pdns/validate.cc +++ b/pdns/validate.cc @@ -1,3 +1,25 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + #include "validate.hh" #include "misc.hh" #include "dnssecinfra.hh" @@ -53,20 +75,20 @@ static vector > getByTag(const skeyset_t& return ret; } -bool isCoveredByNSEC3Hash(const std::string& h, const std::string& beginHash, const std::string& nextHash) +bool isCoveredByNSEC3Hash(const std::string& hash, const std::string& beginHash, const std::string& nextHash) { - return ((beginHash < h && h < nextHash) || // no wrap BEGINNING --- HASH -- END - (nextHash > h && beginHash > nextHash) || // wrap HASH --- END --- BEGINNING - (nextHash < beginHash && beginHash < h) || // wrap other case END --- BEGINNING --- HASH - (beginHash == nextHash && h != beginHash)); // "we have only 1 NSEC3 record, LOL!" + return ((beginHash < hash && hash < nextHash) || // no wrap BEGINNING --- HASH -- END + (nextHash > hash && beginHash > nextHash) || // wrap HASH --- END --- BEGINNING + (nextHash < beginHash && beginHash < hash) || // wrap other case END --- BEGINNING --- HASH + (beginHash == nextHash && hash != beginHash)); // "we have only 1 NSEC3 record, LOL!" } -bool isCoveredByNSEC3Hash(const DNSName& h, const DNSName& beginHash, const DNSName& nextHash) +bool isCoveredByNSEC3Hash(const DNSName& name, const DNSName& beginHash, const DNSName& nextHash) { - return ((beginHash.canonCompare(h) && h.canonCompare(nextHash)) || // no wrap BEGINNING --- HASH -- END - (h.canonCompare(nextHash) && nextHash.canonCompare(beginHash)) || // wrap HASH --- END --- BEGINNING - (nextHash.canonCompare(beginHash) && beginHash.canonCompare(h)) || // wrap other case END --- BEGINNING --- HASH - (beginHash == nextHash && h != beginHash)); // "we have only 1 NSEC3 record, LOL!" + return ((beginHash.canonCompare(name) && name.canonCompare(nextHash)) || // no wrap BEGINNING --- HASH -- END + (name.canonCompare(nextHash) && nextHash.canonCompare(beginHash)) || // wrap HASH --- END --- BEGINNING + (nextHash.canonCompare(beginHash) && beginHash.canonCompare(name)) || // wrap other case END --- BEGINNING --- HASH + (beginHash == nextHash && name != beginHash)); // "we have only 1 NSEC3 record, LOL!" } bool isCoveredByNSEC(const DNSName& name, const DNSName& begin, const DNSName& next) @@ -92,15 +114,15 @@ static std::string getHashFromNSEC3(const DNSName& qname, const NSEC3RecordConte { std::string result; - if (g_maxNSEC3Iterations && nsec3.d_iterations > g_maxNSEC3Iterations) { + if (g_maxNSEC3Iterations != 0 && nsec3.d_iterations > g_maxNSEC3Iterations) { return result; } auto key = std::make_tuple(qname, nsec3.d_salt, nsec3.d_iterations); - auto it = cache.find(key); - if (it != cache.end()) + auto iter = cache.find(key); + if (iter != cache.end()) { - return it->second; + return iter->second; } result = hashQNameWithSalt(nsec3.d_salt, nsec3.d_iterations, qname); @@ -139,17 +161,17 @@ bool denialProvesNoDelegation(const DNSName& zone, const std::vector& continue; } - const string h = getHashFromNSEC3(zone, *nsec3, cache); - if (h.empty()) { + const string hash = getHashFromNSEC3(zone, *nsec3, cache); + if (hash.empty()) { return false; } const string beginHash = fromBase32Hex(record.d_name.getRawLabels()[0]); - if (beginHash == h) { + if (beginHash == hash) { return !nsec3->isSet(QType::NS); } - if (isCoveredByNSEC3Hash(h, beginHash, nsec3->d_nexthash)) { + if (isCoveredByNSEC3Hash(hash, beginHash, nsec3->d_nexthash)) { return !(nsec3->isOptOut()); } } @@ -165,11 +187,7 @@ bool denialProvesNoDelegation(const DNSName& zone, const std::vector& */ bool isWildcardExpanded(unsigned int labelCount, const RRSIGRecordContent& sign) { - if (sign.d_labels < labelCount) { - return true; - } - - return false; + return sign.d_labels < labelCount; } static bool isWildcardExpanded(const DNSName& owner, const std::vector >& signatures) @@ -185,11 +203,8 @@ static bool isWildcardExpanded(const DNSName& owner, const std::vector >& signatures) @@ -246,17 +261,17 @@ static bool provesNoDataWildCard(const DNSName& qname, const uint16_t qtype, con { const DNSName wildcard = g_wildcarddnsname + closestEncloser; VLOG(log, qname << ": Trying to prove that there is no data in wildcard for "<getZoneRepresentation()<(r); + for (const auto& validset : validrrsets) { + VLOG(log, qname << ": Do have: "<getZoneRepresentation()<(record); if (!nsec) { continue; } - DNSName owner = getNSECOwnerName(v.first.first, v.second.signatures); + DNSName owner = getNSECOwnerName(validset.first.first, validset.second.signatures); if (owner != wildcard) { continue; } @@ -293,17 +308,17 @@ static bool provesNoWildCard(const DNSName& qname, const uint16_t qtype, const D { VLOG(log, qname << ": Trying to prove that there is no wildcard for "<getZoneRepresentation()<(r); + for (const auto& validset : validrrsets) { + VLOG(log, qname << ": Do have: "<getZoneRepresentation()<(records); if (!nsec) { continue; } - const DNSName owner = getNSECOwnerName(v.first.first, v.second.signatures); + const DNSName owner = getNSECOwnerName(validset.first.first, validset.second.signatures); VLOG(log, qname << ": Comparing owner: "<isSet(QType::DNAME)) { @@ -342,32 +357,32 @@ static bool provesNSEC3NoWildCard(const DNSName& closestEncloser, uint16_t const auto wildcard = g_wildcarddnsname + closestEncloser; VLOG(log, closestEncloser << ": Trying to prove that there is no wildcard for "<getZoneRepresentation()<(r); + for (const auto& validset : validrrsets) { + VLOG(log, closestEncloser << ": Do have: "<getZoneRepresentation()<(records); if (!nsec3) { continue; } - const DNSName signer = getSigner(v.second.signatures); - if (!v.first.first.isPartOf(signer)) { + const DNSName signer = getSigner(validset.second.signatures); + if (!validset.first.first.isPartOf(signer)) { continue; } - string h = getHashFromNSEC3(wildcard, *nsec3, cache); - if (h.empty()) { + string hash = getHashFromNSEC3(wildcard, *nsec3, cache); + if (hash.empty()) { return false; } - VLOG(log, closestEncloser << ":\tWildcard hash: "< "<d_nexthash)<d_nexthash)) { + if (isCoveredByNSEC3Hash(hash, beginHash, nsec3->d_nexthash)) { VLOG(log, closestEncloser << ":\tWildcard hash is covered"<getZoneRepresentation()<getZoneRepresentation()<(r); + auto nsec = std::dynamic_pointer_cast(record); if (!nsec) { continue; } - const DNSName owner = getNSECOwnerName(v.first.first, v.second.signatures); - const DNSName signer = getSigner(v.second.signatures); - if (!v.first.first.isPartOf(signer) || !owner.isPartOf(signer) ) { + const DNSName owner = getNSECOwnerName(validset.first.first, validset.second.signatures); + const DNSName signer = getSigner(validset.second.signatures); + if (!validset.first.first.isPartOf(signer) || !owner.isPartOf(signer) ) { continue; } @@ -528,7 +543,7 @@ dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, const uint16 */ if (qname.isPartOf(owner) && isNSECAncestorDelegation(signer, owner, *nsec)) { /* this is an "ancestor delegation" NSEC RR */ - if (!(qtype == QType::DS && qname == owner)) { + if (qtype != QType::DS || qname != owner) { VLOG(log, qname << ": An ancestor delegation NSEC RR can only deny the existence of a DS"<isSet(qtype)<<", next: "<d_next<isSet(qtype)<<", next: "<d_next<getZoneRepresentation()<(r); + } else if(validset.first.second==QType::NSEC3) { + for (const auto& record : validset.second.records) { + VLOG(log, qname << ":\t"<getZoneRepresentation()<(record); if (!nsec3) { continue; } - if (v.second.signatures.empty()) { + if (validset.second.signatures.empty()) { continue; } - const DNSName& hashedOwner = v.first.first; - const DNSName signer = getSigner(v.second.signatures); + const DNSName& hashedOwner = validset.first.first; + const DNSName signer = getSigner(validset.second.signatures); if (!hashedOwner.isPartOf(signer)) { VLOG(log, qname << ": Owner "<getZoneRepresentation()<(r); + for(const auto& validset : validrrsets) { + if(validset.first.second==QType::NSEC3) { + for(const auto& record : validset.second.records) { + VLOG(log, qname << ":\t"<getZoneRepresentation()<(record); if (!nsec3) { continue; } - const DNSName signer = getSigner(v.second.signatures); - if (!v.first.first.isPartOf(signer)) { - VLOG(log, qname << ": Owner "<getZoneRepresentation()<(r); - if(!nsec3) + for(const auto& validset : validrrsets) { + if(validset.first.second==QType::NSEC3) { + for(const auto& record : validset.second.records) { + VLOG(log, qname << ":\t"<getZoneRepresentation()<(record); + if (!nsec3) { continue; + } - string h = getHashFromNSEC3(nextCloser, *nsec3, cache); - if (h.empty()) { + string hash = getHashFromNSEC3(nextCloser, *nsec3, cache); + if (hash.empty()) { return dState::INSECURE; } - const DNSName signer = getSigner(v.second.signatures); - if (!v.first.first.isPartOf(signer)) { - VLOG(log, qname << ": Owner "< "<d_nexthash)<d_nexthash)) { + VLOG(log, qname << ": Comparing "< "<d_nexthash)<d_nexthash)) { VLOG(log, qname << ": Denies existence of name "<(rec); @@ -1031,25 +1045,25 @@ cspmap_t harvestCSPFromRecs(const vector& recs) bool getTrustAnchor(const map& anchors, const DNSName& zone, dsmap_t &res) { - const auto& it = anchors.find(zone); + const auto& iter = anchors.find(zone); - if (it == anchors.cend()) { + if (iter == anchors.cend()) { return false; } - res = it->second; + res = iter->second; return true; } bool haveNegativeTrustAnchor(const map& negAnchors, const DNSName& zone, std::string& reason) { - const auto& it = negAnchors.find(zone); + const auto& iter = negAnchors.find(zone); - if (it == negAnchors.cend()) { + if (iter == negAnchors.cend()) { return false; } - reason = it->second; + reason = iter->second; return true; } @@ -1061,10 +1075,10 @@ vState validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& */ for (const auto& dsrc : dsmap) { - auto r = getByTag(tkeys, dsrc.d_tag, dsrc.d_algorithm, log); + auto record = getByTag(tkeys, dsrc.d_tag, dsrc.d_algorithm, log); // cerr<<"looking at DS with tag "< >& } } - return DNSName(); + return {}; } const std::string& vStateToString(vState state) @@ -1220,17 +1232,17 @@ const std::string& vStateToString(vState state) return vStates.at(static_cast(state)); } -std::ostream& operator<<(std::ostream &os, const vState d) +std::ostream& operator<<(std::ostream &ostr, const vState dstate) { - os< dStates = {"no denial", "inconclusive", "nxdomain", "nxqtype", "empty non-terminal", "insecure", "opt-out"}; - os<(d)); - return os; + ostr<(dstate)); + return ostr; } void updateDNSSECValidationState(vState& state, const vState stateUpdate) @@ -1241,10 +1253,7 @@ void updateDNSSECValidationState(vState& state, const vState stateUpdate) else if (stateUpdate == vState::NTA) { state = vState::Insecure; } - else if (vStateIsBogus(stateUpdate)) { - state = stateUpdate; - } - else if (state == vState::Indeterminate) { + else if (vStateIsBogus(stateUpdate) || state == vState::Indeterminate) { state = stateUpdate; } else if (stateUpdate == vState::Insecure) { diff --git a/pdns/validate.hh b/pdns/validate.hh index 1660d98eac44..9ca589572df5 100644 --- a/pdns/validate.hh +++ b/pdns/validate.hh @@ -43,13 +43,18 @@ inline bool vStateIsBogus(vState state) // NSEC(3) results enum class dState : uint8_t { NODENIAL, INCONCLUSIVE, NXDOMAIN, NXQTYPE, ENT, INSECURE, OPTOUT}; -std::ostream& operator<<(std::ostream &os, const vState d); -std::ostream& operator<<(std::ostream &os, const dState d); +std::ostream& operator<<(std::ostream &, vState); +std::ostream& operator<<(std::ostream &, dState); class DNSRecordOracle { public: - virtual std::vector get(const DNSName& qname, uint16_t qtype)=0; + virtual ~DNSRecordOracle() = default; + DNSRecordOracle(const DNSRecordOracle&) = default; + DNSRecordOracle(DNSRecordOracle&&) = default; + DNSRecordOracle& operator=(const DNSRecordOracle&) = default; + DNSRecordOracle& operator=(DNSRecordOracle&&) = default; + virtual std::vector get(const DNSName& qname, uint16_t qtype) = 0; }; @@ -59,37 +64,37 @@ struct ContentSigPair vector> signatures; // ponder adding a validate method that accepts a key }; -typedef map, ContentSigPair> cspmap_t; -typedef std::set dsmap_t; +using cspmap_t = map, ContentSigPair>; +using dsmap_t = std::set; struct sharedDNSKeyRecordContentCompare { - bool operator() (const shared_ptr& a, const shared_ptr& b) const + bool operator() (const shared_ptr& lhs, const shared_ptr& rhs) const { - return *a < *b; + return *lhs < *rhs; } }; -typedef set, sharedDNSKeyRecordContentCompare > skeyset_t; +using skeyset_t = set, sharedDNSKeyRecordContentCompare>; -vState validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t& records, const vector >& signatures, const skeyset_t& keys, const OptLog& log, bool validateAllSigs=true); +vState validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t& toSign, const vector >& signatures, const skeyset_t& keys, const OptLog& log, bool validateAllSigs=true); bool isCoveredByNSEC(const DNSName& name, const DNSName& begin, const DNSName& next); -bool isCoveredByNSEC3Hash(const std::string& h, const std::string& beginHash, const std::string& nextHash); -bool isCoveredByNSEC3Hash(const DNSName& h, const DNSName& beginHash, const DNSName& nextHash); +bool isCoveredByNSEC3Hash(const std::string& hash, const std::string& beginHash, const std::string& nextHash); +bool isCoveredByNSEC3Hash(const DNSName& name, const DNSName& beginHash, const DNSName& nextHash); cspmap_t harvestCSPFromRecs(const vector& recs); bool getTrustAnchor(const map& anchors, const DNSName& zone, dsmap_t &res); bool haveNegativeTrustAnchor(const map& negAnchors, const DNSName& zone, std::string& reason); vState validateDNSKeysAgainstDS(time_t now, const DNSName& zone, const dsmap_t& dsmap, const skeyset_t& tkeys, const sortedRecords_t& toSign, const vector >& sigs, skeyset_t& validkeys, const OptLog&); -dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, const uint16_t qtype, bool referralToUnsigned, bool wantsNoDataProof, const OptLog& log = std::nullopt, bool needsWildcardProof=true, unsigned int wildcardLabelsCount=0); -bool isSupportedDS(const DSRecordContent& ds, const OptLog&); +dState getDenial(const cspmap_t &validrrsets, const DNSName& qname, uint16_t qtype, bool referralToUnsigned, bool wantsNoDataProof, const OptLog& log = std::nullopt, bool needWildcardProof=true, unsigned int wildcardLabelsCount=0); +bool isSupportedDS(const DSRecordContent& dsRecordContent, const OptLog&); DNSName getSigner(const std::vector >& signatures); bool denialProvesNoDelegation(const DNSName& zone, const std::vector& dsrecords); -bool isRRSIGNotExpired(const time_t now, const RRSIGRecordContent& sig); -bool isRRSIGIncepted(const time_t now, const RRSIGRecordContent& sig); +bool isRRSIGNotExpired(time_t now, const RRSIGRecordContent& sig); +bool isRRSIGIncepted(time_t now, const RRSIGRecordContent& sig); bool isWildcardExpanded(unsigned int labelCount, const RRSIGRecordContent& sign); bool isWildcardExpandedOntoItself(const DNSName& owner, unsigned int labelCount, const RRSIGRecordContent& sign); -void updateDNSSECValidationState(vState& state, const vState stateUpdate); +void updateDNSSECValidationState(vState& state, vState stateUpdate); dState matchesNSEC(const DNSName& name, uint16_t qtype, const DNSName& nsecOwner, const NSECRecordContent& nsec, const std::vector>& signatures, const OptLog&); From c0db60c3103ae64011389ba8d4eb151396e8e880 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 17 May 2023 12:54:01 +0200 Subject: [PATCH 193/909] Delint rec-tcp.cc --- .clang-tidy.full | 2 +- pdns/recursordist/rec-main.hh | 4 +- pdns/recursordist/rec-tcp.cc | 348 +++++++++++++++++----------------- pdns/recursordist/syncres.hh | 2 +- 4 files changed, 180 insertions(+), 176 deletions(-) diff --git a/.clang-tidy.full b/.clang-tidy.full index bf8c8c8eca18..f6ba38ee2e97 100644 --- a/.clang-tidy.full +++ b/.clang-tidy.full @@ -113,7 +113,7 @@ CheckOptions: - key: readability-function-size.LineThreshold value: '4294967295' - key: bugprone-easily-swappable-parameters.MinimumLength - value: '2' + value: '4' - key: portability-simd-intrinsics.Suggest value: 'false' - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index 72ded229e7dd..68b59d910eee 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -542,11 +542,11 @@ void protobufLogResponse(const struct dnsheader* dh, LocalStateHolder& dc, bool hadError, bool updateInFlight); +void finishTCPReply(std::unique_ptr&, bool hadError, bool updateInFlight); void checkFastOpenSysctl(bool active, Logr::log_t); void checkTFOconnect(Logr::log_t); void makeTCPServerSockets(deferredAdd_t& deferredAdds, std::set& tcpSockets, Logr::log_t); -void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t&); +void handleNewTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t&); void makeUDPServerSockets(deferredAdd_t& deferredAdds, Logr::log_t); string doTraceRegex(FDWrapper file, vector::const_iterator begin, vector::const_iterator end); diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 3da26229019c..ba84ff4e1083 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -36,7 +36,7 @@ uint16_t TCPConnection::s_maxInFlight; thread_local std::unique_ptr t_tcpClientCounts; -static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var); +static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& var); #if 0 #define TCPLOG(tcpsock, x) \ @@ -49,8 +49,8 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var); std::atomic TCPConnection::s_currentConnections; -TCPConnection::TCPConnection(int fd, const ComboAddress& addr) : - data(2, 0), d_remote(addr), d_fd(fd) +TCPConnection::TCPConnection(int fileDesc, const ComboAddress& addr) : + data(2, 0), d_remote(addr), d_fd(fileDesc) { ++s_currentConnections; (*t_tcpClientCounts)[d_remote]++; @@ -59,68 +59,70 @@ TCPConnection::TCPConnection(int fd, const ComboAddress& addr) : TCPConnection::~TCPConnection() { try { - if (closesocket(d_fd) < 0) + if (closesocket(d_fd) < 0) { SLOG(g_log << Logger::Error << "Error closing socket for TCPConnection" << endl, g_slogtcpin->info(Logr::Error, "Error closing socket for TCPConnection")); + } } catch (const PDNSException& e) { SLOG(g_log << Logger::Error << "Error closing TCPConnection socket: " << e.reason << endl, g_slogtcpin->error(Logr::Error, e.reason, "Error closing TCPConnection socket", "exception", Logging::Loggable("PDNSException"))); } - if (t_tcpClientCounts->count(d_remote) && !(*t_tcpClientCounts)[d_remote]--) + if (t_tcpClientCounts->count(d_remote) != 0 && (*t_tcpClientCounts)[d_remote]-- == 0) { t_tcpClientCounts->erase(d_remote); + } --s_currentConnections; } -static void terminateTCPConnection(int fd) +static void terminateTCPConnection(int fileDesc) { try { - t_fdm->removeReadFD(fd); + t_fdm->removeReadFD(fileDesc); } catch (const FDMultiplexerException& fde) { } } -static void sendErrorOverTCP(std::unique_ptr& dc, int rcode) +static void sendErrorOverTCP(std::unique_ptr& comboWriter, int rcode) { std::vector packet; - if (dc->d_mdp.d_header.qdcount == 0) { + if (comboWriter->d_mdp.d_header.qdcount == 0) { /* header-only */ packet.resize(sizeof(dnsheader)); } else { - DNSPacketWriter pw(packet, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass); - if (dc->d_mdp.hasEDNS()) { + DNSPacketWriter packetWriter(packet, comboWriter->d_mdp.d_qname, comboWriter->d_mdp.d_qtype, comboWriter->d_mdp.d_qclass); + if (comboWriter->d_mdp.hasEDNS()) { /* we try to add the EDNS OPT RR even for truncated answers, as rfc6891 states: "The minimal response MUST be the DNS header, question section, and an OPT record. This MUST also occur when a truncated response (using the DNS header's TC bit) is returned." */ - pw.addOpt(512, 0, 0); - pw.commit(); + packetWriter.addOpt(512, 0, 0); + packetWriter.commit(); } } - dnsheader& header = reinterpret_cast(packet.at(0)); + auto& header = reinterpret_cast(packet.at(0)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) safe cast header.aa = 0; header.ra = 1; header.qr = 1; header.tc = 0; - header.id = dc->d_mdp.d_header.id; - header.rd = dc->d_mdp.d_header.rd; - header.cd = dc->d_mdp.d_header.cd; + header.id = comboWriter->d_mdp.d_header.id; + header.rd = comboWriter->d_mdp.d_header.rd; + header.cd = comboWriter->d_mdp.d_header.cd; header.rcode = rcode; - sendResponseOverTCP(dc, packet); + sendResponseOverTCP(comboWriter, packet); } -void finishTCPReply(std::unique_ptr& dc, bool hadError, bool updateInFlight) +void finishTCPReply(std::unique_ptr& comboWriter, bool hadError, bool updateInFlight) { // update tcp connection status, closing if needed and doing the fd multiplexer accounting - if (updateInFlight && dc->d_tcpConnection->d_requestsInFlight > 0) { - dc->d_tcpConnection->d_requestsInFlight--; + if (updateInFlight && comboWriter->d_tcpConnection->d_requestsInFlight > 0) { + comboWriter->d_tcpConnection->d_requestsInFlight--; } // In the code below, we try to remove the fd from the set, but @@ -128,18 +130,18 @@ void finishTCPReply(std::unique_ptr& dc, bool hadError, bool upd // "Tried to remove unlisted fd" exception. Not that an inflight < limit test // will not work since we do not know if the other mthread got an error or not. if (hadError) { - terminateTCPConnection(dc->d_socket); - dc->d_socket = -1; + terminateTCPConnection(comboWriter->d_socket); + comboWriter->d_socket = -1; return; } - dc->d_tcpConnection->queriesCount++; - if ((g_tcpMaxQueriesPerConn && dc->d_tcpConnection->queriesCount >= g_tcpMaxQueriesPerConn) || (dc->d_tcpConnection->isDropOnIdle() && dc->d_tcpConnection->d_requestsInFlight == 0)) { + comboWriter->d_tcpConnection->queriesCount++; + if ((g_tcpMaxQueriesPerConn > 0 && comboWriter->d_tcpConnection->queriesCount >= g_tcpMaxQueriesPerConn) || (comboWriter->d_tcpConnection->isDropOnIdle() && comboWriter->d_tcpConnection->d_requestsInFlight == 0)) { try { - t_fdm->removeReadFD(dc->d_socket); + t_fdm->removeReadFD(comboWriter->d_socket); } catch (FDMultiplexerException&) { } - dc->d_socket = -1; + comboWriter->d_socket = -1; return; } @@ -147,23 +149,23 @@ void finishTCPReply(std::unique_ptr& dc, bool hadError, bool upd struct timeval ttd = g_now; // If we cross from max to max-1 in flight requests, the fd was not listened to, add it back - if (updateInFlight && dc->d_tcpConnection->d_requestsInFlight == TCPConnection::s_maxInFlight - 1) { + if (updateInFlight && comboWriter->d_tcpConnection->d_requestsInFlight == TCPConnection::s_maxInFlight - 1) { // A read error might have happened. If we add the fd back, it will most likely error again. // This is not a big issue, the next handleTCPClientReadable() will see another read error // and take action. ttd.tv_sec += g_tcpTimeout; - t_fdm->addReadFD(dc->d_socket, handleRunningTCPQuestion, dc->d_tcpConnection, &ttd); + t_fdm->addReadFD(comboWriter->d_socket, handleRunningTCPQuestion, comboWriter->d_tcpConnection, &ttd); return; } // fd might have been removed by read error code, or a read timeout, so expect an exception try { - t_fdm->setReadTTD(dc->d_socket, ttd, g_tcpTimeout); + t_fdm->setReadTTD(comboWriter->d_socket, ttd, g_tcpTimeout); } catch (const FDMultiplexerException&) { // but if the FD was removed because of a timeout while we were sending a response, // we need to re-arm it. If it was an error it will error again. ttd.tv_sec += g_tcpTimeout; - t_fdm->addReadFD(dc->d_socket, handleRunningTCPQuestion, dc->d_tcpConnection, &ttd); + t_fdm->addReadFD(comboWriter->d_socket, handleRunningTCPQuestion, comboWriter->d_tcpConnection, &ttd); } } @@ -174,10 +176,11 @@ void finishTCPReply(std::unique_ptr& dc, bool hadError, bool upd class RunningTCPQuestionGuard { public: - RunningTCPQuestionGuard(int fd) - { - d_fd = fd; - } + RunningTCPQuestionGuard(const RunningTCPQuestionGuard&) = default; + RunningTCPQuestionGuard(RunningTCPQuestionGuard&&) = delete; + RunningTCPQuestionGuard& operator=(const RunningTCPQuestionGuard&) = default; + RunningTCPQuestionGuard& operator=(RunningTCPQuestionGuard&&) = delete; + RunningTCPQuestionGuard(int fileDesc) : d_fd(fileDesc) {} ~RunningTCPQuestionGuard() { if (d_fd != -1) { @@ -195,7 +198,7 @@ class RunningTCPQuestionGuard /* EOF */ return false; } - else if (bytes < 0) { + if (bytes < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { return false; } @@ -208,16 +211,16 @@ class RunningTCPQuestionGuard int d_fd{-1}; }; -static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) +static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& var) // NOLINT(readability-function-cognitive-complexity) https://github.com/PowerDNS/pdns/issues/12791 { - shared_ptr conn = boost::any_cast>(var); + auto conn = boost::any_cast>(var); - RunningTCPQuestionGuard tcpGuard{fd}; + RunningTCPQuestionGuard tcpGuard{fileDesc}; if (conn->state == TCPConnection::PROXYPROTOCOLHEADER) { ssize_t bytes = recv(conn->getFD(), &conn->data.at(conn->proxyProtocolGot), conn->proxyProtocolNeed, 0); if (bytes <= 0) { - tcpGuard.handleTCPReadResult(fd, bytes); + tcpGuard.handleTCPReadResult(fileDesc, bytes); return; } @@ -232,17 +235,17 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) ++t_Counters.at(rec::Counter::proxyProtocolInvalidCount); return; } - else if (remaining < 0) { + if (remaining < 0) { conn->proxyProtocolNeed = -remaining; conn->data.resize(conn->proxyProtocolGot + conn->proxyProtocolNeed); tcpGuard.keep(); return; } - else { + { /* proxy header received */ /* we ignore the TCP field for now, but we could properly set whether the connection was received over UDP or TCP if needed */ - bool tcp; + bool tcp = false; bool proxy = false; size_t used = parseProxyHeader(conn->data, proxy, conn->d_source, conn->d_destination, tcp, conn->proxyProtocolValues); if (used <= 0) { @@ -253,7 +256,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) ++t_Counters.at(rec::Counter::proxyProtocolInvalidCount); return; } - else if (static_cast(used) > g_proxyProtocolMaximumSize) { + if (static_cast(used) > g_proxyProtocolMaximumSize) { if (g_logCommonErrors) { SLOG(g_log << Logger::Error << "Proxy protocol header in packet from TCP client " << conn->d_remote.toStringWithPort() << " is larger than proxy-protocol-maximum-size (" << used << "), dropping" << endl, g_slogtcpin->info(Logr::Error, "Proxy protocol header in packet from TCP client is larger than proxy-protocol-maximum-size", "remote", Logging::Loggable(conn->d_remote), "size", Logging::Loggable(used))); @@ -267,9 +270,9 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) /* note that if the proxy header used a 'LOCAL' command, the original source and destination are untouched so everything should be fine */ conn->d_mappedSource = conn->d_source; if (t_proxyMapping) { - if (auto it = t_proxyMapping->lookup(conn->d_source)) { - conn->d_mappedSource = it->second.address; - ++it->second.stats.netmaskMatches; + if (const auto *iter = t_proxyMapping->lookup(conn->d_source)) { + conn->d_mappedSource = iter->second.address; + ++iter->second.stats.netmaskMatches; } } if (t_allowFrom && !t_allowFrom->match(&conn->d_mappedSource)) { @@ -288,9 +291,10 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) } if (conn->state == TCPConnection::BYTE0) { - ssize_t bytes = recv(conn->getFD(), &conn->data[0], 2, 0); - if (bytes == 1) + ssize_t bytes = recv(conn->getFD(), conn->data.data(), 2, 0); + if (bytes == 1) { conn->state = TCPConnection::BYTE1; + } if (bytes == 2) { conn->qlen = (((unsigned char)conn->data[0]) << 8) + (unsigned char)conn->data[1]; conn->data.resize(conn->qlen); @@ -298,7 +302,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) conn->state = TCPConnection::GETQUESTION; } if (bytes <= 0) { - tcpGuard.handleTCPReadResult(fd, bytes); + tcpGuard.handleTCPReadResult(fileDesc, bytes); return; } } @@ -312,7 +316,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) conn->bytesread = 0; } if (bytes <= 0) { - if (!tcpGuard.handleTCPReadResult(fd, bytes)) { + if (!tcpGuard.handleTCPReadResult(fileDesc, bytes)) { if (g_logCommonErrors) { SLOG(g_log << Logger::Error << "TCP client " << conn->d_remote.toStringWithPort() << " disconnected after first byte" << endl, g_slogtcpin->info(Logr::Error, "TCP client disconnected after first byte", "remote", Logging::Loggable(conn->d_remote))); @@ -325,7 +329,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) if (conn->state == TCPConnection::GETQUESTION) { ssize_t bytes = recv(conn->getFD(), &conn->data[conn->bytesread], conn->qlen - conn->bytesread, 0); if (bytes <= 0) { - if (!tcpGuard.handleTCPReadResult(fd, bytes)) { + if (!tcpGuard.handleTCPReadResult(fileDesc, bytes)) { if (g_logCommonErrors) { SLOG(g_log << Logger::Error << "TCP client " << conn->d_remote.toStringWithPort() << " disconnected while reading question body" << endl, g_slogtcpin->info(Logr::Error, "TCP client disconnected while reading question body", "remote", Logging::Loggable(conn->d_remote))); @@ -333,7 +337,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) } return; } - else if (bytes > std::numeric_limits::max()) { + if (bytes > std::numeric_limits::max()) { if (g_logCommonErrors) { SLOG(g_log << Logger::Error << "TCP client " << conn->d_remote.toStringWithPort() << " sent an invalid question size while reading question body" << endl, g_slogtcpin->info(Logr::Error, "TCP client sent an invalid question size while reading question body", "remote", Logging::Loggable(conn->d_remote))); @@ -343,9 +347,9 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) conn->bytesread += (uint16_t)bytes; if (conn->bytesread == conn->qlen) { conn->state = TCPConnection::BYTE0; - std::unique_ptr dc; + std::unique_ptr comboWriter; try { - dc = std::make_unique(conn->data, g_now, t_pdl); + comboWriter = std::make_unique(conn->data, g_now, t_pdl); } catch (const MOADNSException& mde) { t_Counters.at(rec::Counter::clientParseError)++; @@ -356,24 +360,24 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) return; } - dc->d_tcpConnection = conn; // carry the torch - dc->setSocket(conn->getFD()); // this is the only time a copy is made of the actual fd - dc->d_tcp = true; - dc->setRemote(conn->d_remote); // the address the query was received from - dc->setSource(conn->d_source); // the address we assume the query is coming from, might be set by proxy protocol + comboWriter->d_tcpConnection = conn; // carry the torch + comboWriter->setSocket(conn->getFD()); // this is the only time a copy is made of the actual fd + comboWriter->d_tcp = true; + comboWriter->setRemote(conn->d_remote); // the address the query was received from + comboWriter->setSource(conn->d_source); // the address we assume the query is coming from, might be set by proxy protocol ComboAddress dest; dest.reset(); dest.sin4.sin_family = conn->d_remote.sin4.sin_family; socklen_t len = dest.getSocklen(); - getsockname(conn->getFD(), (sockaddr*)&dest, &len); // if this fails, we're ok with it - dc->setLocal(dest); // the address we received the query on - dc->setDestination(conn->d_destination); // the address we assume the query is received on, might be set by proxy protocol - dc->setMappedSource(conn->d_mappedSource); // the address we assume the query is coming from after table based mapping + getsockname(conn->getFD(), reinterpret_cast(&dest), &len); // if this fails, we're ok with it + comboWriter->setLocal(dest); // the address we received the query on + comboWriter->setDestination(conn->d_destination); // the address we assume the query is received on, might be set by proxy protocol + comboWriter->setMappedSource(conn->d_mappedSource); // the address we assume the query is coming from after table based mapping /* we can't move this if we want to be able to access the values in all queries sent over this connection */ - dc->d_proxyProtocolValues = conn->proxyProtocolValues; + comboWriter->d_proxyProtocolValues = conn->proxyProtocolValues; - struct timeval start; + struct timeval start{}; Utility::gettimeofday(&start, nullptr); DNSName qname; @@ -386,37 +390,37 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) bool logQuery = false; bool qnameParsed = false; - dc->d_eventTrace.setEnabled(SyncRes::s_event_trace_enabled); - dc->d_eventTrace.add(RecEventTrace::ReqRecv); + comboWriter->d_eventTrace.setEnabled(SyncRes::s_event_trace_enabled != 0); + comboWriter->d_eventTrace.add(RecEventTrace::ReqRecv); auto luaconfsLocal = g_luaconfs.getLocal(); if (checkProtobufExport(luaconfsLocal)) { needECS = true; } logQuery = t_protobufServers.servers && luaconfsLocal->protobufExportConfig.logQueries; - dc->d_logResponse = t_protobufServers.servers && luaconfsLocal->protobufExportConfig.logResponses; + comboWriter->d_logResponse = t_protobufServers.servers && luaconfsLocal->protobufExportConfig.logResponses; - if (needECS || (t_pdl && (t_pdl->d_gettag_ffi || t_pdl->d_gettag)) || dc->d_mdp.d_header.opcode == Opcode::Notify) { + if (needECS || (t_pdl && (t_pdl->d_gettag_ffi || t_pdl->d_gettag)) || comboWriter->d_mdp.d_header.opcode == Opcode::Notify) { try { EDNSOptionViewMap ednsOptions; - dc->d_ecsParsed = true; - dc->d_ecsFound = false; + comboWriter->d_ecsParsed = true; + comboWriter->d_ecsFound = false; getQNameAndSubnet(conn->data, &qname, &qtype, &qclass, - dc->d_ecsFound, &dc->d_ednssubnet, g_gettagNeedsEDNSOptions ? &ednsOptions : nullptr); + comboWriter->d_ecsFound, &comboWriter->d_ednssubnet, g_gettagNeedsEDNSOptions ? &ednsOptions : nullptr); qnameParsed = true; if (t_pdl) { try { if (t_pdl->d_gettag_ffi) { - RecursorLua4::FFIParams params(qname, qtype, dc->d_destination, dc->d_source, dc->d_ednssubnet.source, dc->d_data, dc->d_policyTags, dc->d_records, ednsOptions, dc->d_proxyProtocolValues, requestorId, deviceId, deviceName, dc->d_routingTag, dc->d_rcode, dc->d_ttlCap, dc->d_variable, true, logQuery, dc->d_logResponse, dc->d_followCNAMERecords, dc->d_extendedErrorCode, dc->d_extendedErrorExtra, dc->d_responsePaddingDisabled, dc->d_meta); - dc->d_eventTrace.add(RecEventTrace::LuaGetTagFFI); - dc->d_tag = t_pdl->gettag_ffi(params); - dc->d_eventTrace.add(RecEventTrace::LuaGetTagFFI, dc->d_tag, false); + RecursorLua4::FFIParams params(qname, qtype, comboWriter->d_destination, comboWriter->d_source, comboWriter->d_ednssubnet.source, comboWriter->d_data, comboWriter->d_policyTags, comboWriter->d_records, ednsOptions, comboWriter->d_proxyProtocolValues, requestorId, deviceId, deviceName, comboWriter->d_routingTag, comboWriter->d_rcode, comboWriter->d_ttlCap, comboWriter->d_variable, true, logQuery, comboWriter->d_logResponse, comboWriter->d_followCNAMERecords, comboWriter->d_extendedErrorCode, comboWriter->d_extendedErrorExtra, comboWriter->d_responsePaddingDisabled, comboWriter->d_meta); + comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTagFFI); + comboWriter->d_tag = t_pdl->gettag_ffi(params); + comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTagFFI, comboWriter->d_tag, false); } else if (t_pdl->d_gettag) { - dc->d_eventTrace.add(RecEventTrace::LuaGetTag); - dc->d_tag = t_pdl->gettag(dc->d_source, dc->d_ednssubnet.source, dc->d_destination, qname, qtype, &dc->d_policyTags, dc->d_data, ednsOptions, true, requestorId, deviceId, deviceName, dc->d_routingTag, dc->d_proxyProtocolValues); - dc->d_eventTrace.add(RecEventTrace::LuaGetTag, dc->d_tag, false); + comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTag); + comboWriter->d_tag = t_pdl->gettag(comboWriter->d_source, comboWriter->d_ednssubnet.source, comboWriter->d_destination, qname, qtype, &comboWriter->d_policyTags, comboWriter->d_data, ednsOptions, true, requestorId, deviceId, deviceName, comboWriter->d_routingTag, comboWriter->d_proxyProtocolValues); + comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTag, comboWriter->d_tag, false); } } catch (const std::exception& e) { @@ -435,25 +439,25 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) } } - if (dc->d_tag == 0 && !dc->d_responsePaddingDisabled && g_paddingFrom.match(dc->d_remote)) { - dc->d_tag = g_paddingTag; + if (comboWriter->d_tag == 0 && !comboWriter->d_responsePaddingDisabled && g_paddingFrom.match(comboWriter->d_remote)) { + comboWriter->d_tag = g_paddingTag; } const dnsheader_aligned headerdata(conn->data.data()); - const struct dnsheader* dh = headerdata.get(); + const struct dnsheader* dnsheader = headerdata.get(); if (t_protobufServers.servers || t_outgoingProtobufServers.servers) { - dc->d_requestorId = requestorId; - dc->d_deviceId = deviceId; - dc->d_deviceName = deviceName; - dc->d_uuid = getUniqueID(); + comboWriter->d_requestorId = requestorId; + comboWriter->d_deviceId = deviceId; + comboWriter->d_deviceName = deviceName; + comboWriter->d_uuid = getUniqueID(); } if (t_protobufServers.servers) { try { - if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && dc->d_policyTags.empty())) { - protobufLogQuery(luaconfsLocal, dc->d_uuid, dc->d_source, dc->d_destination, dc->d_mappedSource, dc->d_ednssubnet.source, true, dh->id, conn->qlen, qname, qtype, qclass, dc->d_policyTags, dc->d_requestorId, dc->d_deviceId, dc->d_deviceName, dc->d_meta); + if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && comboWriter->d_policyTags.empty())) { + protobufLogQuery(luaconfsLocal, comboWriter->d_uuid, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet.source, true, dnsheader->id, conn->qlen, qname, qtype, qclass, comboWriter->d_policyTags, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta); } } catch (const std::exception& e) { @@ -465,56 +469,56 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) } if (t_pdl) { - bool ipf = t_pdl->ipfilter(dc->d_source, dc->d_destination, *dh, dc->d_eventTrace); + bool ipf = t_pdl->ipfilter(comboWriter->d_source, comboWriter->d_destination, *dnsheader, comboWriter->d_eventTrace); if (ipf) { if (!g_quiet) { - SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " [" << MT->getTid() << "/" << MT->numProcesses() << "] DROPPED TCP question from " << dc->d_source.toStringWithPort() << (dc->d_source != dc->d_remote ? " (via " + dc->d_remote.toStringWithPort() + ")" : "") << " based on policy" << endl, - g_slogtcpin->info(Logr::Info, "Dropped TCP question based on policy", "remote", Logging::Loggable(conn->d_remote), "source", Logging::Loggable(dc->d_source))); + SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " [" << MT->getTid() << "/" << MT->numProcesses() << "] DROPPED TCP question from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << " based on policy" << endl, + g_slogtcpin->info(Logr::Info, "Dropped TCP question based on policy", "remote", Logging::Loggable(conn->d_remote), "source", Logging::Loggable(comboWriter->d_source))); } t_Counters.at(rec::Counter::policyDrops)++; return; } } - if (dc->d_mdp.d_header.qr) { + if (comboWriter->d_mdp.d_header.qr) { t_Counters.at(rec::Counter::ignoredCount)++; if (g_logCommonErrors) { - SLOG(g_log << Logger::Error << "Ignoring answer from TCP client " << dc->getRemote() << " on server socket!" << endl, - g_slogtcpin->info(Logr::Error, "Ignoring answer from TCP client on server socket", "remote", Logging::Loggable(dc->getRemote()))); + SLOG(g_log << Logger::Error << "Ignoring answer from TCP client " << comboWriter->getRemote() << " on server socket!" << endl, + g_slogtcpin->info(Logr::Error, "Ignoring answer from TCP client on server socket", "remote", Logging::Loggable(comboWriter->getRemote()))); } return; } - if (dc->d_mdp.d_header.opcode != Opcode::Query && dc->d_mdp.d_header.opcode != Opcode::Notify) { + if (comboWriter->d_mdp.d_header.opcode != Opcode::Query && comboWriter->d_mdp.d_header.opcode != Opcode::Notify) { t_Counters.at(rec::Counter::ignoredCount)++; if (g_logCommonErrors) { - SLOG(g_log << Logger::Error << "Ignoring unsupported opcode " << Opcode::to_s(dc->d_mdp.d_header.opcode) << " from TCP client " << dc->getRemote() << " on server socket!" << endl, - g_slogtcpin->info(Logr::Error, "Ignoring unsupported opcode from TCP client", "remote", Logging::Loggable(dc->getRemote()), "opcode", Logging::Loggable(Opcode::to_s(dc->d_mdp.d_header.opcode)))); + SLOG(g_log << Logger::Error << "Ignoring unsupported opcode " << Opcode::to_s(comboWriter->d_mdp.d_header.opcode) << " from TCP client " << comboWriter->getRemote() << " on server socket!" << endl, + g_slogtcpin->info(Logr::Error, "Ignoring unsupported opcode from TCP client", "remote", Logging::Loggable(comboWriter->getRemote()), "opcode", Logging::Loggable(Opcode::to_s(comboWriter->d_mdp.d_header.opcode)))); } - sendErrorOverTCP(dc, RCode::NotImp); + sendErrorOverTCP(comboWriter, RCode::NotImp); tcpGuard.keep(); return; } - else if (dh->qdcount == 0) { + if (dnsheader->qdcount == 0) { t_Counters.at(rec::Counter::emptyQueriesCount)++; if (g_logCommonErrors) { - SLOG(g_log << Logger::Error << "Ignoring empty (qdcount == 0) query from " << dc->getRemote() << " on server socket!" << endl, - g_slogtcpin->info(Logr::Error, "Ignoring empty (qdcount == 0) query on server socket", "remote", Logging::Loggable(dc->getRemote()))); + SLOG(g_log << Logger::Error << "Ignoring empty (qdcount == 0) query from " << comboWriter->getRemote() << " on server socket!" << endl, + g_slogtcpin->info(Logr::Error, "Ignoring empty (qdcount == 0) query on server socket", "remote", Logging::Loggable(comboWriter->getRemote()))); } - sendErrorOverTCP(dc, RCode::NotImp); + sendErrorOverTCP(comboWriter, RCode::NotImp); tcpGuard.keep(); return; } - else { + { // We have read a proper query //++t_Counters.at(rec::Counter::qcounter); ++t_Counters.at(rec::Counter::qcounter); ++t_Counters.at(rec::Counter::tcpqcounter); - if (dc->d_mdp.d_header.opcode == Opcode::Notify) { - if (!t_allowNotifyFrom || !t_allowNotifyFrom->match(dc->d_mappedSource)) { + if (comboWriter->d_mdp.d_header.opcode == Opcode::Notify) { + if (!t_allowNotifyFrom || !t_allowNotifyFrom->match(comboWriter->d_mappedSource)) { if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping TCP NOTIFY from " << dc->d_mappedSource.toString() << ", address not matched by allow-notify-from" << endl, - g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, address not matched by allow-notify-from", "source", Logging::Loggable(dc->d_mappedSource))); + SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", address not matched by allow-notify-from" << endl, + g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, address not matched by allow-notify-from", "source", Logging::Loggable(comboWriter->d_mappedSource))); } t_Counters.at(rec::Counter::sourceDisallowedNotify)++; @@ -523,8 +527,8 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) if (!isAllowNotifyForZone(qname)) { if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping TCP NOTIFY from " << dc->d_mappedSource.toString() << ", for " << qname.toLogString() << ", zone not matched by allow-notify-for" << endl, - g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, zone not matched by allow-notify-for", "source", Logging::Loggable(dc->d_mappedSource), "zone", Logging::Loggable(qname))); + SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", for " << qname.toLogString() << ", zone not matched by allow-notify-for" << endl, + g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, zone not matched by allow-notify-for", "source", Logging::Loggable(comboWriter->d_mappedSource), "zone", Logging::Loggable(qname))); } t_Counters.at(rec::Counter::zoneDisallowedNotify)++; @@ -535,41 +539,41 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) string response; RecursorPacketCache::OptPBData pbData{boost::none}; - if (dc->d_mdp.d_header.opcode == Opcode::Query) { + if (comboWriter->d_mdp.d_header.opcode == Opcode::Query) { /* It might seem like a good idea to skip the packet cache lookup if we know that the answer is not cacheable, but it means that the hash would not be computed. If some script decides at a later time to mark back the answer as cacheable we would cache it with a wrong tag, so better safe than sorry. */ - dc->d_eventTrace.add(RecEventTrace::PCacheCheck); - bool cacheHit = checkForCacheHit(qnameParsed, dc->d_tag, conn->data, qname, qtype, qclass, g_now, response, dc->d_qhash, pbData, true, dc->d_source, dc->d_mappedSource); - dc->d_eventTrace.add(RecEventTrace::PCacheCheck, cacheHit, false); + comboWriter->d_eventTrace.add(RecEventTrace::PCacheCheck); + bool cacheHit = checkForCacheHit(qnameParsed, comboWriter->d_tag, conn->data, qname, qtype, qclass, g_now, response, comboWriter->d_qhash, pbData, true, comboWriter->d_source, comboWriter->d_mappedSource); + comboWriter->d_eventTrace.add(RecEventTrace::PCacheCheck, cacheHit, false); if (cacheHit) { if (!g_quiet) { - SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " TCP question answered from packet cache tag=" << dc->d_tag << " from " << dc->d_source.toStringWithPort() << (dc->d_source != dc->d_remote ? " (via " + dc->d_remote.toStringWithPort() + ")" : "") << endl, - g_slogtcpin->info(Logr::Notice, "TCP question answered from packet cache", "tag", Logging::Loggable(dc->d_tag), + SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " TCP question answered from packet cache tag=" << comboWriter->d_tag << " from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << endl, + g_slogtcpin->info(Logr::Notice, "TCP question answered from packet cache", "tag", Logging::Loggable(comboWriter->d_tag), "qname", Logging::Loggable(qname), "qtype", Logging::Loggable(QType(qtype)), - "source", Logging::Loggable(dc->d_source), "remote", Logging::Loggable(dc->d_remote))); + "source", Logging::Loggable(comboWriter->d_source), "remote", Logging::Loggable(comboWriter->d_remote))); } - bool hadError = sendResponseOverTCP(dc, response); - finishTCPReply(dc, hadError, false); - struct timeval now; + bool hadError = sendResponseOverTCP(comboWriter, response); + finishTCPReply(comboWriter, hadError, false); + struct timeval now{}; Utility::gettimeofday(&now, nullptr); uint64_t spentUsec = uSec(now - start); t_Counters.at(rec::Histogram::cumulativeAnswers)(spentUsec); - dc->d_eventTrace.add(RecEventTrace::AnswerSent); + comboWriter->d_eventTrace.add(RecEventTrace::AnswerSent); - if (t_protobufServers.servers && dc->d_logResponse && !(luaconfsLocal->protobufExportConfig.taggedOnly && pbData && !pbData->d_tagged)) { - struct timeval tv + if (t_protobufServers.servers && comboWriter->d_logResponse && (!luaconfsLocal->protobufExportConfig.taggedOnly || !pbData || pbData->d_tagged)) { + struct timeval tval { 0, 0 }; - protobufLogResponse(dh, luaconfsLocal, pbData, tv, true, dc->d_source, dc->d_destination, dc->d_mappedSource, dc->d_ednssubnet, dc->d_uuid, dc->d_requestorId, dc->d_deviceId, dc->d_deviceName, dc->d_meta, dc->d_eventTrace); + protobufLogResponse(dnsheader, luaconfsLocal, pbData, tval, true, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet, comboWriter->d_uuid, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta, comboWriter->d_eventTrace); } - if (dc->d_eventTrace.enabled() && SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_log) { - SLOG(g_log << Logger::Info << dc->d_eventTrace.toString() << endl, - g_slogtcpin->info(Logr::Info, dc->d_eventTrace.toString())); // More fancy? + if (comboWriter->d_eventTrace.enabled() && (SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_log) != 0) { + SLOG(g_log << Logger::Info << comboWriter->d_eventTrace.toString() << endl, + g_slogtcpin->info(Logr::Info, comboWriter->d_eventTrace.toString())); // More fancy? } tcpGuard.keep(); t_Counters.updateSnap(g_regressionTestMode); @@ -577,10 +581,10 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) } // cache hit } // query opcode - if (dc->d_mdp.d_header.opcode == Opcode::Notify) { + if (comboWriter->d_mdp.d_header.opcode == Opcode::Notify) { if (!g_quiet) { - SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " got NOTIFY for " << qname.toLogString() << " from " << dc->d_source.toStringWithPort() << (dc->d_source != dc->d_remote ? " (via " + dc->d_remote.toStringWithPort() + ")" : "") << endl, - g_slogtcpin->info(Logr::Notice, "Got NOTIFY", "qname", Logging::Loggable(qname), "source", Logging::Loggable(dc->d_source), "remote", Logging::Loggable(dc->d_remote))); + SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " got NOTIFY for " << qname.toLogString() << " from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << endl, + g_slogtcpin->info(Logr::Notice, "Got NOTIFY", "qname", Logging::Loggable(qname), "source", Logging::Loggable(comboWriter->d_source), "remote", Logging::Loggable(comboWriter->d_remote))); } requestWipeCaches(qname); @@ -589,21 +593,21 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) // a normal response, as the rest of the code does not // check dh->opcode, but we need to ensure that the response // to this request does not get put into the packet cache - dc->d_variable = true; + comboWriter->d_variable = true; } // setup for startDoResolve() in an mthread ++conn->d_requestsInFlight; if (conn->d_requestsInFlight >= TCPConnection::s_maxInFlight) { - t_fdm->removeReadFD(fd); // should no longer awake ourselves when there is data to read + t_fdm->removeReadFD(fileDesc); // should no longer awake ourselves when there is data to read } else { Utility::gettimeofday(&g_now, nullptr); // needed? struct timeval ttd = g_now; - t_fdm->setReadTTD(fd, ttd, g_tcpTimeout); + t_fdm->setReadTTD(fileDesc, ttd, g_tcpTimeout); } tcpGuard.keep(); - MT->makeThread(startDoResolve, dc.release()); // deletes dc + MT->makeThread(startDoResolve, comboWriter.release()); // deletes dc } // good query } // read full query } // reading query @@ -613,11 +617,11 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var) } //! Handle new incoming TCP connection -void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t&) +void handleNewTCPQuestion(int fileDesc, [[maybe_unused]] FDMultiplexer::funcparam_t& var) { ComboAddress addr; socklen_t addrlen = sizeof(addr); - int newsock = accept(fd, (struct sockaddr*)&addr, &addrlen); + int newsock = accept(fileDesc, reinterpret_cast(&addr), &addrlen); if (newsock >= 0) { if (MT->numProcesses() > g_maxMThreads) { t_Counters.at(rec::Counter::overCapacityDrops)++; @@ -638,16 +642,16 @@ void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t&) bool fromProxyProtocolSource = expectProxyProtocol(addr); ComboAddress mappedSource = addr; if (!fromProxyProtocolSource && t_proxyMapping) { - if (auto it = t_proxyMapping->lookup(addr)) { - mappedSource = it->second.address; - ++it->second.stats.netmaskMatches; + if (const auto *iter = t_proxyMapping->lookup(addr)) { + mappedSource = iter->second.address; + ++iter->second.stats.netmaskMatches; } } if (!fromProxyProtocolSource && t_allowFrom && !t_allowFrom->match(&mappedSource)) { - if (!g_quiet) + if (!g_quiet) { SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping TCP query from " << mappedSource.toString() << ", address neither matched by allow-from nor proxy-protocol-from" << endl, g_slogtcpin->info(Logr::Error, "dropping TCP query address neither matched by allow-from nor proxy-protocol-from", "source", Logging::Loggable(mappedSource))); - + } t_Counters.at(rec::Counter::unauthorizedTCP)++; try { closesocket(newsock); @@ -659,7 +663,7 @@ void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t&) return; } - if (g_maxTCPPerClient && t_tcpClientCounts->count(addr) && (*t_tcpClientCounts)[addr] >= g_maxTCPPerClient) { + if (g_maxTCPPerClient > 0 && t_tcpClientCounts->count(addr) > 0 && (*t_tcpClientCounts)[addr] >= g_maxTCPPerClient) { t_Counters.at(rec::Counter::tcpClientOverflow)++; try { closesocket(newsock); // don't call TCPConnection::closeAndCleanup here - did not enter it in the counts yet! @@ -673,32 +677,32 @@ void handleNewTCPQuestion(int fd, FDMultiplexer::funcparam_t&) setNonBlocking(newsock); setTCPNoDelay(newsock); - std::shared_ptr tc = std::make_shared(newsock, addr); - tc->d_source = addr; - tc->d_destination.reset(); - tc->d_destination.sin4.sin_family = addr.sin4.sin_family; - socklen_t len = tc->d_destination.getSocklen(); - getsockname(tc->getFD(), reinterpret_cast(&tc->d_destination), &len); // if this fails, we're ok with it - tc->d_mappedSource = mappedSource; + std::shared_ptr tcpConn = std::make_shared(newsock, addr); + tcpConn->d_source = addr; + tcpConn->d_destination.reset(); + tcpConn->d_destination.sin4.sin_family = addr.sin4.sin_family; + socklen_t len = tcpConn->d_destination.getSocklen(); + getsockname(tcpConn->getFD(), reinterpret_cast(&tcpConn->d_destination), &len); // if this fails, we're ok with it + tcpConn->d_mappedSource = mappedSource; if (fromProxyProtocolSource) { - tc->proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; - tc->data.resize(tc->proxyProtocolNeed); - tc->state = TCPConnection::PROXYPROTOCOLHEADER; + tcpConn->proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; + tcpConn->data.resize(tcpConn->proxyProtocolNeed); + tcpConn->state = TCPConnection::PROXYPROTOCOLHEADER; } else { - tc->state = TCPConnection::BYTE0; + tcpConn->state = TCPConnection::BYTE0; } - struct timeval ttd; + struct timeval ttd{}; Utility::gettimeofday(&ttd, nullptr); ttd.tv_sec += g_tcpTimeout; - t_fdm->addReadFD(tc->getFD(), handleRunningTCPQuestion, tc, &ttd); + t_fdm->addReadFD(tcpConn->getFD(), handleRunningTCPQuestion, tcpConn, &ttd); } } -static void TCPIOHandlerIO(int fd, FDMultiplexer::funcparam_t& var); +static void TCPIOHandlerIO(int fileDesc, FDMultiplexer::funcparam_t& var); static void TCPIOHandlerStateChange(IOState oldstate, IOState newstate, std::shared_ptr& pid) { @@ -770,11 +774,11 @@ static void TCPIOHandlerStateChange(IOState oldstate, IOState newstate, std::sha } } -static void TCPIOHandlerIO(int fd, FDMultiplexer::funcparam_t& var) +static void TCPIOHandlerIO(int fileDesc, FDMultiplexer::funcparam_t& var) { - std::shared_ptr pid = boost::any_cast>(var); + auto pid = boost::any_cast>(var); assert(pid->tcphandler); - assert(fd == pid->tcphandler->getDescriptor()); + assert(fileDesc == pid->tcphandler->getDescriptor()); IOState newstate = IOState::Done; TCPLOG(pid->tcpsock, "TCPIOHandlerIO: lowState " << int(pid->lowState) << endl); @@ -886,9 +890,9 @@ void checkFastOpenSysctl([[maybe_unused]] bool active, [[maybe_unused]] Logr::lo void checkTFOconnect(Logr::log_t log) { try { - Socket s(AF_INET, SOCK_STREAM); - s.setNonBlocking(); - s.setFastOpenConnect(); + Socket socket(AF_INET, SOCK_STREAM); + socket.setNonBlocking(); + socket.setFastOpenConnect(); } catch (const NetworkError& e) { SLOG(g_log << Logger::Error << "tcp-fast-open-connect enabled but returned error: " << e.what() << endl, @@ -906,7 +910,7 @@ LWResult::Result asendtcp(const PacketBuffer& data, shared_ptr& ha pident->outMSG = data; pident->highState = TCPAction::DoingWrite; - IOState state; + IOState state = IOState::Done; try { TCPLOG(pident->tcpsock, "Initial tryWrite: " << pident->outPos << '/' << pident->outMSG.size() << ' ' << " -> "); state = handler->tryWrite(pident->outMSG, pident->outPos, pident->outMSG.size()); @@ -933,12 +937,12 @@ LWResult::Result asendtcp(const PacketBuffer& data, shared_ptr& ha TCPIOHandlerStateChange(pident->lowState, IOState::Done, pident); return LWResult::Result::Timeout; } - else if (ret == -1) { // error + if (ret == -1) { // error TCPLOG(pident->tcpsock, "PermanentError" << endl); TCPIOHandlerStateChange(pident->lowState, IOState::Done, pident); return LWResult::Result::PermanentError; } - else if (packet.size() != data.size()) { // main loop tells us what it sent out, or empty in case of an error + if (packet.size() != data.size()) { // main loop tells us what it sent out, or empty in case of an error // fd housekeeping done by TCPIOHandlerIO TCPLOG(pident->tcpsock, "PermanentError size mismatch" << endl); return LWResult::Result::PermanentError; @@ -955,7 +959,7 @@ LWResult::Result arecvtcp(PacketBuffer& data, const size_t len, shared_ptrgetDescriptor(), "calling tryRead() " << len << endl); state = handler->tryRead(data, pos, len); @@ -1003,12 +1007,12 @@ LWResult::Result arecvtcp(PacketBuffer& data, const size_t len, shared_ptrlowState, IOState::Done, pident); return LWResult::Result::Timeout; } - else if (ret == -1) { + if (ret == -1) { TCPLOG(pident->tcpsock, "PermanentError" << endl); TCPIOHandlerStateChange(pident->lowState, IOState::Done, pident); return LWResult::Result::PermanentError; } - else if (data.empty()) { // error, EOF or other + if (data.empty()) { // error, EOF or other // fd housekeeping done by TCPIOHandlerIO TCPLOG(pident->tcpsock, "EOF" << endl); return LWResult::Result::PermanentError; @@ -1045,11 +1049,11 @@ void makeTCPServerSockets(deferredAdd_t& deferredAdds, std::set& tcpSockets int err = errno; SLOG(g_log << Logger::Error << "Setsockopt failed for TCP listening socket" << endl, log->error(Logr::Critical, err, "Setsockopt failed for TCP listening socket")); - exit(1); + _exit(1); } if (address.sin6.sin6_family == AF_INET6 && setsockopt(socketFd, IPPROTO_IPV6, IPV6_V6ONLY, &tmp, sizeof(tmp)) < 0) { int err = errno; - SLOG(g_log << Logger::Error << "Failed to set IPv6 socket to IPv6 only, continuing anyhow: " << strerror(err) << endl, + SLOG(g_log << Logger::Error << "Failed to set IPv6 socket to IPv6 only, continuing anyhow: " << stringerror(err) << endl, log->error(Logr::Error, err, "Failed to set IPv6 socket to IPv6 only, continuing anyhow")); } @@ -1089,7 +1093,7 @@ void makeTCPServerSockets(deferredAdd_t& deferredAdds, std::set& tcpSockets #ifdef TCP_FASTOPEN if (setsockopt(socketFd, IPPROTO_TCP, TCP_FASTOPEN, &SyncRes::s_tcp_fast_open, sizeof SyncRes::s_tcp_fast_open) < 0) { int err = errno; - SLOG(g_log << Logger::Error << "Failed to enable TCP Fast Open for listening socket: " << strerror(err) << endl, + SLOG(g_log << Logger::Error << "Failed to enable TCP Fast Open for listening socket: " << stringerror(err) << endl, log->error(Logr::Error, err, "Failed to enable TCP Fast Open for listening socket")); } #else @@ -1099,7 +1103,7 @@ void makeTCPServerSockets(deferredAdd_t& deferredAdds, std::set& tcpSockets } socklen_t socklen = address.sin4.sin_family == AF_INET ? sizeof(address.sin4) : sizeof(address.sin6); - if (::bind(socketFd, (struct sockaddr*)&address, socklen) < 0) { + if (::bind(socketFd, reinterpret_cast(&address), socklen) < 0) { throw PDNSException("Binding TCP server socket for " + address.toStringWithPort() + ": " + stringerror()); } diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 445482b95265..cfdf570f5c81 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -824,7 +824,7 @@ extern thread_local rec::TCounters t_Counters; class TCPConnection : public boost::noncopyable { public: - TCPConnection(int fd, const ComboAddress& addr); + TCPConnection(int fileDesc, const ComboAddress& addr); ~TCPConnection(); int getFD() const From 032240be54d40a4aaf4d26302de44099a7397854 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 17 May 2023 14:06:17 +0200 Subject: [PATCH 194/909] Reformat --- pdns/recursordist/rec-tcp.cc | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index ba84ff4e1083..193979fcc794 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -180,7 +180,8 @@ class RunningTCPQuestionGuard RunningTCPQuestionGuard(RunningTCPQuestionGuard&&) = delete; RunningTCPQuestionGuard& operator=(const RunningTCPQuestionGuard&) = default; RunningTCPQuestionGuard& operator=(RunningTCPQuestionGuard&&) = delete; - RunningTCPQuestionGuard(int fileDesc) : d_fd(fileDesc) {} + RunningTCPQuestionGuard(int fileDesc) : + d_fd(fileDesc) {} ~RunningTCPQuestionGuard() { if (d_fd != -1) { @@ -270,7 +271,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v /* note that if the proxy header used a 'LOCAL' command, the original source and destination are untouched so everything should be fine */ conn->d_mappedSource = conn->d_source; if (t_proxyMapping) { - if (const auto *iter = t_proxyMapping->lookup(conn->d_source)) { + if (const auto* iter = t_proxyMapping->lookup(conn->d_source)) { conn->d_mappedSource = iter->second.address; ++iter->second.stats.netmaskMatches; } @@ -377,7 +378,9 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v all queries sent over this connection */ comboWriter->d_proxyProtocolValues = conn->proxyProtocolValues; - struct timeval start{}; + struct timeval start + { + }; Utility::gettimeofday(&start, nullptr); DNSName qname; @@ -557,7 +560,9 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v bool hadError = sendResponseOverTCP(comboWriter, response); finishTCPReply(comboWriter, hadError, false); - struct timeval now{}; + struct timeval now + { + }; Utility::gettimeofday(&now, nullptr); uint64_t spentUsec = uSec(now - start); t_Counters.at(rec::Histogram::cumulativeAnswers)(spentUsec); @@ -642,7 +647,7 @@ void handleNewTCPQuestion(int fileDesc, [[maybe_unused]] FDMultiplexer::funcpara bool fromProxyProtocolSource = expectProxyProtocol(addr); ComboAddress mappedSource = addr; if (!fromProxyProtocolSource && t_proxyMapping) { - if (const auto *iter = t_proxyMapping->lookup(addr)) { + if (const auto* iter = t_proxyMapping->lookup(addr)) { mappedSource = iter->second.address; ++iter->second.stats.netmaskMatches; } @@ -694,7 +699,9 @@ void handleNewTCPQuestion(int fileDesc, [[maybe_unused]] FDMultiplexer::funcpara tcpConn->state = TCPConnection::BYTE0; } - struct timeval ttd{}; + struct timeval ttd + { + }; Utility::gettimeofday(&ttd, nullptr); ttd.tv_sec += g_tcpTimeout; From b4a5be57217f21091a973f39643bf58442ff9875 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 17 May 2023 14:16:05 +0200 Subject: [PATCH 195/909] Tweaks --- pdns/recursordist/rec-tcp.cc | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 193979fcc794..d814d5721696 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -87,7 +87,7 @@ static void terminateTCPConnection(int fileDesc) static void sendErrorOverTCP(std::unique_ptr& comboWriter, int rcode) { std::vector packet; - if (comboWriter->d_mdp.d_header.qdcount == 0) { + if (comboWriter->d_mdp.d_header.qdcount == 0U) { /* header-only */ packet.resize(sizeof(dnsheader)); } @@ -370,7 +370,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v dest.reset(); dest.sin4.sin_family = conn->d_remote.sin4.sin_family; socklen_t len = dest.getSocklen(); - getsockname(conn->getFD(), reinterpret_cast(&dest), &len); // if this fails, we're ok with it + getsockname(conn->getFD(), reinterpret_cast(&dest), &len); // if this fails, we're ok with it NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) comboWriter->setLocal(dest); // the address we received the query on comboWriter->setDestination(conn->d_destination); // the address we assume the query is received on, might be set by proxy protocol comboWriter->setMappedSource(conn->d_mappedSource); // the address we assume the query is coming from after table based mapping @@ -402,7 +402,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v logQuery = t_protobufServers.servers && luaconfsLocal->protobufExportConfig.logQueries; comboWriter->d_logResponse = t_protobufServers.servers && luaconfsLocal->protobufExportConfig.logResponses; - if (needECS || (t_pdl && (t_pdl->d_gettag_ffi || t_pdl->d_gettag)) || comboWriter->d_mdp.d_header.opcode == Opcode::Notify) { + if (needECS || (t_pdl && (t_pdl->d_gettag_ffi || t_pdl->d_gettag)) || comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { try { EDNSOptionViewMap ednsOptions; @@ -491,7 +491,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v } return; } - if (comboWriter->d_mdp.d_header.opcode != Opcode::Query && comboWriter->d_mdp.d_header.opcode != Opcode::Notify) { + if (comboWriter->d_mdp.d_header.opcode != static_cast(Opcode::Query) && comboWriter->d_mdp.d_header.opcode != static_cast(Opcode::Notify)) { t_Counters.at(rec::Counter::ignoredCount)++; if (g_logCommonErrors) { SLOG(g_log << Logger::Error << "Ignoring unsupported opcode " << Opcode::to_s(comboWriter->d_mdp.d_header.opcode) << " from TCP client " << comboWriter->getRemote() << " on server socket!" << endl, @@ -501,7 +501,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v tcpGuard.keep(); return; } - if (dnsheader->qdcount == 0) { + if (dnsheader->qdcount == 0U) { t_Counters.at(rec::Counter::emptyQueriesCount)++; if (g_logCommonErrors) { SLOG(g_log << Logger::Error << "Ignoring empty (qdcount == 0) query from " << comboWriter->getRemote() << " on server socket!" << endl, @@ -517,7 +517,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v ++t_Counters.at(rec::Counter::qcounter); ++t_Counters.at(rec::Counter::tcpqcounter); - if (comboWriter->d_mdp.d_header.opcode == Opcode::Notify) { + if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { if (!t_allowNotifyFrom || !t_allowNotifyFrom->match(comboWriter->d_mappedSource)) { if (!g_quiet) { SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", address not matched by allow-notify-from" << endl, @@ -542,7 +542,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v string response; RecursorPacketCache::OptPBData pbData{boost::none}; - if (comboWriter->d_mdp.d_header.opcode == Opcode::Query) { + if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Query)) { /* It might seem like a good idea to skip the packet cache lookup if we know that the answer is not cacheable, but it means that the hash would not be computed. If some script decides at a later time to mark back the answer as cacheable we would cache it with a wrong tag, so better safe than sorry. */ @@ -586,7 +586,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v } // cache hit } // query opcode - if (comboWriter->d_mdp.d_header.opcode == Opcode::Notify) { + if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { if (!g_quiet) { SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " got NOTIFY for " << qname.toLogString() << " from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << endl, g_slogtcpin->info(Logr::Notice, "Got NOTIFY", "qname", Logging::Loggable(qname), "source", Logging::Loggable(comboWriter->d_source), "remote", Logging::Loggable(comboWriter->d_remote))); @@ -626,7 +626,7 @@ void handleNewTCPQuestion(int fileDesc, [[maybe_unused]] FDMultiplexer::funcpara { ComboAddress addr; socklen_t addrlen = sizeof(addr); - int newsock = accept(fileDesc, reinterpret_cast(&addr), &addrlen); + int newsock = accept(fileDesc, reinterpret_cast(&addr), &addrlen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) if (newsock >= 0) { if (MT->numProcesses() > g_maxMThreads) { t_Counters.at(rec::Counter::overCapacityDrops)++; @@ -687,7 +687,7 @@ void handleNewTCPQuestion(int fileDesc, [[maybe_unused]] FDMultiplexer::funcpara tcpConn->d_destination.reset(); tcpConn->d_destination.sin4.sin_family = addr.sin4.sin_family; socklen_t len = tcpConn->d_destination.getSocklen(); - getsockname(tcpConn->getFD(), reinterpret_cast(&tcpConn->d_destination), &len); // if this fails, we're ok with it + getsockname(tcpConn->getFD(), reinterpret_cast(&tcpConn->d_destination), &len); // if this fails, we're ok with it NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) tcpConn->d_mappedSource = mappedSource; if (fromProxyProtocolSource) { @@ -784,8 +784,8 @@ static void TCPIOHandlerStateChange(IOState oldstate, IOState newstate, std::sha static void TCPIOHandlerIO(int fileDesc, FDMultiplexer::funcparam_t& var) { auto pid = boost::any_cast>(var); - assert(pid->tcphandler); - assert(fileDesc == pid->tcphandler->getDescriptor()); + assert(pid->tcphandler); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay): def off assert triggers it + assert(fileDesc == pid->tcphandler->getDescriptor()); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay) idem IOState newstate = IOState::Done; TCPLOG(pid->tcpsock, "TCPIOHandlerIO: lowState " << int(pid->lowState) << endl); @@ -1110,7 +1110,7 @@ void makeTCPServerSockets(deferredAdd_t& deferredAdds, std::set& tcpSockets } socklen_t socklen = address.sin4.sin_family == AF_INET ? sizeof(address.sin4) : sizeof(address.sin6); - if (::bind(socketFd, reinterpret_cast(&address), socklen) < 0) { + if (::bind(socketFd, reinterpret_cast(&address), socklen) < 0) { // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) throw PDNSException("Binding TCP server socket for " + address.toStringWithPort() + ": " + stringerror()); } From 27edede4eb7decfcfc6af5fcc7e6f2b662e6e529 Mon Sep 17 00:00:00 2001 From: phonedph1 <20867105+phonedph1@users.noreply.github.com> Date: Thu, 18 May 2023 09:19:59 -0600 Subject: [PATCH 196/909] Update rules-actions.rst --- pdns/dnsdistdist/docs/rules-actions.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index 1a44b838aea5..be3dffaa3f38 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -1291,7 +1291,7 @@ The following actions exist. :param int maxqps: The QPS limit -.. function:: QPSPoolAction(maxqps, poolname) +.. function:: QPSPoolAction(maxqps, poolname [, stop]) .. versionchanged:: 1.8.0 Added the ``stop`` optional parameter. From 6f1bb66b685ea467e94d6b06f443186e0dd80afd Mon Sep 17 00:00:00 2001 From: phonedph1 <20867105+phonedph1@users.noreply.github.com> Date: Thu, 18 May 2023 09:23:43 -0600 Subject: [PATCH 197/909] Update dnsdist-console.cc --- pdns/dnsdist-console.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index 7eff465774b0..e3e5bcf3258c 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -627,7 +627,7 @@ const std::vector g_consoleKeywords{ { "NotRule", true, "selector", "Matches the traffic if the selector rule does not match" }, { "OpcodeRule", true, "code", "Matches queries with opcode code. code can be directly specified as an integer, or one of the built-in DNSOpcodes" }, { "OrRule", true, "selectors", "Matches the traffic if one or more of the the selectors rules does match" }, - { "PoolAction", true, "poolname", "set the packet into the specified pool" }, + { "PoolAction", true, "poolname [, stop]", "set the packet into the specified pool" }, { "PoolAvailableRule", true, "poolname", "Check whether a pool has any servers available to handle queries" }, { "PoolOutstandingRule", true, "poolname, limit", "Check whether a pool has outstanding queries above limit" }, { "printDNSCryptProviderFingerprint", true, "\"/path/to/providerPublic.key\"", "display the fingerprint of the provided resolver public key" }, @@ -639,7 +639,7 @@ const std::vector g_consoleKeywords{ { "QNameSetRule", true, "set", "Matches if the set contains exact qname" }, { "QNameWireLengthRule", true, "min, max", "matches if the qname's length on the wire is less than `min` or more than `max` bytes" }, { "QPSAction", true, "maxqps", "Drop a packet if it does exceed the maxqps queries per second limits. Letting the subsequent rules apply otherwise" }, - { "QPSPoolAction", true, "maxqps, poolname", "Send the packet into the specified pool only if it does not exceed the maxqps queries per second limits. Letting the subsequent rules apply otherwise" }, + { "QPSPoolAction", true, "maxqps, poolname [, stop]", "Send the packet into the specified pool only if it does not exceed the maxqps queries per second limits. Letting the subsequent rules apply otherwise" }, { "QTypeRule", true, "qtype", "matches queries with the specified qtype" }, { "RCodeAction", true, "rcode", "Reply immediately by turning the query into a response with the specified rcode" }, { "RCodeRule", true, "rcode", "matches responses with the specified rcode" }, From 2d28941103f3a651f9818e99d8c778f3c35a0be8 Mon Sep 17 00:00:00 2001 From: Italo Cunha Date: Wed, 24 May 2023 17:23:05 -0300 Subject: [PATCH 198/909] Update base Debian version in Docker docs A minor patch to https://github.com/PowerDNS/pdns/pull/11961 --- Docker-README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Docker-README.md b/Docker-README.md index 8f9691368ed6..504d89b066bc 100644 --- a/Docker-README.md +++ b/Docker-README.md @@ -2,7 +2,7 @@ https://hub.docker.com/u/powerdns offers automatic builds of dnsdist, Auth and Recursor, from the pdns.git master branch. -The images are based on Debian Buster (slim). +The images are based on Debian Bullseye (slim). The Dockerfiles: @@ -57,4 +57,4 @@ There are multiple ways of dealing with these restrictions if you encounter them * dnsdist: `setLocal()` * Auth & Recursor: `local-address` and/or `local-port` -Note: Docker Engine 20.10.0 (released december 2020) removed the need to set the `NET_BIND_SERVICE` capability when attempting to bind to a privileged port. +Note: Docker Engine 20.10.0 (released december 2020) removed the need to set the `NET_BIND_SERVICE` capability when attempting to bind to a privileged port. From 4c32e94c393ef9b4d18d06022b3ae5c972712f03 Mon Sep 17 00:00:00 2001 From: Bishakh Ghosh Date: Fri, 26 May 2023 12:14:55 +0530 Subject: [PATCH 199/909] Documentation fix in HTTP API - zone.rst --- docs/http-api/zone.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/http-api/zone.rst b/docs/http-api/zone.rst index 3e6addc95ffc..3adb26042a47 100644 --- a/docs/http-api/zone.rst +++ b/docs/http-api/zone.rst @@ -121,7 +121,7 @@ Creating new RRset .. code-block:: http - PATCH /api/v1/servers/localhost/example.org. HTTP/1.1 + PATCH /api/v1/servers/localhost/zones/example.org. HTTP/1.1 X-API-Key: secret Content-Type: application/json @@ -138,7 +138,7 @@ Deleting a RRset .. code-block:: http - PATCH /api/v1/servers/localhost/example.org. HTTP/1.1 + PATCH /api/v1/servers/localhost/zones/example.org. HTTP/1.1 X-API-Key: secret Content-Type: application/json From 7a4858f8d2e7b977a7d42789f97e1224cb1c1eaa Mon Sep 17 00:00:00 2001 From: Alexis Romero Date: Fri, 26 May 2023 15:51:46 +0200 Subject: [PATCH 200/909] gh actions: enable ipv6 in docker containers --- .github/workflows/build-and-test-all.yml | 15 +++++++++++---- tasks.py | 1 - 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 3e0c3fe1be4e..4db01a49945f 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -28,7 +28,7 @@ jobs: SANITIZERS: asan+ubsan UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" UNIT_TESTS: yes - PDNS_TEST_NO_IPV6: yes + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 outputs: clang-tidy-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: @@ -97,6 +97,7 @@ jobs: SANITIZERS: ${{ matrix.sanitizers }} UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" UNIT_TESTS: yes + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 defaults: run: working-directory: ./pdns/recursordist/ @@ -168,6 +169,7 @@ jobs: SANITIZERS: ${{ matrix.sanitizers }} UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" UNIT_TESTS: yes + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 defaults: run: working-directory: ./pdns/dnsdistdist/ @@ -231,6 +233,7 @@ jobs: ASAN_OPTIONS: detect_leaks=0 TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ env.REPO_HOME }}/pdns/dnsdistdist/dnsdist-tsan.supp" AUTH_BACKEND_IP_ADDR: "172.17.0.1" + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 strategy: matrix: include: @@ -282,7 +285,7 @@ jobs: LDAPHOST: ldap://ldapserver/ ODBCINI: /github/home/.odbc.ini AUTH_BACKEND_IP_ADDR: "172.17.0.1" - SKIP_IPV6_TESTS: yes + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 strategy: matrix: include: @@ -391,6 +394,7 @@ jobs: env: UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" ASAN_OPTIONS: detect_leaks=0 + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 steps: - uses: actions/checkout@v3 with: @@ -420,6 +424,7 @@ jobs: UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" ASAN_OPTIONS: detect_leaks=0 TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ env.REPO_HOME }}/pdns/recursordist/recursor-tsan.supp" + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 steps: - uses: actions/checkout@v3 with: @@ -451,7 +456,7 @@ jobs: UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp' ASAN_OPTIONS: detect_leaks=0 TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ env.REPO_HOME }}/pdns/recursordist/recursor-tsan.supp" - SKIP_IPV6_TESTS: yes + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 steps: # - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3.1.0 @@ -485,6 +490,7 @@ jobs: UBSAN_OPTIONS: 'print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp' ASAN_OPTIONS: detect_leaks=0 TSAN_OPTIONS: "halt_on_error=1:suppressions=${{ env.REPO_HOME }}/pdns/recursordist/recursor-tsan.supp" + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 steps: - uses: actions/checkout@v3 with: @@ -514,7 +520,7 @@ jobs: TSAN_OPTIONS: "halt_on_error=1:intercept_send=0:suppressions=${{ env.REPO_HOME }}/pdns/dnsdistdist/dnsdist-tsan.supp" # IncludeDir tests are disabled because of a weird interaction between TSAN and these tests which ever only happens on GH actions SKIP_INCLUDEDIR_TESTS: yes - SKIP_IPV6_TESTS: yes + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 steps: - uses: actions/checkout@v3 with: @@ -534,6 +540,7 @@ jobs: runs-on: ubuntu-20.04 container: image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + options: --sysctl net.ipv6.conf.all.disable_ipv6=0 steps: - uses: actions/checkout@v3 with: diff --git a/tasks.py b/tasks.py index 426a428f3b2e..e78e0a55212e 100644 --- a/tasks.py +++ b/tasks.py @@ -776,7 +776,6 @@ def test_auth_backend(c, backend): if os.getenv('SKIP_IPV6_TESTS'): pdns_auth_env_vars += ' context=noipv6' with c.cd('regression-tests.nobackend'): - c.run(f'echo {pdns_auth_env_vars}') c.run(f'{pdns_auth_env_vars} ./runtests') c.run('/opt/pdns-auth/bin/pdnsutil test-algorithms') return From 1ad0d42532e4934290bcf251f9e9865cc4519f01 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Sun, 28 May 2023 22:39:33 +0200 Subject: [PATCH 201/909] pdnsutil: if user pushes unknown key in response to "problem with zone" prompt, do not throw away their changes --- pdns/pdnsutil.cc | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 18b10c24bfe2..6e0466a9705f 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -1264,16 +1264,17 @@ static int editZone(const DNSName &zone, const PDNSColors& col) { cerr << col.red() << col.bold() << "There was a problem with your zone" << col.rst() << "\nOptions are: (e)dit your changes, (r)etry with original zone, (a)pply change anyhow, (q)uit: " << std::flush; int c=read1char(); cerr<<"\n"; - if(c!='a') + if(c=='e') { post.clear(); - if(c=='e') goto editMore; - else if(c=='r') + } else if(c=='r') { + post.clear(); goto editAgain; - else if(c=='q') + } else if(c=='q') { return EXIT_FAILURE; - else if(c!='a') + } else if(c!='a') { goto reAsk; + } } From 0908f75786285456ccd7e64c5966514b72da29dd Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 30 May 2023 09:57:13 +0200 Subject: [PATCH 202/909] rec: Introduce a way to completely disable root-refresh --- pdns/recursordist/docs/appendices/FAQ.rst | 22 +++++++++++++--------- pdns/recursordist/docs/settings.rst | 6 +++++- pdns/recursordist/reczones.cc | 6 +++--- pdns/recursordist/syncres.cc | 3 +++ 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/pdns/recursordist/docs/appendices/FAQ.rst b/pdns/recursordist/docs/appendices/FAQ.rst index d06399833298..7d6110db5e95 100644 --- a/pdns/recursordist/docs/appendices/FAQ.rst +++ b/pdns/recursordist/docs/appendices/FAQ.rst @@ -66,19 +66,23 @@ Handling of root hints On startup, the :program:`Recursor` uses root hints to resolve the names and addresses of the root name servers and puts the record sets found into the record cache. This is needed to be able to resolve names, as the recursive algorithm starts at the root (using cached data) and then tries to resolve delegations until it finds the name servers that are authoritative for the domain in question. -If the :ref:`setting-hint-file` is not set, it wil use a compiled-in table as root hints. -Starting with version 4.6.2, if :ref:`setting-hint-file` is set to ``no``, the :program:`Recursor` will not fill the cache with root data. -This can be used in special cases, e.g. when all queries are forwarded. +If the :ref:`setting-hint-file` is not set, :program:`Recursor` wil use a compiled-in table as root hints. -Note that the root hints and resolved root data can differ if the root hints are outdated. -As long as at least one root server mentioned in the root hints can be contacted, this mechanism will produce the desired record sets corresponding to the actual root server data. - -Periodically, based on the :ref:`setting-max-cache-ttl`, the :program:`Recursor` will refetch the root data using data in its cache. +Periodically, based on the :ref:`setting-max-cache-ttl`, the :program:`Recursor` will refetch the root data using data in its cache by doing a `. NS` query. If that does not succeed, it wil fall back to using the root hints to fill the cache with root data. Prior to version 4.7.0, the period for re-fetching root data was :ref:`setting-max-cache-ttl` divided by 12, with a minimum of 10 seconds. Starting with version 4.7.0, the period is adaptive, starting at 80% of :ref:`setting-max-cache-ttl`, reducing the interval on failure. -There is another detail: after refreshing the root records, the :program:`Recursor` will resolve the ``NS`` records for the top level domain of the root servers. +The root hints and resolved root data can differ if the root hints are outdated. +As long as at least one root server mentioned in the root hints can be contacted, the periodic refresh will produce the desired record sets corresponding to the current up-to-date root server data. + +Starting with version 4.6.2, if :ref:`setting-hint-file` is set to ``no``, the :program:`Recursor` will not prime the cache with root data obtained from hints, but will still do the periodic refresh. +A (recursive) forward configuration is be needed to make the periodic refresh work. + +Starting with version 4.9, setting :ref:`setting-hint-file` to ``no-refresh`` disables both the initial reading of the hints and the periodic refresh of cached root data. +This prevents :program:`Recursor` from resolving names by itself, so it is only useful in cases where all queries are forwarded. + +With versions older than 4.8, there is another detail: after refreshing the root records, the :program:`Recursor` will resolve the ``NS`` records for the top level domain of the root servers. For example, in the default setup the root name servers are called ``[a-m].root-servers.net``, so the :program:`Recursor` will resolve the name servers of the ``.net`` domain. -This is needed to correctly determine zone cuts to be able to decide if the ``.root-servers.net`` domain is DNSSEC protected. +This is needed to correctly determine zone cuts to be able to decide if the ``.root-servers.net`` domain is DNSSEC protected. Newer versions solve this by querying the needed information top-down. diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 427b39904f73..106f5432bd0c 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -926,10 +926,14 @@ If set, EDNS options in incoming queries are extracted and passed to the :func:` Introduced the value ``no`` to disable root-hints processing. +.. versionchanged:: 4.9.0 + + Introduced the value ``no-refresh`` to disable both root-hints processing and periodic refresh of the cached root `NS` records. + If set, the root-hints are read from this file. If empty, the default built-in root hints are used. In some special cases, processing the root hints is not needed, for example when forwarding all queries to another recursor. -For these special cases, it is possible to disable the processing of root hints by setting the value to ``no``. +For these special cases, it is possible to disable the processing of root hints by setting the value to ``no`` or ``no-refresh``. See :ref:`handling-of-root-hints` for more information on root hints handling. .. _setting-ignore-unknown-settings: diff --git a/pdns/recursordist/reczones.cc b/pdns/recursordist/reczones.cc index ba658b19c2be..389dcaee1c0e 100644 --- a/pdns/recursordist/reczones.cc +++ b/pdns/recursordist/reczones.cc @@ -40,10 +40,10 @@ bool primeHints(time_t now) vector nsvec; bool ret = true; - if (hintfile == "no") { + if (hintfile == "no" || hintfile == "no-refresh") { auto log = g_slog->withName("config"); - SLOG(g_log << Logger::Debug << "Priming root disabled by hint-file=no" << endl, - log->info(Logr::Debug, "Priming root disabled by hint-file=no")); + SLOG(g_log << Logger::Debug << "Priming root disabled by hint-file setting" << endl, + log->info(Logr::Debug, "Priming root disabled by hint-file setting")); return ret; } diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 6119a325e991..0e534a3fe02e 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -5863,6 +5863,9 @@ int directResolve(const DNSName& qname, const QType qtype, const QClass qclass, int SyncRes::getRootNS(struct timeval now, asyncresolve_t asyncCallback, unsigned int depth, Logr::log_t log) { + if (::arg()["hint-file"] == "no-refresh") { + return 0; + } SyncRes sr(now); sr.d_prefix = "[getRootNS]"; sr.setDoEDNS0(true); From 6abf49f8dbac05d04cd2d9eb8835dd21339112a1 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 30 May 2023 10:16:52 +0200 Subject: [PATCH 203/909] rec: bound maximum recursion depth to 16. Before #12779, the fixed limit on CNAME chain length (16) effectively worked as recursion depth limit. --- pdns/recursordist/docs/settings.rst | 6 +++++- pdns/recursordist/rec-main.cc | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 427b39904f73..2350117651ad 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -1292,7 +1292,7 @@ This setting, which defaults to 3600 seconds, puts a maximum on the amount of ti ``max-recursion-depth`` ----------------------- - Integer -- Default: 40 +- Default: 16 Total maximum number of internal recursion calls the server may use to answer a single query. 0 means unlimited. @@ -1304,6 +1304,10 @@ If `qname-minimization`_ is enabled, the fallback code in case of a failing reso Before 4.1.0, this settings was unlimited. +.. versionchanged:: 4.9.0 + + Before 4.9.0 this setting's default was 40 and the limit on ``CNAME`` chains (fixed at 16) acted as a bound on he recursion depth. + .. _setting-max-tcp-clients: ``max-tcp-clients`` diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 0e7e3fceb382..81a8fc2a7de9 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2867,7 +2867,7 @@ static void initArgs() ::arg().set("max-ns-per-resolve", "Maximum number of NS records to consider to resolve a name, 0 is no limit") = "13"; ::arg().set("max-ns-address-qperq", "Maximum outgoing NS address queries per query") = "10"; ::arg().set("max-total-msec", "Maximum total wall-clock time per query in milliseconds, 0 for unlimited") = "7000"; - ::arg().set("max-recursion-depth", "Maximum number of internal recursion calls per query, 0 for unlimited") = "40"; + ::arg().set("max-recursion-depth", "Maximum number of internal recursion calls per query, 0 for unlimited") = "16"; ::arg().set("max-udp-queries-per-round", "Maximum number of UDP queries processed per recvmsg() round, before returning back to normal processing") = "10000"; ::arg().set("protobuf-use-kernel-timestamp", "Compute the latency of queries in protobuf messages by using the timestamp set by the kernel when the query was received (when available)") = ""; ::arg().set("distribution-pipe-buffer-size", "Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread") = "0"; From c9a0427b1530bec84c18d8cfca4372e382b2be8a Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 30 May 2023 10:31:32 +0200 Subject: [PATCH 204/909] rec: fix typo in trace message --- pdns/validate.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/validate.cc b/pdns/validate.cc index af4f9d69af54..98edef4a69f3 100644 --- a/pdns/validate.cc +++ b/pdns/validate.cc @@ -953,7 +953,7 @@ vState validateWithKeySet(time_t now, const DNSName& name, const sortedRecords_t auto keysMatchingTag = getByTag(keys, signature->d_tag, signature->d_algorithm, log); if (keysMatchingTag.empty()) { - VLOG(log, name<<"No key provided for "<d_tag<<" and algorithm "<d_algorithm)<d_tag<<" and algorithm "<d_algorithm)< Date: Tue, 30 May 2023 10:39:10 +0200 Subject: [PATCH 205/909] Fix root-priming test, which now depends on a arg being set. --- pdns/recursordist/test-syncres_cc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index f291661e90f1..179d6b0269c0 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -218,6 +218,7 @@ void initSR(bool debug) ::arg().set("version-string", "string reported on version.pdns or version.bind") = "PowerDNS Unit Tests"; ::arg().set("rng") = "auto"; ::arg().set("entropy-source") = "/dev/urandom"; + ::arg().set("hint-file") = ""; } void initSR(std::unique_ptr& sr, bool dnssec, bool debug, time_t fakeNow) From f89d20f5ac1e184e34e963b090edcfbd365694ac Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 30 May 2023 16:02:15 +0200 Subject: [PATCH 206/909] Add the d_orig_ttl sanitization back, there still is a case where it can wrap (which I'm unable to spot right now). --- pdns/recursordist/recursor_cache.cc | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index 8b5b72f908c6..0d237cd75089 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -609,6 +609,12 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, ce.d_ttd = min(maxTTD, static_cast(i.d_ttl)); // XXX this does weird things if TTLs differ in the set ce.d_orig_ttl = ce.d_ttd - ttl_time; + // Even though we record the time the ttd was computed, there still seems to be a case where the computed + // d_orig_ttl can wrap. + // So santize the computed ce.d_orig_ttl to be on the safe side + if (ce.d_orig_ttl < SyncRes::s_minimumTTL || ce.d_orig_ttl > SyncRes::s_maxcachettl) { + ce.d_orig_ttl = SyncRes::s_minimumTTL; + } ce.d_records.push_back(i.getContent()); } From b2d1d86ad632f48fd4ae7dffa26f3eac05a8dce2 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 30 May 2023 17:03:47 +0200 Subject: [PATCH 207/909] auth lmdb: delete duplicate domain entries in deleteDomain --- modules/lmdbbackend/lmdbbackend.cc | 66 ++++++++++++++++-------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 4b5e408bcc28..9363543d8cc6 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1297,56 +1297,62 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) throw DBException(std::string(__PRETTY_FUNCTION__) + " called without a transaction"); } - int transactionDomainId = d_transactiondomainid; - DNSName transactionDomain = d_transactiondomain; - abortTransaction(); - uint32_t id; + LMDBIDvec idvec; - { // get domain id + if (!d_handle_dups) { + // get domain id auto txn = d_tdomains->getROTransaction(); DomainInfo di; - id = txn.get<0>(domain, di); + idvec.push_back(txn.get<0>(domain, di)); + } + else { + auto txn = d_tdomains->getROTransaction(); + + txn.get_multi<0>(domain, idvec); + throw std::runtime_error("in LMDBBackend::deleteDomain, domain was not found"); } - startTransaction(domain, id); + startTransaction(domain, idvec[0]); + for (auto id : idvec) { - { // Remove metadata - auto txn = d_tmeta->getRWTransaction(); - LMDBIDvec ids; + { // Remove metadata + auto txn = d_tmeta->getRWTransaction(); + LMDBIDvec ids; - txn.get_multi<0>(domain, ids); + txn.get_multi<0>(domain, ids); - for (auto& _id : ids) { - txn.del(_id); + for (auto& _id : ids) { + txn.del(_id); + } + + txn.commit(); } - txn.commit(); - } + { // Remove cryptokeys + auto txn = d_tkdb->getRWTransaction(); + LMDBIDvec ids; + txn.get_multi<0>(domain, ids); - { // Remove cryptokeys - auto txn = d_tkdb->getRWTransaction(); - LMDBIDvec ids; - txn.get_multi<0>(domain, ids); + for (auto _id : ids) { + txn.del(_id); + } - for (auto _id : ids) { - txn.del(_id); + txn.commit(); } + // Remove records + commitTransaction(); + startTransaction(domain, id); + + // Remove zone + auto txn = d_tdomains->getRWTransaction(); + txn.del(id); txn.commit(); } - // Remove records - commitTransaction(); - startTransaction(transactionDomain, transactionDomainId); - - // Remove zone - auto txn = d_tdomains->getRWTransaction(); - txn.del(id); - txn.commit(); - return true; } From 38eb2496bacf10df57569d937f6de85b59592c4a Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 30 May 2023 18:50:47 +0200 Subject: [PATCH 208/909] auth lmdb: enforce shards=1 when running in lightning-stream mode --- modules/lmdbbackend/lmdbbackend.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 9363543d8cc6..56bf0327f993 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -673,6 +673,10 @@ LMDBBackend::LMDBBackend(const std::string& suffix) d_random_ids = true; d_handle_dups = true; LMDBLS::s_flag_deleted = true; + + if (atoi(getArg("shards").c_str()) != 1) { + throw std::runtime_error(std::string("running with Lightning Stream support requires shards=1")); + } } bool opened = false; @@ -724,6 +728,11 @@ LMDBBackend::LMDBBackend(const std::string& suffix) MDBOutVal shards; if (!txn->get(pdnsdbi, "shards", shards)) { s_shards = shards.get(); + + if (mustDo("lightning-stream") && s_shards != 1) { + throw std::runtime_error(std::string("running with Lightning Stream support enabled requires a database with exactly 1 shard")); + } + if (s_shards != atoi(getArg("shards").c_str())) { g_log << Logger::Warning << "Note: configured number of lmdb shards (" << atoi(getArg("shards").c_str()) << ") is different from on-disk (" << s_shards << "). Using on-disk shard number" << endl; } From 53fdfae2c0e0aff70bb6ab5a834cffff084fbf7c Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 31 May 2023 09:25:26 +0200 Subject: [PATCH 209/909] only throw when idvec is empty --- modules/lmdbbackend/lmdbbackend.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 56bf0327f993..2357fd2ba72e 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1321,7 +1321,10 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) auto txn = d_tdomains->getROTransaction(); txn.get_multi<0>(domain, idvec); - throw std::runtime_error("in LMDBBackend::deleteDomain, domain was not found"); + + if (idvec.size() == 0) { + throw std::runtime_error("in LMDBBackend::deleteDomain, domain was not found"); + } } startTransaction(domain, idvec[0]); From 76eac3db390d121786d6f3da43e174ff2ebc31f3 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 31 May 2023 09:27:48 +0200 Subject: [PATCH 210/909] Update modules/lmdbbackend/lmdbbackend.cc Co-authored-by: Otto Moerbeek --- modules/lmdbbackend/lmdbbackend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 2357fd2ba72e..d02ef0137b8a 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1322,7 +1322,7 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) txn.get_multi<0>(domain, idvec); - if (idvec.size() == 0) { + if (idvec.empty()) { throw std::runtime_error("in LMDBBackend::deleteDomain, domain was not found"); } } From 2f2cafa93d85e54e8a60b5a118e0c57aec80822f Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 31 May 2023 09:34:02 +0200 Subject: [PATCH 211/909] use d_transactiondomain[id] --- modules/lmdbbackend/lmdbbackend.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index d02ef0137b8a..563522a6aef4 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1306,6 +1306,9 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) throw DBException(std::string(__PRETTY_FUNCTION__) + " called without a transaction"); } + int transactionDomainId = d_transactiondomainid; + DNSName transactionDomain = d_transactiondomain; + abortTransaction(); LMDBIDvec idvec; @@ -1327,7 +1330,7 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) } } - startTransaction(domain, idvec[0]); + startTransaction(transactionDomain, transactionDomainId); for (auto id : idvec) { { // Remove metadata @@ -1357,7 +1360,7 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) // Remove records commitTransaction(); - startTransaction(domain, id); + startTransaction(transactionDomain, transactionDomainId); // Remove zone auto txn = d_tdomains->getRWTransaction(); From 9bd88b4b317aa347e95d723042e4b4098d1b619c Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 31 May 2023 10:25:12 +0200 Subject: [PATCH 212/909] simplify --- modules/lmdbbackend/lmdbbackend.cc | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 563522a6aef4..5d58c436a5b9 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1324,14 +1324,11 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) auto txn = d_tdomains->getROTransaction(); txn.get_multi<0>(domain, idvec); - - if (idvec.empty()) { - throw std::runtime_error("in LMDBBackend::deleteDomain, domain was not found"); - } } - startTransaction(transactionDomain, transactionDomainId); - for (auto id : idvec) { + for (auto id : idvec) { + + startTransaction(domain, id); { // Remove metadata auto txn = d_tmeta->getRWTransaction(); @@ -1360,7 +1357,6 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) // Remove records commitTransaction(); - startTransaction(transactionDomain, transactionDomainId); // Remove zone auto txn = d_tdomains->getRWTransaction(); @@ -1368,6 +1364,8 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) txn.commit(); } + startTransaction(transactionDomain, transactionDomainId); + return true; } From 28b19cd03961e52ea5e7aa091cee5bc8af594c2f Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 31 May 2023 10:33:48 +0200 Subject: [PATCH 213/909] format --- modules/lmdbbackend/lmdbbackend.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 5d58c436a5b9..d6eb3ba0e80c 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1326,8 +1326,8 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) txn.get_multi<0>(domain, idvec); } - for (auto id : idvec) { - + for (auto id : idvec) { + startTransaction(domain, id); { // Remove metadata From 80ad487a185430a2f2878734018fc77803ec3d96 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 31 May 2023 10:33:56 +0200 Subject: [PATCH 214/909] document shards=1 enforcement --- docs/backends/lmdb.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/backends/lmdb.rst b/docs/backends/lmdb.rst index c4a4f939ac43..03ef9623cd0d 100644 --- a/docs/backends/lmdb.rst +++ b/docs/backends/lmdb.rst @@ -137,6 +137,7 @@ Run in Lightning Stream compatible mode. This: * forces ``flag-deleted`` on * forces ``random-ids`` on * handles duplicate entries in databases that can result from domains being added on two Lightning Stream nodes at the same time +* aborts startup if ``shards`` is not set to ``1`` LMDB Structure -------------- From 7dcdce8cafeb1b1fe0c795bc5a8c69909ddd168b Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 9 May 2023 13:15:34 +0200 Subject: [PATCH 215/909] More delinting A set of random files made clean. During this process .clang-tidy.full was also amended a bit. --- pdns/recursordist/rec-taskqueue.cc | 60 +++---- pdns/recursordist/rec-taskqueue.hh | 4 +- pdns/recursordist/taskqueue.cc | 8 +- pdns/recursordist/taskqueue.hh | 36 ++--- pdns/recursordist/ws-recursor.cc | 250 ++++++++++++++++------------- pdns/recursordist/ws-recursor.hh | 10 +- pdns/secpoll.cc | 12 +- pdns/zonemd.cc | 57 ++++--- pdns/zonemd.hh | 32 ++-- 9 files changed, 253 insertions(+), 216 deletions(-) diff --git a/pdns/recursordist/rec-taskqueue.cc b/pdns/recursordist/rec-taskqueue.cc index f805ced72e4c..29cc6d75c889 100644 --- a/pdns/recursordist/rec-taskqueue.cc +++ b/pdns/recursordist/rec-taskqueue.cc @@ -19,6 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + #include "rec-taskqueue.hh" #include "taskqueue.hh" #include "lock.hh" @@ -30,8 +31,8 @@ class TimedSet { public: - TimedSet(time_t t) : - d_expiry_seconds(t) + TimedSet(time_t time) : + d_expiry_seconds(time) { } @@ -40,11 +41,11 @@ class TimedSet // This purge is relatively cheap, as we're walking an ordered index uint64_t erased = 0; auto& ind = d_set.template get(); - auto it = ind.begin(); - while (it != ind.end()) { - if (it->d_ttd < now) { + auto iter = ind.begin(); + while (iter != ind.end()) { + if (iter->d_ttd < now) { ++erased; - it = ind.erase(it); + iter = ind.erase(iter); } else { break; @@ -79,17 +80,18 @@ class TimedSet private: struct Entry { - Entry(const pdns::ResolveTask& task, time_t ttd) : - d_task(task), d_ttd(ttd) {} + Entry(pdns::ResolveTask task, time_t ttd) : + d_task(std::move(task)), d_ttd(ttd) {} pdns::ResolveTask d_task; time_t d_ttd; }; - typedef multi_index_container, member>, - ordered_non_unique, member>>> - timed_set_t; + using timed_set_t = multi_index_container< + Entry, + indexed_by, + member>, + ordered_non_unique, + member>>>; timed_set_t d_set; time_t d_expiry_seconds; unsigned int d_count{0}; @@ -116,15 +118,15 @@ static void resolve(const struct timeval& now, bool logErrors, const pdns::Resol { auto log = g_slog->withName("taskq")->withValues("name", Logging::Loggable(task.d_qname), "qtype", Logging::Loggable(QType(task.d_qtype).toString()), "netmask", Logging::Loggable(task.d_netmask.empty() ? "" : task.d_netmask.toString())); const string msg = "Exception while running a background ResolveTask"; - SyncRes sr(now); + SyncRes resolver(now); vector ret; - sr.setRefreshAlmostExpired(task.d_refreshMode); - sr.setQuerySource(task.d_netmask); - bool ex = true; + resolver.setRefreshAlmostExpired(task.d_refreshMode); + resolver.setQuerySource(task.d_netmask); + bool exceptionOccurred = true; try { log->info(Logr::Debug, "resolving", "refresh", Logging::Loggable(task.d_refreshMode)); - int res = sr.beginResolve(task.d_qname, QType(task.d_qtype), QClass::IN, ret); - ex = false; + int res = resolver.beginResolve(task.d_qname, QType(task.d_qtype), QClass::IN, ret); + exceptionOccurred = false; log->info(Logr::Debug, "done", "rcode", Logging::Loggable(res), "records", Logging::Loggable(ret.size())); } catch (const std::exception& e) { @@ -146,7 +148,7 @@ static void resolve(const struct timeval& now, bool logErrors, const pdns::Resol catch (...) { log->error(Logr::Error, msg, "Unexpectec exception"); } - if (ex) { + if (exceptionOccurred) { if (task.d_refreshMode) { ++s_almost_expired_tasks.exceptions; } @@ -168,15 +170,15 @@ static void tryDoT(const struct timeval& now, bool logErrors, const pdns::Resolv { auto log = g_slog->withName("taskq")->withValues("method", Logging::Loggable("tryDoT"), "name", Logging::Loggable(task.d_qname), "qtype", Logging::Loggable(QType(task.d_qtype).toString()), "ip", Logging::Loggable(task.d_ip)); const string msg = "Exception while running a background tryDoT task"; - SyncRes sr(now); + SyncRes resolver(now); vector ret; - sr.setRefreshAlmostExpired(false); - bool ex = true; + resolver.setRefreshAlmostExpired(false); + bool exceptionOccurred = true; try { log->info(Logr::Debug, "trying DoT"); - bool ok = sr.tryDoT(task.d_qname, QType(task.d_qtype), task.d_nsname, task.d_ip, now.tv_sec); - ex = false; - log->info(Logr::Debug, "done", "ok", Logging::Loggable(ok)); + bool tryOK = resolver.tryDoT(task.d_qname, QType(task.d_qtype), task.d_nsname, task.d_ip, now.tv_sec); + exceptionOccurred = false; + log->info(Logr::Debug, "done", "ok", Logging::Loggable(tryOK)); } catch (const std::exception& e) { log->error(Logr::Error, msg, e.what()); @@ -197,7 +199,7 @@ static void tryDoT(const struct timeval& now, bool logErrors, const pdns::Resolv catch (...) { log->error(Logr::Error, msg, "Unexpected exception"); } - if (ex) { + if (exceptionOccurred) { ++s_resolve_tasks.exceptions; } else { @@ -262,7 +264,7 @@ void pushResolveTask(const DNSName& qname, uint16_t qtype, time_t now, time_t de } } -bool pushTryDoTTask(const DNSName& qname, uint16_t qtype, const ComboAddress& ip, time_t deadline, const DNSName& nsname) +bool pushTryDoTTask(const DNSName& qname, uint16_t qtype, const ComboAddress& ipAddress, time_t deadline, const DNSName& nsname) { if (SyncRes::isUnsupported(qtype)) { auto log = g_slog->withName("taskq")->withValues("name", Logging::Loggable(qname), "qtype", Logging::Loggable(QType(qtype).toString())); @@ -270,7 +272,7 @@ bool pushTryDoTTask(const DNSName& qname, uint16_t qtype, const ComboAddress& ip return false; } - pdns::ResolveTask task{qname, qtype, deadline, false, tryDoT, ip, nsname, {}}; + pdns::ResolveTask task{qname, qtype, deadline, false, tryDoT, ipAddress, nsname, {}}; bool pushed = s_taskQueue.lock()->queue.push(std::move(task)); if (pushed) { ++s_almost_expired_tasks.pushed; diff --git a/pdns/recursordist/rec-taskqueue.hh b/pdns/recursordist/rec-taskqueue.hh index 67bc6e0285a6..425cb55ac05f 100644 --- a/pdns/recursordist/rec-taskqueue.hh +++ b/pdns/recursordist/rec-taskqueue.hh @@ -22,7 +22,7 @@ #pragma once #include -#include +#include class DNSName; union ComboAddress; @@ -36,7 +36,7 @@ void runTasks(size_t max, bool logErrors); bool runTaskOnce(bool logErrors); void pushAlmostExpiredTask(const DNSName& qname, uint16_t qtype, time_t deadline, const Netmask& netmask); void pushResolveTask(const DNSName& qname, uint16_t qtype, time_t now, time_t deadline); -bool pushTryDoTTask(const DNSName& qname, uint16_t qtype, const ComboAddress& ip, time_t deadline, const DNSName& nsname); +bool pushTryDoTTask(const DNSName& qname, uint16_t qtype, const ComboAddress& ipAddress, time_t deadline, const DNSName& nsname); void taskQueueClear(); pdns::ResolveTask taskQueuePop(); diff --git a/pdns/recursordist/taskqueue.cc b/pdns/recursordist/taskqueue.cc index 8382cc4f4bc0..d18a8cb8c9ca 100644 --- a/pdns/recursordist/taskqueue.cc +++ b/pdns/recursordist/taskqueue.cc @@ -45,14 +45,14 @@ ResolveTask TaskQueue::pop() return ret; } -bool ResolveTask::run(bool logErrors) +bool ResolveTask::run(bool logErrors) const { if (d_func == nullptr) { auto log = g_slog->withName("taskq")->withValues("name", Logging::Loggable(d_qname), "qtype", Logging::Loggable(QType(d_qtype).toString())); log->error(Logr::Debug, "null task"); return false; } - struct timeval now; + struct timeval now{}; Utility::gettimeofday(&now); if (d_deadline >= now.tv_sec) { d_func(now, logErrors, *this); @@ -70,8 +70,8 @@ bool ResolveTask::run(bool logErrors) namespace boost { -size_t hash_value(const ComboAddress& a) +size_t hash_value(const ComboAddress& address) { - return ComboAddress::addressOnlyHash()(a); + return ComboAddress::addressOnlyHash()(address); } } diff --git a/pdns/recursordist/taskqueue.hh b/pdns/recursordist/taskqueue.hh index ace34d8d8df8..6f174e05fec1 100644 --- a/pdns/recursordist/taskqueue.hh +++ b/pdns/recursordist/taskqueue.hh @@ -63,23 +63,23 @@ struct ResolveTask DNSName d_nsname; Netmask d_netmask; - bool operator<(const ResolveTask& a) const + bool operator<(const ResolveTask& task) const { - return std::tie(d_qname, d_qtype, d_refreshMode, d_func, d_ip, d_netmask) < std::tie(a.d_qname, a.d_qtype, a.d_refreshMode, a.d_func, a.d_ip, a.d_netmask); + return std::tie(d_qname, d_qtype, d_refreshMode, d_func, d_ip, d_netmask) < std::tie(task.d_qname, task.d_qtype, task.d_refreshMode, task.d_func, task.d_ip, task.d_netmask); } - bool run(bool logErrors); + [[nodiscard]] bool run(bool logErrors) const; }; class TaskQueue { public: - bool empty() const + [[nodiscard]] bool empty() const { return d_queue.empty(); } - size_t size() const + [[nodiscard]] size_t size() const { return d_queue.size(); } @@ -87,12 +87,12 @@ public: bool push(ResolveTask&& task); ResolveTask pop(); - uint64_t getPushes() + [[nodiscard]] uint64_t getPushes() const { return d_pushes; } - uint64_t getExpired() + [[nodiscard]] uint64_t getExpired() const { return d_expired; } @@ -116,19 +116,17 @@ private: { }; - typedef multi_index_container< + using queue_t = multi_index_container< ResolveTask, - indexed_by< - ordered_unique, - composite_key, - member, - member, - member, - member, - member>>, - sequenced>>> - queue_t; + indexed_by, + composite_key, + member, + member, + member, + member, + member>>, + sequenced>>>; queue_t d_queue; uint64_t d_pushes{0}; diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index c25236ed5ab5..324928b88894 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -99,16 +99,16 @@ static void apiServerConfigACL(const std::string& aclType, HttpRequest* req, Htt } } - ostringstream ss; + ostringstream strStream; // Clear -from-file if set, so our changes take effect - ss << aclType << "-file=" << endl; + strStream << aclType << "-file=" << endl; // Clear ACL setting, and provide a "parent" value - ss << aclType << "=" << endl; - ss << aclType << "+=" << nmg.toString() << endl; + strStream << aclType << "=" << endl; + strStream << aclType << "+=" << nmg.toString() << endl; - apiWriteConfigFile(aclType, ss.str()); + apiWriteConfigFile(aclType, strStream.str()); parseACLs(); @@ -146,23 +146,24 @@ static void apiServerConfigAllowNotifyFrom(HttpRequest* req, HttpResponse* resp) static void fillZone(const DNSName& zonename, HttpResponse* resp) { auto iter = SyncRes::t_sstorage.domainmap->find(zonename); - if (iter == SyncRes::t_sstorage.domainmap->end()) + if (iter == SyncRes::t_sstorage.domainmap->end()) { throw ApiException("Could not find domain '" + zonename.toLogString() + "'"); + } const SyncRes::AuthDomain& zone = iter->second; Json::array servers; for (const ComboAddress& server : zone.d_servers) { - servers.push_back(server.toStringWithPort()); + servers.push_back(server.toStringWithPort()); // NOLINT: union } Json::array records; - for (const SyncRes::AuthDomain::records_t::value_type& dr : zone.d_records) { + for (const SyncRes::AuthDomain::records_t::value_type& record : zone.d_records) { records.push_back(Json::object{ - {"name", dr.d_name.toString()}, - {"type", DNSRecordContent::NumberToType(dr.d_type)}, - {"ttl", (double)dr.d_ttl}, - {"content", dr.getContent()->getZoneRepresentation()}}); + {"name", record.d_name.toString()}, + {"type", DNSRecordContent::NumberToType(record.d_type)}, + {"ttl", (double)record.d_ttl}, + {"content", record.getContent()->getZoneRepresentation()}}); } // id is the canonical lookup key, which doesn't actually match the name (in some cases) @@ -179,7 +180,7 @@ static void fillZone(const DNSName& zonename, HttpResponse* resp) resp->setJsonBody(doc); } -static void doCreateZone(const Json document) +static void doCreateZone(const Json& document) { if (::arg()["api-config-dir"].empty()) { throw ApiException("Config Option \"api-config-dir\" must be set"); @@ -191,18 +192,20 @@ static void doCreateZone(const Json document) string singleIPTarget = document["single_target_ip"].string_value(); string kind = toUpper(stringFromJson(document, "kind")); - bool rd = boolFromJson(document, "recursion_desired"); + bool rdFlag = boolFromJson(document, "recursion_desired"); string confbasename = "zone-" + apiZoneNameToId(zone); if (kind == "NATIVE") { - if (rd) + if (rdFlag) { throw ApiException("kind=Native and recursion_desired are mutually exclusive"); + } if (!singleIPTarget.empty()) { try { ComboAddress rem(singleIPTarget); - if (rem.sin4.sin_family != AF_INET) + if (rem.sin4.sin_family != AF_INET) { // NOLINT: union throw ApiException(""); - singleIPTarget = rem.toString(); + } + singleIPTarget = rem.toString(); // NOLINT: union } catch (...) { throw ApiException("Single IP target '" + singleIPTarget + "' is invalid"); @@ -226,25 +229,26 @@ static void doCreateZone(const Json document) else if (kind == "FORWARDED") { string serverlist; for (const auto& value : document["servers"].array_items()) { - string server = value.string_value(); - if (server == "") { + const string& server = value.string_value(); + if (server.empty()) { throw ApiException("Forwarded-to server must not be an empty string"); } try { - ComboAddress ca = parseIPAndPort(server, 53); + ComboAddress address = parseIPAndPort(server, 53); if (!serverlist.empty()) { serverlist += ";"; } - serverlist += ca.toStringWithPort(); + serverlist += address.toStringWithPort(); // NOLINT: union } catch (const PDNSException& e) { throw ApiException(e.reason); } } - if (serverlist == "") + if (serverlist.empty()) { throw ApiException("Need at least one upstream server when forwarding"); + } - if (rd) { + if (rdFlag) { apiWriteConfigFile(confbasename, "forward-zones-recurse+=" + zonename + "=" + serverlist); } else { @@ -289,8 +293,9 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) DNSName zonename = apiNameToDNSName(stringFromJson(document, "name")); auto iter = SyncRes::t_sstorage.domainmap->find(zonename); - if (iter != SyncRes::t_sstorage.domainmap->end()) + if (iter != SyncRes::t_sstorage.domainmap->end()) { throw ApiException("Zone already exists"); + } doCreateZone(document); reloadZoneConfiguration(); @@ -299,15 +304,16 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) return; } - if (req->method != "GET") + if (req->method != "GET") { throw HttpMethodNotAllowedException(); + } Json::array doc; for (const SyncRes::domainmap_t::value_type& val : *SyncRes::t_sstorage.domainmap) { const SyncRes::AuthDomain& zone = val.second; Json::array servers; for (const ComboAddress& server : zone.d_servers) { - servers.push_back(server.toStringWithPort()); + servers.push_back(server.toStringWithPort()); // NOLINT: union } // id is the canonical lookup key, which doesn't actually match the name (in some cases) string zoneId = apiZoneNameToId(val.first); @@ -326,9 +332,10 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { DNSName zonename = apiZoneIdToName(req->parameters["id"]); - SyncRes::domainmap_t::const_iterator iter = SyncRes::t_sstorage.domainmap->find(zonename); - if (iter == SyncRes::t_sstorage.domainmap->end()) + auto iter = SyncRes::t_sstorage.domainmap->find(zonename); + if (iter == SyncRes::t_sstorage.domainmap->end()) { throw ApiException("Could not find domain '" + zonename.toLogString() + "'"); + } if (req->method == "PUT") { Json document = req->json(); @@ -359,18 +366,20 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) { - if (req->method != "GET") + if (req->method != "GET") { throw HttpMethodNotAllowedException(); + } - string q = req->getvars["q"]; - if (q.empty()) + string qVar = req->getvars["q"]; + if (qVar.empty()) { throw ApiException("Query q can't be blank"); + } Json::array doc; for (const SyncRes::domainmap_t::value_type& val : *SyncRes::t_sstorage.domainmap) { string zoneId = apiZoneNameToId(val.first); string zoneName = val.first.toString(); - if (pdns_ci_find(zoneName, q) != string::npos) { + if (pdns_ci_find(zoneName, qVar) != string::npos) { doc.push_back(Json::object{ {"type", "zone"}, {"zone_id", zoneId}, @@ -378,22 +387,23 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) } // if zone name is an exact match, don't bother with returning all records/comments in it - if (val.first == DNSName(q)) { + if (val.first == DNSName(qVar)) { continue; } const SyncRes::AuthDomain& zone = val.second; - for (const SyncRes::AuthDomain::records_t::value_type& rr : zone.d_records) { - if (pdns_ci_find(rr.d_name.toString(), q) == string::npos && pdns_ci_find(rr.getContent()->getZoneRepresentation(), q) == string::npos) + for (const SyncRes::AuthDomain::records_t::value_type& resourceRec : zone.d_records) { + if (pdns_ci_find(resourceRec.d_name.toString(), qVar) == string::npos && pdns_ci_find(resourceRec.getContent()->getZoneRepresentation(), qVar) == string::npos) { continue; + } doc.push_back(Json::object{ {"type", "record"}, {"zone_id", zoneId}, {"zone_name", zoneName}, - {"name", rr.d_name.toString()}, - {"content", rr.getContent()->getZoneRepresentation()}}); + {"name", resourceRec.d_name.toString()}, + {"content", resourceRec.getContent()->getZoneRepresentation()}}); } } resp->setJsonBody(doc); @@ -401,13 +411,14 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) static void apiServerCacheFlush(HttpRequest* req, HttpResponse* resp) { - if (req->method != "PUT") + if (req->method != "PUT") { throw HttpMethodNotAllowedException(); + } DNSName canon = apiNameToDNSName(req->getvars["domain"]); - bool subtree = (req->getvars.count("subtree") > 0 && req->getvars["subtree"].compare("true") == 0); + bool subtree = req->getvars.count("subtree") > 0 && req->getvars["subtree"] == "true"; uint16_t qtype = 0xffff; - if (req->getvars.count("type")) { + if (req->getvars.count("type") != 0) { qtype = QType::chartocode(req->getvars["type"].c_str()); } @@ -419,8 +430,9 @@ static void apiServerCacheFlush(HttpRequest* req, HttpResponse* resp) static void apiServerRPZStats(HttpRequest* req, HttpResponse* resp) { - if (req->method != "GET") + if (req->method != "GET") { throw HttpMethodNotAllowedException(); + } auto luaconf = g_luaconfs.getLocal(); auto numZones = luaconf->dfe.size(); @@ -429,12 +441,14 @@ static void apiServerRPZStats(HttpRequest* req, HttpResponse* resp) for (size_t i = 0; i < numZones; i++) { auto zone = luaconf->dfe.getZone(i); - if (zone == nullptr) + if (zone == nullptr) { continue; + } const auto& name = zone->getName(); auto stats = getRPZZoneStats(name); - if (stats == nullptr) + if (stats == nullptr) { continue; + } Json::object zoneInfo = { {"transfers_failed", (double)stats->d_failedTransfers}, {"transfers_success", (double)stats->d_successfulTransfers}, @@ -452,8 +466,9 @@ static void prometheusMetrics(HttpRequest* req, HttpResponse* resp) { static MetricDefinitionStorage s_metricDefinitions; - if (req->method != "GET") + if (req->method != "GET") { throw HttpMethodNotAllowedException(); + } std::ostringstream output; @@ -467,7 +482,7 @@ static void prometheusMetrics(HttpRequest* req, HttpResponse* resp) MetricDefinition metricDetails; if (s_metricDefinitions.getMetricDetails(metricName, metricDetails)) { - std::string prometheusTypeName = s_metricDefinitions.getPrometheusStringMetricType( + std::string prometheusTypeName = MetricDefinitionStorage::getPrometheusStringMetricType( metricDetails.d_prometheusType); if (prometheusTypeName.empty()) { @@ -508,18 +523,20 @@ static void serveStuff(HttpRequest* req, HttpResponse* resp) { resp->headers["Cache-Control"] = "max-age=86400"; - if (req->url.path == "/") + if (req->url.path == "/") { req->url.path = "/index.html"; +} const string charset = "; charset=utf-8"; - if (boost::ends_with(req->url.path, ".html")) + if (boost::ends_with(req->url.path, ".html")) { resp->headers["Content-Type"] = "text/html" + charset; - else if (boost::ends_with(req->url.path, ".css")) + } else if (boost::ends_with(req->url.path, ".css")) { resp->headers["Content-Type"] = "text/css" + charset; - else if (boost::ends_with(req->url.path, ".js")) + } else if (boost::ends_with(req->url.path, ".js")) { resp->headers["Content-Type"] = "application/javascript" + charset; - else if (boost::ends_with(req->url.path, ".png")) + } else if (boost::ends_with(req->url.path, ".png")) { resp->headers["Content-Type"] = "image/png"; + } resp->headers["X-Content-Type-Options"] = "nosniff"; resp->headers["X-Frame-Options"] = "deny"; @@ -528,8 +545,8 @@ static void serveStuff(HttpRequest* req, HttpResponse* resp) resp->headers["X-XSS-Protection"] = "1; mode=block"; // resp->headers["Content-Security-Policy"] = "default-src 'self'; style-src 'self' 'unsafe-inline'"; - if (!req->url.path.empty() && g_urlmap.count(req->url.path.c_str() + 1)) { - resp->body = g_urlmap.at(req->url.path.c_str() + 1); + if (!req->url.path.empty() && (g_urlmap.count(req->url.path.substr(1)) != 0)) { + resp->body = g_urlmap.at(req->url.path.substr(1)); resp->status = 200; } else { @@ -1172,9 +1189,8 @@ const std::map MetricDefinitionStorage::d_metrics "Number of remote logging events")}, }; -#define CHECK_PROMETHEUS_METRICS 0 +constexpr bool CHECK_PROMETHEUS_METRICS = false; -#if CHECK_PROMETHEUS_METRICS static void validatePrometheusMetrics() { MetricDefinitionStorage s_metricDefinitions; @@ -1196,13 +1212,12 @@ static void validatePrometheusMetrics() } } } -#endif RecursorWebServer::RecursorWebServer(FDMultiplexer* fdm) { -#if CHECK_PROMETHEUS_METRICS - validatePrometheusMetrics(); -#endif + if (CHECK_PROMETHEUS_METRICS) { + validatePrometheusMetrics(); + } d_ws = make_unique(fdm, arg()["webserver-address"], arg().asNum("webserver-port")); d_ws->setSLog(g_slog->withName("webserver")); @@ -1219,7 +1234,7 @@ RecursorWebServer::RecursorWebServer(FDMultiplexer* fdm) // legacy dispatch d_ws->registerApiHandler( - "/jsonstat", [this](HttpRequest* req, HttpResponse* resp) { jsonstat(req, resp); }, true); + "/jsonstat", [](HttpRequest* req, HttpResponse* resp) { jsonstat(req, resp); }, true); d_ws->registerApiHandler("/api/v1/servers/localhost/cache/flush", apiServerCacheFlush); d_ws->registerApiHandler("/api/v1/servers/localhost/config/allow-from", apiServerConfigAllowFrom); d_ws->registerApiHandler("/api/v1/servers/localhost/config/allow-notify-from", &apiServerConfigAllowNotifyFrom); @@ -1234,8 +1249,8 @@ RecursorWebServer::RecursorWebServer(FDMultiplexer* fdm) d_ws->registerApiHandler("/api/v1", apiDiscoveryV1); d_ws->registerApiHandler("/api", apiDiscovery); - for (const auto& u : g_urlmap) { - d_ws->registerWebHandler("/" + u.first, serveStuff); + for (const auto& url : g_urlmap) { + d_ws->registerWebHandler("/" + url.first, serveStuff); } d_ws->registerWebHandler("/", serveStuff); @@ -1247,7 +1262,7 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) { string command; - if (req->getvars.count("command")) { + if (req->getvars.count("command") != 0) { command = req->getvars["command"]; req->getvars.erase("command"); } @@ -1258,36 +1273,43 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) vector queries; bool filter = !req->getvars["public-filtered"].empty(); - if (req->getvars["name"] == "servfail-queries") + if (req->getvars["name"] == "servfail-queries") { queries = broadcastAccFunction>(pleaseGetServfailQueryRing); - else if (req->getvars["name"] == "bogus-queries") + } + else if (req->getvars["name"] == "bogus-queries") { queries = broadcastAccFunction>(pleaseGetBogusQueryRing); - else if (req->getvars["name"] == "queries") + } + else if (req->getvars["name"] == "queries") { queries = broadcastAccFunction>(pleaseGetQueryRing); + } typedef map counts_t; counts_t counts; - for (const query_t& q : queries) { - if (filter) - counts[pair(getRegisteredName(q.first), q.second)]++; - else - counts[pair(q.first, q.second)]++; + for (const query_t& count : queries) { + if (filter) { + counts[pair(getRegisteredName(count.first), count.second)]++; + } else { + counts[pair(count.first, count.second)]++; + } } typedef std::multimap rcounts_t; rcounts_t rcounts; - for (counts_t::const_iterator i = counts.begin(); i != counts.end(); ++i) - rcounts.emplace(-i->second, i->first); + for (const auto& count : counts) { + rcounts.emplace(-count.second, count.first); + } Json::array entries; - unsigned int tot = 0, totIncluded = 0; - for (const rcounts_t::value_type& q : rcounts) { - totIncluded -= q.first; + unsigned int tot = 0; + unsigned int totIncluded = 0; + for (const rcounts_t::value_type& count : rcounts) { + totIncluded -= count.first; entries.push_back(Json::array{ - -q.first, q.second.first.toLogString(), DNSRecordContent::NumberToType(q.second.second)}); - if (tot++ >= 100) + -count.first, count.second.first.toLogString(), DNSRecordContent::NumberToType(count.second.second)}); + if (tot++ >= 100) { break; +} } if (queries.size() != totIncluded) { entries.push_back(Json::array{ @@ -1296,39 +1318,42 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) resp->setJsonBody(Json::object{{"entries", entries}}); return; } - else if (command == "get-remote-ring") { + if (command == "get-remote-ring") { vector queries; - if (req->getvars["name"] == "remotes") + if (req->getvars["name"] == "remotes") { queries = broadcastAccFunction>(pleaseGetRemotes); - else if (req->getvars["name"] == "servfail-remotes") + } else if (req->getvars["name"] == "servfail-remotes") { queries = broadcastAccFunction>(pleaseGetServfailRemotes); - else if (req->getvars["name"] == "bogus-remotes") + } else if (req->getvars["name"] == "bogus-remotes") { queries = broadcastAccFunction>(pleaseGetBogusRemotes); - else if (req->getvars["name"] == "large-answer-remotes") + } else if (req->getvars["name"] == "large-answer-remotes") { queries = broadcastAccFunction>(pleaseGetLargeAnswerRemotes); - else if (req->getvars["name"] == "timeouts") + } else if (req->getvars["name"] == "timeouts") { queries = broadcastAccFunction>(pleaseGetTimeouts); - + } typedef map counts_t; counts_t counts; - for (const ComboAddress& q : queries) { - counts[q]++; + for (const ComboAddress& query : queries) { + counts[query]++; } typedef std::multimap rcounts_t; rcounts_t rcounts; - for (counts_t::const_iterator i = counts.begin(); i != counts.end(); ++i) - rcounts.emplace(-i->second, i->first); + for (const auto& count : counts) { + rcounts.emplace(-count.second, count.first); + } Json::array entries; - unsigned int tot = 0, totIncluded = 0; - for (const rcounts_t::value_type& q : rcounts) { - totIncluded -= q.first; + unsigned int tot = 0; + unsigned int totIncluded = 0; + for (const rcounts_t::value_type& count : rcounts) { + totIncluded -= count.first; entries.push_back(Json::array{ - -q.first, q.second.toString()}); - if (tot++ >= 100) + -count.first, count.second.toString()}); // NOLINT: union + if (tot++ >= 100) { break; + } } if (queries.size() != totIncluded) { entries.push_back(Json::array{ @@ -1338,14 +1363,12 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) resp->setJsonBody(Json::object{{"entries", entries}}); return; } - else { - resp->setErrorResult("Command '" + command + "' not found", 404); - } + resp->setErrorResult("Command '" + command + "' not found", 404); } -void AsyncServerNewConnectionMT(void* p) +void AsyncServerNewConnectionMT(void* arg) { - AsyncServer* server = (AsyncServer*)p; + auto* server = static_cast(arg); try { auto socket = server->accept(); // this is actually a shared_ptr @@ -1379,9 +1402,9 @@ void AsyncServer::newConnection() } // This is an entry point from FDM, so it needs to catch everything. -void AsyncWebServer::serveConnection(std::shared_ptr client) const +void AsyncWebServer::serveConnection(const std::shared_ptr& socket) const { - if (!client->acl(d_acl)) { + if (!socket->acl(d_acl)) { return; } @@ -1402,7 +1425,7 @@ void AsyncWebServer::serveConnection(std::shared_ptr client) const try { YaHTTP::AsyncRequestLoader yarl; yarl.initialize(&req); - client->setNonBlocking(); + socket->setNonBlocking(); const struct timeval timeout { @@ -1410,16 +1433,16 @@ void AsyncWebServer::serveConnection(std::shared_ptr client) const }; std::shared_ptr tlsCtx{nullptr}; if (d_loglevel > WebServer::LogLevel::None) { - client->getRemote(remote); + socket->getRemote(remote); } - auto handler = std::make_shared("", false, client->releaseHandle(), timeout, tlsCtx); + auto handler = std::make_shared("", false, socket->releaseHandle(), timeout, tlsCtx); PacketBuffer data; try { while (!req.complete) { auto ret = arecvtcp(data, 16384, handler, true); if (ret == LWResult::Result::Success) { - string str(reinterpret_cast(data.data()), data.size()); + string str(reinterpret_cast(data.data()), data.size()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) req.complete = yarl.feed(str); } else { @@ -1438,10 +1461,10 @@ void AsyncWebServer::serveConnection(std::shared_ptr client) const logRequest(req, remote); WebServer::handleRequest(req, resp); - ostringstream ss; - resp.write(ss); - const string& s = ss.str(); - reply.insert(reply.end(), s.cbegin(), s.cend()); + ostringstream stringStream; + resp.write(stringStream); + const string& str = stringStream.str(); + reply.insert(reply.end(), str.cbegin(), str.cend()); logResponse(resp, remote, logprefix); @@ -1457,9 +1480,10 @@ void AsyncWebServer::serveConnection(std::shared_ptr client) const req.d_slog->error(Logr::Error, e.reason, "Exception handing request", "exception", Logging::Loggable("PDNSException"))); } catch (std::exception& e) { - if (strstr(e.what(), "timeout") == 0) + if (strstr(e.what(), "timeout") == nullptr) { SLOG(g_log << Logger::Error << logprefix << "STL Exception: " << e.what() << endl, req.d_slog->error(Logr::Error, e.what(), "Exception handing request", "exception", Logging::Loggable("std::exception"))); + } } catch (...) { SLOG(g_log << Logger::Error << logprefix << "Unknown exception" << endl, @@ -1476,10 +1500,12 @@ void AsyncWebServer::serveConnection(std::shared_ptr client) const void AsyncWebServer::go() { - if (!d_server) + if (!d_server) { return; + } auto server = std::dynamic_pointer_cast(d_server); - if (!server) + if (!server) { return; - server->asyncWaitForConnections(d_fdm, [this](const std::shared_ptr& c) { serveConnection(c); }); + } + server->asyncWaitForConnections(d_fdm, [this](const std::shared_ptr& socket) { serveConnection(socket); }); } diff --git a/pdns/recursordist/ws-recursor.hh b/pdns/recursordist/ws-recursor.hh index 1389b43f04e3..7821f10746ed 100644 --- a/pdns/recursordist/ws-recursor.hh +++ b/pdns/recursordist/ws-recursor.hh @@ -37,9 +37,9 @@ public: d_server_socket.setNonBlocking(); }; - friend void AsyncServerNewConnectionMT(void* p); + friend void AsyncServerNewConnectionMT(void* arg); - typedef std::function)> newconnectioncb_t; + using newconnectioncb_t = std::function&)>; void asyncWaitForConnections(FDMultiplexer* fdm, const newconnectioncb_t& callback); private: @@ -57,10 +57,10 @@ public: private: FDMultiplexer* d_fdm; - void serveConnection(std::shared_ptr socket) const; + void serveConnection(const std::shared_ptr& socket) const; protected: - virtual std::shared_ptr createServer() override + std::shared_ptr createServer() override { return std::make_shared(d_listenaddress, d_port); }; @@ -70,7 +70,7 @@ class RecursorWebServer : public boost::noncopyable { public: explicit RecursorWebServer(FDMultiplexer* fdm); - void jsonstat(HttpRequest* req, HttpResponse* resp); + static void jsonstat(HttpRequest* req, HttpResponse* resp); private: std::unique_ptr d_ws{nullptr}; diff --git a/pdns/secpoll.cc b/pdns/secpoll.cc index e798a3b61fe3..8ee4a59bbfbc 100644 --- a/pdns/secpoll.cc +++ b/pdns/secpoll.cc @@ -32,8 +32,9 @@ bool isReleaseVersion(const std::string &version) { } static void setSecPollToUnknownOnOK(int &secPollStatus) { - if(secPollStatus == 1) // it was ok, now it is unknown + if (secPollStatus == 1) { // it was ok, now it is unknown secPollStatus = 0; + } } void processSecPoll(const int res, const std::vector &ret, int &secPollStatus, std::string &secPollMessage) { @@ -44,15 +45,16 @@ void processSecPoll(const int res, const std::vector &ret, int &secPo } if (ret.empty()) { // empty NOERROR... wat? - if(secPollStatus == 1) // it was ok, now it is unknown + if (secPollStatus == 1) { // it was ok, now it is unknown secPollStatus = 0; + } throw PDNSException("Had empty answer on NOERROR RCODE"); } DNSRecord record; - for (auto const &r: ret) { - if (r.d_type == QType::TXT && r.d_place == DNSResourceRecord::Place::ANSWER) { - record = r; + for (auto const &records: ret) { + if (records.d_type == QType::TXT && records.d_place == DNSResourceRecord::Place::ANSWER) { + record = records; break; } } diff --git a/pdns/zonemd.cc b/pdns/zonemd.cc index 89cec85aa3b8..1e5973b8a861 100644 --- a/pdns/zonemd.cc +++ b/pdns/zonemd.cc @@ -36,20 +36,13 @@ void pdns::ZoneMD::readRecords(ZoneParserTNG& zpt) void pdns::ZoneMD::readRecords(const vector& records) { - for (auto& record : records) { + for (const auto& record : records) { readRecord(record); } } -void pdns::ZoneMD::readRecord(const DNSRecord& record) +void pdns::ZoneMD::processRecord(const DNSRecord& record) { - if (!record.d_name.isPartOf(d_zone) && record.d_name != d_zone) { - return; - } - if (record.d_class == QClass::IN && record.d_type == QType::SOA && d_soaRecordContent) { - return; - } - if (record.d_class == QClass::IN && record.d_name == d_zone) { switch (record.d_type) { case QType::SOA: { @@ -107,25 +100,38 @@ void pdns::ZoneMD::readRecord(const DNSRecord& record) if (param == nullptr) { throw PDNSException("Invalid NSEC3PARAM record"); } - if (g_maxNSEC3Iterations && param->d_iterations > g_maxNSEC3Iterations) { + if (g_maxNSEC3Iterations > 0 && param->d_iterations > g_maxNSEC3Iterations) { return; } d_nsec3params.emplace_back(param); d_nsec3label = d_zone; d_nsec3label.prependRawLabel(toBase32Hex(hashQNameWithSalt(param->d_salt, param->d_iterations, d_zone))); // Zap the NSEC3 at labels that we now know are not relevant - for (auto it = d_nsec3s.begin(); it != d_nsec3s.end();) { - if (it->first != d_nsec3label) { - it = d_nsec3s.erase(it); + for (auto item = d_nsec3s.begin(); item != d_nsec3s.end();) { + if (item->first != d_nsec3label) { + item = d_nsec3s.erase(item); } else { - ++it; + ++item; } } break; } } } +} + +void pdns::ZoneMD::readRecord(const DNSRecord& record) +{ + if (!record.d_name.isPartOf(d_zone) && record.d_name != d_zone) { + return; + } + if (record.d_class == QClass::IN && record.d_type == QType::SOA && d_soaRecordContent) { + return; + } + + processRecord(record); + // Until we have seen the NSEC3PARAM record, we save all of them, as we do not know the label for the zone yet if (record.d_class == QClass::IN && (d_nsec3label.empty() || record.d_name == d_nsec3label)) { switch (record.d_type) { @@ -154,7 +160,7 @@ void pdns::ZoneMD::readRecord(const DNSRecord& record) d_resourceRecordSetTTLs[key] = record.d_ttl; } -void pdns::ZoneMD::verify(bool& validationDone, bool& validationOK) +void pdns::ZoneMD::verify(bool& validationDone, bool& validationOK) // NOLINT { validationDone = false; validationOK = false; @@ -165,9 +171,10 @@ void pdns::ZoneMD::verify(bool& validationDone, bool& validationOK) // Get all records and remember RRSets and TTLs // Determine which digests to compute based on accepted zonemd records present - unique_ptr sha384digest{nullptr}, sha512digest{nullptr}; + unique_ptr sha384digest{nullptr}; + unique_ptr sha512digest{nullptr}; - for (const auto& it : d_zonemdRecords) { + for (const auto& item : d_zonemdRecords) { // The SOA Serial field MUST exactly match the ZONEMD Serial // field. If the fields do not match, digest verification MUST // NOT be considered successful with this ZONEMD RR. @@ -179,14 +186,14 @@ void pdns::ZoneMD::verify(bool& validationDone, bool& validationOK) // The Hash Algorithm field MUST be checked. If the verifier does // not support the given hash algorithm, verification MUST NOT be // considered successful with this ZONEMD RR. - const auto duplicate = it.second.duplicate; - const auto& r = it.second.record; - if (!duplicate && r->d_serial == d_soaRecordContent->d_st.serial && r->d_scheme == 1 && (r->d_hashalgo == 1 || r->d_hashalgo == 2)) { + const auto duplicate = item.second.duplicate; + const auto& record = item.second.record; + if (!duplicate && record->d_serial == d_soaRecordContent->d_st.serial && record->d_scheme == 1 && (record->d_hashalgo == 1 || record->d_hashalgo == 2)) { // A supported ZONEMD record - if (r->d_hashalgo == 1) { + if (record->d_hashalgo == 1) { sha384digest = make_unique(384); } - else if (r->d_hashalgo == 2) { + else if (record->d_hashalgo == 2) { sha512digest = make_unique(512); } } @@ -216,14 +223,14 @@ void pdns::ZoneMD::verify(bool& validationDone, bool& validationOK) } sortedRecords_t sorted; - for (auto& rr : rrset.second) { + for (auto& resourceRecord : rrset.second) { if (qtype == QType::RRSIG) { - const auto rrsig = std::dynamic_pointer_cast(rr); + const auto rrsig = std::dynamic_pointer_cast(resourceRecord); if (rrsig->d_type == QType::ZONEMD && qname == d_zone) { continue; } } - sorted.insert(rr); + sorted.insert(resourceRecord); } if (sorted.empty()) { diff --git a/pdns/zonemd.hh b/pdns/zonemd.hh index 3f20d52eaceb..e941a951f5bb 100644 --- a/pdns/zonemd.hh +++ b/pdns/zonemd.hh @@ -50,30 +50,32 @@ public: ValidationFailure }; - ZoneMD(const DNSName& zone) : - d_zone(zone) + ZoneMD(DNSName zone) : + d_zone(std::move(zone)) {} void readRecords(ZoneParserTNG& zpt); void readRecords(const std::vector& records); void readRecord(const DNSRecord& record); + void processRecord(const DNSRecord& record); void verify(bool& validationDone, bool& validationOK); // Return the zone's apex DNSKEYs - const std::set>& getDNSKEYs() const + [[nodiscard]] const std::set>& getDNSKEYs() const { return d_dnskeys; } // Return the zone's apex RRSIGs - const std::vector>& getRRSIGs() const + [[nodiscard]] const std::vector>& getRRSIGs() const { return d_rrsigs; } // Return the zone's apex ZONEMDs - std::vector> getZONEMDs() const + [[nodiscard]] std::vector> getZONEMDs() const { std::vector> ret; + ret.reserve(d_zonemdRecords.size()); for (const auto& zonemd : d_zonemdRecords) { ret.emplace_back(zonemd.second.record); } @@ -81,24 +83,24 @@ public: } // Return the zone's apex NSECs with signatures - const ContentSigPair& getNSECs() const + [[nodiscard]] const ContentSigPair& getNSECs() const { return d_nsecs; } // Return the zone's apex NSEC3s with signatures - const ContentSigPair& getNSEC3s() const + [[nodiscard]] const ContentSigPair& getNSEC3s() const { - const auto it = d_nsec3s.find(d_nsec3label); - return it == d_nsec3s.end() ? empty : d_nsec3s.at(d_nsec3label); + const auto item = d_nsec3s.find(d_nsec3label); + return item == d_nsec3s.end() ? empty : d_nsec3s.at(d_nsec3label); } - const DNSName& getNSEC3Label() const + [[nodiscard]] const DNSName& getNSEC3Label() const { return d_nsec3label; } - const std::vector>& getNSEC3Params() const + [[nodiscard]] const std::vector>& getNSEC3Params() const { return d_nsec3params; } @@ -109,16 +111,16 @@ private: struct CanonRRSetKeyCompare { - bool operator()(const RRSetKey_t& a, const RRSetKey_t& b) const + bool operator()(const RRSetKey_t& lhs, const RRSetKey_t& rhs) const { // FIXME surely we can be smarter here - if (a.first.canonCompare(b.first)) { + if (lhs.first.canonCompare(rhs.first)) { return true; } - if (b.first.canonCompare(a.first)) { + if (rhs.first.canonCompare(lhs.first)) { return false; } - return a.second < b.second; + return lhs.second < rhs.second; } }; From b4de5386c87846da0c523cf229071f94ceb92a54 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 10 May 2023 09:44:52 +0200 Subject: [PATCH 216/909] Reformat --- pdns/recursordist/taskqueue.cc | 4 +++- pdns/recursordist/ws-recursor.cc | 32 ++++++++++++++++++++------------ pdns/recursordist/ws-recursor.hh | 2 +- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/pdns/recursordist/taskqueue.cc b/pdns/recursordist/taskqueue.cc index d18a8cb8c9ca..7e268e4edfd9 100644 --- a/pdns/recursordist/taskqueue.cc +++ b/pdns/recursordist/taskqueue.cc @@ -52,7 +52,9 @@ bool ResolveTask::run(bool logErrors) const log->error(Logr::Debug, "null task"); return false; } - struct timeval now{}; + struct timeval now + { + }; Utility::gettimeofday(&now); if (d_deadline >= now.tv_sec) { d_func(now, logErrors, *this); diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index 324928b88894..9e711c164f9c 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -525,16 +525,19 @@ static void serveStuff(HttpRequest* req, HttpResponse* resp) if (req->url.path == "/") { req->url.path = "/index.html"; -} + } const string charset = "; charset=utf-8"; if (boost::ends_with(req->url.path, ".html")) { resp->headers["Content-Type"] = "text/html" + charset; - } else if (boost::ends_with(req->url.path, ".css")) { + } + else if (boost::ends_with(req->url.path, ".css")) { resp->headers["Content-Type"] = "text/css" + charset; - } else if (boost::ends_with(req->url.path, ".js")) { + } + else if (boost::ends_with(req->url.path, ".js")) { resp->headers["Content-Type"] = "application/javascript" + charset; - } else if (boost::ends_with(req->url.path, ".png")) { + } + else if (boost::ends_with(req->url.path, ".png")) { resp->headers["Content-Type"] = "image/png"; } @@ -1288,7 +1291,8 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) for (const query_t& count : queries) { if (filter) { counts[pair(getRegisteredName(count.first), count.second)]++; - } else { + } + else { counts[pair(count.first, count.second)]++; } } @@ -1309,7 +1313,7 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) -count.first, count.second.first.toLogString(), DNSRecordContent::NumberToType(count.second.second)}); if (tot++ >= 100) { break; -} + } } if (queries.size() != totIncluded) { entries.push_back(Json::array{ @@ -1322,13 +1326,17 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) vector queries; if (req->getvars["name"] == "remotes") { queries = broadcastAccFunction>(pleaseGetRemotes); - } else if (req->getvars["name"] == "servfail-remotes") { + } + else if (req->getvars["name"] == "servfail-remotes") { queries = broadcastAccFunction>(pleaseGetServfailRemotes); - } else if (req->getvars["name"] == "bogus-remotes") { + } + else if (req->getvars["name"] == "bogus-remotes") { queries = broadcastAccFunction>(pleaseGetBogusRemotes); - } else if (req->getvars["name"] == "large-answer-remotes") { + } + else if (req->getvars["name"] == "large-answer-remotes") { queries = broadcastAccFunction>(pleaseGetLargeAnswerRemotes); - } else if (req->getvars["name"] == "timeouts") { + } + else if (req->getvars["name"] == "timeouts") { queries = broadcastAccFunction>(pleaseGetTimeouts); } typedef map counts_t; @@ -1350,7 +1358,7 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) for (const rcounts_t::value_type& count : rcounts) { totIncluded -= count.first; entries.push_back(Json::array{ - -count.first, count.second.toString()}); // NOLINT: union + -count.first, count.second.toString()}); // NOLINT: union if (tot++ >= 100) { break; } @@ -1402,7 +1410,7 @@ void AsyncServer::newConnection() } // This is an entry point from FDM, so it needs to catch everything. -void AsyncWebServer::serveConnection(const std::shared_ptr& socket) const +void AsyncWebServer::serveConnection(const std::shared_ptr& socket) const // NOLINT(readability-function-cognitive-complexity) #12791 Remove NOLINT(readability-function-cognitive-complexity) omoerbeek { if (!socket->acl(d_acl)) { return; diff --git a/pdns/recursordist/ws-recursor.hh b/pdns/recursordist/ws-recursor.hh index 7821f10746ed..18ab40b5b7fc 100644 --- a/pdns/recursordist/ws-recursor.hh +++ b/pdns/recursordist/ws-recursor.hh @@ -39,7 +39,7 @@ public: friend void AsyncServerNewConnectionMT(void* arg); - using newconnectioncb_t = std::function&)>; + using newconnectioncb_t = std::function&)>; void asyncWaitForConnections(FDMultiplexer* fdm, const newconnectioncb_t& callback); private: From 04eaccfcbdcd94cd1f6be58c88394193c066bb8a Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 16 May 2023 12:05:07 +0200 Subject: [PATCH 217/909] Process review comments --- pdns/recursordist/ws-recursor.cc | 14 +++++++------- pdns/zonemd.cc | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index 9e711c164f9c..cefc6a28d8a3 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -154,7 +154,7 @@ static void fillZone(const DNSName& zonename, HttpResponse* resp) Json::array servers; for (const ComboAddress& server : zone.d_servers) { - servers.push_back(server.toStringWithPort()); // NOLINT: union + servers.push_back(server.toStringWithPort()); } Json::array records; @@ -202,10 +202,10 @@ static void doCreateZone(const Json& document) if (!singleIPTarget.empty()) { try { ComboAddress rem(singleIPTarget); - if (rem.sin4.sin_family != AF_INET) { // NOLINT: union + if (rem.sin4.sin_family != AF_INET) { throw ApiException(""); } - singleIPTarget = rem.toString(); // NOLINT: union + singleIPTarget = rem.toString(); } catch (...) { throw ApiException("Single IP target '" + singleIPTarget + "' is invalid"); @@ -238,7 +238,7 @@ static void doCreateZone(const Json& document) if (!serverlist.empty()) { serverlist += ";"; } - serverlist += address.toStringWithPort(); // NOLINT: union + serverlist += address.toStringWithPort(); } catch (const PDNSException& e) { throw ApiException(e.reason); @@ -313,7 +313,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) const SyncRes::AuthDomain& zone = val.second; Json::array servers; for (const ComboAddress& server : zone.d_servers) { - servers.push_back(server.toStringWithPort()); // NOLINT: union + servers.push_back(server.toStringWithPort()); } // id is the canonical lookup key, which doesn't actually match the name (in some cases) string zoneId = apiZoneNameToId(val.first); @@ -1358,7 +1358,7 @@ void RecursorWebServer::jsonstat(HttpRequest* req, HttpResponse* resp) for (const rcounts_t::value_type& count : rcounts) { totIncluded -= count.first; entries.push_back(Json::array{ - -count.first, count.second.toString()}); // NOLINT: union + -count.first, count.second.toString()}); if (tot++ >= 100) { break; } @@ -1450,7 +1450,7 @@ void AsyncWebServer::serveConnection(const std::shared_ptr& socket) cons while (!req.complete) { auto ret = arecvtcp(data, 16384, handler, true); if (ret == LWResult::Result::Success) { - string str(reinterpret_cast(data.data()), data.size()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + string str(reinterpret_cast(data.data()), data.size()); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast): safe cast, data.data() returns unsigned char * req.complete = yarl.feed(str); } else { diff --git a/pdns/zonemd.cc b/pdns/zonemd.cc index 1e5973b8a861..dc1ee7af2524 100644 --- a/pdns/zonemd.cc +++ b/pdns/zonemd.cc @@ -160,7 +160,7 @@ void pdns::ZoneMD::readRecord(const DNSRecord& record) d_resourceRecordSetTTLs[key] = record.d_ttl; } -void pdns::ZoneMD::verify(bool& validationDone, bool& validationOK) // NOLINT +void pdns::ZoneMD::verify(bool& validationDone, bool& validationOK) { validationDone = false; validationOK = false; From e6d4f36b935567256ddcb01a9539bc784a3b814e Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Sun, 28 May 2023 23:05:35 +0200 Subject: [PATCH 218/909] auth: do not answer with broken TYPE0 data when expanding an ENT wildcard --- pdns/packethandler.cc | 2 +- regression-tests/tests/ent-asterisk/command | 1 + regression-tests/tests/ent-asterisk/expected_result | 4 ++++ .../tests/ent-asterisk/expected_result.dnssec | 9 +++++++++ .../tests/ent-asterisk/expected_result.narrow | 11 +++++++++++ .../tests/ent-asterisk/expected_result.nsec3 | 11 +++++++++++ 6 files changed, 37 insertions(+), 1 deletion(-) diff --git a/pdns/packethandler.cc b/pdns/packethandler.cc index 5d603648c510..d83b8393d1f6 100644 --- a/pdns/packethandler.cc +++ b/pdns/packethandler.cc @@ -436,7 +436,7 @@ bool PacketHandler::getBestWildcard(DNSPacket& p, const DNSName &target, DNSName } else #endif - if(rr.dr.d_type == p.qtype.getCode() || rr.dr.d_type == QType::CNAME || (p.qtype.getCode() == QType::ANY && rr.dr.d_type != QType::RRSIG)) { + if(rr.dr.d_type != QType::ENT && (rr.dr.d_type == p.qtype.getCode() || rr.dr.d_type == QType::CNAME || (p.qtype.getCode() == QType::ANY && rr.dr.d_type != QType::RRSIG))) { ret->push_back(rr); } diff --git a/regression-tests/tests/ent-asterisk/command b/regression-tests/tests/ent-asterisk/command index bce5a5ec687f..b183ea74b64b 100755 --- a/regression-tests/tests/ent-asterisk/command +++ b/regression-tests/tests/ent-asterisk/command @@ -1,3 +1,4 @@ #!/bin/sh cleandig sub.host.sub.example.com a dnssec +cleandig sub.host.sub.example.com any dnssec tcp diff --git a/regression-tests/tests/ent-asterisk/expected_result b/regression-tests/tests/ent-asterisk/expected_result index c07355b8cd99..51e64a592fd3 100644 --- a/regression-tests/tests/ent-asterisk/expected_result +++ b/regression-tests/tests/ent-asterisk/expected_result @@ -2,3 +2,7 @@ 2 . 32768 IN OPT Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 Reply to question for qname='sub.host.sub.example.com.', qtype=A +1 example.com. 86400 IN SOA ns1.example.com. ahu.example.com. 2847484148 28800 7200 604800 86400 +2 . 32768 IN OPT +Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='sub.host.sub.example.com.', qtype=ANY diff --git a/regression-tests/tests/ent-asterisk/expected_result.dnssec b/regression-tests/tests/ent-asterisk/expected_result.dnssec index 6be3db6d8519..3c5498c78eee 100644 --- a/regression-tests/tests/ent-asterisk/expected_result.dnssec +++ b/regression-tests/tests/ent-asterisk/expected_result.dnssec @@ -7,3 +7,12 @@ 2 . 32768 IN OPT Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 Reply to question for qname='sub.host.sub.example.com.', qtype=A +1 example.com. 86400 IN RRSIG SOA 13 2 100000 [expiry] [inception] [keytag] example.com. ... +1 example.com. 86400 IN SOA ns1.example.com. ahu.example.com. 2847484148 28800 7200 604800 86400 +1 host.*.sub.example.com. 86400 IN NSEC bar.svcb.example.com. A RRSIG NSEC +1 host.*.sub.example.com. 86400 IN RRSIG NSEC 13 5 86400 [expiry] [inception] [keytag] example.com. ... +1 start4.example.com. 86400 IN NSEC host.*.sub.example.com. A RRSIG NSEC +1 start4.example.com. 86400 IN RRSIG NSEC 13 3 86400 [expiry] [inception] [keytag] example.com. ... +2 . 32768 IN OPT +Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='sub.host.sub.example.com.', qtype=ANY diff --git a/regression-tests/tests/ent-asterisk/expected_result.narrow b/regression-tests/tests/ent-asterisk/expected_result.narrow index d0f8c68d65a7..fa87e0b25921 100644 --- a/regression-tests/tests/ent-asterisk/expected_result.narrow +++ b/regression-tests/tests/ent-asterisk/expected_result.narrow @@ -9,3 +9,14 @@ 2 . 32768 IN OPT Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 Reply to question for qname='sub.host.sub.example.com.', qtype=A +1 5ui8h56r4776maicvhpdegs6chr19i99.example.com. 86400 IN NSEC3 1 [flags] 1 abcd 5UI8H56R4776MAICVHPDEGS6CHR19I9A +1 5ui8h56r4776maicvhpdegs6chr19i99.example.com. 86400 IN RRSIG NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ... +1 example.com. 86400 IN RRSIG SOA 13 2 100000 [expiry] [inception] [keytag] example.com. ... +1 example.com. 86400 IN SOA ns1.example.com. ahu.example.com. 2847484148 28800 7200 604800 86400 +1 hhrsadparthvtuou67trentjstdodla0.example.com. 86400 IN NSEC3 1 [flags] 1 abcd HHRSADPARTHVTUOU67TRENTJSTDODLA1 +1 hhrsadparthvtuou67trentjstdodla0.example.com. 86400 IN RRSIG NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ... +1 pbl3rtqv3mt7eb29gqp0a17o0h42nj76.example.com. 86400 IN NSEC3 1 [flags] 1 abcd PBL3RTQV3MT7EB29GQP0A17O0H42NJ78 +1 pbl3rtqv3mt7eb29gqp0a17o0h42nj76.example.com. 86400 IN RRSIG NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ... +2 . 32768 IN OPT +Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='sub.host.sub.example.com.', qtype=ANY diff --git a/regression-tests/tests/ent-asterisk/expected_result.nsec3 b/regression-tests/tests/ent-asterisk/expected_result.nsec3 index 04967be403fe..127945409770 100644 --- a/regression-tests/tests/ent-asterisk/expected_result.nsec3 +++ b/regression-tests/tests/ent-asterisk/expected_result.nsec3 @@ -9,3 +9,14 @@ 2 . 32768 IN OPT Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 Reply to question for qname='sub.host.sub.example.com.', qtype=A +1 5ui8h56r4776maicvhpdegs6chr19i99.example.com. 86400 IN NSEC3 1 [flags] 1 abcd 5UMB87SUFNRRMLILGL48A5GUUHG7RI58 +1 5ui8h56r4776maicvhpdegs6chr19i99.example.com. 86400 IN RRSIG NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ... +1 example.com. 86400 IN RRSIG SOA 13 2 100000 [expiry] [inception] [keytag] example.com. ... +1 example.com. 86400 IN SOA ns1.example.com. ahu.example.com. 2847484148 28800 7200 604800 86400 +1 hhrsadparthvtuou67trentjstdodla0.example.com. 86400 IN NSEC3 1 [flags] 1 abcd HHTKKD5HB125SGANBTKMQK84LULH60LH +1 hhrsadparthvtuou67trentjstdodla0.example.com. 86400 IN RRSIG NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ... +1 pbkjnd53pnsru5jmaqnk3k936pv2pq5j.example.com. 86400 IN NSEC3 1 [flags] 1 abcd PBL4SE96F8T4H4Q24UQMRQ4KS96AHPV3 A RRSIG +1 pbkjnd53pnsru5jmaqnk3k936pv2pq5j.example.com. 86400 IN RRSIG NSEC3 13 3 86400 [expiry] [inception] [keytag] example.com. ... +2 . 32768 IN OPT +Rcode: 0 (No Error), RD: 0, QR: 1, TC: 0, AA: 1, opcode: 0 +Reply to question for qname='sub.host.sub.example.com.', qtype=ANY From 46572de5ba3365fe446e24457299bbd00b5f2d3e Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 30 May 2023 13:49:03 +0200 Subject: [PATCH 219/909] rec: add SOA to RPZ result if configured to do so Fixes #8232 --- pdns/recursordist/filterpo.hh | 39 +++++++++++++++++++++++++++++- pdns/recursordist/pdns_recursor.cc | 4 +++ pdns/recursordist/rec-lua-conf.cc | 3 +++ pdns/recursordist/rpzloader.cc | 4 +++ pdns/recursordist/syncres.cc | 4 +++ 5 files changed, 53 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/filterpo.hh b/pdns/recursordist/filterpo.hh index 4d11af52ccd6..b5aa306bf737 100644 --- a/pdns/recursordist/filterpo.hh +++ b/pdns/recursordist/filterpo.hh @@ -28,6 +28,7 @@ #include #include #include +#include /* This class implements a filtering policy that is able to fully implement RPZ, but is not bound to it. In other words, it is generic enough to support RPZ, but could get its data from other places. @@ -96,9 +97,11 @@ public: std::unordered_set d_tags; std::string d_name; std::string d_extendedErrorExtra; + DNSRecord d_soa{}; boost::optional d_extendedErrorCode{boost::none}; Priority d_priority{maximumPriority}; bool d_policyOverridesGettag{true}; + bool d_includeSOA{false}; }; struct Policy @@ -168,6 +171,23 @@ public: return true; } + [[nodiscard]] bool getSOA(DNSRecord& rec) const + { + if (d_zoneData) { + rec = d_zoneData->d_soa; + return true; + } + return false; + } + + [[nodiscard]] bool includeSOA() const + { + if (d_zoneData) { + return d_zoneData->d_includeSOA; + } + return false; + } + bool wasHit() const { return (d_type != DNSFilterEngine::PolicyType::None && d_kind != DNSFilterEngine::PolicyKind::NoAction); @@ -187,6 +207,15 @@ public: PolicyKind d_kind; PolicyType d_type; + void addSOAtoRPZResult(vector& ret) const + { + DNSRecord soa{}; + if (includeSOA() && getSOA(soa)) { + soa.d_place = DNSResourceRecord::ADDITIONAL; + ret.emplace_back(soa); + } + } + private: DNSRecord getRecordFromCustom(const DNSName& qname, const std::shared_ptr& custom) const; }; @@ -243,7 +272,10 @@ public: { d_zoneData->d_extendedErrorExtra = extra; } - + void setSOA(DNSRecord soa) + { + d_zoneData->d_soa = std::move(soa); + } const std::string& getName() const { return d_zoneData->d_name; @@ -269,6 +301,11 @@ public: return d_qpolAddr.size() + d_postpolAddr.size() + d_propolName.size() + d_propolNSAddr.size() + d_qpolName.size(); } + void setIncludeSOA(bool flag) + { + d_zoneData->d_includeSOA = flag; + } + void dump(FILE* fp) const; void addClientTrigger(const Netmask& nm, Policy&& pol, bool ignoreDuplicate = false); diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index e1dbcf7bd414..9df794155c60 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -524,17 +524,20 @@ static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy case DNSFilterEngine::PolicyKind::NXDOMAIN: ret.clear(); + appliedPolicy.addSOAtoRPZResult(ret); res = RCode::NXDomain; return PolicyResult::HaveAnswer; case DNSFilterEngine::PolicyKind::NODATA: ret.clear(); + appliedPolicy.addSOAtoRPZResult(ret); res = RCode::NoError; return PolicyResult::HaveAnswer; case DNSFilterEngine::PolicyKind::Truncate: if (!dc->d_tcp) { ret.clear(); + appliedPolicy.addSOAtoRPZResult(ret); res = RCode::NoError; pw.getHeader()->tc = 1; return PolicyResult::HaveAnswer; @@ -570,6 +573,7 @@ static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy } } + appliedPolicy.addSOAtoRPZResult(ret); return PolicyResult::HaveAnswer; } } diff --git a/pdns/recursordist/rec-lua-conf.cc b/pdns/recursordist/rec-lua-conf.cc index c384bd65b2d3..78e5cb90f3df 100644 --- a/pdns/recursordist/rec-lua-conf.cc +++ b/pdns/recursordist/rec-lua-conf.cc @@ -153,6 +153,9 @@ static void parseRPZParameters(rpzOptions_t& have, std::shared_ptrsetExtendedErrorExtra(boost::get(have["extendedErrorExtra"])); } } + if (have.count("includeSOA")) { + zone->setIncludeSOA(boost::get(have["includeSOA"])); + } } typedef std::unordered_map>>> protobufOptions_t; diff --git a/pdns/recursordist/rpzloader.cc b/pdns/recursordist/rpzloader.cc index f81ef2fbce4e..c99480fea315 100644 --- a/pdns/recursordist/rpzloader.cc +++ b/pdns/recursordist/rpzloader.cc @@ -226,6 +226,7 @@ static shared_ptr loadRPZFromServer(Logr::log_t plogger, dr.d_name.makeUsRelative(zoneName); if (dr.d_type == QType::SOA) { sr = getRR(dr); + zone->setSOA(dr); continue; } @@ -293,6 +294,7 @@ std::shared_ptr loadRPZFromFile(const std::string& fname zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps")); zpt.setMaxIncludes(::arg().asNum("max-include-depth")); DNSResourceRecord drr; + DNSRecord soaRecord; DNSName domain; auto log = g_slog->withName("rpz")->withValues("file", Logging::Loggable(fname), "zone", Logging::Loggable(zone->getName())); while (zpt.get(drr)) { @@ -304,6 +306,7 @@ std::shared_ptr loadRPZFromFile(const std::string& fname sr = getRR(dr); domain = dr.d_name; zone->setDomain(domain); + soaRecord = dr; } else if (dr.d_type == QType::NS) { continue; @@ -320,6 +323,7 @@ std::shared_ptr loadRPZFromFile(const std::string& fname if (sr != nullptr) { zone->setRefresh(sr->d_st.refresh); + zone->setSOA(soaRecord); setRPZZoneNewState(zone->getName(), sr->d_st.serial, zone->size(), true, false); } return sr; diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index a2cba559bfbb..1472266b8900 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -3230,12 +3230,14 @@ void SyncRes::handlePolicyHit(const std::string& prefix, const DNSName& qname, c case DNSFilterEngine::PolicyKind::NXDOMAIN: ret.clear(); + d_appliedPolicy.addSOAtoRPZResult(ret); rcode = RCode::NXDomain; done = true; return; case DNSFilterEngine::PolicyKind::NODATA: ret.clear(); + d_appliedPolicy.addSOAtoRPZResult(ret); rcode = RCode::NoError; done = true; return; @@ -3243,6 +3245,7 @@ void SyncRes::handlePolicyHit(const std::string& prefix, const DNSName& qname, c case DNSFilterEngine::PolicyKind::Truncate: if (!d_queryReceivedOverTCP) { ret.clear(); + d_appliedPolicy.addSOAtoRPZResult(ret); rcode = RCode::NoError; throw SendTruncatedAnswerException(); } @@ -3270,6 +3273,7 @@ void SyncRes::handlePolicyHit(const std::string& prefix, const DNSName& qname, c } } } + d_appliedPolicy.addSOAtoRPZResult(ret); } } } From f6a524be8b4fb6b211ff6879e764347e179a3f54 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 30 May 2023 14:24:33 +0200 Subject: [PATCH 220/909] Add test and fix TC=1 adding of SOA record --- pdns/recursordist/docs/lua-config/rpz.rst | 7 ++ pdns/recursordist/pdns_recursor.cc | 1 + pdns/recursordist/syncres.cc | 3 +- regression-tests.recursor-dnssec/test_RPZ.py | 70 +++++++++++++------- 4 files changed, 55 insertions(+), 26 deletions(-) diff --git a/pdns/recursordist/docs/lua-config/rpz.rst b/pdns/recursordist/docs/lua-config/rpz.rst index ee0e388179ce..47e1ac957f29 100644 --- a/pdns/recursordist/docs/lua-config/rpz.rst +++ b/pdns/recursordist/docs/lua-config/rpz.rst @@ -151,6 +151,13 @@ extendedErrorExtra An extended error extra text (:rfc:`8914`) to set on RPZ hits. See :ref:`setting-extended-resolution-errors`. +includeSOA +^^^^^^^^^^ +.. versionadded:: 4.9.0 + +Include the RPZ's SOA record to the reply's additional section if modified by a policy hit. +Defaults to ``no``. + maxTTL ^^^^^^ The maximum TTL value of the synthesized records, overriding a higher value from ``defttl`` or the zone. Default is unlimited. diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 9df794155c60..0ad5b91ed8a1 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -1249,6 +1249,7 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } catch (const SendTruncatedAnswerException& e) { ret.clear(); + sr.d_appliedPolicy.addSOAtoRPZResult(ret); res = RCode::NoError; pw.getHeader()->tc = 1; } diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 1472266b8900..5fc54d5250c3 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -3245,8 +3245,9 @@ void SyncRes::handlePolicyHit(const std::string& prefix, const DNSName& qname, c case DNSFilterEngine::PolicyKind::Truncate: if (!d_queryReceivedOverTCP) { ret.clear(); - d_appliedPolicy.addSOAtoRPZResult(ret); rcode = RCode::NoError; + // Exception handling code in pdns_recursor clears ret as well, so no use to + // fill it here. throw SendTruncatedAnswerException(); } return; diff --git a/regression-tests.recursor-dnssec/test_RPZ.py b/regression-tests.recursor-dnssec/test_RPZ.py index 85268e447232..4215eacd33fb 100644 --- a/regression-tests.recursor-dnssec/test_RPZ.py +++ b/regression-tests.recursor-dnssec/test_RPZ.py @@ -248,7 +248,20 @@ class RPZRecursorTest(RecursorTest): log-rpz-changes=yes """ % (_confdir, _wsPort, _wsPassword, _apiKey) - def checkBlocked(self, name, shouldBeBlocked=True, adQuery=False, singleCheck=False): + def assertAdditionalHasSOA(self, msg): + if not isinstance(msg, dns.message.Message): + raise TypeError("msg is not a dns.message.Message but a %s" % type(msg)) + + found = False + for rrset in msg.additional: + if rrset.rdtype == dns.rdatatype.SOA: + found = True + break + + if not found: + raise AssertionError("No SOA record found in the authority section:\n%s" % msg.to_text()) + + def checkBlocked(self, name, shouldBeBlocked=True, adQuery=False, singleCheck=False, soa=False): query = dns.message.make_query(name, 'A', want_dnssec=True) query.flags |= dns.flags.CD if adQuery: @@ -264,13 +277,15 @@ def checkBlocked(self, name, shouldBeBlocked=True, adQuery=False, singleCheck=Fa expected = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'A', '192.0.2.42') self.assertRRsetInAnswer(res, expected) + if soa: + self.assertAdditionalHasSOA(res) if singleCheck: break def checkNotBlocked(self, name, adQuery=False, singleCheck=False): self.checkBlocked(name, False, adQuery, singleCheck) - def checkCustom(self, qname, qtype, expected): + def checkCustom(self, qname, qtype, expected, soa=False): query = dns.message.make_query(qname, qtype, want_dnssec=True) query.flags |= dns.flags.CD for method in ("sendUDPQuery", "sendTCPQuery"): @@ -278,8 +293,10 @@ def checkCustom(self, qname, qtype, expected): res = sender(query) self.assertRcodeEqual(res, dns.rcode.NOERROR) self.assertRRsetInAnswer(res, expected) + if soa: + self.assertAdditionalHasSOA(res) - def checkNoData(self, qname, qtype): + def checkNoData(self, qname, qtype, soa=False): query = dns.message.make_query(qname, qtype, want_dnssec=True) query.flags |= dns.flags.CD for method in ("sendUDPQuery", "sendTCPQuery"): @@ -287,6 +304,8 @@ def checkNoData(self, qname, qtype): res = sender(query) self.assertRcodeEqual(res, dns.rcode.NOERROR) self.assertEqual(len(res.answer), 0) + if soa: + self.assertAdditionalHasSOA(res) def checkNXD(self, qname, qtype='A'): query = dns.message.make_query(qname, qtype, want_dnssec=True) @@ -298,7 +317,7 @@ def checkNXD(self, qname, qtype='A'): self.assertEqual(len(res.answer), 0) self.assertEqual(len(res.authority), 1) - def checkTruncated(self, qname, qtype='A'): + def checkTruncated(self, qname, qtype='A', soa=False): query = dns.message.make_query(qname, qtype, want_dnssec=True) query.flags |= dns.flags.CD res = self.sendUDPQuery(query) @@ -306,7 +325,8 @@ def checkTruncated(self, qname, qtype='A'): self.assertMessageHasFlags(res, ['QR', 'RA', 'RD', 'CD', 'TC']) self.assertEqual(len(res.answer), 0) self.assertEqual(len(res.authority), 0) - self.assertEqual(len(res.additional), 0) + if soa: + self.assertAdditionalHasSOA(res) res = self.sendTCPQuery(query) self.assertRcodeEqual(res, dns.rcode.NXDOMAIN) @@ -352,7 +372,7 @@ class RPZXFRRecursorTest(RPZRecursorTest): global rpzServerPort _lua_config_file = """ -- The first server is a bogus one, to test that we correctly fail over to the second one - rpzMaster({'127.0.0.1:9999', '127.0.0.1:%d'}, 'zone.rpz.', { refresh=1 }) + rpzMaster({'127.0.0.1:9999', '127.0.0.1:%d'}, 'zone.rpz.', { refresh=1, includeSOA=true}) """ % (rpzServerPort) _confdir = 'RPZXFR' _wsPort = 8042 @@ -408,22 +428,22 @@ def testRPZ(self): # first zone, only a should be blocked self.waitUntilCorrectSerialIsLoaded(1) self.checkRPZStats(1, 1, 1, self._xfrDone) - self.checkBlocked('a.example.') + self.checkBlocked('a.example.', soa=True) self.checkNotBlocked('b.example.') self.checkNotBlocked('c.example.') # second zone, a and b should be blocked self.waitUntilCorrectSerialIsLoaded(2) self.checkRPZStats(2, 2, 1, self._xfrDone) - self.checkBlocked('a.example.') - self.checkBlocked('b.example.') + self.checkBlocked('a.example.', soa=True) + self.checkBlocked('b.example.', soa=True) self.checkNotBlocked('c.example.') # third zone, only b should be blocked self.waitUntilCorrectSerialIsLoaded(3) self.checkRPZStats(3, 1, 1, self._xfrDone) self.checkNotBlocked('a.example.') - self.checkBlocked('b.example.') + self.checkBlocked('b.example.', soa=True) self.checkNotBlocked('c.example.') # fourth zone, only c should be blocked @@ -431,7 +451,7 @@ def testRPZ(self): self.checkRPZStats(4, 1, 1, self._xfrDone) self.checkNotBlocked('a.example.') self.checkNotBlocked('b.example.') - self.checkBlocked('c.example.') + self.checkBlocked('c.example.', soa=True) # fifth zone, we should get a full AXFR this time, and only d should be blocked self.waitUntilCorrectSerialIsLoaded(5) @@ -439,7 +459,7 @@ def testRPZ(self): self.checkNotBlocked('a.example.') self.checkNotBlocked('b.example.') self.checkNotBlocked('c.example.') - self.checkBlocked('d.example.') + self.checkBlocked('d.example.', soa=True) # sixth zone, only e should be blocked, f is a local data record self.waitUntilCorrectSerialIsLoaded(6) @@ -448,10 +468,10 @@ def testRPZ(self): self.checkNotBlocked('b.example.') self.checkNotBlocked('c.example.') self.checkNotBlocked('d.example.') - self.checkCustom('e.example.', 'A', dns.rrset.from_text('e.example.', 0, dns.rdataclass.IN, 'A', '192.0.2.1', '192.0.2.2')) + self.checkCustom('e.example.', 'A', dns.rrset.from_text('e.example.', 0, dns.rdataclass.IN, 'A', '192.0.2.1', '192.0.2.2'), soa=True) self.checkCustom('e.example.', 'MX', dns.rrset.from_text('e.example.', 0, dns.rdataclass.IN, 'MX', '10 mx.example.')) - self.checkNoData('e.example.', 'AAAA') - self.checkCustom('f.example.', 'A', dns.rrset.from_text('f.example.', 0, dns.rdataclass.IN, 'CNAME', 'e.example.')) + self.checkNoData('e.example.', 'AAAA', soa=True) + self.checkCustom('f.example.', 'A', dns.rrset.from_text('f.example.', 0, dns.rdataclass.IN, 'CNAME', 'e.example.'), soa=True) # seventh zone, e should only have one A self.waitUntilCorrectSerialIsLoaded(7) @@ -460,14 +480,14 @@ def testRPZ(self): self.checkNotBlocked('b.example.') self.checkNotBlocked('c.example.') self.checkNotBlocked('d.example.') - self.checkCustom('e.example.', 'A', dns.rrset.from_text('e.example.', 0, dns.rdataclass.IN, 'A', '192.0.2.2')) - self.checkCustom('e.example.', 'MX', dns.rrset.from_text('e.example.', 0, dns.rdataclass.IN, 'MX', '10 mx.example.')) - self.checkNoData('e.example.', 'AAAA') - self.checkCustom('f.example.', 'A', dns.rrset.from_text('f.example.', 0, dns.rdataclass.IN, 'CNAME', 'e.example.')) + self.checkCustom('e.example.', 'A', dns.rrset.from_text('e.example.', 0, dns.rdataclass.IN, 'A', '192.0.2.2'), soa=True) + self.checkCustom('e.example.', 'MX', dns.rrset.from_text('e.example.', 0, dns.rdataclass.IN, 'MX', '10 mx.example.'), soa=True) + self.checkNoData('e.example.', 'AAAA', soa=True) + self.checkCustom('f.example.', 'A', dns.rrset.from_text('f.example.', 0, dns.rdataclass.IN, 'CNAME', 'e.example.'), soa=True) # check that the policy is disabled for AD=1 queries self.checkNotBlocked('e.example.', True) # check non-custom policies - self.checkTruncated('tc.example.') + self.checkTruncated('tc.example.', soa=True) self.checkDropped('drop.example.') # eighth zone, all entries should be gone @@ -493,7 +513,7 @@ def testRPZ(self): self.checkNotBlocked('c.example.') self.checkNotBlocked('d.example.') self.checkNotBlocked('e.example.') - self.checkBlocked('f.example.') + self.checkBlocked('f.example.', soa=True) self.checkNXD('tc.example.') self.checkNXD('drop.example.') @@ -508,7 +528,7 @@ def testRPZ(self): self.checkNotBlocked('d.example.') self.checkNotBlocked('e.example.') self.checkNXD('f.example.') - self.checkBlocked('g.example.') + self.checkBlocked('g.example.', soa=True) self.checkNXD('tc.example.') self.checkNXD('drop.example.') @@ -519,7 +539,7 @@ class RPZFileRecursorTest(RPZRecursorTest): _confdir = 'RPZFile' _lua_config_file = """ - rpzFile('configs/%s/zone.rpz', { policyName="zone.rpz." }) + rpzFile('configs/%s/zone.rpz', { policyName="zone.rpz.", includeSOA=true }) """ % (_confdir) _config_template = """ auth-zones=example=configs/%s/example.zone @@ -555,7 +575,7 @@ def generateRecursorConfig(cls, confdir): def testRPZ(self): self.checkCustom('a.example.', 'A', dns.rrset.from_text('a.example.', 0, dns.rdataclass.IN, 'A', '192.0.2.42', '192.0.2.43')) self.checkCustom('a.example.', 'TXT', dns.rrset.from_text('a.example.', 0, dns.rdataclass.IN, 'TXT', '"some text"')) - self.checkBlocked('z.example.') + self.checkBlocked('z.example.', soa=True) self.checkNotBlocked('b.example.') self.checkNotBlocked('c.example.') self.checkNotBlocked('d.example.') @@ -563,7 +583,7 @@ def testRPZ(self): # check that the policy is disabled for AD=1 queries self.checkNotBlocked('z.example.', True) # check non-custom policies - self.checkTruncated('tc.example.') + self.checkTruncated('tc.example.', soa=True) self.checkDropped('drop.example.') class RPZFileDefaultPolRecursorTest(RPZRecursorTest): From 0afb9bbc22615096d36715fd056e3d8344793cbb Mon Sep 17 00:00:00 2001 From: Erik Winkels Date: Thu, 1 Jun 2023 11:41:23 +0200 Subject: [PATCH 221/909] Add Bookworm to repo test script. Add Debian Bookworm for `auth-master` & `auth-48` to repo test script. --- build-scripts/docker/repo-test/generate-repo-files.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/build-scripts/docker/repo-test/generate-repo-files.py b/build-scripts/docker/repo-test/generate-repo-files.py index 7e4cc8b76839..956695c79474 100755 --- a/build-scripts/docker/repo-test/generate-repo-files.py +++ b/build-scripts/docker/repo-test/generate-repo-files.py @@ -25,7 +25,7 @@ # Globals -g_version = '1.0.2' +g_version = '1.0.3' g_verbose = False @@ -182,6 +182,10 @@ def write_release_files (release): 'dnsdist-17', 'dnsdist-18', 'dnsdist-master']: write_dockerfile('el', '9', release) + if release in ['auth-48', 'auth-master']: + write_dockerfile('debian', 'bookworm', release) + write_list_file('debian', 'bookworm', release) + # Test Release Functions def build (dockerfile): From 060e92d6fa0b2f73741c36ce36158202672ae3ed Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 1 Jun 2023 13:04:59 +0200 Subject: [PATCH 222/909] auth-4.8.0: docs and secpoll --- docs/changelog/4.8.rst | 40 ++++++++++++++++++++++++++++++++++++++++ docs/secpoll.zone | 5 +++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/docs/changelog/4.8.rst b/docs/changelog/4.8.rst index 7cca29733864..cd4af69a0bee 100644 --- a/docs/changelog/4.8.rst +++ b/docs/changelog/4.8.rst @@ -1,6 +1,46 @@ Changelogs for 4.8.x ==================== +.. changelog:: + :version: 4.8.0 + :released: 1st of June 2023 + + This is release 4.8.0 of the Authoritative Server. + + In 4.8, the LMDB backend gains a new Lightning Stream-compatible schema, which requires a data migration (this is automatic, and there is no migration back to the old schema). + LMDB backend users should pay extra attention to the :doc:`Upgrade Notes <../upgrading>`. + + `Lightning Stream `_ is an `open source `_ data syncer that allows multiple nodes to sync LMDB (Lightning Memory-Mapped Database) data to and from an S3 (compatible) bucket. This has particular advantages in distributed and/or large-scale applications (i.e. ~1 million records), making DNS replication much, much easier to manage. + + We are excited about how Lightning Stream simplifies running multiple distributed PowerDNS Authoritative servers, with full support for keeping record data and DNSSEC keys in sync, from multiple writers. + + 4.8.0 improves the handling of accidental duplicate domains -- deleting a zone now deletes all versions of it. + This release also contains a few other fixes, please see the list below. + + .. change:: + :tags: Bug Fixes + :pullreq: 12869 + + do not answer with broken TYPE0 data when expanding an ENT wildcard + + .. change:: + :tags: Bug Fixes + :pullreq: 12872 + + lmdb: delete duplicate domain entries in deleteDomain + + .. change:: + :tags: Bug Fixes + :pullreq: 12868 + + pdnsutil: if user pushes unknown key in response to "problem with zone" prompt, do not throw away their changes + + .. change:: + :tags: Bug Fixes + :pullreq: 12828 + + add setting workaround-11804-max-chunk-records + .. changelog:: :version: 4.8.0-beta1 :released: 4th of May 2023 diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 470b39aa16a0..233509b0ccde 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023050402 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023060101 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -119,7 +119,8 @@ auth-4.7.2.security-status 60 IN TXT "1 OK" auth-4.7.3.security-status 60 IN TXT "1 OK" auth-4.7.4.security-status 60 IN TXT "1 OK" auth-4.8.0-alpha1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -auth-4.8.0-beta1.security-status 60 IN TXT "1 Unsupported pre-release" +auth-4.8.0-beta1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" +auth-4.8.0.security-status 60 IN TXT "1 OK" ; Auth Debian auth-3.4.1-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2015-02/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-03/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-04/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-05/" From bd7066a03928abeea8a5b3923e809f6a9ee94edf Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 1 Jun 2023 14:03:58 +0200 Subject: [PATCH 223/909] auth upgrading: fix 4.6/4.7 header; update LMDB text --- .github/actions/spell-check/expect.txt | 1 + docs/upgrading.rst | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 43b7f2bacdf5..b451e038dc8e 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -424,6 +424,7 @@ feedrecord ffi ffipolicy filedescriptor +finalised findclientpolicy Firefox firewalled diff --git a/docs/upgrading.rst b/docs/upgrading.rst index 2fa79898a592..5021c714dda6 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -21,8 +21,11 @@ If you upgrade your database (by starting 4.8.0 without ``lmdb-schema-version=4` Upgrading is only supported from database schema versions 3 and 4, that is, databases created/upgraded by version 4.4 and up. -4.6.0 to 4.7.0 or master ------------------------- +In version 4.8.0, schema version 5 is finalised. +Databases created with -alpha1 or -beta1 work with 4.8.0. + +4.6.0 to 4.7.0 +-------------- Schema changes ^^^^^^^^^^^^^^ From d92e93c7661a553da94598a714b6050d9f1a4693 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 1 Jun 2023 18:57:17 +0200 Subject: [PATCH 224/909] swagger-syntax-check: run outside of Docker --- .github/workflows/build-and-test-all.yml | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 4db01a49945f..9c33fb83938c 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -538,14 +538,17 @@ jobs: swagger-syntax-check: if: ${{ !github.event.schedule || vars.SCHEDULED_JOBS_BUILD_AND_TEST_ALL }} runs-on: ubuntu-20.04 - container: - image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master - options: --sysctl net.ipv6.conf.all.disable_ipv6=0 + # FIXME: https://github.com/PowerDNS/pdns/pull/12880 + # container: + # image: ghcr.io/powerdns/base-pdns-ci-image/debian-11-pdns-base:master + # options: --sysctl net.ipv6.conf.all.disable_ipv6=0 steps: + - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 with: fetch-depth: 5 submodules: recursive + - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade - run: inv install-swagger-tools - run: inv swagger-syntax-check From dae2f88456fc61d6db66b7dd303ed15c8bc58419 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 1 Jun 2023 20:39:56 +0200 Subject: [PATCH 225/909] builder-dispatch: add debian-bookworm target to defaults --- .github/workflows/builder-dispatch.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/builder-dispatch.yml b/.github/workflows/builder-dispatch.yml index a8eb5e19689c..4db7f7e46f11 100644 --- a/.github/workflows/builder-dispatch.yml +++ b/.github/workflows/builder-dispatch.yml @@ -20,6 +20,7 @@ on: el-9 debian-buster debian-bullseye + debian-bookworm ubuntu-focal ubuntu-jammy ref: From e5b2404df15f38a044334276e82c8410e9cd6fd8 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 31 May 2023 10:28:00 +0200 Subject: [PATCH 226/909] Prep for rec-4.9.0-beta1 --- docs/secpoll.zone | 3 +- pdns/recursordist/docs/appendices/FAQ.rst | 4 +-- pdns/recursordist/docs/changelog/4.9.rst | 41 +++++++++++++++++++++++ pdns/recursordist/docs/upgrade.rst | 3 +- 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 233509b0ccde..8fe514f2cf6a 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023060101 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023060201 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -350,6 +350,7 @@ recursor-4.8.2.security-status 60 IN TXT "3 Upgrade now recursor-4.8.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.8.4.security-status 60 IN TXT "1 OK" recursor-4.9.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release" +recursor-4.9.0-beta1.security-status 60 IN TXT "1 Unsupported pre-release" ; Recursor Debian recursor-3.6.2-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/" diff --git a/pdns/recursordist/docs/appendices/FAQ.rst b/pdns/recursordist/docs/appendices/FAQ.rst index 7d6110db5e95..74a2e30535ee 100644 --- a/pdns/recursordist/docs/appendices/FAQ.rst +++ b/pdns/recursordist/docs/appendices/FAQ.rst @@ -69,7 +69,7 @@ This is needed to be able to resolve names, as the recursive algorithm starts at If the :ref:`setting-hint-file` is not set, :program:`Recursor` wil use a compiled-in table as root hints. Periodically, based on the :ref:`setting-max-cache-ttl`, the :program:`Recursor` will refetch the root data using data in its cache by doing a `. NS` query. -If that does not succeed, it wil fall back to using the root hints to fill the cache with root data. +If that does not succeed, it will fall back to using the root hints to fill the cache with root data. Prior to version 4.7.0, the period for re-fetching root data was :ref:`setting-max-cache-ttl` divided by 12, with a minimum of 10 seconds. Starting with version 4.7.0, the period is adaptive, starting at 80% of :ref:`setting-max-cache-ttl`, reducing the interval on failure. @@ -77,7 +77,7 @@ The root hints and resolved root data can differ if the root hints are outdated. As long as at least one root server mentioned in the root hints can be contacted, the periodic refresh will produce the desired record sets corresponding to the current up-to-date root server data. Starting with version 4.6.2, if :ref:`setting-hint-file` is set to ``no``, the :program:`Recursor` will not prime the cache with root data obtained from hints, but will still do the periodic refresh. -A (recursive) forward configuration is be needed to make the periodic refresh work. +A (recursive) forward configuration is needed to make the periodic refresh work. Starting with version 4.9, setting :ref:`setting-hint-file` to ``no-refresh`` disables both the initial reading of the hints and the periodic refresh of cached root data. This prevents :program:`Recursor` from resolving names by itself, so it is only useful in cases where all queries are forwarded. diff --git a/pdns/recursordist/docs/changelog/4.9.rst b/pdns/recursordist/docs/changelog/4.9.rst index b0976cb1267e..40aa96987994 100644 --- a/pdns/recursordist/docs/changelog/4.9.rst +++ b/pdns/recursordist/docs/changelog/4.9.rst @@ -1,5 +1,46 @@ Changelogs for 4.9.X ==================== +.. changelog:: + :version: 4.9.0-beta1 + :released: 2nd of June 2023 + + .. change:: + :tags: Improvements + :pullreq: 12861 + :tickets: 12848 + + Introduce a way to completely disable root-refresh. + + .. change:: + :tags: Bug Fixes + :pullreq: 12673 + + Sanitize d_orig_ttl stored in record cache. + + .. change:: + :tags: Improvements + :pullreq: 12838,12837,12836,12790 + + Delint some files to make clang-tidy not report any issue. + + .. change:: + :tags: Bug Fixes + :pullreq: 12829 + :tickets: 12790 + + Fix clang-tidy botch with respect to spelling of "log-fail". + + .. change:: + :tags: Improvements + :pullreq: 12779,12862 + + Distinguish between recursion depth and CNAME chain length. + + .. change:: + :tags: Improvements + :pullreq: 12750 + + Log if the answer was marked variable by SyncRes and if it was stored into the packet cache (if !quiet). .. changelog:: :version: 4.9.0-alpha1 diff --git a/pdns/recursordist/docs/upgrade.rst b/pdns/recursordist/docs/upgrade.rst index 871186e6d3e7..b8b25de0cd63 100644 --- a/pdns/recursordist/docs/upgrade.rst +++ b/pdns/recursordist/docs/upgrade.rst @@ -31,8 +31,9 @@ See :doc:`performance`. - The :ref:`setting-pdns-distributes-queries` default has been changed to ``no``. - The :ref:`setting-reuseport` default has been changed to ``yes``. - - The :ref:`setting-packetcache-ttl` default has been changed to 24 hours. +- The :ref:`setting-max-recursion-depth` default has been changed to 16. Before it was, 40, but effectively the CNAME length chain limit (fixed at 16) took precedence. +- The :ref:`setting-hint-file` setting gained a new special value to disable refreshing of root hints completely. See :ref:`handling-of-root-hints`. :program:`rec_control` ^^^^^^^^^^^^^^^^^^^^^^ From 07984b953b4575b0c8a56ec703221ffff7ac9436 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 2 Jun 2023 14:16:40 +0200 Subject: [PATCH 227/909] delint --- pdns/recursordist/rec-lua-conf.cc | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/pdns/recursordist/rec-lua-conf.cc b/pdns/recursordist/rec-lua-conf.cc index 78e5cb90f3df..4c471d2481bd 100644 --- a/pdns/recursordist/rec-lua-conf.cc +++ b/pdns/recursordist/rec-lua-conf.cc @@ -101,10 +101,10 @@ typedef std::unordered_map& zone, std::string& polName, boost::optional& defpol, bool& defpolOverrideLocal, uint32_t& maxTTL) { - if (have.count("policyName")) { + if (have.count("policyName") != 0) { polName = boost::get(have["policyName"]); } - if (have.count("defpol")) { + if (have.count("defpol") != 0) { defpol = DNSFilterEngine::Policy(); defpol->d_kind = (DNSFilterEngine::PolicyKind)boost::get(have["defpol"]); defpol->setName(polName); @@ -112,26 +112,28 @@ static void parseRPZParameters(rpzOptions_t& have, std::shared_ptrd_custom.push_back(DNSRecordContent::mastermake(QType::CNAME, QClass::IN, boost::get(have["defcontent"]))); - if (have.count("defttl")) + if (have.count("defttl") != 0) { defpol->d_ttl = static_cast(boost::get(have["defttl"])); - else + } + else { defpol->d_ttl = -1; // get it from the zone + } } - if (have.count("defpolOverrideLocalData")) { + if (have.count("defpolOverrideLocalData") != 0) { defpolOverrideLocal = boost::get(have["defpolOverrideLocalData"]); } } - if (have.count("maxTTL")) { + if (have.count("maxTTL") != 0) { maxTTL = boost::get(have["maxTTL"]); } - if (have.count("zoneSizeHint")) { + if (have.count("zoneSizeHint") != 0) { auto zoneSizeHint = static_cast(boost::get(have["zoneSizeHint"])); if (zoneSizeHint > 0) { zone->reserve(zoneSizeHint); } } - if (have.count("tags")) { + if (have.count("tags") != 0) { const auto tagsTable = boost::get>>(have["tags"]); std::unordered_set tags; for (const auto& tag : tagsTable) { @@ -139,21 +141,21 @@ static void parseRPZParameters(rpzOptions_t& have, std::shared_ptrsetTags(std::move(tags)); } - if (have.count("overridesGettag")) { + if (have.count("overridesGettag") != 0) { zone->setPolicyOverridesGettag(boost::get(have["overridesGettag"])); } - if (have.count("extendedErrorCode")) { + if (have.count("extendedErrorCode") != 0) { auto code = boost::get(have["extendedErrorCode"]); if (code > std::numeric_limits::max()) { throw std::runtime_error("Invalid extendedErrorCode value " + std::to_string(code) + " in RPZ configuration"); } zone->setExtendedErrorCode(static_cast(code)); - if (have.count("extendedErrorExtra")) { + if (have.count("extendedErrorExtra") != 0) { zone->setExtendedErrorExtra(boost::get(have["extendedErrorExtra"])); } } - if (have.count("includeSOA")) { + if (have.count("includeSOA") != 0) { zone->setIncludeSOA(boost::get(have["includeSOA"])); } } From 38b248a6cfc01f4598b31f2d706c76e079c5017e Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 5 Jun 2023 16:34:15 +0200 Subject: [PATCH 228/909] auth 4.8: EOL update --- docs/appendices/EOL.rst | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/docs/appendices/EOL.rst b/docs/appendices/EOL.rst index 3bffee0a6693..44d8619ed2fb 100644 --- a/docs/appendices/EOL.rst +++ b/docs/appendices/EOL.rst @@ -7,13 +7,13 @@ The two releases before that get critical updates only. Older releases are marked end of life and receive no updates at all. Pre-releases do not receive immediate security updates. -The currently supported release train of PowerDNS Authoritative Server is 4.7. +The currently supported release train of PowerDNS Authoritative Server is 4.8. -PowerDNS Authoritative Server 4.6 will only receive critical updates and will be end of life after PowerDNS Authoritative Server 4.9 is released. +PowerDNS Authoritative Server 4.7 will only receive critical updates and will be end of life after PowerDNS Authoritative Server 4.10 is released. -PowerDNS Authoritative Server 4.5 will only receive critical updates and will be end of life after PowerDNS Authoritative Server 4.8 is released. +PowerDNS Authoritative Server 4.6 will only receive critical updates and will be end of life after PowerDNS Authoritative Server 4.9 is released. -PowerDNS Authoritative Server 4.0 through 4.4, 3.x, and 2.x are End of Life. +PowerDNS Authoritative Server 4.0 through 4.5, 3.x, and 2.x are End of Life. Note: Users with a commercial agreement with PowerDNS.COM BV or Open-Xchange can receive extended support for releases which are End Of Life. If you are @@ -26,6 +26,10 @@ such a user, these EOL statements do not apply to you. - Release date - Critical-Only updates - End of Life + * - 4.8 + - 1st of June 2023 + - ~ December 2023 + - ~ December 2024 * - 4.7 - 20th of October 2022 - ~ April 2023 @@ -37,7 +41,7 @@ such a user, these EOL statements do not apply to you. * - 4.5 - July 13 2021 - 25th of January 2022 - - ~ March 2023 + - EOL June 2023 * - 4.4 - December 18 2020 - 25th of January 2022 From 04cee9810cab8a785e381fd636dc674bbef9c959 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 6 Jun 2023 16:11:59 +0200 Subject: [PATCH 229/909] rec: implement a way to disable specific DNSSEC algorithms This could be needed when runing RHEL9, to avoid having zones signed with algo 5 or 7 going Bogus. RHEL9 does not support these algorithms, unless the globalsecurity policy is modified. --- pdns/dnssecinfra.cc | 17 ++++++++++++++++- pdns/dnssecinfra.hh | 3 +++ pdns/recursordist/rec-main.cc | 27 +++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 1 deletion(-) diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index 5a8e3cd96fcb..c2d76a35d079 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -453,10 +453,25 @@ string getMessageForRRSET(const DNSName& qname, const RRSIGRecordContent& rrc, c return toHash; } +std::unordered_set DNSCryptoKeyEngine::s_switchedOff; + +bool DNSCryptoKeyEngine::isAlgorithmSwitchedOff(unsigned int algo) +{ + return s_switchedOff.count(algo) != 0; +} + +void DNSCryptoKeyEngine::switchOffAlgorithm(unsigned int algo) +{ + s_switchedOff.insert(algo); +} + bool DNSCryptoKeyEngine::isAlgorithmSupported(unsigned int algo) { + if (isAlgorithmSwitchedOff(algo)) { + return false; + } const makers_t& makers = getMakers(); - makers_t::const_iterator iter = makers.find(algo); + auto iter = makers.find(algo); return iter != makers.cend(); } diff --git a/pdns/dnssecinfra.hh b/pdns/dnssecinfra.hh index c6ddb5bc0ec6..c1628fca1ba9 100644 --- a/pdns/dnssecinfra.hh +++ b/pdns/dnssecinfra.hh @@ -166,6 +166,8 @@ class DNSCryptoKeyEngine static std::unique_ptr makeFromPublicKeyString(unsigned int algorithm, const std::string& raw); static std::unique_ptr make(unsigned int algorithm); static bool isAlgorithmSupported(unsigned int algo); + static bool isAlgorithmSwitchedOff(unsigned int algo); + static void switchOffAlgorithm(unsigned int algo); static bool isDigestSupported(uint8_t digest); using maker_t = std::unique_ptr (unsigned int); @@ -189,6 +191,7 @@ class DNSCryptoKeyEngine static allmakers_t s_allmakers; return s_allmakers; } + static std::unordered_set s_switchedOff; protected: const unsigned int d_algorithm; diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 416609fa70a9..563dab5b1542 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1452,6 +1452,32 @@ static int initDNSSEC(Logr::log_t log) g_dnssecLogBogus = ::arg().mustDo("dnssec-log-bogus"); g_maxNSEC3Iterations = ::arg().asNum("nsec3-max-iterations"); + + vector nums; + if (!::arg()["dnssec-disabled-algorithms"].empty()) { + stringtok(nums, ::arg()["dnssec-disabled-algorithms"], ", "); + for (auto num: nums) { + DNSCryptoKeyEngine::switchOffAlgorithm(pdns::checked_stoi(num)); + } + } else { + // Auto determine algos to switch off + } + if (!nums.empty()) { + if (!g_slogStructured) { + g_log << Logger::Warning << "Disabled DNSSEC algorithm: "; + for (auto i = nums.begin(); i != nums.end(); ++i) { + if (i != nums.begin()) { + g_log << Logger::Warning << ", "; + } + g_log << Logger::Warning << *i; + } + g_log << Logger::Warning << endl; + } + else { + log->info(Logr::Notice, "Disabled DNSSEC algorithms", "algorithms", Logging::IterLoggable(nums.begin(), nums.end())); + } + } + return 0; } @@ -2746,6 +2772,7 @@ static void initArgs() ::arg().set("dnssec", "DNSSEC mode: off/process-no-validate/process (default)/log-fail/validate") = "process"; ::arg().set("dnssec-log-bogus", "Log DNSSEC bogus validations") = "no"; ::arg().set("signature-inception-skew", "Allow the signature inception to be off by this number of seconds") = "60"; + ::arg().set("dnssec-disabled-algorithms", "List of DNSSEC algorithm numbers that are considered unsupported") = ""; ::arg().set("daemon", "Operate as a daemon") = "no"; ::arg().setSwitch("write-pid", "Write a PID file") = "yes"; ::arg().set("loglevel", "Amount of logging. Higher is more. Do not set below 3") = "6"; From b602982fc5b4fb9139dec591541e0c070ceb47f5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 8 Mar 2023 18:25:30 +0100 Subject: [PATCH 230/909] YaHTTP: Prevent integer overflow on very large chunks If the chunk_size is very close to the maximum value of an integer, we trigger an integer overflow when checking if we have a trailing newline after the payload. Reported by OSS-Fuzz as: https://oss-fuzz.com/testcase-detail/6439610474692608 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=56804 --- ext/yahttp/yahttp/reqresp.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ext/yahttp/yahttp/reqresp.cpp b/ext/yahttp/yahttp/reqresp.cpp index dc49cb64f601..e5f9c95eccd9 100644 --- a/ext/yahttp/yahttp/reqresp.cpp +++ b/ext/yahttp/yahttp/reqresp.cpp @@ -1,5 +1,7 @@ #include "yahttp.hpp" +#include + namespace YaHTTP { template class AsyncLoader; @@ -177,6 +179,9 @@ namespace YaHTTP { throw ParseError("Unable to parse chunk size"); } if (chunk_size == 0) { state = 3; break; } // last chunk + if (chunk_size > (std::numeric_limits::max() - 2)) { + throw ParseError("Chunk is too large"); + } } else { int crlf=1; if (buffer.size() < static_cast(chunk_size+1)) return false; // expect newline From 81a9420715139879f925156e2c6ec0cd12a3bf84 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 7 Jun 2023 10:19:13 +0200 Subject: [PATCH 231/909] Impelement verification of algos 5 and 7 --- pdns/dnssecinfra.cc | 142 ++++++++++++++++++++++++++-------- pdns/dnssecinfra.hh | 2 + pdns/recursordist/rec-main.cc | 9 ++- 3 files changed, 119 insertions(+), 34 deletions(-) diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index c2d76a35d079..ae2bcfebc69d 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -291,6 +291,103 @@ bool DNSCryptoKeyEngine::testOne(int algo) return ret; } +static map ICSStringToMap(const string& argStr) +{ + unsigned int algorithm = 0; + string sline; + string key; + string value; + string raw; + std::istringstream str(argStr); + map stormap; + + while(std::getline(str, sline)) { + std::tie(key,value)=splitField(sline, ':'); + boost::trim(value); + if(pdns_iequals(key,"algorithm")) { + pdns::checked_stoi_into(algorithm, value); + stormap["algorithm"] = std::to_string(algorithm); + continue; + } + if (pdns_iequals(key,"pin")) { + stormap["pin"] = value; + continue; + } + if (pdns_iequals(key,"engine")) { + stormap["engine"] = value; + continue; + } + if (pdns_iequals(key,"slot")) { + int slot = std::stoi(value); + stormap["slot"]=std::to_string(slot); + continue; + } + if (pdns_iequals(key,"label")) { + stormap["label"] = value; + continue; + } + if(pdns_iequals(key, "Private-key-format")) { + continue; + } + raw.clear(); + B64Decode(value, raw); + stormap[toLower(key)] = raw; + } + return stormap; +} + +void DNSCryptoKeyEngine::testVerify(unsigned int algo, maker_t* verifier) +{ + const string message("Hi! How is life?"); + const string pubkey5 = "AwEAAe2srzo8UfPx5WwoRXTRdo0H8U4iYW6qneronwKlRtXrpOqgZWPtYGVZl1Q7JXqbxxH9aVK5iK6aYOVfxbwwGHejaY0NraqrxL60F5FhHGHg+zox1en8kEX2TcQHxoZaiK1iUgPkMrHJlX5yI5+p2V4qap5VPQsR/WfeFVudNsBEF/XRvg0Exh65fPI/e8sYNgAiflzdN9/5RM644r6viBdieuwUNwEV2HPizCBMssYzx2F29CqNseToqCKQlj1tghuGAsiiSKeosfDLlRPDe/uxtij0wqe0FNybj1oL3OG8Lq3xp8yXIG4CF59xmRDKdnGDmVycKzUWkVOZpesCsUU="; + const string sig5 = "nMnMakbQiiCKIYsEiv4R75+8wvjQav2LPGIKucbqUZUz5sy1ovc2Pp7JVcOuyVyzQu5XH+CetDnTlqiEJWFHNU1jqEwwFK83GVOLABtvXSOvgmGwZGnHOouAchkrzgSSBoEh3+UUN3OsFZA21q6TZVRJBNBm7Ch/PxqSBkFS46ko/qLAUJ1p7/ymzwGNhuOfguHO3dAJ+LgcrNGLZQFDJ1aqT3kZ7LtXX2CQdd7EXgUs6VkE4Z3JN1RmPTk8kAJdZ4JLUR6lgu1dRlSPLGzqv+5d1yI7+h+B0LFNuDdQblDlBstO3LEs1KSaQld+TqVExpjj87oEg6wL/G/XOGabmQ=="; + + const string pubkey7 = "AwEAAc4n7xPG6yJe6YAsg6oQ+7YjbL7wuDLCP4juOSaDsst2Mehc5eYdT7xJT2H9foTIq7ABkkp8Er1Bh6gDzB/0xvArARdH6DS3P5pUP6w5Zoz4Gu79y3pP6IsR3ZyhiQRSnht1ElnIGZzb1zpi7Y4Y8LZ18NYN2qdLasXx/h6hpRjdcF1s7svZKvfJdvCSgDHHD/JFtDGSOn6qt6i5UFSrObxMUMWbxfOsnqr/eXUQcF/aePdqDXO47yDaSH8sFZoglgvEDiOIkky9DV5VKamvVW8anxE5Vv7y4EPpZKXB3CgUW+NvaoasdgYPFmGM4EcnXh2EFFnSPDL6iwDubiL7s2k="; + const string sig7 = "B04Oqmh/nF6BybBGsInauTXH6nlW3VhT2PeSzXVaxQ42QsbbXUgIKuzp2/R7diiEBzbbQ3Eg5vtHOKfEQDkArmOR1oU6yIkyrKHsJkpCvclCyaFiJXrwxkH+A2y8vB+loeDMJKJVwjn7fH9zwBI3Mk7SFuOgYXgzBUNhb5DeQ9RzRbxMcpSc8Cgtjn+QpmTNgL6olpBNsStYz9bSLXBk1EGhmZeBYhliw/2Fse75OoRxIuufKiN6sAD5bKQxp73QQUU+yunVuSeHJizNct8b4f9RXFe49wtZWt5rB0oYXG6zUv0Dq7xJHpUq6v1eB2wf2NucftCKwWu18r4TxkVC5A=="; + + string b64pubkey; + string b64sig; + switch (algo) { + case DNSSECKeeper::RSASHA1: + b64pubkey = pubkey5; + b64sig = sig5; + break; + case DNSSECKeeper::RSASHA1NSEC3SHA1: + b64pubkey = pubkey7; + b64sig = sig7; + break; + default: + throw runtime_error("Verification of verifier called for unimplemented case"); + } + + string pubkey; + string sig; + B64Decode(b64pubkey, pubkey); + B64Decode(b64sig, sig); + auto dckeVerify = verifier(algo); + dckeVerify->fromPublicKeyString(pubkey); + + auto ret = dckeVerify->verify(message, sig); + if (!ret) { + throw runtime_error("Verification of verifier "+dckeVerify->getName() + " failed"); + } +} + +bool DNSCryptoKeyEngine::verifyOne(unsigned int algo) +{ + bool ret=true; + + for (auto* verifier : getAllMakers()[algo]) { + try { + testVerify(algo, verifier); + } + catch (std::exception& e) { + ret = false; + } + } + return ret; +} + void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t* signer, maker_t* verifier) { auto dckeCreate = creator(algo); @@ -316,40 +413,10 @@ void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t cout<<"("<getBits()<<" bits) "; unsigned int udiffCreate = dt.udiff() / 100; - { // FIXME: this block copy/pasted from makeFromISCString + { DNSKEYRecordContent dkrc; - unsigned int algorithm = 0; - string sline, key, value, raw; - std::istringstream str(dckeCreate->convertToISC()); - map stormap; - - while(std::getline(str, sline)) { - std::tie(key,value)=splitField(sline, ':'); - boost::trim(value); - if(pdns_iequals(key,"algorithm")) { - pdns::checked_stoi_into(algorithm, value); - stormap["algorithm"]=std::to_string(algorithm); - continue; - } else if (pdns_iequals(key,"pin")) { - stormap["pin"]=value; - continue; - } else if (pdns_iequals(key,"engine")) { - stormap["engine"]=value; - continue; - } else if (pdns_iequals(key,"slot")) { - int slot = std::stoi(value); - stormap["slot"]=std::to_string(slot); - continue; - } else if (pdns_iequals(key,"label")) { - stormap["label"]=value; - continue; - } - else if(pdns_iequals(key, "Private-key-format")) - continue; - raw.clear(); - B64Decode(value, raw); - stormap[toLower(key)]=raw; - } + auto stormap = ICSStringToMap(dckeCreate->convertToISC()); + dckeSign->fromISCMap(dkrc, stormap); if(!dckeSign->checkKey()) { throw runtime_error("Verification of key with creator "+dckeCreate->getName()+" with signer "+dckeSign->getName()+" and verifier "+dckeVerify->getName()+" failed"); @@ -364,6 +431,15 @@ void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t signature = dckeSign->sign(message); unsigned int udiffSign= dt.udiff()/100, udiffVerify; +#if 0 + if (algo == 7) { + auto pubkey = Base64Encode(dckeSign->getPublicKeyString()); + auto sig = Base64Encode(signature); + cerr << "PubKey: " << pubkey << endl; + cerr << "Signature: " << sig << endl; + } +#endif + dckeVerify->fromPublicKeyString(dckeSign->getPublicKeyString()); if (dckeVerify->getPublicKeyString().compare(dckeSign->getPublicKeyString())) { throw runtime_error("Comparison of public key loaded into verifier produced by signer failed"); diff --git a/pdns/dnssecinfra.hh b/pdns/dnssecinfra.hh index c1628fca1ba9..7d7da8e7ddfe 100644 --- a/pdns/dnssecinfra.hh +++ b/pdns/dnssecinfra.hh @@ -177,6 +177,8 @@ class DNSCryptoKeyEngine static vector> listAllAlgosWithBackend(); static bool testAll(); static bool testOne(int algo); + static bool verifyOne(unsigned int algo); + static void testVerify(unsigned int algo, maker_t* verifier); private: using makers_t = std::map; diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 563dab5b1542..8e80cefff4a8 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -38,6 +38,7 @@ #include "rec-taskqueue.hh" #include "secpoll-recursor.hh" #include "logging.hh" +#include "dnsseckeeper.hh" #ifdef NOD_ENABLED #include "nod.hh" @@ -1460,7 +1461,13 @@ static int initDNSSEC(Logr::log_t log) DNSCryptoKeyEngine::switchOffAlgorithm(pdns::checked_stoi(num)); } } else { - // Auto determine algos to switch off + for (auto algo : { DNSSECKeeper::RSASHA1, DNSSECKeeper::RSASHA1NSEC3SHA1 }) { + if (!DNSCryptoKeyEngine::verifyOne(algo)) { + cerr << "XXXX " << algo << endl; + DNSCryptoKeyEngine::switchOffAlgorithm(algo); + nums.push_back(std::to_string(algo)); + } + } } if (!nums.empty()) { if (!g_slogStructured) { From 5d5aa757e9bc8ef3c054b7244178eb24da6b828a Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 7 Jun 2023 11:42:48 +0200 Subject: [PATCH 232/909] Distinguish auto and manual disabling in logging --- pdns/recursordist/rec-main.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 8e80cefff4a8..1e3838baafb4 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1455,7 +1455,9 @@ static int initDNSSEC(Logr::log_t log) g_maxNSEC3Iterations = ::arg().asNum("nsec3-max-iterations"); vector nums; + bool automatic = true; if (!::arg()["dnssec-disabled-algorithms"].empty()) { + automatic = false; stringtok(nums, ::arg()["dnssec-disabled-algorithms"], ", "); for (auto num: nums) { DNSCryptoKeyEngine::switchOffAlgorithm(pdns::checked_stoi(num)); @@ -1463,7 +1465,6 @@ static int initDNSSEC(Logr::log_t log) } else { for (auto algo : { DNSSECKeeper::RSASHA1, DNSSECKeeper::RSASHA1NSEC3SHA1 }) { if (!DNSCryptoKeyEngine::verifyOne(algo)) { - cerr << "XXXX " << algo << endl; DNSCryptoKeyEngine::switchOffAlgorithm(algo); nums.push_back(std::to_string(algo)); } @@ -1471,7 +1472,7 @@ static int initDNSSEC(Logr::log_t log) } if (!nums.empty()) { if (!g_slogStructured) { - g_log << Logger::Warning << "Disabled DNSSEC algorithm: "; + g_log << Logger::Warning << (automatic ? "Automatically" : "Manually") << " disabled DNSSEC algorithms: "; for (auto i = nums.begin(); i != nums.end(); ++i) { if (i != nums.begin()) { g_log << Logger::Warning << ", "; @@ -1481,7 +1482,7 @@ static int initDNSSEC(Logr::log_t log) g_log << Logger::Warning << endl; } else { - log->info(Logr::Notice, "Disabled DNSSEC algorithms", "algorithms", Logging::IterLoggable(nums.begin(), nums.end())); + log->info(Logr::Notice, "Disabled DNSSEC algorithms", "automatically", Logging::Loggable(automatic), "algorithms", Logging::IterLoggable(nums.begin(), nums.end())); } } From a47ea8ec60bb36df5c4d1c4f0c22c5d447da376f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 7 Jun 2023 12:10:26 +0200 Subject: [PATCH 233/909] Add rec_control command to list supported algo names --- pdns/dnssecinfra.cc | 25 +++++++++++++++++++ pdns/dnssecinfra.hh | 1 + .../docs/manpages/rec_control.1.rst | 3 +++ pdns/recursordist/rec-main.cc | 2 +- pdns/recursordist/rec_channel_rec.cc | 4 +++ 5 files changed, 34 insertions(+), 1 deletion(-) diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index ae2bcfebc69d..095aaab63bd3 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -231,6 +231,31 @@ vector> DNSCryptoKeyEngine::listAllAlgosWithBackend() return ret; } +string DNSCryptoKeyEngine::listSupportedAlgoNames() +{ + set algos; + auto pairs = DNSCryptoKeyEngine::listAllAlgosWithBackend(); + for (const auto& pair : pairs) { + algos.insert(pair.first); + } + string ret; + bool first = true; + for (auto algo : algos) { + if (!first) { + ret.append(" "); + } + else { + first = false; + } + ret.append(DNSSECKeeper::algorithm2name(algo)); + if (isAlgorithmSwitchedOff(algo)) { + ret.append("(disabled)"); + } + } + ret.append("\n"); + return ret; +} + void DNSCryptoKeyEngine::report(unsigned int algo, maker_t* maker, bool fallback) { getAllMakers()[algo].push_back(maker); diff --git a/pdns/dnssecinfra.hh b/pdns/dnssecinfra.hh index 7d7da8e7ddfe..f8de78e9c522 100644 --- a/pdns/dnssecinfra.hh +++ b/pdns/dnssecinfra.hh @@ -179,6 +179,7 @@ class DNSCryptoKeyEngine static bool testOne(int algo); static bool verifyOne(unsigned int algo); static void testVerify(unsigned int algo, maker_t* verifier); + static string listSupportedAlgoNames(); private: using makers_t = std::map; diff --git a/pdns/recursordist/docs/manpages/rec_control.1.rst b/pdns/recursordist/docs/manpages/rec_control.1.rst index c78fccbbc7c6..69817ea5e802 100644 --- a/pdns/recursordist/docs/manpages/rec_control.1.rst +++ b/pdns/recursordist/docs/manpages/rec_control.1.rst @@ -181,6 +181,9 @@ help Shows a list of supported commands understood by the running :program:`pdns_recursor` +list-dnssec-algos + List supported (and potentially disabled) DNSSEC algorithms. + ping Check if server is alive. diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 1e3838baafb4..086f7053f843 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1459,7 +1459,7 @@ static int initDNSSEC(Logr::log_t log) if (!::arg()["dnssec-disabled-algorithms"].empty()) { automatic = false; stringtok(nums, ::arg()["dnssec-disabled-algorithms"], ", "); - for (auto num: nums) { + for (const auto& num: nums) { DNSCryptoKeyEngine::switchOffAlgorithm(pdns::checked_stoi(num)); } } else { diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index f2a7d628e78d..dbcf7b84356f 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -2056,6 +2056,7 @@ RecursorControlChannel::Answer RecursorControlParser::getAnswer(int s, const str "get-remotelogger-stats get remote logger statistics\n" "hash-password [work-factor] ask for a password then return the hashed version\n" "help get this list\n" + "list-dnssec-algos list supported DNSSEC algorithms\n" "ping check that all threads are alive\n" "quit stop the recursor daemon\n" "quit-nicely stop the recursor daemon nicely\n" @@ -2310,6 +2311,9 @@ RecursorControlChannel::Answer RecursorControlParser::getAnswer(int s, const str if (cmd == "get-remotelogger-stats") { return {0, getRemoteLoggerStats()}; } + if (cmd == "list-dnssec-algos") { + return {0, DNSCryptoKeyEngine::listSupportedAlgoNames() }; + } return {1, "Unknown command '" + cmd + "', try 'help'\n"}; } From 1baa6cb681174ed3c9050738ccdb81ef0272dea5 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 7 Jun 2023 12:27:30 +0200 Subject: [PATCH 234/909] Add docs --- pdns/recursordist/docs/settings.rst | 17 +++++++++++++++++ pdns/recursordist/rec-main.cc | 7 ++++--- pdns/recursordist/rec_channel_rec.cc | 2 +- 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index d9ae370ac3c9..3ce5681e75ed 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -533,6 +533,23 @@ Set the mode for DNSSEC processing, as detailed in :doc:`dnssec`. ``validate`` Full blown DNSSEC validation. Send SERVFAIL to clients on bogus responses. +.. _setting-dnssec-disabled-algorithms: + +``dnssec-disabled-algorithms`` +------------------------------ +.. versionadded:: 4.9.0 + +- Comma separated list of DNSSEC algorithm numbers +- Default: (none) + +A list of DNSSEC algorithm numbers that should be considered disabled. +These algorithms will not be used to validate DNSSEC signatures. +Zones (only) signed with these algorithms will be considered ``Insecure``. + +If this setting is empty (the default), :program:`Recursor` will determine which algorithms to disable automatically. +This is important on systems that have a default strict crypto policy, like RHEL9 derived systems. +On such systems not disabling some algorithms (or changing the security policy) will make affected zones to be considered ``Bogus`` as using these algorithms fails. + .. _setting-dnssec-log-bogus: ``dnssec-log-bogus`` diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 086f7053f843..7b8c4ee9ff6c 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1459,11 +1459,12 @@ static int initDNSSEC(Logr::log_t log) if (!::arg()["dnssec-disabled-algorithms"].empty()) { automatic = false; stringtok(nums, ::arg()["dnssec-disabled-algorithms"], ", "); - for (const auto& num: nums) { + for (const auto& num : nums) { DNSCryptoKeyEngine::switchOffAlgorithm(pdns::checked_stoi(num)); } - } else { - for (auto algo : { DNSSECKeeper::RSASHA1, DNSSECKeeper::RSASHA1NSEC3SHA1 }) { + } + else { + for (auto algo : {DNSSECKeeper::RSASHA1, DNSSECKeeper::RSASHA1NSEC3SHA1}) { if (!DNSCryptoKeyEngine::verifyOne(algo)) { DNSCryptoKeyEngine::switchOffAlgorithm(algo); nums.push_back(std::to_string(algo)); diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index dbcf7b84356f..11aa5ec8cec1 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -2312,7 +2312,7 @@ RecursorControlChannel::Answer RecursorControlParser::getAnswer(int s, const str return {0, getRemoteLoggerStats()}; } if (cmd == "list-dnssec-algos") { - return {0, DNSCryptoKeyEngine::listSupportedAlgoNames() }; + return {0, DNSCryptoKeyEngine::listSupportedAlgoNames()}; } return {1, "Unknown command '" + cmd + "', try 'help'\n"}; From 833b07fe444663ba3cb0782a2c67d8a52abf2542 Mon Sep 17 00:00:00 2001 From: Klaus Darilion Date: Wed, 6 Apr 2022 12:37:52 +0000 Subject: [PATCH 235/909] new option 'ignore-errors' for setting 'outgoing-axfr-expand-alias' If the ALIAS target can not be resolved during AXFR the AXFR will fail. To allow outgoing AXFR also if the ALIAS targets are broken set this setting to 'ignore-errors', but be warned, this will lead to inconsistent zones between Primary and Secondary name server. --- docs/guides/alias.rst | 9 +++++++-- docs/settings.rst | 11 ++++++++++- pdns/auth-main.cc | 2 +- pdns/tcpreceiver.cc | 21 +++++++++++++++------ 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/docs/guides/alias.rst b/docs/guides/alias.rst index 2efb6b63bacd..b85762cbaa4a 100644 --- a/docs/guides/alias.rst +++ b/docs/guides/alias.rst @@ -34,6 +34,8 @@ When the authoritative server receives a query for the A-record for ``example.net``, it will resolve the A record for ``mywebapp.paas-provider.net`` and serve an answer for ``example.net`` with that A record. +If the ALIAS target can not be resolved (SERVFAIL) or does not exist +(NXDOMAIN) the authoritative server will answer SERVFAIL. When a zone containing ALIAS records is transferred over AXFR, the :ref:`setting-outgoing-axfr-expand-alias` @@ -42,6 +44,11 @@ default), ALIAS records are sent as-is (RRType 65401 and a DNSName in the RDATA) in the AXFR. When set to 'yes', PowerDNS will lookup the A and AAAA records of the name in the ALIAS-record and send the results in the AXFR. +If the ALIAS target can not be resolved during AXFR the AXFR will fail. +To allow outgoing AXFR also if the ALIAS targets are broken you can set +:ref:`setting-outgoing-axfr-expand-alias` to 'ignore-errors', but +be warned, this will lead to inconsistent zones between the Primary and +Secondary name servers. Set ``outgoing-axfr-expand-alias`` to 'yes' if your slaves don't understand ALIAS or should not look up the addresses themselves. Note @@ -62,5 +69,3 @@ Starting with the PowerDNS Authoritative Server 4.0.0, DNSSEC 'washing' of ALIAS records is supported on AXFR (**not** on live-signing). Set ``outgoing-axfr-expand-alias`` to 'yes' and enable DNSSEC for the zone on the master. PowerDNS will sign the A/AAAA records during the AXFR. - - diff --git a/docs/settings.rst b/docs/settings.rst index 32c8dde935e8..bff6068e968a 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -1278,9 +1278,12 @@ To notify all IP addresses apart from the 192.168.0.0/24 subnet use the followin ``outgoing-axfr-expand-alias`` ------------------------------ -- Boolean +- One of ``no``, ``yes``, or ``ignore-errors``, String - Default: no +.. versionchanged:: 4.9.0 + Option `ignore-errors` added. + If this is enabled, ALIAS records are expanded (synthesized to their A/AAAA) during outgoing AXFR. This means slaves will not automatically follow changes in those A/AAAA records unless you AXFR regularly! @@ -1289,6 +1292,12 @@ If this is disabled (the default), ALIAS records are sent verbatim during outgoing AXFR. Note that if your slaves do not support ALIAS, they will return NODATA for A/AAAA queries for such names. +If the ALIAS target can not be resolved during AXFR the AXFR will fail. +To allow outgoing AXFR also if the ALIAS targets are broken set this +setting to `ignore-errors`. +Be warned, this will lead to inconsistent zones between Primary and +Secondary name servers. + .. _setting-overload-queue-length: ``overload-queue-length`` diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index 5bf5e1ccf622..65170674b222 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -304,7 +304,7 @@ static void declareArguments() ::arg().set("security-poll-suffix", "Zone name from which to query security update notifications") = "secpoll.powerdns.com."; ::arg().setSwitch("expand-alias", "Expand ALIAS records") = "no"; - ::arg().setSwitch("outgoing-axfr-expand-alias", "Expand ALIAS records during outgoing AXFR") = "no"; + ::arg().set("outgoing-axfr-expand-alias", "Expand ALIAS records during outgoing AXFR") = "no"; ::arg().setSwitch("8bit-dns", "Allow 8bit dns queries") = "no"; #ifdef HAVE_LUA_RECORDS ::arg().setSwitch("enable-lua-records", "Process LUA records for all zones (metadata overrides this)") = "no"; diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 12db956bb758..77ae0808f7d1 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -823,15 +823,24 @@ int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr& q, } zrr.dr.d_name.makeUsLowerCase(); if(zrr.dr.d_name.isPartOf(target)) { - if (zrr.dr.d_type == QType::ALIAS && ::arg().mustDo("outgoing-axfr-expand-alias")) { + if (zrr.dr.d_type == QType::ALIAS && (::arg().mustDo("outgoing-axfr-expand-alias") || ::arg()["outgoing-axfr-expand-alias"] == "ignore-errors")) { vector ips; int ret1 = stubDoResolve(getRR(zrr.dr)->getContent(), QType::A, ips); int ret2 = stubDoResolve(getRR(zrr.dr)->getContent(), QType::AAAA, ips); - if(ret1 != RCode::NoError || ret2 != RCode::NoError) { - g_log<getZoneRepresentation()<<", aborting AXFR"<setRcode(RCode::ServFail); - sendPacket(outpacket,outsock); - return 0; + if (ret1 != RCode::NoError || ret2 != RCode::NoError) { + if (::arg()["outgoing-axfr-expand-alias"] != "ignore-errors") { + g_log<getZoneRepresentation()<<", aborting AXFR"<setRcode(RCode::ServFail); + sendPacket(outpacket,outsock); + return 0; + } else { + if (ret1 != RCode::NoError) { + g_log<getZoneRepresentation()<<", continuing AXFR"<getZoneRepresentation()<<", continuing AXFR"< Date: Mon, 5 Jun 2023 22:36:40 +0200 Subject: [PATCH 236/909] auth: log ALIAS resolve failure at AXFR time on Error --- pdns/tcpreceiver.cc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 77ae0808f7d1..b84053ea3f70 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -828,19 +828,20 @@ int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr& q, int ret1 = stubDoResolve(getRR(zrr.dr)->getContent(), QType::A, ips); int ret2 = stubDoResolve(getRR(zrr.dr)->getContent(), QType::AAAA, ips); if (ret1 != RCode::NoError || ret2 != RCode::NoError) { - if (::arg()["outgoing-axfr-expand-alias"] != "ignore-errors") { - g_log<getZoneRepresentation()<<", aborting AXFR"<setRcode(RCode::ServFail); - sendPacket(outpacket,outsock); - return 0; - } else { + if (::arg()["outgoing-axfr-expand-alias"] == "ignore-errors") { if (ret1 != RCode::NoError) { - g_log<getZoneRepresentation()<<", continuing AXFR"<getZoneRepresentation() << ", continuing AXFR" << endl; } if (ret2 != RCode::NoError) { - g_log<getZoneRepresentation()<<", continuing AXFR"<getZoneRepresentation() << ", continuing AXFR" << endl; } } + else { + g_log << Logger::Warning << logPrefix << zrr.dr.d_name.toLogString() << ": error resolving for ALIAS " << zrr.dr.getContent()->getZoneRepresentation() << ", aborting AXFR" << endl; + outpacket->setRcode(RCode::ServFail); + sendPacket(outpacket, outsock); + return 0; + } } for (auto& ip: ips) { zrr.dr.d_type = ip.dr.d_type; From 4387eb5ea84198a4f13261684dfb32cfa99195f1 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 8 Jun 2023 11:30:01 +0200 Subject: [PATCH 237/909] Keep track of metrics for NOD and UDR events. While there, change level of ndr logs to Notice, it was Debug before --- pdns/recursordist/pdns_recursor.cc | 4 +++- pdns/recursordist/rec-tcounters.hh | 2 ++ pdns/recursordist/rec_channel_rec.cc | 3 +++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index e1dbcf7bd414..87d639d0188c 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -590,6 +590,7 @@ static bool nodCheckNewDomain(Logr::log_t nodlogger, const DNSName& dname) SLOG(g_log << Logger::Notice << "Newly observed domain nod=" << dname << endl, nodlogger->info(Logr::Notice, "New domain observed")); } + t_Counters.at(rec::Counter::nodCount)++; ret = true; } } @@ -628,12 +629,13 @@ static bool udrCheckUniqueDNSRecord(Logr::log_t nodlogger, const DNSName& dname, if (g_udrLog) { // This should also probably log to a dedicated file. SLOG(g_log << Logger::Notice << "Unique response observed: qname=" << dname << " qtype=" << QType(qtype) << " rrtype=" << QType(record.d_type) << " rrname=" << record.d_name << " rrcontent=" << record.getContent()->getZoneRepresentation() << endl, - nodlogger->info(Logr::Debug, "New response observed", + nodlogger->info(Logr::Notice, "New response observed", "qtype", Logging::Loggable(QType(qtype)), "rrtype", Logging::Loggable(QType(record.d_type)), "rrname", Logging::Loggable(record.d_name), "rrcontent", Logging::Loggable(record.getContent()->getZoneRepresentation()));); } + t_Counters.at(rec::Counter::udrCount)++; ret = true; } } diff --git a/pdns/recursordist/rec-tcounters.hh b/pdns/recursordist/rec-tcounters.hh index 7d59bde46cfc..23e17efe5667 100644 --- a/pdns/recursordist/rec-tcounters.hh +++ b/pdns/recursordist/rec-tcounters.hh @@ -94,6 +94,8 @@ enum class Counter : uint8_t dns64prefixanswers, maintenanceUsec, maintenanceCalls, + nodCount, + udrCount, numberOfCounters }; diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index f2a7d628e78d..ce807e542cc4 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -1501,6 +1501,9 @@ static void registerAllStats1() addGetStat("maintenance-usec", [] { return g_Counters.sum(rec::Counter::maintenanceUsec); }); addGetStat("maintenance-calls", [] { return g_Counters.sum(rec::Counter::maintenanceCalls); }); + addGetStat("nod-count", [] { return g_Counters.sum(rec::Counter::nodCount); }); + addGetStat("udr-count", [] { return g_Counters.sum(rec::Counter::udrCount); }); + /* make sure that the ECS stats are properly initialized */ SyncRes::clearECSStats(); for (size_t idx = 0; idx < SyncRes::s_ecsResponsesBySubnetSize4.size(); idx++) { From bff67b6e6661027f0df1104bfca45171a6c0a15c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 8 Jun 2023 11:52:02 +0200 Subject: [PATCH 238/909] Add Prometheus and SNMP version of NOD/UDR metrics --- pdns/recursordist/RECURSOR-MIB.txt | 22 +++++++++++++++++++++- pdns/recursordist/docs/metrics.rst | 10 ++++++++++ pdns/recursordist/rec-snmp.cc | 6 ++++++ pdns/recursordist/ws-recursor.cc | 10 ++++++++++ 4 files changed, 47 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/RECURSOR-MIB.txt b/pdns/recursordist/RECURSOR-MIB.txt index 40b26617a90a..318e9bfcf6bc 100644 --- a/pdns/recursordist/RECURSOR-MIB.txt +++ b/pdns/recursordist/RECURSOR-MIB.txt @@ -57,6 +57,9 @@ rec MODULE-IDENTITY REVISION "202302240000Z" DESCRIPTION "Added metrics for sharded packet cache contention" + REVISION "202306080000Z" + DESCRIPTION "Added metrics for NOD and UDR events" + ::= { powerdns 2 } powerdns OBJECT IDENTIFIER ::= { enterprises 43315 } @@ -1231,6 +1234,21 @@ packetCacheAcquired OBJECT-TYPE "Number of packet cache lock acquisitions" ::= { stats 146 } +nodCount OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Count of NOD events" + ::= { stats 147 } + +udrCount OBJECT-TYPE + SYNTAX Counter64 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Count of UDR events" + ::= { stats 148 } --- --- Traps / Notifications @@ -1425,7 +1443,9 @@ recGroup OBJECT-GROUP authrcode14Count, authrcode15Count, packetCacheContended, - packetCacheAcquired + packetCacheAcquired, + nodCount, + udrCount } STATUS current DESCRIPTION "Objects conformance group for PowerDNS Recursor" diff --git a/pdns/recursordist/docs/metrics.rst b/pdns/recursordist/docs/metrics.rst index d54137492c24..7a4508df4088 100644 --- a/pdns/recursordist/docs/metrics.rst +++ b/pdns/recursordist/docs/metrics.rst @@ -551,6 +551,16 @@ no-packet-error ^^^^^^^^^^^^^^^ number of erroneous received packets +nod-count +^^^^^^^^^ +.. versionadded:: 4.9.0 +Count of NOD events + +udr-count +^^^^^^^^^ +.. versionadded:: 4.9.0 +Count of UDR events + nod-lookups-dropped-oversize ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Number of NOD lookups dropped because they would exceed the maximum name length diff --git a/pdns/recursordist/rec-snmp.cc b/pdns/recursordist/rec-snmp.cc index 35519347618a..9b491efa69ad 100644 --- a/pdns/recursordist/rec-snmp.cc +++ b/pdns/recursordist/rec-snmp.cc @@ -170,6 +170,9 @@ static const oid rcode15AnswersOID[] = {RECURSOR_STATS_OID, 144}; static const oid packetCacheContendedOID[] = {RECURSOR_STATS_OID, 145}; static const oid packetCacheAcquiredOID[] = {RECURSOR_STATS_OID, 146}; +static const oid nodCountOID[] = {RECURSOR_STATS_OID, 147}; +static const oid udrCountOID[] = {RECURSOR_STATS_OID, 148}; + static std::unordered_map s_statsMap; /* We are never called for a GETNEXT if it's registered as a @@ -425,5 +428,8 @@ RecursorSNMPAgent::RecursorSNMPAgent(const std::string& name, const std::string& RCODE(14); RCODE(15); + registerCounter64Stat("nod-count", nodCountOID, OID_LENGTH(nodCountOID)); + registerCounter64Stat("udr-count", udrCountOID, OID_LENGTH(udrCountOID)); + #endif /* HAVE_NET_SNMP */ } diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index cefc6a28d8a3..2b7c288e870f 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -1190,6 +1190,13 @@ const std::map MetricDefinitionStorage::d_metrics {"remote-logger-count-o-0", MetricDefinition(PrometheusMetricType::multicounter, "Number of remote logging events")}, + {"nod-count", + MetricDefinition(PrometheusMetricType::counter, + "Count of NOD events")}, + + {"udr-count", + MetricDefinition(PrometheusMetricType::counter, + "Count of UDR events")}, }; constexpr bool CHECK_PROMETHEUS_METRICS = false; @@ -1207,6 +1214,9 @@ static void validatePrometheusMetrics() if (metricName.find("cumul-") == 0) { continue; } + if (metricName.find("auth-") == 0 && metricName.find("-answers") != string::npos) { + continue; + } MetricDefinition metricDetails; if (!s_metricDefinitions.getMetricDetails(metricName, metricDetails)) { From efd3ab2e060eeb246d77b4155eecdaa1249b4302 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 8 Jun 2023 12:11:26 +0200 Subject: [PATCH 239/909] Extend SNMP test to include new OIDs --- regression-tests.recursor-dnssec/test_SNMP.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests.recursor-dnssec/test_SNMP.py b/regression-tests.recursor-dnssec/test_SNMP.py index df688828f511..9a04090ebded 100644 --- a/regression-tests.recursor-dnssec/test_SNMP.py +++ b/regression-tests.recursor-dnssec/test_SNMP.py @@ -21,7 +21,7 @@ class TestSNMP(RecursorTest): """ def _checkStatsValues(self, results): - for i in list(range(1, 93)): + for i in list(range(1, 148)): oid = self._snmpOID + '.1.' + str(i) + '.0' self.assertTrue(oid in results) self.assertTrue(isinstance(results[oid], Counter64)) From 992fc809137915300354a4c6a6268e4e405d92ec Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 8 Jun 2023 12:44:17 +0200 Subject: [PATCH 240/909] rec: keep track of max depth reaches and report it if !quiet This is enough for now, mostly a metric only interesting to devs --- pdns/recursordist/pdns_recursor.cc | 4 +++- pdns/recursordist/syncres.cc | 1 + pdns/recursordist/syncres.hh | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index e1dbcf7bd414..644541d639b6 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -1791,6 +1791,7 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity g_log << ", dnssec=" << sr.getValidationState(); } g_log << " answer-is-variable=" << sr.wasVariable() << ", into-packetcache=" << intoPC; + g_log << " maxdepth=" << sr.d_maxdepth; g_log << endl; } else { @@ -1807,7 +1808,8 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity "rcode", Logging::Loggable(res), "validationState", Logging::Loggable(sr.getValidationState()), "answer-is-variable", Logging::Loggable(sr.wasVariable()), - "into-packetcache", Logging::Loggable(intoPC)); + "into-packetcache", Logging::Loggable(intoPC), + "maxdepth", Logging::Loggable(sr.d_maxdepth)); } } diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index a2cba559bfbb..c6be854ae189 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1824,6 +1824,7 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName& qname, const QType qtyp LOG(prefix << qname << ": Wants " << (d_doDNSSEC ? "" : "NO ") << "DNSSEC processing, " << (d_requireAuthData ? "" : "NO ") << "auth data required by query for " << qtype << endl); + d_maxdepth = std::max(d_maxdepth, depth); if (s_maxdepth > 0) { auto bound = getAdjustedRecursionBound(); // Use a stricter bound if throttling diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 539216bc3b09..c61e78a0de68 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -570,6 +570,7 @@ public: unsigned int d_timeouts; unsigned int d_unreachables; unsigned int d_totUsec; + unsigned int d_maxdepth{0}; // Initialized ony once, as opposed to d_now which gets updated after outgoing requests const struct timeval d_fixednow; From dae6c766c01e0be590d249e8e3c3e52f36bb0470 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 8 Jun 2023 12:49:01 +0200 Subject: [PATCH 241/909] (Partial) Tidy --- pdns/recursordist/rec-snmp.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pdns/recursordist/rec-snmp.cc b/pdns/recursordist/rec-snmp.cc index 9b491efa69ad..162fb3bf66d1 100644 --- a/pdns/recursordist/rec-snmp.cc +++ b/pdns/recursordist/rec-snmp.cc @@ -170,8 +170,8 @@ static const oid rcode15AnswersOID[] = {RECURSOR_STATS_OID, 144}; static const oid packetCacheContendedOID[] = {RECURSOR_STATS_OID, 145}; static const oid packetCacheAcquiredOID[] = {RECURSOR_STATS_OID, 146}; -static const oid nodCountOID[] = {RECURSOR_STATS_OID, 147}; -static const oid udrCountOID[] = {RECURSOR_STATS_OID, 148}; +static const std::array nodCountOID = {RECURSOR_STATS_OID, 147}; +static const std::array udrCountOID = {RECURSOR_STATS_OID, 148}; static std::unordered_map s_statsMap; @@ -428,8 +428,8 @@ RecursorSNMPAgent::RecursorSNMPAgent(const std::string& name, const std::string& RCODE(14); RCODE(15); - registerCounter64Stat("nod-count", nodCountOID, OID_LENGTH(nodCountOID)); - registerCounter64Stat("udr-count", udrCountOID, OID_LENGTH(udrCountOID)); + registerCounter64Stat("nod-count", nodCountOID.data(), nodCountOID.size()); + registerCounter64Stat("udr-count", udrCountOID.data(), udrCountOID.size()); #endif /* HAVE_NET_SNMP */ } From 8e40f5385175f4a1b344ee371aeb27fab7da58d4 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 8 Jun 2023 13:22:43 +0200 Subject: [PATCH 242/909] Prometheus does not like counter names ending in -count --- pdns/recursordist/RECURSOR-MIB.txt | 8 ++++---- pdns/recursordist/docs/metrics.rst | 4 ++-- pdns/recursordist/rec-snmp.cc | 8 ++++---- pdns/recursordist/rec_channel_rec.cc | 4 ++-- pdns/recursordist/ws-recursor.cc | 4 ++-- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/pdns/recursordist/RECURSOR-MIB.txt b/pdns/recursordist/RECURSOR-MIB.txt index 318e9bfcf6bc..f80eab30c0df 100644 --- a/pdns/recursordist/RECURSOR-MIB.txt +++ b/pdns/recursordist/RECURSOR-MIB.txt @@ -1234,7 +1234,7 @@ packetCacheAcquired OBJECT-TYPE "Number of packet cache lock acquisitions" ::= { stats 146 } -nodCount OBJECT-TYPE +nodEvents OBJECT-TYPE SYNTAX Counter64 MAX-ACCESS read-only STATUS current @@ -1242,7 +1242,7 @@ nodCount OBJECT-TYPE "Count of NOD events" ::= { stats 147 } -udrCount OBJECT-TYPE +udrEvents OBJECT-TYPE SYNTAX Counter64 MAX-ACCESS read-only STATUS current @@ -1444,8 +1444,8 @@ recGroup OBJECT-GROUP authrcode15Count, packetCacheContended, packetCacheAcquired, - nodCount, - udrCount + nodEvents, + udrEvents } STATUS current DESCRIPTION "Objects conformance group for PowerDNS Recursor" diff --git a/pdns/recursordist/docs/metrics.rst b/pdns/recursordist/docs/metrics.rst index 7a4508df4088..9247a9955ca6 100644 --- a/pdns/recursordist/docs/metrics.rst +++ b/pdns/recursordist/docs/metrics.rst @@ -551,12 +551,12 @@ no-packet-error ^^^^^^^^^^^^^^^ number of erroneous received packets -nod-count +nod-events ^^^^^^^^^ .. versionadded:: 4.9.0 Count of NOD events -udr-count +udr-events ^^^^^^^^^ .. versionadded:: 4.9.0 Count of UDR events diff --git a/pdns/recursordist/rec-snmp.cc b/pdns/recursordist/rec-snmp.cc index 162fb3bf66d1..8773a158f1c5 100644 --- a/pdns/recursordist/rec-snmp.cc +++ b/pdns/recursordist/rec-snmp.cc @@ -170,8 +170,8 @@ static const oid rcode15AnswersOID[] = {RECURSOR_STATS_OID, 144}; static const oid packetCacheContendedOID[] = {RECURSOR_STATS_OID, 145}; static const oid packetCacheAcquiredOID[] = {RECURSOR_STATS_OID, 146}; -static const std::array nodCountOID = {RECURSOR_STATS_OID, 147}; -static const std::array udrCountOID = {RECURSOR_STATS_OID, 148}; +static const std::array nodEventsOID = {RECURSOR_STATS_OID, 147}; +static const std::array udrEventsOID = {RECURSOR_STATS_OID, 148}; static std::unordered_map s_statsMap; @@ -428,8 +428,8 @@ RecursorSNMPAgent::RecursorSNMPAgent(const std::string& name, const std::string& RCODE(14); RCODE(15); - registerCounter64Stat("nod-count", nodCountOID.data(), nodCountOID.size()); - registerCounter64Stat("udr-count", udrCountOID.data(), udrCountOID.size()); + registerCounter64Stat("nod-events", nodEventsOID.data(), nodEventsOID.size()); + registerCounter64Stat("udr-events", udrEventsOID.data(), udrEventsOID.size()); #endif /* HAVE_NET_SNMP */ } diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index ce807e542cc4..f49243b6ba3c 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -1501,8 +1501,8 @@ static void registerAllStats1() addGetStat("maintenance-usec", [] { return g_Counters.sum(rec::Counter::maintenanceUsec); }); addGetStat("maintenance-calls", [] { return g_Counters.sum(rec::Counter::maintenanceCalls); }); - addGetStat("nod-count", [] { return g_Counters.sum(rec::Counter::nodCount); }); - addGetStat("udr-count", [] { return g_Counters.sum(rec::Counter::udrCount); }); + addGetStat("nod-events", [] { return g_Counters.sum(rec::Counter::nodCount); }); + addGetStat("udr-events", [] { return g_Counters.sum(rec::Counter::udrCount); }); /* make sure that the ECS stats are properly initialized */ SyncRes::clearECSStats(); diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index 2b7c288e870f..46efe7a8c4ea 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -1190,11 +1190,11 @@ const std::map MetricDefinitionStorage::d_metrics {"remote-logger-count-o-0", MetricDefinition(PrometheusMetricType::multicounter, "Number of remote logging events")}, - {"nod-count", + {"nod-events", MetricDefinition(PrometheusMetricType::counter, "Count of NOD events")}, - {"udr-count", + {"udr-events", MetricDefinition(PrometheusMetricType::counter, "Count of UDR events")}, }; From e3f3c9a45a687300c79d3a8f1c0d1e5d1d615f75 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 9 Jun 2023 11:51:04 +0200 Subject: [PATCH 243/909] rec: Prevent duplicate C/DNAMEs to be included when doing serve-stale This can happen if the CNAME record itself was found, but its target not --- pdns/recursordist/syncres.cc | 60 +++++++++++++++++++++++------------- pdns/recursordist/syncres.hh | 2 +- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index c6be854ae189..074488d2a0f5 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1733,7 +1733,7 @@ int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector= 0 ? RCode::to_s(res) : std::to_string(res)) << "/" << ret.size() << endl); return res; } @@ -1841,7 +1841,9 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName& qname, const QType qtyp for (int loop = 0; loop < iterations; loop++) { d_serveStale = loop == 1; - + if (d_serveStale) { + LOG(prefix << qname << ": Restart, with serve-stale enabled" << endl); + } // This is a difficult way of expressing "this is a normal query", i.e. not getRootNS. if (!(d_updatingRootNS && qtype.getCode() == QType::NS && qname.isRoot())) { DNSName authname(qname); @@ -1879,7 +1881,7 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName& qname, const QType qtyp /* When we are looking for a DS, we want to the non-CNAME cache check first because we can actually have a DS (from the parent zone) AND a CNAME (from the child zone), and what we really want is the DS */ - if (qtype != QType::DS && doCNAMECacheCheck(qname, qtype, ret, depth, prefix, res, context, wasAuthZone, wasForwardRecurse)) { // will reroute us if needed + if (qtype != QType::DS && doCNAMECacheCheck(qname, qtype, ret, depth, prefix, res, context, wasAuthZone, wasForwardRecurse, loop == 1)) { // will reroute us if needed d_wasOutOfBand = wasAuthZone; // Here we have an issue. If we were prevented from going out to the network (cache-only was set, possibly because we // are in QM Step0) we might have a CNAME but not the corresponding target. @@ -1928,7 +1930,7 @@ int SyncRes::doResolveNoQNameMinimization(const DNSName& qname, const QType qtyp } /* if we have not found a cached DS (or denial of), now is the time to look for a CNAME */ - if (qtype == QType::DS && doCNAMECacheCheck(qname, qtype, ret, depth, prefix, res, context, wasAuthZone, wasForwardRecurse)) { // will reroute us if needed + if (qtype == QType::DS && doCNAMECacheCheck(qname, qtype, ret, depth, prefix, res, context, wasAuthZone, wasForwardRecurse, loop == 1)) { // will reroute us if needed d_wasOutOfBand = wasAuthZone; // Here we have an issue. If we were prevented from going out to the network (cache-only was set, possibly because we // are in QM Step0) we might have a CNAME but not the corresponding target. @@ -2420,7 +2422,7 @@ static pair scanForCNAMELoop(const DNSName& name, const vect return {false, numCNames}; } -bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse) // NOLINT(readability-function-cognitive-complexity) +bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse, bool checkForDups) // NOLINT(readability-function-cognitive-complexity) { vector cset; vector> signatures; @@ -2504,27 +2506,41 @@ bool SyncRes::doCNAMECacheCheck(const DNSName& qname, const QType qtype, vector< LOG(prefix << qname << ": Found cache " << foundQT.toString() << " hit for '" << foundName << "|" << foundQT.toString() << "' to '" << record.getContent()->getZoneRepresentation() << "', validation state is " << context.state << endl); DNSRecord dr = record; + auto alreadyPresent = false; + + if (checkForDups) { + // This can happen on the 2nd iteration of the servestale loop, where the first iteration + // added a C/DNAME record, but the target resolve failed + for (const auto& dnsrec : ret) { + if (dnsrec.d_type == foundQT && dnsrec.d_name == record.d_name) { + alreadyPresent = true; + break; + } + } + } dr.d_ttl -= d_now.tv_sec; dr.d_ttl = std::min(dr.d_ttl, capTTL); const uint32_t ttl = dr.d_ttl; - ret.reserve(ret.size() + 2 + signatures.size() + authorityRecs.size()); - ret.push_back(dr); + if (!alreadyPresent) { + ret.reserve(ret.size() + 2 + signatures.size() + authorityRecs.size()); + ret.push_back(dr); - for (const auto& signature : signatures) { - DNSRecord sigdr; - sigdr.d_type = QType::RRSIG; - sigdr.d_name = foundName; - sigdr.d_ttl = ttl; - sigdr.setContent(signature); - sigdr.d_place = DNSResourceRecord::ANSWER; - sigdr.d_class = QClass::IN; - ret.push_back(sigdr); - } - - for (const auto& rec : authorityRecs) { - DNSRecord authDR(*rec); - authDR.d_ttl = ttl; - ret.push_back(authDR); + for (const auto& signature : signatures) { + DNSRecord sigdr; + sigdr.d_type = QType::RRSIG; + sigdr.d_name = foundName; + sigdr.d_ttl = ttl; + sigdr.setContent(signature); + sigdr.d_place = DNSResourceRecord::ANSWER; + sigdr.d_class = QClass::IN; + ret.push_back(sigdr); + } + + for (const auto& rec : authorityRecs) { + DNSRecord authDR(*rec); + authDR.d_ttl = ttl; + ret.push_back(authDR); + } } DNSName newTarget; diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index c61e78a0de68..2b3a3082d112 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -623,7 +623,7 @@ private: bool isRecursiveForwardOrAuth(const DNSName& qname) const; bool isForwardOrAuth(const DNSName& qname) const; domainmap_t::const_iterator getBestAuthZone(DNSName* qname) const; - bool doCNAMECacheCheck(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse); + bool doCNAMECacheCheck(const DNSName& qname, QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context, bool wasAuthZone, bool wasForwardRecurse, bool checkForDups); bool doCacheCheck(const DNSName& qname, const DNSName& authname, bool wasForwardedOrAuthZone, bool wasAuthZone, bool wasForwardRecurse, QType qtype, vector& ret, unsigned int depth, const string& prefix, int& res, Context& context); void getBestNSFromCache(const DNSName& qname, QType qtype, vector& bestns, bool* flawedNSSet, unsigned int depth, const string& prefix, set& beenthere, const boost::optional& cutOffDomain = boost::none); DNSName getBestNSNamesFromCache(const DNSName& qname, QType qtype, NsSet& nsset, bool* flawedNSSet, unsigned int depth, const string& prefix, set& beenthere); From 725bf8033245bd87b65dfb55ece21099440e92ee Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 12 May 2023 11:00:25 +0200 Subject: [PATCH 244/909] Reformat --- .not-formatted | 2 - pdns/arguments.cc | 301 ++++++++++++++++++++++------------------------ pdns/arguments.hh | 76 ++++++------ 3 files changed, 184 insertions(+), 195 deletions(-) diff --git a/.not-formatted b/.not-formatted index a9f2b5c61554..cbe3421eb765 100644 --- a/.not-formatted +++ b/.not-formatted @@ -4,8 +4,6 @@ ./ext/lmdb-safe/lmdb-typed.hh ./ext/probds/murmur3.cc ./pdns/anadns.hh -./pdns/arguments.cc -./pdns/arguments.hh ./pdns/auth-caches.cc ./pdns/auth-carbon.cc ./pdns/auth-packetcache.cc diff --git a/pdns/arguments.cc b/pdns/arguments.cc index 7f9f9b558c10..70f66a93eb84 100644 --- a/pdns/arguments.cc +++ b/pdns/arguments.cc @@ -45,74 +45,73 @@ const ArgvMap::param_t::const_iterator ArgvMap::end() return d_params.end(); } -string & ArgvMap::set(const string &var) +string& ArgvMap::set(const string& var) { return d_params[var]; } -void ArgvMap::setDefault(const string &var, const string &value) +void ArgvMap::setDefault(const string& var, const string& value) { - if(! defaultmap.count(var)) + if (!defaultmap.count(var)) defaultmap.insert(pair(var, value)); } void ArgvMap::setDefaults() { - for (const auto& i: d_params) - if(! defaultmap.count(i.first)) + for (const auto& i : d_params) + if (!defaultmap.count(i.first)) defaultmap.insert(i); } -bool ArgvMap::mustDo(const string &var) +bool ArgvMap::mustDo(const string& var) { - return ((*this)[var]!="no") && ((*this)[var]!="off"); + return ((*this)[var] != "no") && ((*this)[var] != "off"); } -vectorArgvMap::list() +vector ArgvMap::list() { vector ret; - for (const auto& i: d_params) + for (const auto& i : d_params) ret.push_back(i.first); return ret; } -string ArgvMap::getHelp(const string &item) +string ArgvMap::getHelp(const string& item) { return helpmap[item]; } -string & ArgvMap::set(const string &var, const string &help) +string& ArgvMap::set(const string& var, const string& help) { - helpmap[var]=help; - d_typeMap[var]="Parameter"; + helpmap[var] = help; + d_typeMap[var] = "Parameter"; return set(var); } -void ArgvMap::setCmd(const string &var, const string &help) +void ArgvMap::setCmd(const string& var, const string& help) { - helpmap[var]=help; - d_typeMap[var]="Command"; - set(var)="no"; + helpmap[var] = help; + d_typeMap[var] = "Command"; + set(var) = "no"; } -string & ArgvMap::setSwitch(const string &var, const string &help) +string& ArgvMap::setSwitch(const string& var, const string& help) { - helpmap[var]=help; - d_typeMap[var]="Switch"; + helpmap[var] = help; + d_typeMap[var] = "Switch"; return set(var); } - -bool ArgvMap::contains(const string &var, const string &val) +bool ArgvMap::contains(const string& var, const string& val) { const auto& param = d_params.find(var); - if(param == d_params.end() || param->second.empty()) { + if (param == d_params.end() || param->second.empty()) { return false; } vector parts; stringtok(parts, param->second, ", \t"); - for (const auto& part: parts) { + for (const auto& part : parts) { if (part == val) { return true; } @@ -123,38 +122,35 @@ bool ArgvMap::contains(const string &var, const string &val) string ArgvMap::helpstring(string prefix) { - if(prefix=="no") - prefix=""; + if (prefix == "no") + prefix = ""; string help; - for (const auto& i: helpmap) { - if(!prefix.empty() && i.first.find(prefix) != 0) // only print items with prefix - continue; - - help+=" --"; - help+=i.first; - - string type=d_typeMap[i.first]; - - if(type=="Parameter") - help+="=..."; - else if(type=="Switch") - { - help+=" | --"+i.first+"=yes"; - help+=" | --"+i.first+"=no"; - } + for (const auto& i : helpmap) { + if (!prefix.empty() && i.first.find(prefix) != 0) // only print items with prefix + continue; + help += " --"; + help += i.first; - help+="\n\t"; - help+=i.second; - help+="\n"; + string type = d_typeMap[i.first]; + if (type == "Parameter") + help += "=..."; + else if (type == "Switch") { + help += " | --" + i.first + "=yes"; + help += " | --" + i.first + "=no"; } + + help += "\n\t"; + help += i.second; + help += "\n"; + } return help; } -const string ArgvMap::formatOne(bool running, bool full, const string &var, const string &help, const string& theDefault, const string& current) +const string ArgvMap::formatOne(bool running, bool full, const string& var, const string& help, const string& theDefault, const string& current) { string out; @@ -165,13 +161,14 @@ const string ArgvMap::formatOne(bool running, bool full, const string &var, cons out += "\t"; out += help; out += "\n#\n"; - } else { + } + else { if (theDefault == current) { return ""; } } - if (! running || theDefault == current) { + if (!running || theDefault == current) { out += "# "; } @@ -180,7 +177,8 @@ const string ArgvMap::formatOne(bool running, bool full, const string &var, cons if (full) { out += "\n"; } - } else { + } + else { out += var + "=" + theDefault + "\n\n"; } @@ -193,28 +191,28 @@ string ArgvMap::configstring(bool running, bool full) string help; if (running) - help="# Autogenerated configuration file based on running instance ("+nowTime()+")\n\n"; + help = "# Autogenerated configuration file based on running instance (" + nowTime() + ")\n\n"; else - help="# Autogenerated configuration file template\n\n"; + help = "# Autogenerated configuration file template\n\n"; // Affects parsing, should come first. help += formatOne(running, full, "ignore-unknown-settings", helpmap["ignore-unknown-settings"], defaultmap["ignore-unknown-settings"], d_params["ignore-unknown-settings"]); - for(const auto& i: helpmap) { + for (const auto& i : helpmap) { if (d_typeMap[i.first] == "Command") continue; if (i.first == "ignore-unknown-settings") continue; if (!defaultmap.count(i.first)) { - throw ArgException(string("Default for setting '")+i.first+"' not set"); + throw ArgException(string("Default for setting '") + i.first + "' not set"); } help += formatOne(running, full, i.first, i.second, defaultmap[i.first], d_params[i.first]); } if (running) { - for(const auto& i: d_unknownParams) { + for (const auto& i : d_unknownParams) { help += formatOne(running, full, i.first, "unknown setting", "", i.second); } } @@ -222,142 +220,142 @@ string ArgvMap::configstring(bool running, bool full) return help; } -const string & ArgvMap::operator[](const string &arg) +const string& ArgvMap::operator[](const string& arg) { - if(!parmIsset(arg)) - throw ArgException(string("Undefined but needed argument: '")+arg+"'"); + if (!parmIsset(arg)) + throw ArgException(string("Undefined but needed argument: '") + arg + "'"); return d_params[arg]; } -mode_t ArgvMap::asMode(const string &arg) +mode_t ArgvMap::asMode(const string& arg) { mode_t mode; - const char *cptr_orig; - char *cptr_ret = nullptr; + const char* cptr_orig; + char* cptr_ret = nullptr; - if(!parmIsset(arg)) - throw ArgException(string("Undefined but needed argument: '")+arg+"'"); + if (!parmIsset(arg)) + throw ArgException(string("Undefined but needed argument: '") + arg + "'"); cptr_orig = d_params[arg].c_str(); mode = static_cast(strtol(cptr_orig, &cptr_ret, 8)); if (mode == 0 && cptr_ret == cptr_orig) throw ArgException("'" + arg + string("' contains invalid octal mode")); - return mode; + return mode; } -gid_t ArgvMap::asGid(const string &arg) +gid_t ArgvMap::asGid(const string& arg) { gid_t gid; - const char *cptr_orig; - char *cptr_ret = nullptr; + const char* cptr_orig; + char* cptr_ret = nullptr; - if(!parmIsset(arg)) - throw ArgException(string("Undefined but needed argument: '")+arg+"'"); + if (!parmIsset(arg)) + throw ArgException(string("Undefined but needed argument: '") + arg + "'"); cptr_orig = d_params[arg].c_str(); gid = static_cast(strtol(cptr_orig, &cptr_ret, 0)); if (gid == 0 && cptr_ret == cptr_orig) { // try to resolve - struct group *group = getgrnam(d_params[arg].c_str()); + struct group* group = getgrnam(d_params[arg].c_str()); if (group == nullptr) - throw ArgException("'" + arg + string("' contains invalid group")); + throw ArgException("'" + arg + string("' contains invalid group")); gid = group->gr_gid; - } - return gid; + } + return gid; } -uid_t ArgvMap::asUid(const string &arg) +uid_t ArgvMap::asUid(const string& arg) { uid_t uid; - const char *cptr_orig; - char *cptr_ret = nullptr; + const char* cptr_orig; + char* cptr_ret = nullptr; - if(!parmIsset(arg)) - throw ArgException(string("Undefined but needed argument: '")+arg+"'"); + if (!parmIsset(arg)) + throw ArgException(string("Undefined but needed argument: '") + arg + "'"); cptr_orig = d_params[arg].c_str(); uid = static_cast(strtol(cptr_orig, &cptr_ret, 0)); if (uid == 0 && cptr_ret == cptr_orig) { // try to resolve - struct passwd *pwent = getpwnam(d_params[arg].c_str()); + struct passwd* pwent = getpwnam(d_params[arg].c_str()); if (pwent == nullptr) - throw ArgException("'" + arg + string("' contains invalid group")); + throw ArgException("'" + arg + string("' contains invalid group")); uid = pwent->pw_uid; - } - return uid; + } + return uid; } -int ArgvMap::asNum(const string &arg, int def) +int ArgvMap::asNum(const string& arg, int def) { int retval; - const char *cptr_orig; - char *cptr_ret = nullptr; + const char* cptr_orig; + char* cptr_ret = nullptr; - if(!parmIsset(arg)) - throw ArgException(string("Undefined but needed argument: '")+arg+"'"); + if (!parmIsset(arg)) + throw ArgException(string("Undefined but needed argument: '") + arg + "'"); // use default for empty values if (d_params[arg].empty()) - return def; + return def; cptr_orig = d_params[arg].c_str(); retval = static_cast(strtol(cptr_orig, &cptr_ret, 0)); if (!retval && cptr_ret == cptr_orig) - throw ArgException("'"+arg+"' value '"+string(cptr_orig) + string( "' is not a valid number")); + throw ArgException("'" + arg + "' value '" + string(cptr_orig) + string("' is not a valid number")); return retval; } -bool ArgvMap::isEmpty(const string &arg) +bool ArgvMap::isEmpty(const string& arg) { - if(!parmIsset(arg)) + if (!parmIsset(arg)) return true; - return d_params[arg].empty(); + return d_params[arg].empty(); } -double ArgvMap::asDouble(const string &arg) +double ArgvMap::asDouble(const string& arg) { double retval; - const char *cptr_orig; - char *cptr_ret = nullptr; + const char* cptr_orig; + char* cptr_ret = nullptr; - if(!parmIsset(arg)) - throw ArgException(string("Undefined but needed argument: '")+arg+"'"); + if (!parmIsset(arg)) + throw ArgException(string("Undefined but needed argument: '") + arg + "'"); if (d_params[arg].empty()) - return 0.0; + return 0.0; cptr_orig = d_params[arg].c_str(); retval = strtod(cptr_orig, &cptr_ret); if (retval == 0 && cptr_ret == cptr_orig) - throw ArgException("'"+arg+string("' is not valid double")); + throw ArgException("'" + arg + string("' is not valid double")); return retval; } ArgvMap::ArgvMap() { - set("ignore-unknown-settings","Configuration settings to ignore if they are unknown")=""; + set("ignore-unknown-settings", "Configuration settings to ignore if they are unknown") = ""; } -bool ArgvMap::parmIsset(const string &var) +bool ArgvMap::parmIsset(const string& var) { return d_params.find(var) != d_params.end(); } // ATM Shared between Recursor and Auth, is that a good idea? -static const map deprecateList = { - { "stats-api-blacklist", "stats-api-disabled-list" }, - { "stats-carbon-blacklist", "stats-carbon-disabled-list" }, - { "stats-rec-control-blacklist", "stats-rec-control-disabled-list" }, - { "stats-snmp-blacklist", "stats-snmp-disabled-list" }, - { "edns-subnet-whitelist", "edns-subnet-allow-list" }, - { "new-domain-whitelist", "new-domain-ignore-list" }, - { "snmp-master-socket", "snmp-daemon-socket" }, - { "xpf-allow-from", "Proxy Protocol" }, - { "xpf-rr-code", "Proxy Protocol" }, +static const map deprecateList = { + {"stats-api-blacklist", "stats-api-disabled-list"}, + {"stats-carbon-blacklist", "stats-carbon-disabled-list"}, + {"stats-rec-control-blacklist", "stats-rec-control-disabled-list"}, + {"stats-snmp-blacklist", "stats-snmp-disabled-list"}, + {"edns-subnet-whitelist", "edns-subnet-allow-list"}, + {"new-domain-whitelist", "new-domain-ignore-list"}, + {"snmp-master-socket", "snmp-daemon-socket"}, + {"xpf-allow-from", "Proxy Protocol"}, + {"xpf-rr-code", "Proxy Protocol"}, }; void ArgvMap::warnIfDeprecated(const string& var) @@ -369,102 +367,96 @@ void ArgvMap::warnIfDeprecated(const string& var) } } -void ArgvMap::parseOne(const string &arg, const string &parseOnly, bool lax) +void ArgvMap::parseOne(const string& arg, const string& parseOnly, bool lax) { string var, val; string::size_type pos; bool incremental = false; - if(arg.find("--") == 0 && (pos=arg.find("+="))!=string::npos) // this is a --port+=25 case + if (arg.find("--") == 0 && (pos = arg.find("+=")) != string::npos) // this is a --port+=25 case { - var=arg.substr(2,pos-2); - val=arg.substr(pos+2); + var = arg.substr(2, pos - 2); + val = arg.substr(pos + 2); incremental = true; } - else if(arg.find("--") == 0 && (pos=arg.find('='))!=string::npos) // this is a --port=25 case + else if (arg.find("--") == 0 && (pos = arg.find('=')) != string::npos) // this is a --port=25 case { - var=arg.substr(2,pos-2); - val=arg.substr(pos+1); + var = arg.substr(2, pos - 2); + val = arg.substr(pos + 1); } - else if(arg.find("--") == 0 && (arg.find('=')==string::npos)) // this is a --daemon case + else if (arg.find("--") == 0 && (arg.find('=') == string::npos)) // this is a --daemon case { - var=arg.substr(2); - val=""; + var = arg.substr(2); + val = ""; } - else if(arg[0]=='-' && arg.length() > 1) - { - var=arg.substr(1); - val=""; + else if (arg[0] == '-' && arg.length() > 1) { + var = arg.substr(1); + val = ""; } else // command d_cmds.push_back(arg); boost::trim(var); - if(var!="" && (parseOnly.empty() || var==parseOnly)) { + if (var != "" && (parseOnly.empty() || var == parseOnly)) { if (!lax) { warnIfDeprecated(var); } - pos=val.find_first_not_of(" \t"); // strip leading whitespace - if(pos && pos!=string::npos) - val=val.substr(pos); - if(parmIsset(var)) - { - if(incremental) - { - if(d_params[var].empty()) - { - if(!d_cleared.count(var)) - throw ArgException("Incremental setting '"+var+"' without a parent"); + pos = val.find_first_not_of(" \t"); // strip leading whitespace + if (pos && pos != string::npos) + val = val.substr(pos); + if (parmIsset(var)) { + if (incremental) { + if (d_params[var].empty()) { + if (!d_cleared.count(var)) + throw ArgException("Incremental setting '" + var + "' without a parent"); d_params[var] = val; } else d_params[var] += ", " + val; } - else - { + else { d_params[var] = val; d_cleared.insert(var); } } - else - { + else { // unknown setting encountered. see if its on the ignore list before throwing. vector parts; stringtok(parts, d_params["ignore-unknown-settings"], " ,\t\n\r"); if (find(parts.begin(), parts.end(), var) != parts.end()) { d_unknownParams[var] = val; - SLOG(g_log<info(Logr::Warning, "Ignoring unknown setting as requested", "name", Logging::Loggable(var))); return; } if (!lax) { - throw ArgException("Trying to set unknown setting '"+var+"'"); + throw ArgException("Trying to set unknown setting '" + var + "'"); } } } } -const vector&ArgvMap::getCommands() +const vector& ArgvMap::getCommands() { return d_cmds; } -void ArgvMap::parse(int &argc, char **argv, bool lax) +void ArgvMap::parse(int& argc, char** argv, bool lax) { d_cmds.clear(); d_cleared.clear(); - for(int n=1;n &extraConfigs) { +void ArgvMap::gatherIncludes(std::vector& extraConfigs) +{ extraConfigs.clear(); if (d_params["include-dir"].empty()) return; // nothing to do - DIR *dir; + DIR* dir; if (!(dir = opendir(d_params["include-dir"].c_str()))) { int err = errno; string msg = d_params["include-dir"] + " is not accessible: " + strerror(err); @@ -571,7 +564,7 @@ void ArgvMap::gatherIncludes(std::vector &extraConfigs) { throw ArgException(msg); } - struct dirent *ent; + struct dirent* ent; while ((ent = readdir(dir)) != nullptr) { if (ent->d_name[0] == '.') continue; // skip any dots diff --git a/pdns/arguments.hh b/pdns/arguments.hh index a242fd0d4be3..402608220a30 100644 --- a/pdns/arguments.hh +++ b/pdns/arguments.hh @@ -71,54 +71,52 @@ typedef PDNSException ArgException; \endcode */ - - class ArgvMap { public: ArgvMap(); - void parse(int &argc, char **argv, bool lax=false); //!< use this to parse from argc and argv - void laxParse(int &argc, char **argv) //!< use this to parse from argc and argv + void parse(int& argc, char** argv, bool lax = false); //!< use this to parse from argc and argv + void laxParse(int& argc, char** argv) //!< use this to parse from argc and argv { - parse(argc,argv,true); + parse(argc, argv, true); } - void preParse(int &argc, char **argv, const string &arg); //!< use this to preparse a single var - bool preParseFile(const char *fname, const string &arg, const string& theDefault=""); //!< use this to preparse a single var in configuration + void preParse(int& argc, char** argv, const string& arg); //!< use this to preparse a single var + bool preParseFile(const char* fname, const string& arg, const string& theDefault = ""); //!< use this to preparse a single var in configuration bool file(const char* fname, bool lax = false); //!< Parses a file with parameters bool file(const char* fname, bool lax, bool included); - bool laxFile(const char *fname) + bool laxFile(const char* fname) { - return file(fname,true); + return file(fname, true); } - bool parseFile(const char *fname, const string& arg, bool lax); // param_t; //!< use this if you need to know the content of the map - bool parmIsset(const string &var); //!< Checks if a parameter is set to *a* value - bool mustDo(const string &var); //!< if a switch is given, if we must do something (--help) - int asNum(const string &var, int def=0); //!< return a variable value as a number or the default if the variable is empty - mode_t asMode(const string &var); //!< return value interpreted as octal number - uid_t asUid(const string &var); //!< return user id, resolves if necessary - gid_t asGid(const string &var); //!< return group id, resolves if necessary - double asDouble(const string &var); //!< return a variable value as a number - string &set(const string &); //!< Gives a writable reference and allocates space for it - string &set(const string &, const string &); //!< Does the same but also allows one to specify a help message - void setCmd(const string &, const string &); //!< Add a command flag - string &setSwitch(const string &, const string &); //!< Add a switch flag - string helpstring(string prefix=""); //!< generates the --help + bool parseFile(const char* fname, const string& arg, bool lax); // param_t; //!< use this if you need to know the content of the map + bool parmIsset(const string& var); //!< Checks if a parameter is set to *a* value + bool mustDo(const string& var); //!< if a switch is given, if we must do something (--help) + int asNum(const string& var, int def = 0); //!< return a variable value as a number or the default if the variable is empty + mode_t asMode(const string& var); //!< return value interpreted as octal number + uid_t asUid(const string& var); //!< return user id, resolves if necessary + gid_t asGid(const string& var); //!< return group id, resolves if necessary + double asDouble(const string& var); //!< return a variable value as a number + string& set(const string&); //!< Gives a writable reference and allocates space for it + string& set(const string&, const string&); //!< Does the same but also allows one to specify a help message + void setCmd(const string&, const string&); //!< Add a command flag + string& setSwitch(const string&, const string&); //!< Add a switch flag + string helpstring(string prefix = ""); //!< generates the --help string configstring(bool current, bool full); //!< generates the --config - bool contains(const string &var, const string &val); - bool isEmpty(const string &var); //!< checks if variable has value - void setDefault(const string &var, const string &value); + bool contains(const string& var, const string& val); + bool isEmpty(const string& var); //!< checks if variable has value + void setDefault(const string& var, const string& value); void setDefaults(); - vectorlist(); - string getHelp(const string &item); + vector list(); + string getHelp(const string& item); const param_t::const_iterator begin(); //!< iterator semantics const param_t::const_iterator end(); //!< iterator semantics - const string &operator[](const string &); //!< iterator semantics - const vector&getCommands(); - void gatherIncludes(std::vector &extraConfigs); + const string& operator[](const string&); //!< iterator semantics + const vector& getCommands(); + void gatherIncludes(std::vector& extraConfigs); #ifdef RECURSOR void setSLog(Logr::log_t log) { @@ -127,13 +125,13 @@ public: #endif private: void warnIfDeprecated(const string& var); - void parseOne(const string &unparsed, const string &parseOnly="", bool lax=false); - const string formatOne(bool running, bool full, const string &var, const string &help, const string& theDefault, const string& value); - map d_params; - map d_unknownParams; - map helpmap; - map defaultmap; - map d_typeMap; + void parseOne(const string& unparsed, const string& parseOnly = "", bool lax = false); + const string formatOne(bool running, bool full, const string& var, const string& help, const string& theDefault, const string& value); + map d_params; + map d_unknownParams; + map helpmap; + map defaultmap; + map d_typeMap; vector d_cmds; std::set d_cleared; #ifdef RECURSOR @@ -141,4 +139,4 @@ private: #endif }; -extern ArgvMap &arg(); +extern ArgvMap& arg(); From bace7695aad62cc7631dc201e1714bbf12a54d3d Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 12 May 2023 11:01:14 +0200 Subject: [PATCH 245/909] Delint arguments.cc and arguments.hh --- pdns/arguments.cc | 226 +++++++++++++++++++++++++--------------------- pdns/arguments.hh | 27 +++--- 2 files changed, 136 insertions(+), 117 deletions(-) diff --git a/pdns/arguments.cc b/pdns/arguments.cc index 70f66a93eb84..32811e51171b 100644 --- a/pdns/arguments.cc +++ b/pdns/arguments.cc @@ -35,12 +35,12 @@ #include #include -const ArgvMap::param_t::const_iterator ArgvMap::begin() +ArgvMap::param_t::const_iterator ArgvMap::begin() { return d_params.begin(); } -const ArgvMap::param_t::const_iterator ArgvMap::end() +ArgvMap::param_t::const_iterator ArgvMap::end() { return d_params.end(); } @@ -52,15 +52,18 @@ string& ArgvMap::set(const string& var) void ArgvMap::setDefault(const string& var, const string& value) { - if (!defaultmap.count(var)) + if (defaultmap.count(var) == 0) { defaultmap.insert(pair(var, value)); + } } void ArgvMap::setDefaults() { - for (const auto& i : d_params) - if (!defaultmap.count(i.first)) - defaultmap.insert(i); + for (const auto& param : d_params) { + if (defaultmap.count(param.first) == 0) { + defaultmap.insert(param); + } + } } bool ArgvMap::mustDo(const string& var) @@ -71,8 +74,10 @@ bool ArgvMap::mustDo(const string& var) vector ArgvMap::list() { vector ret; - for (const auto& i : d_params) - ret.push_back(i.first); + ret.reserve(d_params.size()); + for (const auto& param : d_params) { + ret.push_back(param.first); + } return ret; } @@ -111,46 +116,43 @@ bool ArgvMap::contains(const string& var, const string& val) vector parts; stringtok(parts, param->second, ", \t"); - for (const auto& part : parts) { - if (part == val) { - return true; - } - } - - return false; + return std::any_of(parts.begin(), parts.end(), [&](const std::string& str) { return str == val; }); } string ArgvMap::helpstring(string prefix) { - if (prefix == "no") + if (prefix == "no") { prefix = ""; + } string help; - for (const auto& i : helpmap) { - if (!prefix.empty() && i.first.find(prefix) != 0) // only print items with prefix + for (const auto& helpitem : helpmap) { + if (!prefix.empty() && helpitem.first.find(prefix) != 0) { // only print items with prefix continue; + } help += " --"; - help += i.first; + help += helpitem.first; - string type = d_typeMap[i.first]; + string type = d_typeMap[helpitem.first]; - if (type == "Parameter") + if (type == "Parameter") { help += "=..."; + } else if (type == "Switch") { - help += " | --" + i.first + "=yes"; - help += " | --" + i.first + "=no"; + help += " | --" + helpitem.first + "=yes"; + help += " | --" + helpitem.first + "=no"; } help += "\n\t"; - help += i.second; + help += helpitem.second; help += "\n"; } return help; } -const string ArgvMap::formatOne(bool running, bool full, const string& var, const string& help, const string& theDefault, const string& current) +string ArgvMap::formatOne(bool running, bool full, const string& var, const string& help, const string& theDefault, const string& current) { string out; @@ -190,30 +192,34 @@ string ArgvMap::configstring(bool running, bool full) { string help; - if (running) + if (running) { help = "# Autogenerated configuration file based on running instance (" + nowTime() + ")\n\n"; - else + } + else { help = "# Autogenerated configuration file template\n\n"; + } // Affects parsing, should come first. help += formatOne(running, full, "ignore-unknown-settings", helpmap["ignore-unknown-settings"], defaultmap["ignore-unknown-settings"], d_params["ignore-unknown-settings"]); - for (const auto& i : helpmap) { - if (d_typeMap[i.first] == "Command") + for (const auto& helpietm : helpmap) { + if (d_typeMap[helpietm.first] == "Command") { continue; - if (i.first == "ignore-unknown-settings") + } + if (helpietm.first == "ignore-unknown-settings") { continue; + } - if (!defaultmap.count(i.first)) { - throw ArgException(string("Default for setting '") + i.first + "' not set"); + if (defaultmap.count(helpietm.first) == 0) { + throw ArgException(string("Default for setting '") + helpietm.first + "' not set"); } - help += formatOne(running, full, i.first, i.second, defaultmap[i.first], d_params[i.first]); + help += formatOne(running, full, helpietm.first, helpietm.second, defaultmap[helpietm.first], d_params[helpietm.first]); } if (running) { - for (const auto& i : d_unknownParams) { - help += formatOne(running, full, i.first, "unknown setting", "", i.second); + for (const auto& unknown : d_unknownParams) { + help += formatOne(running, full, unknown.first, "unknown setting", "", unknown.second); } } @@ -222,44 +228,45 @@ string ArgvMap::configstring(bool running, bool full) const string& ArgvMap::operator[](const string& arg) { - if (!parmIsset(arg)) + if (!parmIsset(arg)) { throw ArgException(string("Undefined but needed argument: '") + arg + "'"); + } return d_params[arg]; } mode_t ArgvMap::asMode(const string& arg) { - mode_t mode; - const char* cptr_orig; - char* cptr_ret = nullptr; - - if (!parmIsset(arg)) + if (!parmIsset(arg)) { throw ArgException(string("Undefined but needed argument: '") + arg + "'"); + } - cptr_orig = d_params[arg].c_str(); - mode = static_cast(strtol(cptr_orig, &cptr_ret, 8)); - if (mode == 0 && cptr_ret == cptr_orig) + const auto* const cptr_orig = d_params[arg].c_str(); + char* cptr_ret = nullptr; + + auto mode = static_cast(strtol(cptr_orig, &cptr_ret, 8)); + if (mode == 0 && cptr_ret == cptr_orig) { throw ArgException("'" + arg + string("' contains invalid octal mode")); + } return mode; } gid_t ArgvMap::asGid(const string& arg) { - gid_t gid; - const char* cptr_orig; - char* cptr_ret = nullptr; - - if (!parmIsset(arg)) + if (!parmIsset(arg)) { throw ArgException(string("Undefined but needed argument: '") + arg + "'"); + } - cptr_orig = d_params[arg].c_str(); - gid = static_cast(strtol(cptr_orig, &cptr_ret, 0)); + const auto* cptr_orig = d_params[arg].c_str(); + char* cptr_ret = nullptr; + auto gid = static_cast(strtol(cptr_orig, &cptr_ret, 0)); if (gid == 0 && cptr_ret == cptr_orig) { // try to resolve - struct group* group = getgrnam(d_params[arg].c_str()); - if (group == nullptr) + + struct group* group = getgrnam(d_params[arg].c_str()); // NOLINT: called before going multi-threaded + if (group == nullptr) { throw ArgException("'" + arg + string("' contains invalid group")); + } gid = group->gr_gid; } return gid; @@ -267,20 +274,20 @@ gid_t ArgvMap::asGid(const string& arg) uid_t ArgvMap::asUid(const string& arg) { - uid_t uid; - const char* cptr_orig; - char* cptr_ret = nullptr; - - if (!parmIsset(arg)) + if (!parmIsset(arg)) { throw ArgException(string("Undefined but needed argument: '") + arg + "'"); + } + + const auto* cptr_orig = d_params[arg].c_str(); + char* cptr_ret = nullptr; - cptr_orig = d_params[arg].c_str(); - uid = static_cast(strtol(cptr_orig, &cptr_ret, 0)); + auto uid = static_cast(strtol(cptr_orig, &cptr_ret, 0)); if (uid == 0 && cptr_ret == cptr_orig) { // try to resolve - struct passwd* pwent = getpwnam(d_params[arg].c_str()); - if (pwent == nullptr) + struct passwd* pwent = getpwnam(d_params[arg].c_str()); // NOLINT: called before going multi-threaded + if (pwent == nullptr) { throw ArgException("'" + arg + string("' contains invalid group")); + } uid = pwent->pw_uid; } return uid; @@ -288,49 +295,50 @@ uid_t ArgvMap::asUid(const string& arg) int ArgvMap::asNum(const string& arg, int def) { - int retval; - const char* cptr_orig; - char* cptr_ret = nullptr; - - if (!parmIsset(arg)) + if (!parmIsset(arg)) { throw ArgException(string("Undefined but needed argument: '") + arg + "'"); + } // use default for empty values - if (d_params[arg].empty()) + if (d_params[arg].empty()) { return def; + } - cptr_orig = d_params[arg].c_str(); - retval = static_cast(strtol(cptr_orig, &cptr_ret, 0)); - if (!retval && cptr_ret == cptr_orig) + const auto* cptr_orig = d_params[arg].c_str(); + char* cptr_ret = nullptr; + auto retval = static_cast(strtol(cptr_orig, &cptr_ret, 0)); + if (retval == 0 && cptr_ret == cptr_orig) { throw ArgException("'" + arg + "' value '" + string(cptr_orig) + string("' is not a valid number")); + } return retval; } bool ArgvMap::isEmpty(const string& arg) { - if (!parmIsset(arg)) + if (!parmIsset(arg)) { return true; + } return d_params[arg].empty(); } double ArgvMap::asDouble(const string& arg) { - double retval; - const char* cptr_orig; - char* cptr_ret = nullptr; - - if (!parmIsset(arg)) + if (!parmIsset(arg)) { throw ArgException(string("Undefined but needed argument: '") + arg + "'"); + } - if (d_params[arg].empty()) + if (d_params[arg].empty()) { return 0.0; + } - cptr_orig = d_params[arg].c_str(); - retval = strtod(cptr_orig, &cptr_ret); + const auto* cptr_orig = d_params[arg].c_str(); + char* cptr_ret = nullptr; + auto retval = strtod(cptr_orig, &cptr_ret); - if (retval == 0 && cptr_ret == cptr_orig) + if (retval == 0 && cptr_ret == cptr_orig) { throw ArgException("'" + arg + string("' is not valid double")); + } return retval; } @@ -369,8 +377,9 @@ void ArgvMap::warnIfDeprecated(const string& var) void ArgvMap::parseOne(const string& arg, const string& parseOnly, bool lax) { - string var, val; - string::size_type pos; + string var; + string val; + string::size_type pos = 0; bool incremental = false; if (arg.find("--") == 0 && (pos = arg.find("+=")) != string::npos) // this is a --port+=25 case @@ -393,27 +402,31 @@ void ArgvMap::parseOne(const string& arg, const string& parseOnly, bool lax) var = arg.substr(1); val = ""; } - else // command + else { // command d_cmds.push_back(arg); + } boost::trim(var); - if (var != "" && (parseOnly.empty() || var == parseOnly)) { + if (!var.empty() && (parseOnly.empty() || var == parseOnly)) { if (!lax) { warnIfDeprecated(var); } pos = val.find_first_not_of(" \t"); // strip leading whitespace - if (pos && pos != string::npos) + if (pos != 0 && pos != string::npos) { val = val.substr(pos); + } if (parmIsset(var)) { if (incremental) { if (d_params[var].empty()) { - if (!d_cleared.count(var)) + if (d_cleared.count(var) == 0) { throw ArgException("Incremental setting '" + var + "' without a parent"); + } d_params[var] = val; } - else + else { d_params[var] += ", " + val; + } } else { d_params[var] = val; @@ -447,17 +460,18 @@ void ArgvMap::parse(int& argc, char** argv, bool lax) { d_cmds.clear(); d_cleared.clear(); - for (int n = 1; n < argc; n++) { - parseOne(argv[n], "", lax); + for (int i = 1; i < argc; i++) { + parseOne(argv[i], "", lax); // NOLINT: Posix argument parsing } } void ArgvMap::preParse(int& argc, char** argv, const string& arg) { - for (int n = 1; n < argc; n++) { - string varval = argv[n]; - if (varval.find("--" + arg) == 0) - parseOne(argv[n]); + for (int i = 1; i < argc; i++) { + string varval = argv[i]; // NOLINT: Posix argument parsing + if (varval.find("--" + arg) == 0) { + parseOne(argv[i]); // NOLINT: Posix argument parsing + } } } @@ -552,28 +566,32 @@ bool ArgvMap::file(const char* fname, bool lax, bool included) void ArgvMap::gatherIncludes(std::vector& extraConfigs) { extraConfigs.clear(); - if (d_params["include-dir"].empty()) + if (d_params["include-dir"].empty()) { return; // nothing to do + } - DIR* dir; - if (!(dir = opendir(d_params["include-dir"].c_str()))) { + DIR* dir = nullptr; + if ((dir = opendir(d_params["include-dir"].c_str())) == nullptr) { int err = errno; - string msg = d_params["include-dir"] + " is not accessible: " + strerror(err); + string msg = d_params["include-dir"] + " is not accessible: " + stringerror(err); SLOG(g_log << Logger::Error << msg << std::endl, d_log->error(Logr::Error, err, "Directory is not accessible", "name", Logging::Loggable(d_params["include-dir"]))); throw ArgException(msg); } - struct dirent* ent; - while ((ent = readdir(dir)) != nullptr) { - if (ent->d_name[0] == '.') + struct dirent* ent = nullptr; + while ((ent = readdir(dir)) != nullptr) { // NOLINT(concurrency-mt-unsafe): see Linux man page + if (ent->d_name[0] == '.') { continue; // skip any dots + } if (boost::ends_with(ent->d_name, ".conf")) { // build name - string name = d_params["include-dir"] + "/" + ent->d_name; // FIXME: Use some path separator + string name = d_params["include-dir"] + "/" + ent->d_name; // NOLINT: Posix API // ensure it's readable file - struct stat st; - if (stat(name.c_str(), &st) || !S_ISREG(st.st_mode)) { + struct stat statInfo + { + }; + if (stat(name.c_str(), &statInfo) != 0 || !S_ISREG(statInfo.st_mode)) { string msg = name + " is not a regular file"; SLOG(g_log << Logger::Error << msg << std::endl, d_log->info(Logr::Error, "Unable to open non-regular file", "name", Logging::Loggable(name))); diff --git a/pdns/arguments.hh b/pdns/arguments.hh index 402608220a30..fa5bfcf35547 100644 --- a/pdns/arguments.hh +++ b/pdns/arguments.hh @@ -35,7 +35,7 @@ #include "namespaces.hh" #include "logging.hh" -typedef PDNSException ArgException; +using ArgException = PDNSException; /** This class helps parsing argc and argv into a map of parameters. We have 3 kinds of formats: @@ -90,30 +90,31 @@ public: return file(fname, true); } bool parseFile(const char* fname, const string& arg, bool lax); // param_t; //!< use this if you need to know the content of the map bool parmIsset(const string& var); //!< Checks if a parameter is set to *a* value bool mustDo(const string& var); //!< if a switch is given, if we must do something (--help) - int asNum(const string& var, int def = 0); //!< return a variable value as a number or the default if the variable is empty - mode_t asMode(const string& var); //!< return value interpreted as octal number - uid_t asUid(const string& var); //!< return user id, resolves if necessary - gid_t asGid(const string& var); //!< return group id, resolves if necessary - double asDouble(const string& var); //!< return a variable value as a number + int asNum(const string& arg, int def = 0); //!< return a variable value as a number or the default if the variable is empty + mode_t asMode(const string& arg); //!< return value interpreted as octal number + uid_t asUid(const string& arg); //!< return user id, resolves if necessary + gid_t asGid(const string& arg); //!< return group id, resolves if necessary + double asDouble(const string& arg); //!< return a variable value as a number string& set(const string&); //!< Gives a writable reference and allocates space for it string& set(const string&, const string&); //!< Does the same but also allows one to specify a help message void setCmd(const string&, const string&); //!< Add a command flag string& setSwitch(const string&, const string&); //!< Add a switch flag string helpstring(string prefix = ""); //!< generates the --help - string configstring(bool current, bool full); //!< generates the --config + string configstring(bool running, bool full); //!< generates the --config bool contains(const string& var, const string& val); - bool isEmpty(const string& var); //!< checks if variable has value + bool isEmpty(const string& arg); //!< checks if variable has value void setDefault(const string& var, const string& value); void setDefaults(); vector list(); string getHelp(const string& item); - const param_t::const_iterator begin(); //!< iterator semantics - const param_t::const_iterator end(); //!< iterator semantics + using param_t = map; //!< use this if you need to know the content of the map + + param_t::const_iterator begin(); //!< iterator semantics + param_t::const_iterator end(); //!< iterator semantics const string& operator[](const string&); //!< iterator semantics const vector& getCommands(); void gatherIncludes(std::vector& extraConfigs); @@ -125,8 +126,8 @@ public: #endif private: void warnIfDeprecated(const string& var); - void parseOne(const string& unparsed, const string& parseOnly = "", bool lax = false); - const string formatOne(bool running, bool full, const string& var, const string& help, const string& theDefault, const string& value); + void parseOne(const string& arg, const string& parseOnly = "", bool lax = false); + static string formatOne(bool running, bool full, const string& var, const string& help, const string& theDefault, const string& current); map d_params; map d_unknownParams; map helpmap; From 455eba699569ebbc9cd30ef41b7d04269a8942f1 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 12 Jun 2023 09:40:18 +0200 Subject: [PATCH 246/909] rec: Escape (by prepending "PDNS") message keys that are special to systemd-journal --- pdns/misc.hh | 20 ++++++++++++-------- pdns/recursordist/rec-main.cc | 32 ++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 10 deletions(-) diff --git a/pdns/misc.hh b/pdns/misc.hh index 8800cd7f5390..5757cccc5c27 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -414,17 +414,21 @@ struct CIStringCompare struct CIStringComparePOSIX { - bool operator() (const std::string& lhs, const std::string& rhs) + bool operator() (const std::string& lhs, const std::string& rhs) const { - std::string::const_iterator a,b; const std::locale &loc = std::locale("POSIX"); - a=lhs.begin();b=rhs.begin(); - while(a!=lhs.end()) { - if (b==rhs.end() || std::tolower(*b,loc) special = { + "message", + "message_id", + "priority", + "code_file", + "code_line", + "code_func", + "errno", + "invocation_id", + "user_invocation_id", + "syslog_facility", + "syslog_identifier", + "syslog_pid", + "syslog_timestamp", + "syslog_raw", + "documentation", + "tid", + "unit", + "user_unit", + "object_pid" + }; + // First map SL priority to syslog's Urgency Logger::Urgency u = entry.d_priority ? Logger::Urgency(entry.d_priority) : Logger::Info; if (u > s_logUrgency) { @@ -931,8 +954,13 @@ static void loggerSDBackend(const Logging::Entry& entry) } std::array timebuf{}; appendKeyAndVal("TIMESTAMP", toTimestampStringMilli(entry.d_timestamp, timebuf)); - for (auto const& v : entry.values) { - appendKeyAndVal(toUpper(v.first), v.second); + for (const auto& value : entry.values) { + if (value.first.at(0) == '_' || special.count(value.first) != 0) { + string key{"PDNS"}; + key.append(value.first); + appendKeyAndVal(toUpper(key), value.second); + } + appendKeyAndVal(toUpper(value.first), value.second); } // Thread id filled in by backend, since the SL code does not know about RecursorThreads // We use the Recursor thread, other threads get id 0. May need to revisit. From a3d3c01a4691d9b189d776e302828bb0c6149105 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 12 Jun 2023 09:08:10 +0200 Subject: [PATCH 247/909] Add tests to see if CNAME records are not included multiple times --- pdns/recursordist/test-syncres_cc1.cc | 86 +++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/pdns/recursordist/test-syncres_cc1.cc b/pdns/recursordist/test-syncres_cc1.cc index 3d642a17240c..0cee43468bc1 100644 --- a/pdns/recursordist/test-syncres_cc1.cc +++ b/pdns/recursordist/test-syncres_cc1.cc @@ -1733,6 +1733,92 @@ BOOST_AUTO_TEST_CASE(test_cname_length) BOOST_CHECK_EQUAL(length, SyncRes::s_max_CNAMES_followed + 1); } +BOOST_AUTO_TEST_CASE(test_cname_target_servfail) +{ + std::unique_ptr sr; + initSR(sr); + + primeHints(); + + const DNSName target("cname.powerdns.com."); + const DNSName cnameTarget("cname-target.powerdns.com"); + + sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { + if (isRootServer(ip)) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, domain, QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); + addRecordToLW(res, "a.gtld-servers.net.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600); + return LWResult::Result::Success; + } + if (ip == ComboAddress("192.0.2.1:53")) { + + if (domain == target) { + setLWResult(res, 0, true, false, false); + addRecordToLW(res, domain, QType::CNAME, cnameTarget.toString()); + return LWResult::Result::Success; + } + if (domain == cnameTarget) { + return LWResult::Result::PermanentError; + } + + return LWResult::Result::Success; + } + + return LWResult::Result::Timeout; + }); + + vector ret; + int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::ServFail); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_CHECK(ret[0].d_type == QType::CNAME); + BOOST_CHECK_EQUAL(ret[0].d_name, target); +} + +BOOST_AUTO_TEST_CASE(test_cname_target_servfail_servestale) +{ + std::unique_ptr sr; + initSR(sr); + MemRecursorCache::s_maxServedStaleExtensions = 1440; + + primeHints(); + + const DNSName target("cname.powerdns.com."); + const DNSName cnameTarget("cname-target.powerdns.com"); + + sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { + if (isRootServer(ip)) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, domain, QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); + addRecordToLW(res, "a.gtld-servers.net.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600); + return LWResult::Result::Success; + } + else if (ip == ComboAddress("192.0.2.1:53")) { + + if (domain == target) { + setLWResult(res, 0, true, false, false); + addRecordToLW(res, domain, QType::CNAME, cnameTarget.toString()); + return LWResult::Result::Success; + } + if (domain == cnameTarget) { + return LWResult::Result::PermanentError; + } + + return LWResult::Result::Success; + } + + return LWResult::Result::Timeout; + }); + + vector ret; + int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + // different compared no non-servestale case (returns ServFail), handled by pdns_recursor + BOOST_CHECK_EQUAL(res, -1); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_CHECK(ret[0].d_type == QType::CNAME); + BOOST_CHECK_EQUAL(ret[0].d_name, target); +} + BOOST_AUTO_TEST_CASE(test_time_limit) { std::unique_ptr sr; From e59cfbbe9bb4ada299ff27a24deba535213a799d Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 12 Jun 2023 10:14:03 +0200 Subject: [PATCH 248/909] Process review comments --- pdns/recursordist/docs/metrics.rst | 4 ++-- regression-tests.recursor-dnssec/test_SNMP.py | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/docs/metrics.rst b/pdns/recursordist/docs/metrics.rst index 9247a9955ca6..3700652d9c41 100644 --- a/pdns/recursordist/docs/metrics.rst +++ b/pdns/recursordist/docs/metrics.rst @@ -552,12 +552,12 @@ no-packet-error number of erroneous received packets nod-events -^^^^^^^^^ +^^^^^^^^^^ .. versionadded:: 4.9.0 Count of NOD events udr-events -^^^^^^^^^ +^^^^^^^^^^ .. versionadded:: 4.9.0 Count of UDR events diff --git a/regression-tests.recursor-dnssec/test_SNMP.py b/regression-tests.recursor-dnssec/test_SNMP.py index 9a04090ebded..4ad78640cbcc 100644 --- a/regression-tests.recursor-dnssec/test_SNMP.py +++ b/regression-tests.recursor-dnssec/test_SNMP.py @@ -21,11 +21,15 @@ class TestSNMP(RecursorTest): """ def _checkStatsValues(self, results): - for i in list(range(1, 148)): + count = 148 + for i in list(range(1, count)): oid = self._snmpOID + '.1.' + str(i) + '.0' self.assertTrue(oid in results) self.assertTrue(isinstance(results[oid], Counter64)) + oid = self._snmpOID + '.1.' + str(count + 1) + '.0' + self.assertFalse(oid in results) + # check uptime > 0 self.assertGreater(results['1.3.6.1.4.1.43315.2.1.75.0'], 0) # check memory usage > 0 From 003559e18ada5e91e53f8cad44726d0df5cdb445 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 12 Jun 2023 10:33:47 +0200 Subject: [PATCH 249/909] delint --- pdns/recursordist/test-syncres_cc1.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/pdns/recursordist/test-syncres_cc1.cc b/pdns/recursordist/test-syncres_cc1.cc index 0cee43468bc1..3676524d3c09 100644 --- a/pdns/recursordist/test-syncres_cc1.cc +++ b/pdns/recursordist/test-syncres_cc1.cc @@ -1735,22 +1735,22 @@ BOOST_AUTO_TEST_CASE(test_cname_length) BOOST_AUTO_TEST_CASE(test_cname_target_servfail) { - std::unique_ptr sr; - initSR(sr); + std::unique_ptr resolver; + initSR(resolver); primeHints(); const DNSName target("cname.powerdns.com."); const DNSName cnameTarget("cname-target.powerdns.com"); - sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { - if (isRootServer(ip)) { + resolver->setAsyncCallback([target, cnameTarget](const ComboAddress& ipAddress, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, const boost::optional& /* context */, LWResult* res, bool* /* chained */) { + if (isRootServer(ipAddress)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, domain, QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); addRecordToLW(res, "a.gtld-servers.net.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600); return LWResult::Result::Success; } - if (ip == ComboAddress("192.0.2.1:53")) { + if (ipAddress == ComboAddress("192.0.2.1:53")) { if (domain == target) { setLWResult(res, 0, true, false, false); @@ -1768,7 +1768,7 @@ BOOST_AUTO_TEST_CASE(test_cname_target_servfail) }); vector ret; - int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + int res = resolver->beginResolve(target, QType(QType::A), QClass::IN, ret); BOOST_CHECK_EQUAL(res, RCode::ServFail); BOOST_REQUIRE_EQUAL(ret.size(), 1U); BOOST_CHECK(ret[0].d_type == QType::CNAME); @@ -1777,8 +1777,8 @@ BOOST_AUTO_TEST_CASE(test_cname_target_servfail) BOOST_AUTO_TEST_CASE(test_cname_target_servfail_servestale) { - std::unique_ptr sr; - initSR(sr); + std::unique_ptr resolver; + initSR(resolver); MemRecursorCache::s_maxServedStaleExtensions = 1440; primeHints(); @@ -1786,14 +1786,14 @@ BOOST_AUTO_TEST_CASE(test_cname_target_servfail_servestale) const DNSName target("cname.powerdns.com."); const DNSName cnameTarget("cname-target.powerdns.com"); - sr->setAsyncCallback([target, cnameTarget](const ComboAddress& ip, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { - if (isRootServer(ip)) { + resolver->setAsyncCallback([target, cnameTarget](const ComboAddress& ipAddress, const DNSName& domain, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, const boost::optional& /* context */, LWResult* res, bool* /* chained */) { + if (isRootServer(ipAddress)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, domain, QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY, 172800); addRecordToLW(res, "a.gtld-servers.net.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600); return LWResult::Result::Success; } - else if (ip == ComboAddress("192.0.2.1:53")) { + if (ipAddress == ComboAddress("192.0.2.1:53")) { if (domain == target) { setLWResult(res, 0, true, false, false); @@ -1811,7 +1811,7 @@ BOOST_AUTO_TEST_CASE(test_cname_target_servfail_servestale) }); vector ret; - int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + int res = resolver->beginResolve(target, QType(QType::A), QClass::IN, ret); // different compared no non-servestale case (returns ServFail), handled by pdns_recursor BOOST_CHECK_EQUAL(res, -1); BOOST_REQUIRE_EQUAL(ret.size(), 1U); From d0d3a8a8dce8868a474d62aac2fe213ae6c9ed74 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 12 Jun 2023 10:41:02 +0200 Subject: [PATCH 250/909] rec: uid_t and gid_t can be unsigned, so doing > on and -1 value is tricky --- pdns/recursordist/rec-main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 416609fa70a9..8c9fefe1c32c 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -682,7 +682,7 @@ static void makeControlChannelSocket(int processNum = -1) sockowner = ::arg().asUid("socket-owner"); } - if (sockgroup > -1 || sockowner > -1) { + if (sockgroup != static_cast(-1) || sockowner != static_cast(-1)) { if (chown(sockname.c_str(), sockowner, sockgroup) < 0) { unixDie("Failed to chown control socket"); } From 35bbac75efbd4fb8a9523ab3974bea5507484f65 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 12 Jun 2023 11:04:51 +0200 Subject: [PATCH 251/909] dnsdist: Remove a racy test in the AsynchronousHolder unit tests We are adding an expired event so the worker thread of the AsynchronousHolder can pick it up immediately, even before we come back from the call to push(), which leads to a racy test. This was observed on GitHub Actions when running with TSAN: ``` FAIL: testrunner ================ Running 170 test cases... test-dnsdistasync.cc(156): error: in "test_dnsdistasync/test_AddingExpiredEvent": check !holder->empty() has failed *** 1 failure is detected in the test module "unit" FAIL testrunner (exit status: 201) ``` --- pdns/dnsdistdist/test-dnsdistasync.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/pdns/dnsdistdist/test-dnsdistasync.cc b/pdns/dnsdistdist/test-dnsdistasync.cc index 802ba4021d11..b1fbebca053b 100644 --- a/pdns/dnsdistdist/test-dnsdistasync.cc +++ b/pdns/dnsdistdist/test-dnsdistasync.cc @@ -153,7 +153,6 @@ BOOST_AUTO_TEST_CASE(test_AddingExpiredEvent) sender = query->d_sender; BOOST_REQUIRE(sender != nullptr); holder->push(asyncID, queryID, ttd, std::move(query)); - BOOST_CHECK(!holder->empty()); } // sleep for 20 ms From 897c8fd3bd46e8148926b39094f34883fe33ae1c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 12 Jun 2023 11:02:02 +0200 Subject: [PATCH 252/909] Don't double print and delint --- pdns/recursordist/rec-main.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index c63874c8413b..8ff4e4d545d2 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -905,7 +905,6 @@ static const char* toTimestampStringMilli(const struct timeval& tval, std::array return buf.data(); } -#define HAVE_SYSTEMD #ifdef HAVE_SYSTEMD static void loggerSDBackend(const Logging::Entry& entry) { @@ -928,20 +927,19 @@ static void loggerSDBackend(const Logging::Entry& entry) "tid", "unit", "user_unit", - "object_pid" - }; + "object_pid"}; // First map SL priority to syslog's Urgency - Logger::Urgency u = entry.d_priority ? Logger::Urgency(entry.d_priority) : Logger::Info; - if (u > s_logUrgency) { + Logger::Urgency urgency = entry.d_priority != 0 ? Logger::Urgency(entry.d_priority) : Logger::Info; + if (urgency > s_logUrgency) { // We do not log anything if the Urgency of the message is lower than the requested loglevel. // Not that lower Urgency means higher number. return; } // We need to keep the string in mem until sd_journal_sendv has ben called vector strings; - auto appendKeyAndVal = [&strings](const string& k, const string& v) { - strings.emplace_back(k + "=" + v); + auto appendKeyAndVal = [&strings](const string& key, const string& value) { + strings.emplace_back(key + "=" + value); }; appendKeyAndVal("MESSAGE", entry.message); if (entry.error) { @@ -960,7 +958,9 @@ static void loggerSDBackend(const Logging::Entry& entry) key.append(value.first); appendKeyAndVal(toUpper(key), value.second); } - appendKeyAndVal(toUpper(value.first), value.second); + else { + appendKeyAndVal(toUpper(value.first), value.second); + } } // Thread id filled in by backend, since the SL code does not know about RecursorThreads // We use the Recursor thread, other threads get id 0. May need to revisit. @@ -968,9 +968,9 @@ static void loggerSDBackend(const Logging::Entry& entry) vector iov; iov.reserve(strings.size()); - for (const auto& s : strings) { + for (const auto& str : strings) { // iovec has no 2 arg constructor, so make it explicit - iov.emplace_back(iovec{const_cast(reinterpret_cast(s.data())), s.size()}); + iov.emplace_back(iovec{const_cast(reinterpret_cast(str.data())), str.size()}); // NOLINT: it's the API } sd_journal_sendv(iov.data(), static_cast(iov.size())); } From a2458070bde28fed5a85a27657da1c03b60dd82e Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 7 Jun 2023 13:11:33 +0200 Subject: [PATCH 253/909] Tidy and process review comments --- pdns/dnssecinfra.cc | 28 ++- pdns/dnssecinfra.hh | 3 +- pdns/recursordist/docs/settings.rst | 2 + pdns/recursordist/rec_channel.hh | 10 +- pdns/recursordist/rec_channel_rec.cc | 252 ++++++++++++++------------- 5 files changed, 153 insertions(+), 142 deletions(-) diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index 095aaab63bd3..04ce29193b0d 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -316,7 +316,7 @@ bool DNSCryptoKeyEngine::testOne(int algo) return ret; } -static map ICSStringToMap(const string& argStr) +static map ISCStringtoMap(const string& argStr) { unsigned int algorithm = 0; string sline; @@ -361,7 +361,7 @@ static map ICSStringToMap(const string& argStr) return stormap; } -void DNSCryptoKeyEngine::testVerify(unsigned int algo, maker_t* verifier) +bool DNSCryptoKeyEngine::testVerify(unsigned int algo, maker_t* verifier) { const string message("Hi! How is life?"); const string pubkey5 = "AwEAAe2srzo8UfPx5WwoRXTRdo0H8U4iYW6qneronwKlRtXrpOqgZWPtYGVZl1Q7JXqbxxH9aVK5iK6aYOVfxbwwGHejaY0NraqrxL60F5FhHGHg+zox1en8kEX2TcQHxoZaiK1iUgPkMrHJlX5yI5+p2V4qap5VPQsR/WfeFVudNsBEF/XRvg0Exh65fPI/e8sYNgAiflzdN9/5RM644r6viBdieuwUNwEV2HPizCBMssYzx2F29CqNseToqCKQlj1tghuGAsiiSKeosfDLlRPDe/uxtij0wqe0FNybj1oL3OG8Lq3xp8yXIG4CF59xmRDKdnGDmVycKzUWkVOZpesCsUU="; @@ -393,21 +393,22 @@ void DNSCryptoKeyEngine::testVerify(unsigned int algo, maker_t* verifier) dckeVerify->fromPublicKeyString(pubkey); auto ret = dckeVerify->verify(message, sig); - if (!ret) { - throw runtime_error("Verification of verifier "+dckeVerify->getName() + " failed"); - } + return ret; } bool DNSCryptoKeyEngine::verifyOne(unsigned int algo) { - bool ret=true; + bool ret = false; for (auto* verifier : getAllMakers()[algo]) { try { - testVerify(algo, verifier); + ret = testVerify(algo, verifier); } catch (std::exception& e) { - ret = false; + // Empty + } + if (!ret) { + break; } } return ret; @@ -440,7 +441,7 @@ void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t { DNSKEYRecordContent dkrc; - auto stormap = ICSStringToMap(dckeCreate->convertToISC()); + auto stormap = ISCStringtoMap(dckeCreate->convertToISC()); dckeSign->fromISCMap(dkrc, stormap); if(!dckeSign->checkKey()) { @@ -456,15 +457,6 @@ void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t signature = dckeSign->sign(message); unsigned int udiffSign= dt.udiff()/100, udiffVerify; -#if 0 - if (algo == 7) { - auto pubkey = Base64Encode(dckeSign->getPublicKeyString()); - auto sig = Base64Encode(signature); - cerr << "PubKey: " << pubkey << endl; - cerr << "Signature: " << sig << endl; - } -#endif - dckeVerify->fromPublicKeyString(dckeSign->getPublicKeyString()); if (dckeVerify->getPublicKeyString().compare(dckeSign->getPublicKeyString())) { throw runtime_error("Comparison of public key loaded into verifier produced by signer failed"); diff --git a/pdns/dnssecinfra.hh b/pdns/dnssecinfra.hh index f8de78e9c522..2ba501764050 100644 --- a/pdns/dnssecinfra.hh +++ b/pdns/dnssecinfra.hh @@ -178,7 +178,7 @@ class DNSCryptoKeyEngine static bool testAll(); static bool testOne(int algo); static bool verifyOne(unsigned int algo); - static void testVerify(unsigned int algo, maker_t* verifier); + static bool testVerify(unsigned int algo, maker_t* verifier); static string listSupportedAlgoNames(); private: @@ -194,6 +194,7 @@ class DNSCryptoKeyEngine static allmakers_t s_allmakers; return s_allmakers; } + // Must be set before going multi-threaded and not changed after that static std::unordered_set s_switchedOff; protected: diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 3ce5681e75ed..2d4790d7da5f 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -547,6 +547,8 @@ These algorithms will not be used to validate DNSSEC signatures. Zones (only) signed with these algorithms will be considered ``Insecure``. If this setting is empty (the default), :program:`Recursor` will determine which algorithms to disable automatically. +This is done for specific algorithms only, currently algorithms 5 (``RSASHA1``) and 7 (``RSASHA1NSEC3SHA1``). + This is important on systems that have a default strict crypto policy, like RHEL9 derived systems. On such systems not disabling some algorithms (or changing the security policy) will make affected zones to be considered ``Bogus`` as using these algorithms fails. diff --git a/pdns/recursordist/rec_channel.hh b/pdns/recursordist/rec_channel.hh index 0ad0545f1baf..784539fb2f2a 100644 --- a/pdns/recursordist/rec_channel.hh +++ b/pdns/recursordist/rec_channel.hh @@ -78,13 +78,11 @@ private: class RecursorControlParser { public: - RecursorControlParser() - { - } - static void nop(void) {} - typedef void func_t(void); + RecursorControlParser() = default; + static void nop() {} + using func_t = void(); - RecursorControlChannel::Answer getAnswer(int s, const std::string& question, func_t** func); + static RecursorControlChannel::Answer getAnswer(int socket, const std::string& question, func_t** command); }; enum class StatComponent diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index 11aa5ec8cec1..cafc5c6db6d0 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -2007,87 +2007,138 @@ static void* pleaseSupplantProxyMapping(const ProxyMapping& pm) return nullptr; } -RecursorControlChannel::Answer RecursorControlParser::getAnswer(int s, const string& question, RecursorControlParser::func_t** command) +static RecursorControlChannel::Answer help() +{ + return {0, + "add-dont-throttle-names [N...] add names that are not allowed to be throttled\n" + "add-dont-throttle-netmasks [N...]\n" + " add netmasks that are not allowed to be throttled\n" + "add-nta DOMAIN [REASON] add a Negative Trust Anchor for DOMAIN with the comment REASON\n" + "add-ta DOMAIN DSRECORD add a Trust Anchor for DOMAIN with data DSRECORD\n" + "current-queries show currently active queries\n" + "clear-dont-throttle-names [N...] remove names that are not allowed to be throttled. If N is '*', remove all\n" + "clear-dont-throttle-netmasks [N...]\n" + " remove netmasks that are not allowed to be throttled. If N is '*', remove all\n" + "clear-nta [DOMAIN]... Clear the Negative Trust Anchor for DOMAINs, if no DOMAIN is specified, remove all\n" + "clear-ta [DOMAIN]... Clear the Trust Anchor for DOMAINs\n" + "dump-cache dump cache contents to the named file\n" + "dump-dot-probe-map dump the contents of the DoT probe map to the named file\n" + "dump-edns [status] dump EDNS status to the named file\n" + "dump-failedservers dump the failed servers to the named file\n" + "dump-non-resolving dump non-resolving nameservers addresses to the named file\n" + "dump-nsspeeds dump nsspeeds statistics to the named file\n" + "dump-saved-parent-ns-sets \n" + " dump saved parent ns sets that were successfully used as fallback\n" + "dump-rpz dump the content of a RPZ zone to the named file\n" + "dump-throttlemap dump the contents of the throttle map to the named file\n" + "get [key1] [key2] .. get specific statistics\n" + "get-all get all statistics\n" + "get-dont-throttle-names get the list of names that are not allowed to be throttled\n" + "get-dont-throttle-netmasks get the list of netmasks that are not allowed to be throttled\n" + "get-ntas get all configured Negative Trust Anchors\n" + "get-tas get all configured Trust Anchors\n" + "get-parameter [key1] [key2] .. get configuration parameters\n" + "get-proxymapping-stats get proxy mapping statistics\n" + "get-qtypelist get QType statistics\n" + " notice: queries from cache aren't being counted yet\n" + "get-remotelogger-stats get remote logger statistics\n" + "hash-password [work-factor] ask for a password then return the hashed version\n" + "help get this list\n" + "list-dnssec-algos list supported DNSSEC algorithms\n" + "ping check that all threads are alive\n" + "quit stop the recursor daemon\n" + "quit-nicely stop the recursor daemon nicely\n" + "reload-acls reload ACLS\n" + "reload-lua-script [filename] (re)load Lua script\n" + "reload-lua-config [filename] (re)load Lua configuration file\n" + "reload-zones reload all auth and forward zones\n" + "set-ecs-minimum-ttl value set ecs-minimum-ttl-override\n" + "set-max-cache-entries value set new maximum cache size\n" + "set-max-packetcache-entries val set new maximum packet cache size\n" + "set-minimum-ttl value set minimum-ttl-override\n" + "set-carbon-server set a carbon server for telemetry\n" + "set-dnssec-log-bogus SETTING enable (SETTING=yes) or disable (SETTING=no) logging of DNSSEC validation failures\n" + "set-event-trace-enabled SETTING set logging of event trace messages, 0 = disabled, 1 = protobuf, 2 = log file, 3 = both\n" + "trace-regex [regex file] emit resolution trace for matching queries (no arguments clears tracing)\n" + "top-largeanswer-remotes show top remotes receiving large answers\n" + "top-queries show top queries\n" + "top-pub-queries show top queries grouped by public suffix list\n" + "top-remotes show top remotes\n" + "top-timeouts show top downstream timeouts\n" + "top-servfail-queries show top queries receiving servfail answers\n" + "top-bogus-queries show top queries validating as bogus\n" + "top-pub-servfail-queries show top queries receiving servfail answers grouped by public suffix list\n" + "top-pub-bogus-queries show top queries validating as bogus grouped by public suffix list\n" + "top-servfail-remotes show top remotes receiving servfail answers\n" + "top-bogus-remotes show top remotes receiving bogus answers\n" + "unload-lua-script unload Lua script\n" + "version return Recursor version number\n" + "wipe-cache domain0 [domain1] .. wipe domain data from cache\n" + "wipe-cache-typed type domain0 [domain1] .. wipe domain data with qtype from cache\n"}; +} + +template +static RecursorControlChannel::Answer luaconfig(T begin, T end) +{ + if (begin != end) { + ::arg().set("lua-config-file") = *begin; + } + try { + luaConfigDelayedThreads delayedLuaThreads; + ProxyMapping proxyMapping; + loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads, proxyMapping); + startLuaConfigDelayedThreads(delayedLuaThreads, g_luaconfs.getCopy().generation); + broadcastFunction([=] { return pleaseSupplantProxyMapping(proxyMapping); }); + g_log << Logger::Warning << "Reloaded Lua configuration file '" << ::arg()["lua-config-file"] << "', requested via control channel" << endl; + return {0, "Reloaded Lua configuration file '" + ::arg()["lua-config-file"] + "'\n"}; + } + catch (std::exception& e) { + return {1, "Unable to load Lua script from '" + ::arg()["lua-config-file"] + "': " + e.what() + "\n"}; + } + catch (const PDNSException& e) { + return {1, "Unable to load Lua script from '" + ::arg()["lua-config-file"] + "': " + e.reason + "\n"}; + } +} + +static RecursorControlChannel::Answer reloadACLs() +{ + if (!::arg()["chroot"].empty()) { + g_log << Logger::Error << "Unable to reload ACL when chroot()'ed, requested via control channel" << endl; + return {1, "Unable to reload ACL when chroot()'ed, please restart\n"}; + } + + try { + parseACLs(); + } + catch (std::exception& e) { + g_log << Logger::Error << "Reloading ACLs failed (Exception: " << e.what() << ")" << endl; + return {1, e.what() + string("\n")}; + } + catch (PDNSException& ae) { + g_log << Logger::Error << "Reloading ACLs failed (PDNSException: " << ae.reason << ")" << endl; + return {1, ae.reason + string("\n")}; + } + return {0, "ok\n"}; +} + +RecursorControlChannel::Answer RecursorControlParser::getAnswer(int socket, const string& question, RecursorControlParser::func_t** command) { *command = nop; vector words; stringtok(words, question); - if (words.empty()) + if (words.empty()) { return {1, "invalid command\n"}; + } string cmd = toLower(words[0]); - vector::const_iterator begin = words.begin() + 1, end = words.end(); + auto begin = words.begin() + 1; + auto end = words.end(); // should probably have a smart dispatcher here, like auth has - if (cmd == "help") - return {0, - "add-dont-throttle-names [N...] add names that are not allowed to be throttled\n" - "add-dont-throttle-netmasks [N...]\n" - " add netmasks that are not allowed to be throttled\n" - "add-nta DOMAIN [REASON] add a Negative Trust Anchor for DOMAIN with the comment REASON\n" - "add-ta DOMAIN DSRECORD add a Trust Anchor for DOMAIN with data DSRECORD\n" - "current-queries show currently active queries\n" - "clear-dont-throttle-names [N...] remove names that are not allowed to be throttled. If N is '*', remove all\n" - "clear-dont-throttle-netmasks [N...]\n" - " remove netmasks that are not allowed to be throttled. If N is '*', remove all\n" - "clear-nta [DOMAIN]... Clear the Negative Trust Anchor for DOMAINs, if no DOMAIN is specified, remove all\n" - "clear-ta [DOMAIN]... Clear the Trust Anchor for DOMAINs\n" - "dump-cache dump cache contents to the named file\n" - "dump-dot-probe-map dump the contents of the DoT probe map to the named file\n" - "dump-edns [status] dump EDNS status to the named file\n" - "dump-failedservers dump the failed servers to the named file\n" - "dump-non-resolving dump non-resolving nameservers addresses to the named file\n" - "dump-nsspeeds dump nsspeeds statistics to the named file\n" - "dump-saved-parent-ns-sets \n" - " dump saved parent ns sets that were successfully used as fallback\n" - "dump-rpz dump the content of a RPZ zone to the named file\n" - "dump-throttlemap dump the contents of the throttle map to the named file\n" - "get [key1] [key2] .. get specific statistics\n" - "get-all get all statistics\n" - "get-dont-throttle-names get the list of names that are not allowed to be throttled\n" - "get-dont-throttle-netmasks get the list of netmasks that are not allowed to be throttled\n" - "get-ntas get all configured Negative Trust Anchors\n" - "get-tas get all configured Trust Anchors\n" - "get-parameter [key1] [key2] .. get configuration parameters\n" - "get-proxymapping-stats get proxy mapping statistics\n" - "get-qtypelist get QType statistics\n" - " notice: queries from cache aren't being counted yet\n" - "get-remotelogger-stats get remote logger statistics\n" - "hash-password [work-factor] ask for a password then return the hashed version\n" - "help get this list\n" - "list-dnssec-algos list supported DNSSEC algorithms\n" - "ping check that all threads are alive\n" - "quit stop the recursor daemon\n" - "quit-nicely stop the recursor daemon nicely\n" - "reload-acls reload ACLS\n" - "reload-lua-script [filename] (re)load Lua script\n" - "reload-lua-config [filename] (re)load Lua configuration file\n" - "reload-zones reload all auth and forward zones\n" - "set-ecs-minimum-ttl value set ecs-minimum-ttl-override\n" - "set-max-cache-entries value set new maximum cache size\n" - "set-max-packetcache-entries val set new maximum packet cache size\n" - "set-minimum-ttl value set minimum-ttl-override\n" - "set-carbon-server set a carbon server for telemetry\n" - "set-dnssec-log-bogus SETTING enable (SETTING=yes) or disable (SETTING=no) logging of DNSSEC validation failures\n" - "set-event-trace-enabled SETTING set logging of event trace messages, 0 = disabled, 1 = protobuf, 2 = log file, 3 = both\n" - "trace-regex [regex file] emit resolution trace for matching queries (no arguments clears tracing)\n" - "top-largeanswer-remotes show top remotes receiving large answers\n" - "top-queries show top queries\n" - "top-pub-queries show top queries grouped by public suffix list\n" - "top-remotes show top remotes\n" - "top-timeouts show top downstream timeouts\n" - "top-servfail-queries show top queries receiving servfail answers\n" - "top-bogus-queries show top queries validating as bogus\n" - "top-pub-servfail-queries show top queries receiving servfail answers grouped by public suffix list\n" - "top-pub-bogus-queries show top queries validating as bogus grouped by public suffix list\n" - "top-servfail-remotes show top remotes receiving servfail answers\n" - "top-bogus-remotes show top remotes receiving bogus answers\n" - "unload-lua-script unload Lua script\n" - "version return Recursor version number\n" - "wipe-cache domain0 [domain1] .. wipe domain data from cache\n" - "wipe-cache-typed type domain0 [domain1] .. wipe domain data with qtype from cache\n"}; - + if (cmd == "help") { + return help(); + } if (cmd == "get-all") { return {0, getAllStats()}; } @@ -2109,31 +2160,31 @@ RecursorControlChannel::Answer RecursorControlParser::getAnswer(int s, const str return {0, "bye nicely\n"}; } if (cmd == "dump-cache") { - return doDumpCache(s); + return doDumpCache(socket); } if (cmd == "dump-dot-probe-map") { - return doDumpToFile(s, pleaseDumpDoTProbeMap, cmd, false); + return doDumpToFile(socket, pleaseDumpDoTProbeMap, cmd, false); } if (cmd == "dump-ednsstatus" || cmd == "dump-edns") { - return doDumpToFile(s, pleaseDumpEDNSMap, cmd, false); + return doDumpToFile(socket, pleaseDumpEDNSMap, cmd, false); } if (cmd == "dump-nsspeeds") { - return doDumpToFile(s, pleaseDumpNSSpeeds, cmd, false); + return doDumpToFile(socket, pleaseDumpNSSpeeds, cmd, false); } if (cmd == "dump-failedservers") { - return doDumpToFile(s, pleaseDumpFailedServers, cmd, false); + return doDumpToFile(socket, pleaseDumpFailedServers, cmd, false); } if (cmd == "dump-saved-parent-ns-sets") { - return doDumpToFile(s, pleaseDumpSavedParentNSSets, cmd, false); + return doDumpToFile(socket, pleaseDumpSavedParentNSSets, cmd, false); } if (cmd == "dump-rpz") { - return doDumpRPZ(s, begin, end); + return doDumpRPZ(socket, begin, end); } if (cmd == "dump-throttlemap") { - return doDumpToFile(s, pleaseDumpThrottleMap, cmd, false); + return doDumpToFile(socket, pleaseDumpThrottleMap, cmd, false); } if (cmd == "dump-non-resolving") { - return doDumpToFile(s, pleaseDumpNonResolvingNS, cmd, false); + return doDumpToFile(socket, pleaseDumpNonResolvingNS, cmd, false); } if (cmd == "wipe-cache" || cmd == "flushname") { return {0, doWipeCache(begin, end, 0xffff)}; @@ -2153,54 +2204,21 @@ RecursorControlChannel::Answer RecursorControlParser::getAnswer(int s, const str return doQueueReloadLuaScript(begin, end); } if (cmd == "reload-lua-config") { - if (begin != end) - ::arg().set("lua-config-file") = *begin; - - try { - luaConfigDelayedThreads delayedLuaThreads; - ProxyMapping proxyMapping; - loadRecursorLuaConfig(::arg()["lua-config-file"], delayedLuaThreads, proxyMapping); - startLuaConfigDelayedThreads(delayedLuaThreads, g_luaconfs.getCopy().generation); - broadcastFunction([=] { return pleaseSupplantProxyMapping(proxyMapping); }); - g_log << Logger::Warning << "Reloaded Lua configuration file '" << ::arg()["lua-config-file"] << "', requested via control channel" << endl; - return {0, "Reloaded Lua configuration file '" + ::arg()["lua-config-file"] + "'\n"}; - } - catch (std::exception& e) { - return {1, "Unable to load Lua script from '" + ::arg()["lua-config-file"] + "': " + e.what() + "\n"}; - } - catch (const PDNSException& e) { - return {1, "Unable to load Lua script from '" + ::arg()["lua-config-file"] + "': " + e.reason + "\n"}; - } + return luaconfig(begin, end); } if (cmd == "set-carbon-server") { return {0, doSetCarbonServer(begin, end)}; } if (cmd == "trace-regex") { - return {0, doTraceRegex(begin == end ? FDWrapper(-1) : getfd(s), begin, end)}; + return {0, doTraceRegex(begin == end ? FDWrapper(-1) : getfd(socket), begin, end)}; } if (cmd == "unload-lua-script") { vector empty; - empty.push_back(string()); + empty.emplace_back(); return doQueueReloadLuaScript(empty.begin(), empty.end()); } if (cmd == "reload-acls") { - if (!::arg()["chroot"].empty()) { - g_log << Logger::Error << "Unable to reload ACL when chroot()'ed, requested via control channel" << endl; - return {1, "Unable to reload ACL when chroot()'ed, please restart\n"}; - } - - try { - parseACLs(); - } - catch (std::exception& e) { - g_log << Logger::Error << "Reloading ACLs failed (Exception: " << e.what() << ")" << endl; - return {1, e.what() + string("\n")}; - } - catch (PDNSException& ae) { - g_log << Logger::Error << "Reloading ACLs failed (PDNSException: " << ae.reason << ")" << endl; - return {1, ae.reason + string("\n")}; - } - return {0, "ok\n"}; + return reloadACLs(); } if (cmd == "top-remotes") { return {0, doGenericTopRemotes(pleaseGetRemotes)}; From 621fe9ca2d1db609039d7be553e1fd4ca3a49f55 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 1 Jun 2023 15:57:13 +0200 Subject: [PATCH 254/909] bump sdist builders to alpine 3.18 --- builder-support/dockerfiles/Dockerfile.authoritative | 4 ++-- builder-support/dockerfiles/Dockerfile.dnsdist | 4 ++-- builder-support/dockerfiles/Dockerfile.recursor | 4 ++-- builder-support/dockerfiles/Dockerfile.target.sdist | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/builder-support/dockerfiles/Dockerfile.authoritative b/builder-support/dockerfiles/Dockerfile.authoritative index d1128a75406f..b9318faa85f9 100644 --- a/builder-support/dockerfiles/Dockerfile.authoritative +++ b/builder-support/dockerfiles/Dockerfile.authoritative @@ -1,9 +1,9 @@ -FROM alpine:3.10 as pdns-authoritative +FROM alpine:3.18 as pdns-authoritative ARG BUILDER_CACHE_BUSTER= RUN apk add --no-cache gcc g++ make tar autoconf automake protobuf-dev lua-dev \ libtool file boost-dev curl openssl-dev ragel python3 \ - flex bison git + flex bison git bash # the pdns/ dir is a bit broad, but who cares :) ADD configure.ac Makefile.am COPYING INSTALL NOTICE README /pdns-authoritative/ diff --git a/builder-support/dockerfiles/Dockerfile.dnsdist b/builder-support/dockerfiles/Dockerfile.dnsdist index a6ba2f342121..94438c308c86 100644 --- a/builder-support/dockerfiles/Dockerfile.dnsdist +++ b/builder-support/dockerfiles/Dockerfile.dnsdist @@ -1,8 +1,8 @@ -FROM alpine:3.10 as dnsdist +FROM alpine:3.18 as dnsdist ARG BUILDER_CACHE_BUSTER= RUN apk add --no-cache gcc g++ make tar autoconf automake protobuf-dev lua-dev \ - libtool file boost-dev ragel python3 git libedit-dev + libtool file boost-dev ragel python3 git libedit-dev bash ADD builder/helpers/set-configure-ac-version.sh /dnsdist/builder/helpers/ ADD COPYING /dnsdist/ diff --git a/builder-support/dockerfiles/Dockerfile.recursor b/builder-support/dockerfiles/Dockerfile.recursor index 2a2db79e88f8..2a37f3e9bc8d 100644 --- a/builder-support/dockerfiles/Dockerfile.recursor +++ b/builder-support/dockerfiles/Dockerfile.recursor @@ -1,9 +1,9 @@ -FROM alpine:3.10 as pdns-recursor +FROM alpine:3.18 as pdns-recursor ARG BUILDER_CACHE_BUSTER= RUN apk add --no-cache gcc g++ make tar autoconf automake protobuf-dev lua-dev \ libtool file boost-dev curl openssl-dev ragel python3 \ - flex bison git + flex bison git bash ADD COPYING NOTICE /pdns-recursor/ @EXEC sdist_dirs=(build-aux m4 pdns ext docs) diff --git a/builder-support/dockerfiles/Dockerfile.target.sdist b/builder-support/dockerfiles/Dockerfile.target.sdist index 6bc27fb3ce93..919fb6ebac64 100644 --- a/builder-support/dockerfiles/Dockerfile.target.sdist +++ b/builder-support/dockerfiles/Dockerfile.target.sdist @@ -10,7 +10,7 @@ @INCLUDE Dockerfile.dnsdist @ENDIF -FROM alpine:3.10 as sdist +FROM alpine:3.18 as sdist ARG BUILDER_CACHE_BUSTER= @IF [ -z "$M_authoritative$M_recursor$M_dnsdist$M_all" ] From cdb00dca1aa7e4431923e328213e900cba54d320 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 09:27:39 +0200 Subject: [PATCH 255/909] Typo in var name spotted by @Habbie --- pdns/arguments.cc | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pdns/arguments.cc b/pdns/arguments.cc index 32811e51171b..a1081ddd704e 100644 --- a/pdns/arguments.cc +++ b/pdns/arguments.cc @@ -202,19 +202,19 @@ string ArgvMap::configstring(bool running, bool full) // Affects parsing, should come first. help += formatOne(running, full, "ignore-unknown-settings", helpmap["ignore-unknown-settings"], defaultmap["ignore-unknown-settings"], d_params["ignore-unknown-settings"]); - for (const auto& helpietm : helpmap) { - if (d_typeMap[helpietm.first] == "Command") { + for (const auto& helpitem : helpmap) { + if (d_typeMap[helpitem.first] == "Command") { continue; } - if (helpietm.first == "ignore-unknown-settings") { + if (helpitem.first == "ignore-unknown-settings") { continue; } - if (defaultmap.count(helpietm.first) == 0) { - throw ArgException(string("Default for setting '") + helpietm.first + "' not set"); + if (defaultmap.count(helpitem.first) == 0) { + throw ArgException(string("Default for setting '") + helpitem.first + "' not set"); } - help += formatOne(running, full, helpietm.first, helpietm.second, defaultmap[helpietm.first], d_params[helpietm.first]); + help += formatOne(running, full, helpitem.first, helpitem.second, defaultmap[helpitem.first], d_params[helpitem.first]); } if (running) { From 3fc6d61ca79cd59d3a620badb2255429a04e6155 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 17 Mar 2022 17:02:05 +0100 Subject: [PATCH 256/909] dnsdist: Implement Channels for communication between threads Internally this uses the same mechanism as before, passing pointers over a pipe, but the new classes make that easier to use: - clear separation between sender and receiver - clear ownership of the descriptor - less code duplication --- pdns/dnsdistdist/Makefile.am | 2 + pdns/dnsdistdist/channel.cc | 109 +++++++++++++++ pdns/dnsdistdist/channel.hh | 261 +++++++++++++++++++++++++++++++++++ 3 files changed, 372 insertions(+) create mode 100644 pdns/dnsdistdist/channel.cc create mode 100644 pdns/dnsdistdist/channel.hh diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 439ca398ab62..44487953ffe0 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -130,6 +130,7 @@ dnsdist_SOURCES = \ burtle.hh \ cachecleaner.hh \ capabilities.cc capabilities.hh \ + channel.cc channel.hh \ circular_buffer.hh \ connection-management.hh \ credentials.cc credentials.hh \ @@ -242,6 +243,7 @@ testrunner_SOURCES = \ base64.hh \ bpf-filter.cc bpf-filter.hh \ cachecleaner.hh \ + channel.cc channel.hh \ circular_buffer.hh \ connection-management.hh \ credentials.cc credentials.hh \ diff --git a/pdns/dnsdistdist/channel.cc b/pdns/dnsdistdist/channel.cc new file mode 100644 index 000000000000..dfa33697658f --- /dev/null +++ b/pdns/dnsdistdist/channel.cc @@ -0,0 +1,109 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "channel.hh" + +namespace pdns +{ +namespace channel +{ + + Notifier::Notifier(FDWrapper&& fd) : + d_fd(std::move(fd)) + { + } + + bool Notifier::notify() const + { + char data = 'a'; + auto sent = write(d_fd.getHandle(), &data, sizeof(data)); + if (sent != sizeof(data)) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return false; + } + else { + throw std::runtime_error("Unable to write to channel notifier pipe: " + stringerror()); + } + } + return true; + } + + Waiter::Waiter(FDWrapper&& fd) : + d_fd(std::move(fd)) + { + } + + void Waiter::clear() const + { + ssize_t got; + do { + char data; + got = read(d_fd.getHandle(), &data, sizeof(data)); + if (got == 0) { + throw std::runtime_error("EOF while clearing channel notifier pipe"); + } + else if (got == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + break; + } + throw std::runtime_error("Error while clearing channel notifier pipe: " + stringerror()); + } + } while (got); + } + + int Waiter::getDescriptor() const + { + return d_fd.getHandle(); + } + + std::pair createNotificationQueue(bool nonBlocking, size_t pipeBufferSize) + { + int fds[2] = { -1, -1}; + if (pipe(fds) < 0) { + throw std::runtime_error("Error creating notification channel pipe: " + stringerror()); + } + + if (nonBlocking && !setNonBlocking(fds[0])) { + int err = errno; + close(fds[0]); + close(fds[1]); + throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); + } + + if (nonBlocking && !setNonBlocking(fds[1])) { + int err = errno; + close(fds[0]); + close(fds[1]); + throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); + } + + if (pipeBufferSize > 0 && getPipeBufferSize(fds[0]) < pipeBufferSize) { + setPipeBufferSize(fds[0], pipeBufferSize); + } + + FDWrapper sender(fds[1]); + FDWrapper receiver(fds[0]); + + return std::pair(Notifier(std::move(sender)), Waiter(std::move(receiver))); + } +} +} diff --git a/pdns/dnsdistdist/channel.hh b/pdns/dnsdistdist/channel.hh new file mode 100644 index 000000000000..247264c5d497 --- /dev/null +++ b/pdns/dnsdistdist/channel.hh @@ -0,0 +1,261 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once +#include +#include + +#include "misc.hh" + +namespace pdns +{ +namespace channel +{ + /** + * The sender's end of a channel used to pass objects between threads. + * + * A sender can be used by several threads in a safe way. + */ + template + class Sender + { + public: + Sender() + { + } + Sender(FDWrapper&& fd) : + d_fd(std::move(fd)) + { + } + Sender(const Sender&) = delete; + Sender& operator=(const Sender&) = delete; + Sender(Sender&&) = default; + Sender& operator=(Sender&&) = default; + /** + * \brief Try to send the supplied object to the other end of that channel. Might block if the channel was created in blocking mode. + * + * \return True if the object was properly sent, False if the channel is full. + * + * \throw runtime_error if the channel is broken, for example if the other end has been closed. + */ + bool send(std::unique_ptr&&) const; + + private: + FDWrapper d_fd; + }; + + /** + * The receiver's end of a channel used to pass objects between threads. + * + * A receiver can be used by several threads in a safe way, but in that case spurious wake up might happen. + */ + template + class Receiver + { + public: + Receiver() + { + } + Receiver(FDWrapper&& fd) : + d_fd(std::move(fd)) + { + } + Receiver(const Receiver&) = delete; + Receiver& operator=(const Receiver&) = delete; + Receiver(Receiver&&) = default; + Receiver& operator=(Receiver&&) = default; + /** + * \brief Try to read an object sent by the other end of that channel. Might block if the channel was created in blocking mode. + * + * \return An object if one was available, and std::nullopt otherwise. + * + * \throw runtime_error if the channel is broken, for example if the other end has been closed. + */ + std::optional> receive() const; + + /** + * \brief Get a descriptor that can be used with an I/O multiplexer to wait for an object to become available. + * + * \return A valid descriptor or -1 if the Receiver was not properly initialized. + */ + int getDescriptor() const + { + return d_fd.getHandle(); + } + + private: + FDWrapper d_fd; + }; + + /** + * \brief Create a channel to pass objects between threads, accepting multiple senders and receivers. + * + * \return A pair of Sender and Receiver objects. + * + * \throw runtime_error if the channel creation failed. + */ + template + std::pair, Receiver> createObjectQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); + + /** + * The notifier's end of a channel used to communicate between threads. + * + * A notifier can be used by several threads in a safe way. + */ + class Notifier + { + public: + Notifier() + { + } + Notifier(FDWrapper&&); + Notifier(const Notifier&) = delete; + Notifier& operator=(const Notifier&) = delete; + Notifier(Notifier&&) = default; + Notifier& operator=(Notifier&&) = default; + + /** + * \brief Queue a notification to wake up the other end of the channel. + * + * \return True if the notification was properly sent, False if the channel is full. + * + * \throw runtime_error if the channel is broken, for example if the other end has been closed. + */ + bool notify() const; + + private: + FDWrapper d_fd; + }; + + /** + * The waiter's end of a channel used to communicate between threads. + * + * A waiter can be used by several threads in a safe way, but in that case spurious wake up might happen. + */ + class Waiter + { + public: + Waiter(FDWrapper&&); + Waiter(const Waiter&) = delete; + Waiter& operator=(const Waiter&) = delete; + Waiter(Waiter&&) = default; + Waiter& operator=(Waiter&&) = default; + + /** + * \brief Clear all notifications queued on that channel, if any. + */ + void clear() const; + /** + * \brief Get a descriptor that can be used with an I/O multiplexer to wait for a notification to arrive. + * + * \return A valid descriptor or -1 if the Waiter was not properly initialized. + */ + int getDescriptor() const; + + private: + FDWrapper d_fd; + }; + + /** + * \brief Create a channel to notify one thread from another one, accepting multiple senders and receivers. + * + * \return A pair of Notifier and Sender objects. + * + * \throw runtime_error if the channel creation failed. + */ + std::pair createNotificationQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); + + template + bool Sender::send(std::unique_ptr&& object) const + { + auto ptr = object.release(); + static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranted not to interleaved and to either fully succeed or fail"); + ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); + + if (sent != sizeof(ptr)) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return false; + } + else { + throw std::runtime_error("Unable to write to channel:" + stringerror()); + } + delete ptr; + } + + return true; + } + + template + std::optional> Receiver::receive() const + { + std::optional> result; + T* obj{nullptr}; + ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); + if (got == sizeof(obj)) { + return std::unique_ptr(obj); + } + else if (got == 0) { + throw std::runtime_error("EOF while reading from Channel receiver"); + } + else if (got == -1) { + if (errno == EAGAIN || errno == EINTR) { + return result; + } + throw std::runtime_error("Error while reading from Channel receiver: " + stringerror()); + } + else { + throw std::runtime_error("Partial read from Channel receiver"); + } + } + + template + std::pair, Receiver> createObjectQueue(bool nonBlocking, size_t pipeBufferSize) + { + int fds[2] = { -1, -1}; + if (pipe(fds) < 0) { + throw std::runtime_error("Error creating channel pipe: " + stringerror()); + } + + if (nonBlocking && !setNonBlocking(fds[0])) { + int err = errno; + close(fds[0]); + close(fds[1]); + throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); + } + + if (nonBlocking && !setNonBlocking(fds[1])) { + int err = errno; + close(fds[0]); + close(fds[1]); + throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); + } + + if (pipeBufferSize > 0 && getPipeBufferSize(fds[0]) < pipeBufferSize) { + setPipeBufferSize(fds[0], pipeBufferSize); + } + + FDWrapper sender(fds[1]); + FDWrapper receiver(fds[0]); + + return std::pair(Sender(std::move(sender)), Receiver(std::move(receiver))); + } +} +} From 0a5cb88309c3bb8af51ceddc6b00a0530422c532 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 17 Mar 2022 10:12:08 +0100 Subject: [PATCH 257/909] dnsdist: Refactoring of the outgoing DoH code with pdns::channel --- pdns/dnsdistdist/dnsdist-nghttp2.cc | 142 ++++++++-------------------- 1 file changed, 41 insertions(+), 101 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 5c745eac1c13..34e8abe5eb43 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -32,6 +32,7 @@ #include "dnsdist-downstream-connection.hh" #include "dolog.hh" +#include "channel.hh" #include "iputils.hh" #include "libssl.hh" #include "noinitvector.hh" @@ -368,12 +369,14 @@ void DoHConnectionToBackend::queueQuery(std::shared_ptr& sender, class DoHClientThreadData { public: - DoHClientThreadData() : - mplexer(std::unique_ptr(FDMultiplexer::getMultiplexerSilent())) + DoHClientThreadData(pdns::channel::Receiver&& receiver) : + mplexer(std::unique_ptr(FDMultiplexer::getMultiplexerSilent())), + d_receiver(std::move(receiver)) { } std::unique_ptr mplexer{nullptr}; + pdns::channel::Receiver d_receiver; }; void DoHConnectionToBackend::handleReadableIOCallback(int fd, FDMultiplexer::funcparam_t& param) @@ -856,53 +859,43 @@ DoHConnectionToBackend::DoHConnectionToBackend(const std::shared_ptr(param); - CrossProtocolQuery* tmp{nullptr}; - ssize_t got = read(pipefd, &tmp, sizeof(tmp)); - if (got == 0) { - throw std::runtime_error("EOF while reading from the DoH cross-protocol pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode"); - } - else if (got == -1) { - if (errno == EAGAIN || errno == EINTR) { + std::unique_ptr cpq{nullptr}; + try { + auto tmp = threadData->d_receiver.receive(); + if (!tmp) { return; } - throw std::runtime_error("Error while reading from the DoH cross-protocol pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode:" + stringerror()); + cpq = std::move(*tmp); } - else if (got != sizeof(tmp)) { - throw std::runtime_error("Partial read while reading from the DoH cross-protocol pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode"); + catch (const std::exception& e) { + throw std::runtime_error("Error while reading from the DoH cross-protocol channel:" + std::string(e.what())); } - try { - struct timeval now; - gettimeofday(&now, nullptr); + struct timeval now; + gettimeofday(&now, nullptr); - std::shared_ptr tqs = tmp->getTCPQuerySender(); - auto query = std::move(tmp->query); - auto downstreamServer = std::move(tmp->downstream); - delete tmp; - tmp = nullptr; + std::shared_ptr tqs = cpq->getTCPQuerySender(); + auto query = std::move(cpq->query); + auto downstreamServer = std::move(cpq->downstream); + cpq.reset(); - try { - auto downstream = t_downstreamDoHConnectionsManager.getConnectionToDownstream(threadData->mplexer, downstreamServer, now, std::move(query.d_proxyProtocolPayload)); - downstream->queueQuery(tqs, std::move(query)); - } - catch (...) { - tqs->notifyIOError(std::move(query.d_idstate), now); - } + try { + auto downstream = t_downstreamDoHConnectionsManager.getConnectionToDownstream(threadData->mplexer, downstreamServer, now, std::move(query.d_proxyProtocolPayload)); + downstream->queueQuery(tqs, std::move(query)); } catch (...) { - delete tmp; - tmp = nullptr; + tqs->notifyIOError(std::move(query.d_idstate), now); } } -static void dohClientThread(int crossProtocolPipeFD) +static void dohClientThread(pdns::channel::Receiver&& receiver) { setThreadName("dnsdist/dohClie"); try { - DoHClientThreadData data; - data.mplexer->addReadFD(crossProtocolPipeFD, handleCrossProtocolQuery, &data); + DoHClientThreadData data(std::move(receiver)); + data.mplexer->addReadFD(data.d_receiver.getDescriptor(), handleCrossProtocolQuery, &data); struct timeval now; gettimeofday(&now, nullptr); @@ -976,40 +969,26 @@ struct DoHClientCollection::DoHWorkerThread { } - DoHWorkerThread(int crossProtocolPipe) : - d_crossProtocolQueryPipe(crossProtocolPipe) + DoHWorkerThread(pdns::channel::Sender&& sender) : + d_sender(std::move(sender)) { } DoHWorkerThread(DoHWorkerThread&& rhs) : - d_crossProtocolQueryPipe(rhs.d_crossProtocolQueryPipe) + d_sender(std::move(rhs.d_sender)) { - rhs.d_crossProtocolQueryPipe = -1; } DoHWorkerThread& operator=(DoHWorkerThread&& rhs) { - if (d_crossProtocolQueryPipe != -1) { - close(d_crossProtocolQueryPipe); - } - - d_crossProtocolQueryPipe = rhs.d_crossProtocolQueryPipe; - rhs.d_crossProtocolQueryPipe = -1; - + d_sender = std::move(rhs.d_sender); return *this; } DoHWorkerThread(const DoHWorkerThread& rhs) = delete; DoHWorkerThread& operator=(const DoHWorkerThread&) = delete; - ~DoHWorkerThread() - { - if (d_crossProtocolQueryPipe != -1) { - close(d_crossProtocolQueryPipe); - } - } - - int d_crossProtocolQueryPipe{-1}; + pdns::channel::Sender d_sender; }; DoHClientCollection::DoHClientCollection(size_t numberOfThreads) : @@ -1024,13 +1003,8 @@ bool DoHClientCollection::passCrossProtocolQueryToThread(std::unique_ptr bool { - if (pipe(fds) < 0) { - errlog("Error creating the DoH thread %s pipe: %s", type, stringerror()); - return false; - } - - if (!setNonBlocking(fds[0])) { - int err = errno; - close(fds[0]); - close(fds[1]); - errlog("Error setting the DoH thread %s pipe non-blocking: %s", type, stringerror(err)); - return false; - } - - if (!setNonBlocking(fds[1])) { - int err = errno; - close(fds[0]); - close(fds[1]); - errlog("Error setting the DoH thread %s pipe non-blocking: %s", type, stringerror(err)); - return false; - } - - if (g_tcpInternalPipeBufferSize > 0 && getPipeBufferSize(fds[0]) < g_tcpInternalPipeBufferSize) { - setPipeBufferSize(fds[0], g_tcpInternalPipeBufferSize); - } - - return true; - }; - - int crossProtocolFDs[2] = {-1, -1}; - if (!preparePipe(crossProtocolFDs, "cross-protocol")) { - return; - } - - vinfolog("Adding DoH Client thread"); + try { + auto [sender, receiver] = pdns::channel::createObjectQueue(true, g_tcpInternalPipeBufferSize); - { + vinfolog("Adding DoH Client thread"); std::lock_guard lock(d_mutex); if (d_numberOfThreads >= d_clientThreads.size()) { vinfolog("Adding a new DoH client thread would exceed the vector size (%d/%d), skipping. Consider increasing the maximum amount of DoH client threads with setMaxDoHClientThreads() in the configuration.", d_numberOfThreads, d_clientThreads.size()); - close(crossProtocolFDs[0]); - close(crossProtocolFDs[1]); return; } - /* from now on this side of the pipe will be managed by that object, - no need to worry about it */ - DoHWorkerThread worker(crossProtocolFDs[1]); + DoHWorkerThread worker(std::move(sender)); try { - std::thread t1(dohClientThread, crossProtocolFDs[0]); + std::thread t1(dohClientThread, std::move(receiver)); t1.detach(); } catch (const std::runtime_error& e) { - /* the thread creation failed, don't leak */ + /* the thread creation failed */ errlog("Error creating a DoH thread: %s", e.what()); - close(crossProtocolFDs[0]); return; } d_clientThreads.at(d_numberOfThreads) = std::move(worker); ++d_numberOfThreads; } + catch (const std::exception& e) { + errlog("Error creating the DoH channel: %s", e.what()); + return; + } #else /* HAVE_NGHTTP2 */ throw std::runtime_error("DoHClientCollection::addThread() called but nghttp2 support is not available"); #endif /* HAVE_NGHTTP2 */ From dd5381f58f90bbbcf650825d65b79cee6243486c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 17 Mar 2022 16:26:08 +0100 Subject: [PATCH 258/909] dnsdist: Refactoring of the TCP/TLS workers using channels --- pdns/dnsdist-tcp.cc | 215 +++++++---------------- pdns/dnsdistdist/dnsdist-tcp-upstream.hh | 7 +- pdns/dnsdistdist/dnsdist-tcp.hh | 25 +-- 3 files changed, 82 insertions(+), 165 deletions(-) diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index a5af69e2ced7..17309a4f6642 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -118,7 +118,7 @@ std::shared_ptr IncomingTCPConnectionState::getDownstrea return downstream; } -static void tcpClientThread(int pipefd, int crossProtocolQueriesPipeFD, int crossProtocolResponsesListenPipeFD, int crossProtocolResponsesWritePipeFD, std::vector tcpAcceptStates); +static void tcpClientThread(pdns::channel::Receiver&& queryReceiver, pdns::channel::Receiver&& crossProtocolQueryReceiver, pdns::channel::Receiver&& crossProtocolResponseReceiver, pdns::channel::Sender&& crossProtocolResponseSender, std::vector tcpAcceptStates); TCPClientCollection::TCPClientCollection(size_t maxThreads, std::vector tcpAcceptStates): d_tcpclientthreads(maxThreads), d_maxthreads(maxThreads) { @@ -129,83 +129,37 @@ TCPClientCollection::TCPClientCollection(size_t maxThreads, std::vector& tcpAcceptStates) { - auto preparePipe = [](int fds[2], const std::string& type) -> bool { - if (pipe(fds) < 0) { - errlog("Error creating the TCP thread %s pipe: %s", type, stringerror()); - return false; - } - - if (!setNonBlocking(fds[0])) { - int err = errno; - close(fds[0]); - close(fds[1]); - errlog("Error setting the TCP thread %s pipe non-blocking: %s", type, stringerror(err)); - return false; - } - - if (!setNonBlocking(fds[1])) { - int err = errno; - close(fds[0]); - close(fds[1]); - errlog("Error setting the TCP thread %s pipe non-blocking: %s", type, stringerror(err)); - return false; - } - - if (g_tcpInternalPipeBufferSize > 0 && getPipeBufferSize(fds[0]) < g_tcpInternalPipeBufferSize) { - setPipeBufferSize(fds[0], g_tcpInternalPipeBufferSize); - } - - return true; - }; + try { + auto [queryChannelSender, queryChannelReceiver] = pdns::channel::createObjectQueue(true, g_tcpInternalPipeBufferSize); - int pipefds[2] = { -1, -1}; - if (!preparePipe(pipefds, "communication")) { - return; - } + auto [crossProtocolQueryChannelSender, crossProtocolQueryChannelReceiver] = pdns::channel::createObjectQueue(true, g_tcpInternalPipeBufferSize); - int crossProtocolQueriesFDs[2] = { -1, -1}; - if (!preparePipe(crossProtocolQueriesFDs, "cross-protocol queries")) { - return; - } + auto [crossProtocolResponseChannelSender, crossProtocolResponseChannelReceiver] = pdns::channel::createObjectQueue(true, g_tcpInternalPipeBufferSize); - int crossProtocolResponsesFDs[2] = { -1, -1}; - if (!preparePipe(crossProtocolResponsesFDs, "cross-protocol responses")) { - return; - } + vinfolog("Adding TCP Client thread"); - vinfolog("Adding TCP Client thread"); - - { if (d_numthreads >= d_tcpclientthreads.size()) { vinfolog("Adding a new TCP client thread would exceed the vector size (%d/%d), skipping. Consider increasing the maximum amount of TCP client threads with setMaxTCPClientThreads() in the configuration.", d_numthreads.load(), d_tcpclientthreads.size()); - close(crossProtocolQueriesFDs[0]); - close(crossProtocolQueriesFDs[1]); - close(crossProtocolResponsesFDs[0]); - close(crossProtocolResponsesFDs[1]); - close(pipefds[0]); - close(pipefds[1]); return; } - /* from now on this side of the pipe will be managed by that object, - no need to worry about it */ - TCPWorkerThread worker(pipefds[1], crossProtocolQueriesFDs[1], crossProtocolResponsesFDs[1]); + TCPWorkerThread worker(std::move(queryChannelSender), std::move(crossProtocolQueryChannelSender)); + try { - std::thread t1(tcpClientThread, pipefds[0], crossProtocolQueriesFDs[0], crossProtocolResponsesFDs[0], crossProtocolResponsesFDs[1], tcpAcceptStates); + std::thread t1(tcpClientThread, std::move(queryChannelReceiver), std::move(crossProtocolQueryChannelReceiver), std::move(crossProtocolResponseChannelReceiver), std::move(crossProtocolResponseChannelSender), tcpAcceptStates); t1.detach(); } catch (const std::runtime_error& e) { - /* the thread creation failed, don't leak */ errlog("Error creating a TCP thread: %s", e.what()); - close(pipefds[0]); - close(crossProtocolQueriesFDs[0]); - close(crossProtocolResponsesFDs[0]); return; } d_tcpclientthreads.at(d_numthreads) = std::move(worker); ++d_numthreads; } + catch (const std::exception& e) { + errlog("Error creating TCP worker: %", e.what()); + } } std::unique_ptr g_tcpclientthreads; @@ -620,23 +574,16 @@ std::unique_ptr getTCPCrossProtocolQueryFromDQ(DNSQuestion& void IncomingTCPConnectionState::handleCrossProtocolResponse(const struct timeval& now, TCPResponse&& response) { - if (d_threadData.crossProtocolResponsesPipe == -1) { - throw std::runtime_error("Invalid pipe descriptor in TCP Cross Protocol Query Sender"); - } - std::shared_ptr state = shared_from_this(); - auto ptr = new TCPCrossProtocolResponse(std::move(response), state, now); - static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranteed not to be interleaved and to either fully succeed or fail"); - ssize_t sent = write(d_threadData.crossProtocolResponsesPipe, &ptr, sizeof(ptr)); - if (sent != sizeof(ptr)) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { + try { + auto ptr = std::make_unique(std::move(response), state, now); + if (!state->d_threadData.crossProtocolResponseSender.send(std::move(ptr))) { ++g_stats.tcpCrossProtocolResponsePipeFull; vinfolog("Unable to pass a cross-protocol response to the TCP worker thread because the pipe is full"); } - else { - vinfolog("Unable to pass a cross-protocol response to the TCP worker thread because we couldn't write to the pipe: %s", stringerror()); - } - delete ptr; + } + catch (const std::exception& e) { + vinfolog("Unable to pass a cross-protocol response to the TCP worker thread because we couldn't write to the pipe: %s", stringerror()); } } @@ -1151,111 +1098,82 @@ static void handleIncomingTCPQuery(int pipefd, FDMultiplexer::funcparam_t& param { auto threadData = boost::any_cast(param); - ConnectionInfo* citmp{nullptr}; - - ssize_t got = read(pipefd, &citmp, sizeof(citmp)); - if (got == 0) { - throw std::runtime_error("EOF while reading from the TCP acceptor pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode"); - } - else if (got == -1) { - if (errno == EAGAIN || errno == EINTR) { + std::unique_ptr citmp{nullptr}; + try { + auto tmp = threadData->queryReceiver.receive(); + if (!tmp) { return; } - throw std::runtime_error("Error while reading from the TCP acceptor pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode:" + stringerror()); + citmp = std::move(*tmp); } - else if (got != sizeof(citmp)) { - throw std::runtime_error("Partial read while reading from the TCP acceptor pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode"); + catch (const std::exception& e) { + throw std::runtime_error("Error while reading from the TCP query channel: " + std::string(e.what())); } - try { - g_tcpclientthreads->decrementQueuedCount(); + g_tcpclientthreads->decrementQueuedCount(); - struct timeval now; - gettimeofday(&now, nullptr); - auto state = std::make_shared(std::move(*citmp), *threadData, now); - delete citmp; - citmp = nullptr; - - IncomingTCPConnectionState::handleIO(state, now); - } - catch (...) { - delete citmp; - citmp = nullptr; - throw; - } + struct timeval now; + gettimeofday(&now, nullptr); + auto state = std::make_shared(std::move(*citmp), *threadData, now); + IncomingTCPConnectionState::handleIO(state, now); } static void handleCrossProtocolQuery(int pipefd, FDMultiplexer::funcparam_t& param) { auto threadData = boost::any_cast(param); - CrossProtocolQuery* tmp{nullptr}; - ssize_t got = read(pipefd, &tmp, sizeof(tmp)); - if (got == 0) { - throw std::runtime_error("EOF while reading from the TCP cross-protocol pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode"); - } - else if (got == -1) { - if (errno == EAGAIN || errno == EINTR) { + std::unique_ptr cpq{nullptr}; + try { + auto tmp = threadData->crossProtocolQueryReceiver.receive(); + if (!tmp) { return; } - throw std::runtime_error("Error while reading from the TCP cross-protocol pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode:" + stringerror()); + cpq = std::move(*tmp); } - else if (got != sizeof(tmp)) { - throw std::runtime_error("Partial read while reading from the TCP cross-protocol pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode"); + catch (const std::exception& e) { + throw std::runtime_error("Error while reading from the TCP cross-protocol channel: " + std::string(e.what())); } - try { - struct timeval now; - gettimeofday(&now, nullptr); + struct timeval now; + gettimeofday(&now, nullptr); - std::shared_ptr tqs = tmp->getTCPQuerySender(); - auto query = std::move(tmp->query); - auto downstreamServer = std::move(tmp->downstream); - auto proxyProtocolPayloadSize = tmp->proxyProtocolPayloadSize; - delete tmp; - tmp = nullptr; + std::shared_ptr tqs = cpq->getTCPQuerySender(); + auto query = std::move(cpq->query); + auto downstreamServer = std::move(cpq->downstream); + auto proxyProtocolPayloadSize = cpq->proxyProtocolPayloadSize; - try { - auto downstream = t_downstreamTCPConnectionsManager.getConnectionToDownstream(threadData->mplexer, downstreamServer, now, std::string()); + try { + auto downstream = t_downstreamTCPConnectionsManager.getConnectionToDownstream(threadData->mplexer, downstreamServer, now, std::string()); - prependSizeToTCPQuery(query.d_buffer, proxyProtocolPayloadSize); - query.d_proxyProtocolPayloadAddedSize = proxyProtocolPayloadSize; + prependSizeToTCPQuery(query.d_buffer, proxyProtocolPayloadSize); + query.d_proxyProtocolPayloadAddedSize = proxyProtocolPayloadSize; - vinfolog("Got query for %s|%s from %s (%s, %d bytes), relayed to %s", query.d_idstate.qname.toLogString(), QType(query.d_idstate.qtype).toString(), query.d_idstate.origRemote.toStringWithPort(), query.d_idstate.protocol.toString(), query.d_buffer.size(), downstreamServer->getNameWithAddr()); + vinfolog("Got query for %s|%s from %s (%s, %d bytes), relayed to %s", query.d_idstate.qname.toLogString(), QType(query.d_idstate.qtype).toString(), query.d_idstate.origRemote.toStringWithPort(), query.d_idstate.protocol.toString(), query.d_buffer.size(), downstreamServer->getNameWithAddr()); - downstream->queueQuery(tqs, std::move(query)); - } - catch (...) { - tqs->notifyIOError(std::move(query.d_idstate), now); - } + downstream->queueQuery(tqs, std::move(query)); } catch (...) { - delete tmp; - tmp = nullptr; + tqs->notifyIOError(std::move(query.d_idstate), now); } } static void handleCrossProtocolResponse(int pipefd, FDMultiplexer::funcparam_t& param) { - TCPCrossProtocolResponse* tmp{nullptr}; + auto threadData = boost::any_cast(param); - ssize_t got = read(pipefd, &tmp, sizeof(tmp)); - if (got == 0) { - throw std::runtime_error("EOF while reading from the TCP cross-protocol response pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode"); - } - else if (got == -1) { - if (errno == EAGAIN || errno == EINTR) { + std::unique_ptr cpr{nullptr}; + try { + auto tmp = threadData->crossProtocolResponseReceiver.receive(); + if (!tmp) { return; } - throw std::runtime_error("Error while reading from the TCP cross-protocol response pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode:" + stringerror()); + cpr = std::move(*tmp); } - else if (got != sizeof(tmp)) { - throw std::runtime_error("Partial read while reading from the TCP cross-protocol response pipe (" + std::to_string(pipefd) + ") in " + std::string(isNonBlocking(pipefd) ? "non-blocking" : "blocking") + " mode"); + catch (const std::exception& e) { + throw std::runtime_error("Error while reading from the TCP cross-protocol response: " + std::string(e.what())); } - auto response = std::move(*tmp); - delete tmp; - tmp = nullptr; + auto response = std::move(*cpr); try { if (response.d_response.d_buffer.empty()) { @@ -1283,7 +1201,7 @@ struct TCPAcceptorParam static void acceptNewConnection(const TCPAcceptorParam& param, TCPClientThreadData* threadData); -static void tcpClientThread(int pipefd, int crossProtocolQueriesPipeFD, int crossProtocolResponsesListenPipeFD, int crossProtocolResponsesWritePipeFD, std::vector tcpAcceptStates) +static void tcpClientThread(pdns::channel::Receiver&& queryReceiver, pdns::channel::Receiver&& crossProtocolQueryReceiver, pdns::channel::Receiver&& crossProtocolResponseReceiver, pdns::channel::Sender&& crossProtocolResponseSender, std::vector tcpAcceptStates) { /* we get launched with a pipe on which we receive file descriptors from clients that we own from that point on */ @@ -1292,11 +1210,14 @@ static void tcpClientThread(int pipefd, int crossProtocolQueriesPipeFD, int cros try { TCPClientThreadData data; - /* this is the writing end! */ - data.crossProtocolResponsesPipe = crossProtocolResponsesWritePipeFD; - data.mplexer->addReadFD(pipefd, handleIncomingTCPQuery, &data); - data.mplexer->addReadFD(crossProtocolQueriesPipeFD, handleCrossProtocolQuery, &data); - data.mplexer->addReadFD(crossProtocolResponsesListenPipeFD, handleCrossProtocolResponse, &data); + data.crossProtocolResponseSender = std::move(crossProtocolResponseSender); + data.queryReceiver = std::move(queryReceiver); + data.crossProtocolQueryReceiver = std::move(crossProtocolQueryReceiver); + data.crossProtocolResponseReceiver = std::move(crossProtocolResponseReceiver); + + data.mplexer->addReadFD(data.queryReceiver.getDescriptor(), handleIncomingTCPQuery, &data); + data.mplexer->addReadFD(data.crossProtocolQueryReceiver.getDescriptor(), handleCrossProtocolQuery, &data); + data.mplexer->addReadFD(data.crossProtocolResponseReceiver.getDescriptor(), handleCrossProtocolResponse, &data); /* only used in single acceptor mode for now */ auto acl = g_ACL.getLocal(); diff --git a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh index 59c4df410d24..04a5ff4da682 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh +++ b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh @@ -3,6 +3,8 @@ #include "dolog.hh" #include "dnsdist-tcp.hh" +class TCPCrossProtocolResponse; + class TCPClientThreadData { public: @@ -15,7 +17,10 @@ public: LocalStateHolder> localRespRuleActions; LocalStateHolder> localCacheInsertedRespRuleActions; std::unique_ptr mplexer{nullptr}; - int crossProtocolResponsesPipe{-1}; + pdns::channel::Receiver queryReceiver; + pdns::channel::Receiver crossProtocolQueryReceiver; + pdns::channel::Receiver crossProtocolResponseReceiver; + pdns::channel::Sender crossProtocolResponseSender; }; class IncomingTCPConnectionState : public TCPQuerySender, public std::enable_shared_from_this diff --git a/pdns/dnsdistdist/dnsdist-tcp.hh b/pdns/dnsdistdist/dnsdist-tcp.hh index 3d11f1a4f497..04fb37737413 100644 --- a/pdns/dnsdistdist/dnsdist-tcp.hh +++ b/pdns/dnsdistdist/dnsdist-tcp.hh @@ -22,6 +22,7 @@ #pragma once #include +#include "channel.hh" #include "iputils.hh" #include "dnsdist.hh" @@ -213,20 +214,16 @@ public: } uint64_t pos = d_pos++; - auto pipe = d_tcpclientthreads.at(pos % d_numthreads).d_newConnectionPipe.getHandle(); - auto tmp = conn.release(); - /* we need to increment this counter _before_ writing to the pipe, otherwise there is a very real possiblity that the other end decrement the counter before we can increment it, leading to an underflow */ ++d_queued; - if (write(pipe, &tmp, sizeof(tmp)) != sizeof(tmp)) { + if (!d_tcpclientthreads.at(pos % d_numthreads).d_querySender.send(std::move(conn))) { --d_queued; ++g_stats.tcpQueryPipeFull; - delete tmp; - tmp = nullptr; return false; } + return true; } @@ -237,13 +234,8 @@ public: } uint64_t pos = d_pos++; - auto pipe = d_tcpclientthreads.at(pos % d_numthreads).d_crossProtocolQueriesPipe.getHandle(); - auto tmp = cpq.release(); - - if (write(pipe, &tmp, sizeof(tmp)) != sizeof(tmp)) { + if (!d_tcpclientthreads.at(pos % d_numthreads).d_crossProtocolQuerySender.send(std::move(cpq))) { ++g_stats.tcpCrossProtocolQueryPipeFull; - delete tmp; - tmp = nullptr; return false; } @@ -279,8 +271,8 @@ private: { } - TCPWorkerThread(int newConnPipe, int crossProtocolQueriesPipe, int crossProtocolResponsesPipe) : - d_newConnectionPipe(newConnPipe), d_crossProtocolQueriesPipe(crossProtocolQueriesPipe), d_crossProtocolResponsesPipe(crossProtocolResponsesPipe) + TCPWorkerThread(pdns::channel::Sender&& querySender, pdns::channel::Sender&& crossProtocolQuerySender) : + d_querySender(std::move(querySender)), d_crossProtocolQuerySender(std::move(crossProtocolQuerySender)) { } @@ -289,9 +281,8 @@ private: TCPWorkerThread(const TCPWorkerThread& rhs) = delete; TCPWorkerThread& operator=(const TCPWorkerThread&) = delete; - FDWrapper d_newConnectionPipe; - FDWrapper d_crossProtocolQueriesPipe; - FDWrapper d_crossProtocolResponsesPipe; + pdns::channel::Sender d_querySender; + pdns::channel::Sender d_crossProtocolQuerySender; }; std::vector d_tcpclientthreads; From 73b4f2437022e82d91014fca3dfc5ea9774bb09e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 18 Mar 2022 10:22:10 +0100 Subject: [PATCH 259/909] dnsdist: Fix formatting in channel.{cc,hh} --- pdns/dnsdistdist/channel.cc | 2 +- pdns/dnsdistdist/channel.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/channel.cc b/pdns/dnsdistdist/channel.cc index dfa33697658f..75cca8a70642 100644 --- a/pdns/dnsdistdist/channel.cc +++ b/pdns/dnsdistdist/channel.cc @@ -77,7 +77,7 @@ namespace channel std::pair createNotificationQueue(bool nonBlocking, size_t pipeBufferSize) { - int fds[2] = { -1, -1}; + int fds[2] = {-1, -1}; if (pipe(fds) < 0) { throw std::runtime_error("Error creating notification channel pipe: " + stringerror()); } diff --git a/pdns/dnsdistdist/channel.hh b/pdns/dnsdistdist/channel.hh index 247264c5d497..55ee5f956d7e 100644 --- a/pdns/dnsdistdist/channel.hh +++ b/pdns/dnsdistdist/channel.hh @@ -229,7 +229,7 @@ namespace channel template std::pair, Receiver> createObjectQueue(bool nonBlocking, size_t pipeBufferSize) { - int fds[2] = { -1, -1}; + int fds[2] = {-1, -1}; if (pipe(fds) < 0) { throw std::runtime_error("Error creating channel pipe: " + stringerror()); } From 52f6247b5a24ad58af41d085dfb049475b8a2ca5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 18 Mar 2022 10:32:42 +0100 Subject: [PATCH 260/909] dnsdist: Wrap the pipe descriptors earlier, do not leak on send errors --- pdns/dnsdistdist/channel.cc | 18 +++++++----------- pdns/dnsdistdist/channel.hh | 20 ++++++++------------ 2 files changed, 15 insertions(+), 23 deletions(-) diff --git a/pdns/dnsdistdist/channel.cc b/pdns/dnsdistdist/channel.cc index 75cca8a70642..dd25c6d34eee 100644 --- a/pdns/dnsdistdist/channel.cc +++ b/pdns/dnsdistdist/channel.cc @@ -82,27 +82,23 @@ namespace channel throw std::runtime_error("Error creating notification channel pipe: " + stringerror()); } - if (nonBlocking && !setNonBlocking(fds[0])) { + FDWrapper sender(fds[1]); + FDWrapper receiver(fds[0]); + + if (nonBlocking && !setNonBlocking(receiver.getHandle())) { int err = errno; - close(fds[0]); - close(fds[1]); throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); } - if (nonBlocking && !setNonBlocking(fds[1])) { + if (nonBlocking && !setNonBlocking(sender.getHandle())) { int err = errno; - close(fds[0]); - close(fds[1]); throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); } - if (pipeBufferSize > 0 && getPipeBufferSize(fds[0]) < pipeBufferSize) { - setPipeBufferSize(fds[0], pipeBufferSize); + if (pipeBufferSize > 0 && getPipeBufferSize(receiver.getHandle()) < pipeBufferSize) { + setPipeBufferSize(receiver.getHandle(), pipeBufferSize); } - FDWrapper sender(fds[1]); - FDWrapper receiver(fds[0]); - return std::pair(Notifier(std::move(sender)), Waiter(std::move(receiver))); } } diff --git a/pdns/dnsdistdist/channel.hh b/pdns/dnsdistdist/channel.hh index 55ee5f956d7e..5698fb7ba3e7 100644 --- a/pdns/dnsdistdist/channel.hh +++ b/pdns/dnsdistdist/channel.hh @@ -191,13 +191,13 @@ namespace channel ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); if (sent != sizeof(ptr)) { + delete ptr; if (errno == EAGAIN || errno == EWOULDBLOCK) { return false; } else { throw std::runtime_error("Unable to write to channel:" + stringerror()); } - delete ptr; } return true; @@ -234,27 +234,23 @@ namespace channel throw std::runtime_error("Error creating channel pipe: " + stringerror()); } - if (nonBlocking && !setNonBlocking(fds[0])) { + FDWrapper sender(fds[1]); + FDWrapper receiver(fds[0]); + + if (nonBlocking && !setNonBlocking(receiver.getHandle())) { int err = errno; - close(fds[0]); - close(fds[1]); throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); } - if (nonBlocking && !setNonBlocking(fds[1])) { + if (nonBlocking && !setNonBlocking(sender.getHandle())) { int err = errno; - close(fds[0]); - close(fds[1]); throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); } - if (pipeBufferSize > 0 && getPipeBufferSize(fds[0]) < pipeBufferSize) { - setPipeBufferSize(fds[0], pipeBufferSize); + if (pipeBufferSize > 0 && getPipeBufferSize(receiver.getHandle()) < pipeBufferSize) { + setPipeBufferSize(receiver.getHandle(), pipeBufferSize); } - FDWrapper sender(fds[1]); - FDWrapper receiver(fds[0]); - return std::pair(Sender(std::move(sender)), Receiver(std::move(receiver))); } } From 790a6a604eaca8cb40a1fe40ed82867394e0812b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 8 Apr 2022 17:17:00 +0200 Subject: [PATCH 261/909] dnsdist: Refactoring of the SNMP code with channels --- pdns/dnsdist-snmp.cc | 6 ++-- pdns/dnsdistdist/channel.hh | 64 +++++++++++++++++++++++++---------- pdns/recursordist/rec-snmp.cc | 2 +- pdns/snmp-agent.cc | 51 +++++++++++----------------- pdns/snmp-agent.hh | 11 +++--- 5 files changed, 73 insertions(+), 61 deletions(-) diff --git a/pdns/dnsdist-snmp.cc b/pdns/dnsdist-snmp.cc index d853a32d04ea..149acbc511bb 100644 --- a/pdns/dnsdist-snmp.cc +++ b/pdns/dnsdist-snmp.cc @@ -411,7 +411,7 @@ bool DNSDistSNMPAgent::sendBackendStatusChangeTrap(const DownstreamState& dss) backendStatus.c_str(), backendStatus.size()); - return sendTrap(d_trapPipe[1], varList); + return sendTrap(d_sender, varList); #else return true; #endif /* HAVE_NET_SNMP */ @@ -436,7 +436,7 @@ bool DNSDistSNMPAgent::sendCustomTrap(const std::string& reason) reason.c_str(), reason.size()); - return sendTrap(d_trapPipe[1], varList); + return sendTrap(d_sender, varList); #else return true; #endif /* HAVE_NET_SNMP */ @@ -542,7 +542,7 @@ bool DNSDistSNMPAgent::sendDNSTrap(const DNSQuestion& dq, const std::string& rea reason.c_str(), reason.size()); - return sendTrap(d_trapPipe[1], varList); + return sendTrap(d_sender, varList); #else return true; #endif /* HAVE_NET_SNMP */ diff --git a/pdns/dnsdistdist/channel.hh b/pdns/dnsdistdist/channel.hh index 5698fb7ba3e7..5c352870ed60 100644 --- a/pdns/dnsdistdist/channel.hh +++ b/pdns/dnsdistdist/channel.hh @@ -34,7 +34,7 @@ namespace channel * * A sender can be used by several threads in a safe way. */ - template + template > class Sender { public: @@ -56,7 +56,7 @@ namespace channel * * \throw runtime_error if the channel is broken, for example if the other end has been closed. */ - bool send(std::unique_ptr&&) const; + bool send(std::unique_ptr&&) const; private: FDWrapper d_fd; @@ -67,7 +67,7 @@ namespace channel * * A receiver can be used by several threads in a safe way, but in that case spurious wake up might happen. */ - template + template > class Receiver { public: @@ -89,7 +89,8 @@ namespace channel * * \throw runtime_error if the channel is broken, for example if the other end has been closed. */ - std::optional> receive() const; + std::optional> receive() const; + std::optional> receive(D deleter) const; /** * \brief Get a descriptor that can be used with an I/O multiplexer to wait for an object to become available. @@ -112,8 +113,8 @@ namespace channel * * \throw runtime_error if the channel creation failed. */ - template - std::pair, Receiver> createObjectQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); + template > + std::pair, Receiver> createObjectQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); /** * The notifier's end of a channel used to communicate between threads. @@ -183,15 +184,19 @@ namespace channel */ std::pair createNotificationQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); - template - bool Sender::send(std::unique_ptr&& object) const + template + bool Sender::send(std::unique_ptr&& object) const { - auto ptr = object.release(); + // we do not release right away because we might need the custom deleter later + auto ptr = object.get(); static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranted not to interleaved and to either fully succeed or fail"); ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); - if (sent != sizeof(ptr)) { - delete ptr; + if (sent == sizeof(ptr)) { + // we cannot touch it anymore + object.release(); + } + else { if (errno == EAGAIN || errno == EWOULDBLOCK) { return false; } @@ -203,14 +208,37 @@ namespace channel return true; } - template - std::optional> Receiver::receive() const + template + std::optional> Receiver::receive() const + { + std::optional> result; + T* obj{nullptr}; + ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); + if (got == sizeof(obj)) { + return std::unique_ptr(obj); + } + else if (got == 0) { + throw std::runtime_error("EOF while reading from Channel receiver"); + } + else if (got == -1) { + if (errno == EAGAIN || errno == EINTR) { + return result; + } + throw std::runtime_error("Error while reading from Channel receiver: " + stringerror()); + } + else { + throw std::runtime_error("Partial read from Channel receiver"); + } + } + + template + std::optional> Receiver::receive(D deleter) const { - std::optional> result; + std::optional> result; T* obj{nullptr}; ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); if (got == sizeof(obj)) { - return std::unique_ptr(obj); + return std::unique_ptr(obj, deleter); } else if (got == 0) { throw std::runtime_error("EOF while reading from Channel receiver"); @@ -226,8 +254,8 @@ namespace channel } } - template - std::pair, Receiver> createObjectQueue(bool nonBlocking, size_t pipeBufferSize) + template + std::pair, Receiver> createObjectQueue(bool nonBlocking, size_t pipeBufferSize) { int fds[2] = {-1, -1}; if (pipe(fds) < 0) { @@ -251,7 +279,7 @@ namespace channel setPipeBufferSize(receiver.getHandle(), pipeBufferSize); } - return std::pair(Sender(std::move(sender)), Receiver(std::move(receiver))); + return std::pair(Sender(std::move(sender)), Receiver(std::move(receiver))); } } } diff --git a/pdns/recursordist/rec-snmp.cc b/pdns/recursordist/rec-snmp.cc index 8773a158f1c5..7a0fbd5f888b 100644 --- a/pdns/recursordist/rec-snmp.cc +++ b/pdns/recursordist/rec-snmp.cc @@ -268,7 +268,7 @@ bool RecursorSNMPAgent::sendCustomTrap(const std::string& reason) reason.c_str(), reason.size()); - return sendTrap(d_trapPipe[1], varList); + return sendTrap(d_sender, varList); #endif /* HAVE_NET_SNMP */ return true; } diff --git a/pdns/snmp-agent.cc b/pdns/snmp-agent.cc index 18a088ea4353..b70a5b280dc4 100644 --- a/pdns/snmp-agent.cc +++ b/pdns/snmp-agent.cc @@ -41,32 +41,31 @@ int SNMPAgent::setCounter64Value(netsnmp_request_info* request, return SNMP_ERR_NOERROR; } -bool SNMPAgent::sendTrap(int fd, +bool SNMPAgent::sendTrap(pdns::channel::Sender& sender, netsnmp_variable_list* varList) { - ssize_t written = write(fd, &varList, sizeof(varList)); - - if (written != sizeof(varList)) { - snmp_free_varbind(varList); + try { + auto obj = std::unique_ptr(varList, snmp_free_varbind); + return sender.send(std::move(obj)); + } + catch (...) { return false; } - return true; } void SNMPAgent::handleTrapsEvent() { - netsnmp_variable_list* varList = nullptr; - ssize_t got = 0; - - do { - got = read(d_trapPipe[0], &varList, sizeof(varList)); - - if (got == sizeof(varList)) { - send_v2trap(varList); - snmp_free_varbind(varList); + try { + while (true) { + auto obj = d_receiver.receive(snmp_free_varbind); + if (!obj) { + break; + } + send_v2trap(obj->get()); } } - while (got > 0); + catch (const std::exception& e) { + } } void SNMPAgent::handleSNMPQueryEvent(int fd) @@ -121,7 +120,7 @@ void SNMPAgent::worker() /* we want to be notified if a trap is waiting to be sent */ - mplexer->addReadFD(d_trapPipe[0], &handleTrapsCB, this); + mplexer->addReadFD(d_receiver.getDescriptor(), &handleTrapsCB, this); while(true) { netsnmp_large_fd_set_init(&fdset, FD_SETSIZE); @@ -187,20 +186,8 @@ SNMPAgent::SNMPAgent(const std::string& name, const std::string& daemonSocket) init_snmp(name.c_str()); - if (pipe(d_trapPipe) < 0) - unixDie("Creating pipe"); - - if (!setNonBlocking(d_trapPipe[0])) { - close(d_trapPipe[0]); - close(d_trapPipe[1]); - unixDie("Setting pipe non-blocking"); - } - - if (!setNonBlocking(d_trapPipe[1])) { - close(d_trapPipe[0]); - close(d_trapPipe[1]); - unixDie("Setting pipe non-blocking"); - } - + auto [sender, receiver] = pdns::channel::createObjectQueue(true); + d_sender = std::move(sender); + d_receiver = std::move(receiver); #endif /* HAVE_NET_SNMP */ } diff --git a/pdns/snmp-agent.hh b/pdns/snmp-agent.hh index e4ba13420dd2..f5df62ba746d 100644 --- a/pdns/snmp-agent.hh +++ b/pdns/snmp-agent.hh @@ -16,6 +16,7 @@ #endif /* HAVE_NET_SNMP */ #include "mplexer.hh" +#include "channel.hh" class SNMPAgent { @@ -23,11 +24,6 @@ public: SNMPAgent(const std::string& name, const std::string& daemonSocket); virtual ~SNMPAgent() { -#ifdef HAVE_NET_SNMP - - close(d_trapPipe[0]); - close(d_trapPipe[1]); -#endif /* HAVE_NET_SNMP */ } void run() @@ -48,10 +44,11 @@ protected: static const oid snmpTrapOID[]; static const size_t snmpTrapOIDLen; - static bool sendTrap(int fd, + static bool sendTrap(pdns::channel::Sender& sender, netsnmp_variable_list* varList); - int d_trapPipe[2] = { -1, -1}; + pdns::channel::Sender d_sender; + pdns::channel::Receiver d_receiver; #endif /* HAVE_NET_SNMP */ private: void worker(); From b8f54b252908c4fd176703327b0576cc70dd8347 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 8 Apr 2022 17:57:44 +0200 Subject: [PATCH 262/909] dnsdist: Convert DoH to pdns::channel --- pdns/dnsdistdist/doh.cc | 145 +++++++++++++--------------------------- pdns/doh.hh | 3 + 2 files changed, 50 insertions(+), 98 deletions(-) diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 021eec32d2d0..9feca6521876 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -172,38 +172,20 @@ struct DOHServerConfig { DOHServerConfig(uint32_t idleTimeout, uint32_t internalPipeBufferSize): accept_ctx(std::make_shared()) { - int fd[2]; #ifndef USE_SINGLE_ACCEPTOR_THREAD - if (pipe(fd) < 0) { - unixDie("Creating a pipe for DNS over HTTPS"); - } - dohquerypair[0] = fd[1]; - dohquerypair[1] = fd[0]; - - setNonBlocking(dohquerypair[0]); - if (internalPipeBufferSize > 0) { - setPipeBufferSize(dohquerypair[0], internalPipeBufferSize); + { + auto [sender, receiver] = pdns::channel::createObjectQueue(true, internalPipeBufferSize); + d_querySender = std::move(sender); + d_queryReceiver = std::move(receiver); } #endif /* USE_SINGLE_ACCEPTOR_THREAD */ - if (pipe(fd) < 0) { -#ifndef USE_SINGLE_ACCEPTOR_THREAD - close(dohquerypair[0]); - close(dohquerypair[1]); -#endif /* USE_SINGLE_ACCEPTOR_THREAD */ - unixDie("Creating a pipe for DNS over HTTPS"); - } - - dohresponsepair[0] = fd[1]; - dohresponsepair[1] = fd[0]; - - setNonBlocking(dohresponsepair[0]); - if (internalPipeBufferSize > 0) { - setPipeBufferSize(dohresponsepair[0], internalPipeBufferSize); + { + auto [sender, receiver] = pdns::channel::createObjectQueue(true, internalPipeBufferSize); + d_responseSender = std::move(sender); + d_responseReceiver = std::move(receiver); } - setNonBlocking(dohresponsepair[1]); - h2o_config_init(&h2o_config); h2o_config.http2.idle_timeout = idleTimeout * 1000; /* if you came here for a way to make the number of concurrent streams (concurrent requests per connection) @@ -225,42 +207,28 @@ struct DOHServerConfig ClientState* cs{nullptr}; std::shared_ptr df{nullptr}; #ifndef USE_SINGLE_ACCEPTOR_THREAD - int dohquerypair[2]{-1,-1}; + pdns::channel::Sender d_querySender; + pdns::channel::Receiver d_queryReceiver; #endif /* USE_SINGLE_ACCEPTOR_THREAD */ - int dohresponsepair[2]{-1,-1}; + pdns::channel::Sender d_responseSender; + pdns::channel::Receiver d_responseReceiver; }; /* This internal function sends back the object to the main thread to send a reply. The caller should NOT release or touch the unit after calling this function */ static void sendDoHUnitToTheMainThread(DOHUnitUniquePtr&& du, const char* description) { - /* taking a naked pointer since we are about to send that pointer over a pipe */ - auto ptr = du.release(); - /* increasing the reference counter. This should not be strictly needed because - we already hold a reference and will only release it if we failed to send the - pointer over the pipe, but TSAN seems confused when the responder thread gets - a reply from a backend before the send() syscall sending the corresponding query - to that backend has returned in the initial thread. - The memory barrier needed to increase that counter seems to work around that. - */ - ptr->get(); - static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranteed not to be interleaved and to either fully succeed or fail"); - - ssize_t sent = write(ptr->rsock, &ptr, sizeof(ptr)); - if (sent != sizeof(ptr)) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { + if (du->responseSender == nullptr) { + return; + } + try { + if (!du->responseSender->send(std::move(du))) { ++g_stats.dohResponsePipeFull; vinfolog("Unable to pass a %s to the DoH worker thread because the pipe is full", description); } - else { - vinfolog("Unable to pass a %s to the DoH worker thread because we couldn't write to the pipe: %s", description, stringerror()); - } - - /* we fail to write over the pipe so we do not need to hold to that ref anymore */ - ptr->release(); + } catch (const std::exception& e) { + vinfolog("Unable to pass a %s to the DoH worker thread because we couldn't write to the pipe: %s", description, e.what()); } - /* we decrement the counter incremented above at the beginning of that function */ - ptr->release(); } /* This function is called from other threads than the main DoH one, @@ -452,7 +420,7 @@ class DoHTCPCrossQuerySender : public TCPQuerySender } auto du = std::move(response.d_idstate.du); - if (du->rsock == -1) { + if (du->responseSender == nullptr) { return; } @@ -514,7 +482,7 @@ class DoHTCPCrossQuerySender : public TCPQuerySender return; } - if (query.du->rsock == -1) { + if (query.du->responseSender == nullptr) { return; } @@ -869,13 +837,13 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re /* we are doing quite some copies here, sorry about that, but we can't keep accessing the req object once we are in a different thread because the request might get killed by h2o at pretty much any time */ - auto du = std::make_unique(std::move(query), std::move(path), std::string(req->authority.base, req->authority.len)); + auto du = std::unique_ptr(new DOHUnit(std::move(query), std::move(path), std::string(req->authority.base, req->authority.len)), DOHUnit::release); du->dsc = dsc; du->req = req; du->ids.origDest = local; du->ids.origRemote = remote; du->ids.protocol = dnsdist::Protocol::DoH; - du->rsock = dsc->dohresponsepair[0]; + du->responseSender = &dsc->d_responseSender; if (req->scheme != nullptr) { du->scheme = std::string(req->scheme->name.base, req->scheme->name.len); } @@ -897,32 +865,21 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re } #endif /* HAVE_H2O_SOCKET_GET_SSL_SERVER_NAME */ du->self = reinterpret_cast(h2o_mem_alloc_shared(&req->pool, sizeof(*self), on_generator_dispose)); - auto ptr = du.release(); - *(ptr->self) = ptr; + *(du->self) = du.get(); #ifdef USE_SINGLE_ACCEPTOR_THREAD - processDOHQuery(DOHUnitUniquePtr(ptr, DOHUnit::release), true); + processDOHQuery(DOHUnitUniquePtr(du.release(), DOHUnit::release), true); #else /* USE_SINGLE_ACCEPTOR_THREAD */ - try { - static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranteed not to be interleaved and to either fully succeed or fail"); - ssize_t sent = write(dsc->dohquerypair[0], &ptr, sizeof(ptr)); - if (sent != sizeof(ptr)) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - ++g_stats.dohQueryPipeFull; - vinfolog("Unable to pass a DoH query to the DoH worker thread because the pipe is full"); - } - else { - vinfolog("Unable to pass a DoH query to the DoH worker thread because we couldn't write to the pipe: %s", stringerror()); - } - ptr->release(); - ptr = nullptr; + try { + if (!dsc->d_querySender.send(std::move(du))) { + ++g_stats.dohQueryPipeFull; + vinfolog("Unable to pass a DoH query to the DoH worker thread because the pipe is full"); h2o_send_error_500(req, "Internal Server Error", "Internal Server Error", 0); } } catch (...) { - if (ptr != nullptr) { - ptr->release(); - } + vinfolog("Unable to pass a DoH query to the DoH worker thread because we couldn't write to the pipe: %s", stringerror()); + h2o_send_error_500(req, "Internal Server Error", "Internal Server Error", 0); } #endif /* USE_SINGLE_ACCEPTOR_THREAD */ } @@ -1268,23 +1225,17 @@ void DOHUnit::setHTTPResponse(uint16_t statusCode, PacketBuffer&& body_, const s /* query has been parsed by h2o, which called doh_handler() in the main DoH thread. In order not to block for long, doh_handler() called doh_dispatch_query() which allocated a DOHUnit object and passed it to us */ -static void dnsdistclient(int qsock) +static void dnsdistclient(pdns::channel::Receiver&& receiver) { setThreadName("dnsdist/doh-cli"); for(;;) { try { - DOHUnit* ptr = nullptr; - ssize_t got = read(qsock, &ptr, sizeof(ptr)); - if (got < 0) { - warnlog("Error receiving internal DoH query: %s", strerror(errno)); - continue; - } - else if (static_cast(got) < sizeof(ptr)) { + auto tmp = receiver.receive(DOHUnit::release); + if (!tmp) { continue; } - - DOHUnitUniquePtr du(ptr, DOHUnit::release); + auto du = std::move(*tmp); /* we are not in the main DoH thread anymore, so there is a real risk of a race condition where h2o kills the query while we are processing it, so we can't touch the content of du->req until we are back into the @@ -1308,7 +1259,7 @@ static void dnsdistclient(int qsock) #endif /* USE_SINGLE_ACCEPTOR_THREAD */ /* Called in the main DoH thread if h2o finds that dnsdist gave us an answer by writing into - the dohresponsepair[0] side of the pipe so from: + the response channel so from: - handleDOHTimeout() when we did not get a response fast enough (called either from the health check thread (active) or from the frontend ones (reused)) - dnsdistclient (error 500 because processDOHQuery() returned a negative value) @@ -1321,23 +1272,21 @@ static void on_dnsdist(h2o_socket_t *listener, const char *err) for the CPU, the first thing we need to do is to send responses to free slots anyway, otherwise queries and responses are piling up in our pipes, consuming memory and likely coming up too late after the client has gone away */ + DOHServerConfig* dsc = reinterpret_cast(listener->data); while (true) { - DOHUnit *ptr = nullptr; - DOHServerConfig* dsc = reinterpret_cast(listener->data); - ssize_t got = read(dsc->dohresponsepair[1], &ptr, sizeof(ptr)); - - if (got < 0) { - if (errno != EWOULDBLOCK && errno != EAGAIN) { - errlog("Error reading a DOH internal response: %s", strerror(errno)); + std::unique_ptr du{nullptr, DOHUnit::release}; + try { + auto tmp = dsc->d_responseReceiver.receive(DOHUnit::release); + if (!tmp) { + return; } - return; + du = std::move(*tmp); } - else if (static_cast(got) != sizeof(ptr)) { - errlog("Error reading a DoH internal response, got %d bytes instead of the expected %d", got, sizeof(ptr)); + catch (const std::exception& e) { + errlog("Error reading a DOH internal response: %s", e.what()); return; } - DOHUnitUniquePtr du(ptr, DOHUnit::release); if (!du->req) { // it got killed in flight du->self = nullptr; continue; @@ -1647,7 +1596,7 @@ void dohThread(ClientState* cs) dsc->h2o_config.server_name = h2o_iovec_init(df->d_serverTokens.c_str(), df->d_serverTokens.size()); #ifndef USE_SINGLE_ACCEPTOR_THREAD - std::thread dnsdistThread(dnsdistclient, dsc->dohquerypair[1]); + std::thread dnsdistThread(dnsdistclient, std::move(dsc->d_queryReceiver)); dnsdistThread.detach(); // gets us better error reporting #endif @@ -1668,7 +1617,7 @@ void dohThread(ClientState* cs) dsc->h2o_ctx.storage.entries[0].data = dsc.get(); ++dsc->h2o_ctx.storage.size; - auto sock = h2o_evloop_socket_create(dsc->h2o_ctx.loop, dsc->dohresponsepair[1], H2O_SOCKET_FLAG_DONT_READ); + auto sock = h2o_evloop_socket_create(dsc->h2o_ctx.loop, dsc->d_responseReceiver.getDescriptor(), H2O_SOCKET_FLAG_DONT_READ); sock->data = dsc.get(); // this listens to responses from dnsdist to turn into http responses diff --git a/pdns/doh.hh b/pdns/doh.hh index 96e65f1be2b3..5cc94439d8f8 100644 --- a/pdns/doh.hh +++ b/pdns/doh.hh @@ -19,10 +19,12 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ + #pragma once #include +#include "channel.hh" #include "iputils.hh" #include "libssl.hh" #include "noinitvector.hh" @@ -247,6 +249,7 @@ struct DOHUnit st_h2o_req_t* req{nullptr}; DOHUnit** self{nullptr}; DOHServerConfig* dsc{nullptr}; + pdns::channel::Sender* responseSender{nullptr}; std::atomic d_refcnt{1}; size_t query_at{0}; size_t proxyProtocolPayloadSize{0}; From eae269cbbe180b89750d72da0e2ac6f1d74c2635 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 8 Apr 2022 20:02:23 +0200 Subject: [PATCH 263/909] dnsdist: Add missing pragma once to DoH --- pdns/doh.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/doh.hh b/pdns/doh.hh index 5cc94439d8f8..2b8397d68805 100644 --- a/pdns/doh.hh +++ b/pdns/doh.hh @@ -19,6 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#pragma once #pragma once From 7f98f4ba738265a6f51b4d315201abb9b60756e2 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 10 Jun 2022 17:34:56 +0200 Subject: [PATCH 264/909] Move channel files from pdns/dnsdistdist to pdns --- pdns/Makefile.am | 1 + pdns/channel.cc | 105 +++++++++++++ pdns/channel.hh | 285 +++++++++++++++++++++++++++++++++++ pdns/dnsdistdist/channel.cc | 106 +------------ pdns/dnsdistdist/channel.hh | 286 +----------------------------------- 5 files changed, 393 insertions(+), 390 deletions(-) create mode 100644 pdns/channel.cc create mode 100644 pdns/channel.hh mode change 100644 => 120000 pdns/dnsdistdist/channel.cc mode change 100644 => 120000 pdns/dnsdistdist/channel.hh diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 88229c32a741..f9e8c632cd24 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1602,6 +1602,7 @@ fuzz_target_proxyprotocol_LDFLAGS = $(fuzz_targets_ldflags) fuzz_target_proxyprotocol_LDADD = $(fuzz_targets_libs) fuzz_target_dnsdistcache_SOURCES = \ + channel.hh channel.cc \ dns.cc dns.hh \ dnsdist-cache.cc dnsdist-cache.hh \ dnsdist-ecs.cc dnsdist-ecs.hh \ diff --git a/pdns/channel.cc b/pdns/channel.cc new file mode 100644 index 000000000000..dd25c6d34eee --- /dev/null +++ b/pdns/channel.cc @@ -0,0 +1,105 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "channel.hh" + +namespace pdns +{ +namespace channel +{ + + Notifier::Notifier(FDWrapper&& fd) : + d_fd(std::move(fd)) + { + } + + bool Notifier::notify() const + { + char data = 'a'; + auto sent = write(d_fd.getHandle(), &data, sizeof(data)); + if (sent != sizeof(data)) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return false; + } + else { + throw std::runtime_error("Unable to write to channel notifier pipe: " + stringerror()); + } + } + return true; + } + + Waiter::Waiter(FDWrapper&& fd) : + d_fd(std::move(fd)) + { + } + + void Waiter::clear() const + { + ssize_t got; + do { + char data; + got = read(d_fd.getHandle(), &data, sizeof(data)); + if (got == 0) { + throw std::runtime_error("EOF while clearing channel notifier pipe"); + } + else if (got == -1) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + break; + } + throw std::runtime_error("Error while clearing channel notifier pipe: " + stringerror()); + } + } while (got); + } + + int Waiter::getDescriptor() const + { + return d_fd.getHandle(); + } + + std::pair createNotificationQueue(bool nonBlocking, size_t pipeBufferSize) + { + int fds[2] = {-1, -1}; + if (pipe(fds) < 0) { + throw std::runtime_error("Error creating notification channel pipe: " + stringerror()); + } + + FDWrapper sender(fds[1]); + FDWrapper receiver(fds[0]); + + if (nonBlocking && !setNonBlocking(receiver.getHandle())) { + int err = errno; + throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); + } + + if (nonBlocking && !setNonBlocking(sender.getHandle())) { + int err = errno; + throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); + } + + if (pipeBufferSize > 0 && getPipeBufferSize(receiver.getHandle()) < pipeBufferSize) { + setPipeBufferSize(receiver.getHandle(), pipeBufferSize); + } + + return std::pair(Notifier(std::move(sender)), Waiter(std::move(receiver))); + } +} +} diff --git a/pdns/channel.hh b/pdns/channel.hh new file mode 100644 index 000000000000..5c352870ed60 --- /dev/null +++ b/pdns/channel.hh @@ -0,0 +1,285 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once +#include +#include + +#include "misc.hh" + +namespace pdns +{ +namespace channel +{ + /** + * The sender's end of a channel used to pass objects between threads. + * + * A sender can be used by several threads in a safe way. + */ + template > + class Sender + { + public: + Sender() + { + } + Sender(FDWrapper&& fd) : + d_fd(std::move(fd)) + { + } + Sender(const Sender&) = delete; + Sender& operator=(const Sender&) = delete; + Sender(Sender&&) = default; + Sender& operator=(Sender&&) = default; + /** + * \brief Try to send the supplied object to the other end of that channel. Might block if the channel was created in blocking mode. + * + * \return True if the object was properly sent, False if the channel is full. + * + * \throw runtime_error if the channel is broken, for example if the other end has been closed. + */ + bool send(std::unique_ptr&&) const; + + private: + FDWrapper d_fd; + }; + + /** + * The receiver's end of a channel used to pass objects between threads. + * + * A receiver can be used by several threads in a safe way, but in that case spurious wake up might happen. + */ + template > + class Receiver + { + public: + Receiver() + { + } + Receiver(FDWrapper&& fd) : + d_fd(std::move(fd)) + { + } + Receiver(const Receiver&) = delete; + Receiver& operator=(const Receiver&) = delete; + Receiver(Receiver&&) = default; + Receiver& operator=(Receiver&&) = default; + /** + * \brief Try to read an object sent by the other end of that channel. Might block if the channel was created in blocking mode. + * + * \return An object if one was available, and std::nullopt otherwise. + * + * \throw runtime_error if the channel is broken, for example if the other end has been closed. + */ + std::optional> receive() const; + std::optional> receive(D deleter) const; + + /** + * \brief Get a descriptor that can be used with an I/O multiplexer to wait for an object to become available. + * + * \return A valid descriptor or -1 if the Receiver was not properly initialized. + */ + int getDescriptor() const + { + return d_fd.getHandle(); + } + + private: + FDWrapper d_fd; + }; + + /** + * \brief Create a channel to pass objects between threads, accepting multiple senders and receivers. + * + * \return A pair of Sender and Receiver objects. + * + * \throw runtime_error if the channel creation failed. + */ + template > + std::pair, Receiver> createObjectQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); + + /** + * The notifier's end of a channel used to communicate between threads. + * + * A notifier can be used by several threads in a safe way. + */ + class Notifier + { + public: + Notifier() + { + } + Notifier(FDWrapper&&); + Notifier(const Notifier&) = delete; + Notifier& operator=(const Notifier&) = delete; + Notifier(Notifier&&) = default; + Notifier& operator=(Notifier&&) = default; + + /** + * \brief Queue a notification to wake up the other end of the channel. + * + * \return True if the notification was properly sent, False if the channel is full. + * + * \throw runtime_error if the channel is broken, for example if the other end has been closed. + */ + bool notify() const; + + private: + FDWrapper d_fd; + }; + + /** + * The waiter's end of a channel used to communicate between threads. + * + * A waiter can be used by several threads in a safe way, but in that case spurious wake up might happen. + */ + class Waiter + { + public: + Waiter(FDWrapper&&); + Waiter(const Waiter&) = delete; + Waiter& operator=(const Waiter&) = delete; + Waiter(Waiter&&) = default; + Waiter& operator=(Waiter&&) = default; + + /** + * \brief Clear all notifications queued on that channel, if any. + */ + void clear() const; + /** + * \brief Get a descriptor that can be used with an I/O multiplexer to wait for a notification to arrive. + * + * \return A valid descriptor or -1 if the Waiter was not properly initialized. + */ + int getDescriptor() const; + + private: + FDWrapper d_fd; + }; + + /** + * \brief Create a channel to notify one thread from another one, accepting multiple senders and receivers. + * + * \return A pair of Notifier and Sender objects. + * + * \throw runtime_error if the channel creation failed. + */ + std::pair createNotificationQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); + + template + bool Sender::send(std::unique_ptr&& object) const + { + // we do not release right away because we might need the custom deleter later + auto ptr = object.get(); + static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranted not to interleaved and to either fully succeed or fail"); + ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); + + if (sent == sizeof(ptr)) { + // we cannot touch it anymore + object.release(); + } + else { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return false; + } + else { + throw std::runtime_error("Unable to write to channel:" + stringerror()); + } + } + + return true; + } + + template + std::optional> Receiver::receive() const + { + std::optional> result; + T* obj{nullptr}; + ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); + if (got == sizeof(obj)) { + return std::unique_ptr(obj); + } + else if (got == 0) { + throw std::runtime_error("EOF while reading from Channel receiver"); + } + else if (got == -1) { + if (errno == EAGAIN || errno == EINTR) { + return result; + } + throw std::runtime_error("Error while reading from Channel receiver: " + stringerror()); + } + else { + throw std::runtime_error("Partial read from Channel receiver"); + } + } + + template + std::optional> Receiver::receive(D deleter) const + { + std::optional> result; + T* obj{nullptr}; + ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); + if (got == sizeof(obj)) { + return std::unique_ptr(obj, deleter); + } + else if (got == 0) { + throw std::runtime_error("EOF while reading from Channel receiver"); + } + else if (got == -1) { + if (errno == EAGAIN || errno == EINTR) { + return result; + } + throw std::runtime_error("Error while reading from Channel receiver: " + stringerror()); + } + else { + throw std::runtime_error("Partial read from Channel receiver"); + } + } + + template + std::pair, Receiver> createObjectQueue(bool nonBlocking, size_t pipeBufferSize) + { + int fds[2] = {-1, -1}; + if (pipe(fds) < 0) { + throw std::runtime_error("Error creating channel pipe: " + stringerror()); + } + + FDWrapper sender(fds[1]); + FDWrapper receiver(fds[0]); + + if (nonBlocking && !setNonBlocking(receiver.getHandle())) { + int err = errno; + throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); + } + + if (nonBlocking && !setNonBlocking(sender.getHandle())) { + int err = errno; + throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); + } + + if (pipeBufferSize > 0 && getPipeBufferSize(receiver.getHandle()) < pipeBufferSize) { + setPipeBufferSize(receiver.getHandle(), pipeBufferSize); + } + + return std::pair(Sender(std::move(sender)), Receiver(std::move(receiver))); + } +} +} diff --git a/pdns/dnsdistdist/channel.cc b/pdns/dnsdistdist/channel.cc deleted file mode 100644 index dd25c6d34eee..000000000000 --- a/pdns/dnsdistdist/channel.cc +++ /dev/null @@ -1,105 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include "channel.hh" - -namespace pdns -{ -namespace channel -{ - - Notifier::Notifier(FDWrapper&& fd) : - d_fd(std::move(fd)) - { - } - - bool Notifier::notify() const - { - char data = 'a'; - auto sent = write(d_fd.getHandle(), &data, sizeof(data)); - if (sent != sizeof(data)) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return false; - } - else { - throw std::runtime_error("Unable to write to channel notifier pipe: " + stringerror()); - } - } - return true; - } - - Waiter::Waiter(FDWrapper&& fd) : - d_fd(std::move(fd)) - { - } - - void Waiter::clear() const - { - ssize_t got; - do { - char data; - got = read(d_fd.getHandle(), &data, sizeof(data)); - if (got == 0) { - throw std::runtime_error("EOF while clearing channel notifier pipe"); - } - else if (got == -1) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - break; - } - throw std::runtime_error("Error while clearing channel notifier pipe: " + stringerror()); - } - } while (got); - } - - int Waiter::getDescriptor() const - { - return d_fd.getHandle(); - } - - std::pair createNotificationQueue(bool nonBlocking, size_t pipeBufferSize) - { - int fds[2] = {-1, -1}; - if (pipe(fds) < 0) { - throw std::runtime_error("Error creating notification channel pipe: " + stringerror()); - } - - FDWrapper sender(fds[1]); - FDWrapper receiver(fds[0]); - - if (nonBlocking && !setNonBlocking(receiver.getHandle())) { - int err = errno; - throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); - } - - if (nonBlocking && !setNonBlocking(sender.getHandle())) { - int err = errno; - throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); - } - - if (pipeBufferSize > 0 && getPipeBufferSize(receiver.getHandle()) < pipeBufferSize) { - setPipeBufferSize(receiver.getHandle(), pipeBufferSize); - } - - return std::pair(Notifier(std::move(sender)), Waiter(std::move(receiver))); - } -} -} diff --git a/pdns/dnsdistdist/channel.cc b/pdns/dnsdistdist/channel.cc new file mode 120000 index 000000000000..54617106c484 --- /dev/null +++ b/pdns/dnsdistdist/channel.cc @@ -0,0 +1 @@ +../channel.cc \ No newline at end of file diff --git a/pdns/dnsdistdist/channel.hh b/pdns/dnsdistdist/channel.hh deleted file mode 100644 index 5c352870ed60..000000000000 --- a/pdns/dnsdistdist/channel.hh +++ /dev/null @@ -1,285 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#pragma once -#include -#include - -#include "misc.hh" - -namespace pdns -{ -namespace channel -{ - /** - * The sender's end of a channel used to pass objects between threads. - * - * A sender can be used by several threads in a safe way. - */ - template > - class Sender - { - public: - Sender() - { - } - Sender(FDWrapper&& fd) : - d_fd(std::move(fd)) - { - } - Sender(const Sender&) = delete; - Sender& operator=(const Sender&) = delete; - Sender(Sender&&) = default; - Sender& operator=(Sender&&) = default; - /** - * \brief Try to send the supplied object to the other end of that channel. Might block if the channel was created in blocking mode. - * - * \return True if the object was properly sent, False if the channel is full. - * - * \throw runtime_error if the channel is broken, for example if the other end has been closed. - */ - bool send(std::unique_ptr&&) const; - - private: - FDWrapper d_fd; - }; - - /** - * The receiver's end of a channel used to pass objects between threads. - * - * A receiver can be used by several threads in a safe way, but in that case spurious wake up might happen. - */ - template > - class Receiver - { - public: - Receiver() - { - } - Receiver(FDWrapper&& fd) : - d_fd(std::move(fd)) - { - } - Receiver(const Receiver&) = delete; - Receiver& operator=(const Receiver&) = delete; - Receiver(Receiver&&) = default; - Receiver& operator=(Receiver&&) = default; - /** - * \brief Try to read an object sent by the other end of that channel. Might block if the channel was created in blocking mode. - * - * \return An object if one was available, and std::nullopt otherwise. - * - * \throw runtime_error if the channel is broken, for example if the other end has been closed. - */ - std::optional> receive() const; - std::optional> receive(D deleter) const; - - /** - * \brief Get a descriptor that can be used with an I/O multiplexer to wait for an object to become available. - * - * \return A valid descriptor or -1 if the Receiver was not properly initialized. - */ - int getDescriptor() const - { - return d_fd.getHandle(); - } - - private: - FDWrapper d_fd; - }; - - /** - * \brief Create a channel to pass objects between threads, accepting multiple senders and receivers. - * - * \return A pair of Sender and Receiver objects. - * - * \throw runtime_error if the channel creation failed. - */ - template > - std::pair, Receiver> createObjectQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); - - /** - * The notifier's end of a channel used to communicate between threads. - * - * A notifier can be used by several threads in a safe way. - */ - class Notifier - { - public: - Notifier() - { - } - Notifier(FDWrapper&&); - Notifier(const Notifier&) = delete; - Notifier& operator=(const Notifier&) = delete; - Notifier(Notifier&&) = default; - Notifier& operator=(Notifier&&) = default; - - /** - * \brief Queue a notification to wake up the other end of the channel. - * - * \return True if the notification was properly sent, False if the channel is full. - * - * \throw runtime_error if the channel is broken, for example if the other end has been closed. - */ - bool notify() const; - - private: - FDWrapper d_fd; - }; - - /** - * The waiter's end of a channel used to communicate between threads. - * - * A waiter can be used by several threads in a safe way, but in that case spurious wake up might happen. - */ - class Waiter - { - public: - Waiter(FDWrapper&&); - Waiter(const Waiter&) = delete; - Waiter& operator=(const Waiter&) = delete; - Waiter(Waiter&&) = default; - Waiter& operator=(Waiter&&) = default; - - /** - * \brief Clear all notifications queued on that channel, if any. - */ - void clear() const; - /** - * \brief Get a descriptor that can be used with an I/O multiplexer to wait for a notification to arrive. - * - * \return A valid descriptor or -1 if the Waiter was not properly initialized. - */ - int getDescriptor() const; - - private: - FDWrapper d_fd; - }; - - /** - * \brief Create a channel to notify one thread from another one, accepting multiple senders and receivers. - * - * \return A pair of Notifier and Sender objects. - * - * \throw runtime_error if the channel creation failed. - */ - std::pair createNotificationQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); - - template - bool Sender::send(std::unique_ptr&& object) const - { - // we do not release right away because we might need the custom deleter later - auto ptr = object.get(); - static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranted not to interleaved and to either fully succeed or fail"); - ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); - - if (sent == sizeof(ptr)) { - // we cannot touch it anymore - object.release(); - } - else { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return false; - } - else { - throw std::runtime_error("Unable to write to channel:" + stringerror()); - } - } - - return true; - } - - template - std::optional> Receiver::receive() const - { - std::optional> result; - T* obj{nullptr}; - ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); - if (got == sizeof(obj)) { - return std::unique_ptr(obj); - } - else if (got == 0) { - throw std::runtime_error("EOF while reading from Channel receiver"); - } - else if (got == -1) { - if (errno == EAGAIN || errno == EINTR) { - return result; - } - throw std::runtime_error("Error while reading from Channel receiver: " + stringerror()); - } - else { - throw std::runtime_error("Partial read from Channel receiver"); - } - } - - template - std::optional> Receiver::receive(D deleter) const - { - std::optional> result; - T* obj{nullptr}; - ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); - if (got == sizeof(obj)) { - return std::unique_ptr(obj, deleter); - } - else if (got == 0) { - throw std::runtime_error("EOF while reading from Channel receiver"); - } - else if (got == -1) { - if (errno == EAGAIN || errno == EINTR) { - return result; - } - throw std::runtime_error("Error while reading from Channel receiver: " + stringerror()); - } - else { - throw std::runtime_error("Partial read from Channel receiver"); - } - } - - template - std::pair, Receiver> createObjectQueue(bool nonBlocking, size_t pipeBufferSize) - { - int fds[2] = {-1, -1}; - if (pipe(fds) < 0) { - throw std::runtime_error("Error creating channel pipe: " + stringerror()); - } - - FDWrapper sender(fds[1]); - FDWrapper receiver(fds[0]); - - if (nonBlocking && !setNonBlocking(receiver.getHandle())) { - int err = errno; - throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); - } - - if (nonBlocking && !setNonBlocking(sender.getHandle())) { - int err = errno; - throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); - } - - if (pipeBufferSize > 0 && getPipeBufferSize(receiver.getHandle()) < pipeBufferSize) { - setPipeBufferSize(receiver.getHandle(), pipeBufferSize); - } - - return std::pair(Sender(std::move(sender)), Receiver(std::move(receiver))); - } -} -} diff --git a/pdns/dnsdistdist/channel.hh b/pdns/dnsdistdist/channel.hh new file mode 120000 index 000000000000..799a313ab82e --- /dev/null +++ b/pdns/dnsdistdist/channel.hh @@ -0,0 +1 @@ +../channel.hh \ No newline at end of file From 5841c6fdc698cc7012ae428c4643f9426d1392cc Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 21 Oct 2022 20:12:01 +0200 Subject: [PATCH 265/909] dnsdist: Move the DelayPipe to pdns::channel --- pdns/channel.cc | 35 ++++--- pdns/channel.hh | 135 +++++++++++++++----------- pdns/delaypipe.cc | 58 ++++------- pdns/delaypipe.hh | 7 +- pdns/dnsdist-tcp.cc | 6 +- pdns/dnsdistdist/dnsdist-nghttp2.cc | 2 +- pdns/dnsdistdist/doh.cc | 4 +- pdns/dnsdistdist/test-delaypipe_hh.cc | 10 +- pdns/misc.hh | 13 ++- pdns/snmp-agent.cc | 2 +- 10 files changed, 146 insertions(+), 126 deletions(-) diff --git a/pdns/channel.cc b/pdns/channel.cc index dd25c6d34eee..bebbdf4380b4 100644 --- a/pdns/channel.cc +++ b/pdns/channel.cc @@ -35,20 +35,25 @@ namespace channel bool Notifier::notify() const { char data = 'a'; - auto sent = write(d_fd.getHandle(), &data, sizeof(data)); - if (sent != sizeof(data)) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return false; - } - else { - throw std::runtime_error("Unable to write to channel notifier pipe: " + stringerror()); + while (true) { + auto sent = write(d_fd.getHandle(), &data, sizeof(data)); + if (sent != sizeof(data)) { + if (errno == EINTR) { + continue; + } + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return false; + } + else { + throw std::runtime_error("Unable to write to channel notifier pipe: " + stringerror()); + } } + return true; } - return true; } - Waiter::Waiter(FDWrapper&& fd) : - d_fd(std::move(fd)) + Waiter::Waiter(FDWrapper&& fd, bool throwOnEOF) : + d_fd(std::move(fd)), d_throwOnEOF(throwOnEOF) { } @@ -59,9 +64,15 @@ namespace channel char data; got = read(d_fd.getHandle(), &data, sizeof(data)); if (got == 0) { + if (!d_throwOnEOF) { + return; + } throw std::runtime_error("EOF while clearing channel notifier pipe"); } else if (got == -1) { + if (errno == EINTR) { + continue; + } if (errno == EAGAIN || errno == EWOULDBLOCK) { break; } @@ -75,7 +86,7 @@ namespace channel return d_fd.getHandle(); } - std::pair createNotificationQueue(bool nonBlocking, size_t pipeBufferSize) + std::pair createNotificationQueue(bool nonBlocking, size_t pipeBufferSize, bool throwOnEOF) { int fds[2] = {-1, -1}; if (pipe(fds) < 0) { @@ -99,7 +110,7 @@ namespace channel setPipeBufferSize(receiver.getHandle(), pipeBufferSize); } - return std::pair(Notifier(std::move(sender)), Waiter(std::move(receiver))); + return std::pair(Notifier(std::move(sender)), Waiter(std::move(receiver), throwOnEOF)); } } } diff --git a/pdns/channel.hh b/pdns/channel.hh index 5c352870ed60..fd82ca197033 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -57,6 +57,7 @@ namespace channel * \throw runtime_error if the channel is broken, for example if the other end has been closed. */ bool send(std::unique_ptr&&) const; + void close(); private: FDWrapper d_fd; @@ -74,8 +75,8 @@ namespace channel Receiver() { } - Receiver(FDWrapper&& fd) : - d_fd(std::move(fd)) + Receiver(FDWrapper&& fd, bool throwOnEOF = true) : + d_fd(std::move(fd)), d_throwOnEOF(throwOnEOF) { } Receiver(const Receiver&) = delete; @@ -89,8 +90,8 @@ namespace channel * * \throw runtime_error if the channel is broken, for example if the other end has been closed. */ - std::optional> receive() const; - std::optional> receive(D deleter) const; + std::optional> receive(); + std::optional> receive(D deleter); /** * \brief Get a descriptor that can be used with an I/O multiplexer to wait for an object to become available. @@ -101,9 +102,18 @@ namespace channel { return d_fd.getHandle(); } + /** + * \brief Whether the remote end has closed the channel. + */ + bool isClosed() const + { + return d_closed; + } private: FDWrapper d_fd; + bool d_closed{false}; + bool d_throwOnEOF{true}; }; /** @@ -114,7 +124,7 @@ namespace channel * \throw runtime_error if the channel creation failed. */ template > - std::pair, Receiver> createObjectQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); + std::pair, Receiver> createObjectQueue(bool sendNonBlocking = true, bool writeNonBlocking = true, size_t pipeBufferSize = 0, bool throwOnEOF = true); /** * The notifier's end of a channel used to communicate between threads. @@ -154,7 +164,7 @@ namespace channel class Waiter { public: - Waiter(FDWrapper&&); + Waiter(FDWrapper&&, bool throwOnEOF = true); Waiter(const Waiter&) = delete; Waiter& operator=(const Waiter&) = delete; Waiter(Waiter&&) = default; @@ -170,9 +180,18 @@ namespace channel * \return A valid descriptor or -1 if the Waiter was not properly initialized. */ int getDescriptor() const; + /** + * \brief Whether the remote end has closed the channel. + */ + bool isClosed() const + { + return d_closed; + } private: FDWrapper d_fd; + bool d_closed{false}; + bool d_throwOnEOF{true}; }; /** @@ -182,7 +201,7 @@ namespace channel * * \throw runtime_error if the channel creation failed. */ - std::pair createNotificationQueue(bool nonBlocking = true, size_t pipeBufferSize = 0); + std::pair createNotificationQueue(bool nonBlocking = true, size_t pipeBufferSize = 0, bool throwOnEOF = true); template bool Sender::send(std::unique_ptr&& object) const @@ -190,72 +209,74 @@ namespace channel // we do not release right away because we might need the custom deleter later auto ptr = object.get(); static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranted not to interleaved and to either fully succeed or fail"); - ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); + while (true) { + ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); - if (sent == sizeof(ptr)) { - // we cannot touch it anymore - object.release(); - } - else { - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return false; + if (sent == sizeof(ptr)) { + // we cannot touch it anymore + object.release(); + return true; } else { - throw std::runtime_error("Unable to write to channel:" + stringerror()); + if (errno == EINTR) { + continue; + } + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return false; + } + else { + throw std::runtime_error("Unable to write to channel:" + stringerror()); + } } } + } - return true; + template + void Sender::close() + { + d_fd.reset(); } template - std::optional> Receiver::receive() const + std::optional> Receiver::receive() { - std::optional> result; - T* obj{nullptr}; - ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); - if (got == sizeof(obj)) { - return std::unique_ptr(obj); - } - else if (got == 0) { - throw std::runtime_error("EOF while reading from Channel receiver"); - } - else if (got == -1) { - if (errno == EAGAIN || errno == EINTR) { - return result; - } - throw std::runtime_error("Error while reading from Channel receiver: " + stringerror()); - } - else { - throw std::runtime_error("Partial read from Channel receiver"); - } + return receive(std::default_delete()); } template - std::optional> Receiver::receive(D deleter) const + std::optional> Receiver::receive(D deleter) { - std::optional> result; - T* obj{nullptr}; - ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); - if (got == sizeof(obj)) { - return std::unique_ptr(obj, deleter); - } - else if (got == 0) { - throw std::runtime_error("EOF while reading from Channel receiver"); - } - else if (got == -1) { - if (errno == EAGAIN || errno == EINTR) { - return result; + while (true) { + std::optional> result; + T* obj{nullptr}; + ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); + if (got == sizeof(obj)) { + return std::unique_ptr(obj, deleter); + } + else if (got == 0) { + d_closed = true; + if (!d_throwOnEOF) { + return result; + } + throw std::runtime_error("EOF while reading from Channel receiver"); + } + else if (got == -1) { + if (errno == EINTR) { + continue; + } + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return result; + } + throw std::runtime_error("Error while reading from Channel receiver: " + stringerror()); + } + else { + throw std::runtime_error("Partial read from Channel receiver"); } - throw std::runtime_error("Error while reading from Channel receiver: " + stringerror()); - } - else { - throw std::runtime_error("Partial read from Channel receiver"); } } template - std::pair, Receiver> createObjectQueue(bool nonBlocking, size_t pipeBufferSize) + std::pair, Receiver> createObjectQueue(bool sendNonBlocking, bool receiveNonBlocking, size_t pipeBufferSize, bool throwOnEOF) { int fds[2] = {-1, -1}; if (pipe(fds) < 0) { @@ -265,12 +286,12 @@ namespace channel FDWrapper sender(fds[1]); FDWrapper receiver(fds[0]); - if (nonBlocking && !setNonBlocking(receiver.getHandle())) { + if (receiveNonBlocking && !setNonBlocking(receiver.getHandle())) { int err = errno; throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); } - if (nonBlocking && !setNonBlocking(sender.getHandle())) { + if (sendNonBlocking && !setNonBlocking(sender.getHandle())) { int err = errno; throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); } @@ -279,7 +300,7 @@ namespace channel setPipeBufferSize(receiver.getHandle(), pipeBufferSize); } - return std::pair(Sender(std::move(sender)), Receiver(std::move(receiver))); + return std::pair(Sender(std::move(sender)), Receiver(std::move(receiver), throwOnEOF)); } } } diff --git a/pdns/delaypipe.cc b/pdns/delaypipe.cc index be363d639191..645bcf56109f 100644 --- a/pdns/delaypipe.cc +++ b/pdns/delaypipe.cc @@ -28,34 +28,23 @@ template ObjectPipe::ObjectPipe() { - if(pipe(d_fds)) - unixDie("pipe"); -} - -template -ObjectPipe::~ObjectPipe() -{ - ::close(d_fds[0]); - if(d_fds[1] >= 0) - ::close(d_fds[1]); + auto [sender, receiver] = pdns::channel::createObjectQueue(false, true, 0, false); + d_sender = std::move(sender); + d_receiver = std::move(receiver); } template void ObjectPipe::close() { - if(d_fds[1] < 0) - return; - ::close(d_fds[1]); // the writing side - d_fds[1]=-1; + d_sender.close(); } template void ObjectPipe::write(T& t) { - auto ptr = new T(t); - if(::write(d_fds[1], &ptr, sizeof(ptr)) != sizeof(ptr)) { - delete ptr; - unixDie("write"); + auto ptr = std::make_unique(t); + if (!d_sender.send(std::move(ptr))) { + unixDie("writing to the DelayPipe"); } } @@ -63,7 +52,7 @@ template int ObjectPipe::readTimeout(T* t, double msec) { while (true) { - int ret = waitForData(d_fds[0], 0, 1000*msec); + int ret = waitForData(d_receiver.getDescriptor(), 0, 1000*msec); if (ret < 0) { if (errno == EINTR) { continue; @@ -74,26 +63,21 @@ int ObjectPipe::readTimeout(T* t, double msec) return -1; } - T* ptr = nullptr; - ret = ::read(d_fds[0], &ptr, sizeof(ptr)); // this is BLOCKING! - - if (ret < 0) { - if (errno == EINTR) { + try { + auto tmp = d_receiver.receive(); + if (!tmp) { + if (d_receiver.isClosed()) { + return 0; + } continue; } - unixDie("read"); - } - else if (ret == 0) { - return false; - } - if (ret != sizeof(ptr)) { - throw std::runtime_error("Partial read, should not happen 2"); + *t = **tmp; + return 1; + } + catch (const std::exception& e) { + throw std::runtime_error("reading from the delay pipe: " + std::string(e.what())); } - - *t = *ptr; - delete ptr; - return 1; } } @@ -149,7 +133,7 @@ void DelayPipe::worker() The other special case is that the first we have to do.. is in the past, so we need to do it immediately. */ - + double delay=-1; // infinite struct timespec now; if(!d_work.empty()) { @@ -160,7 +144,7 @@ void DelayPipe::worker() } } if(delay != 0 ) { - int ret = d_pipe.readTimeout(&c, delay); + int ret = d_pipe.readTimeout(&c, delay); if(ret > 0) { // we got an object d_work.emplace(c.when, c.what); } diff --git a/pdns/delaypipe.hh b/pdns/delaypipe.hh index ad1626a9990e..b12fd50eac1b 100644 --- a/pdns/delaypipe.hh +++ b/pdns/delaypipe.hh @@ -20,10 +20,11 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once -#include #include #include +#include "channel.hh" + /** General idea: many threads submit work to this class, but only one executes it. The work should therefore be entirely trivial. The implementation is that submitter threads create an object that represents the work, and it gets sent over a pipe @@ -41,12 +42,12 @@ class ObjectPipe { public: ObjectPipe(); - ~ObjectPipe(); void write(T& t); int readTimeout(T* t, double msec); //!< -1 is timeout, 0 is no data, 1 is data. msec<0 waits infinitely long. msec==0 = undefined void close(); private: - int d_fds[2]; + pdns::channel::Sender d_sender; + pdns::channel::Receiver d_receiver; }; template diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 17309a4f6642..b72f0e0f5f9e 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -130,11 +130,11 @@ TCPClientCollection::TCPClientCollection(size_t maxThreads, std::vector& tcpAcceptStates) { try { - auto [queryChannelSender, queryChannelReceiver] = pdns::channel::createObjectQueue(true, g_tcpInternalPipeBufferSize); + auto [queryChannelSender, queryChannelReceiver] = pdns::channel::createObjectQueue(true, true, g_tcpInternalPipeBufferSize); - auto [crossProtocolQueryChannelSender, crossProtocolQueryChannelReceiver] = pdns::channel::createObjectQueue(true, g_tcpInternalPipeBufferSize); + auto [crossProtocolQueryChannelSender, crossProtocolQueryChannelReceiver] = pdns::channel::createObjectQueue(true, true, g_tcpInternalPipeBufferSize); - auto [crossProtocolResponseChannelSender, crossProtocolResponseChannelReceiver] = pdns::channel::createObjectQueue(true, g_tcpInternalPipeBufferSize); + auto [crossProtocolResponseChannelSender, crossProtocolResponseChannelReceiver] = pdns::channel::createObjectQueue(true, true, g_tcpInternalPipeBufferSize); vinfolog("Adding TCP Client thread"); diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 34e8abe5eb43..52403b9b048f 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -1015,7 +1015,7 @@ void DoHClientCollection::addThread() { #ifdef HAVE_NGHTTP2 try { - auto [sender, receiver] = pdns::channel::createObjectQueue(true, g_tcpInternalPipeBufferSize); + auto [sender, receiver] = pdns::channel::createObjectQueue(true, true, g_tcpInternalPipeBufferSize); vinfolog("Adding DoH Client thread"); std::lock_guard lock(d_mutex); diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 9feca6521876..57da686ee53f 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -174,14 +174,14 @@ struct DOHServerConfig { #ifndef USE_SINGLE_ACCEPTOR_THREAD { - auto [sender, receiver] = pdns::channel::createObjectQueue(true, internalPipeBufferSize); + auto [sender, receiver] = pdns::channel::createObjectQueue(true, true, internalPipeBufferSize); d_querySender = std::move(sender); d_queryReceiver = std::move(receiver); } #endif /* USE_SINGLE_ACCEPTOR_THREAD */ { - auto [sender, receiver] = pdns::channel::createObjectQueue(true, internalPipeBufferSize); + auto [sender, receiver] = pdns::channel::createObjectQueue(true, true, internalPipeBufferSize); d_responseSender = std::move(sender); d_responseReceiver = std::move(receiver); } diff --git a/pdns/dnsdistdist/test-delaypipe_hh.cc b/pdns/dnsdistdist/test-delaypipe_hh.cc index 9e678ee40e47..41040a906f33 100644 --- a/pdns/dnsdistdist/test-delaypipe_hh.cc +++ b/pdns/dnsdistdist/test-delaypipe_hh.cc @@ -22,8 +22,7 @@ BOOST_AUTO_TEST_CASE(test_object_pipe) { op.close(); BOOST_CHECK_EQUAL(op.readTimeout(&i, 1), 0); - -}; +} std::atomic done = 0; BOOST_AUTO_TEST_CASE(test_delay_pipe_small) { @@ -53,9 +52,9 @@ BOOST_AUTO_TEST_CASE(test_delay_pipe_small) { sleep(1); BOOST_CHECK_EQUAL(done, n); -}; +} -BOOST_AUTO_TEST_CASE(test_delay_pipe_big) { +BOOST_AUTO_TEST_CASE(test_delay_pipe_big) { done=0; struct Work { @@ -74,7 +73,6 @@ BOOST_AUTO_TEST_CASE(test_delay_pipe_big) { sleep(1); BOOST_CHECK_EQUAL(done, n); -}; - +} BOOST_AUTO_TEST_SUITE_END(); diff --git a/pdns/misc.hh b/pdns/misc.hh index 5757cccc5c27..1a40a14d2bcf 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -794,10 +794,7 @@ struct FDWrapper ~FDWrapper() { - if (d_fd != -1) { - close(d_fd); - d_fd = -1; - } + reset(); } FDWrapper(FDWrapper&& rhs) noexcept : d_fd(rhs.d_fd) @@ -825,6 +822,14 @@ struct FDWrapper return d_fd; } + void reset() + { + if (d_fd != -1) { + ::close(d_fd); + d_fd = -1; + } + } + private: int d_fd{-1}; }; diff --git a/pdns/snmp-agent.cc b/pdns/snmp-agent.cc index b70a5b280dc4..1ab0bd938fe4 100644 --- a/pdns/snmp-agent.cc +++ b/pdns/snmp-agent.cc @@ -186,7 +186,7 @@ SNMPAgent::SNMPAgent(const std::string& name, const std::string& daemonSocket) init_snmp(name.c_str()); - auto [sender, receiver] = pdns::channel::createObjectQueue(true); + auto [sender, receiver] = pdns::channel::createObjectQueue(true, true); d_sender = std::move(sender); d_receiver = std::move(receiver); #endif /* HAVE_NET_SNMP */ From bb22687528aa8ab33543860ff03968f04a5a09cb Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Sat, 22 Oct 2022 16:59:22 +0200 Subject: [PATCH 266/909] rec: Add missing channel.cc and channel.hh symbolic links --- pdns/recursordist/Makefile.am | 1 + pdns/recursordist/channel.cc | 1 + pdns/recursordist/channel.hh | 1 + 3 files changed, 3 insertions(+) create mode 120000 pdns/recursordist/channel.cc create mode 120000 pdns/recursordist/channel.hh diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index dc30a296c0b2..ac6a44ea4730 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -108,6 +108,7 @@ pdns_recursor_SOURCES = \ burtle.hh \ cachecleaner.hh \ capabilities.cc capabilities.hh \ + channel.cc channel.hh \ circular_buffer.hh \ comment.hh \ credentials.cc credentials.hh \ diff --git a/pdns/recursordist/channel.cc b/pdns/recursordist/channel.cc new file mode 120000 index 000000000000..54617106c484 --- /dev/null +++ b/pdns/recursordist/channel.cc @@ -0,0 +1 @@ +../channel.cc \ No newline at end of file diff --git a/pdns/recursordist/channel.hh b/pdns/recursordist/channel.hh new file mode 120000 index 000000000000..799a313ab82e --- /dev/null +++ b/pdns/recursordist/channel.hh @@ -0,0 +1 @@ +../channel.hh \ No newline at end of file From 91bf355bb7931df2c61902d36f55d266b219c96a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 9 Dec 2022 16:58:15 +0100 Subject: [PATCH 267/909] dnsdist: Add TSAN annotations in the channel code So Thread Sanitizer knows that the object we are passing is no longer used in the sender, and will now be used in the receiver (happens-before). --- pdns/channel.hh | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/pdns/channel.hh b/pdns/channel.hh index fd82ca197033..b13b3f988150 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -25,6 +25,20 @@ #include "misc.hh" +/* g++ defines __SANITIZE_THREAD__ + clang++ supports the nice __has_feature(thread_sanitizer), + let's merge them */ +#if defined(__has_feature) +#if __has_feature(thread_sanitizer) +#define __SANITIZE_THREAD__ 1 +#endif +#endif + +#if __SANITIZE_THREAD__ +extern "C" void __tsan_acquire(void *addr); +extern "C" void __tsan_release(void *addr); +#endif + namespace pdns { namespace channel @@ -210,6 +224,9 @@ namespace channel auto ptr = object.get(); static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranted not to interleaved and to either fully succeed or fail"); while (true) { +#if __SANITIZE_THREAD__ + __tsan_release(ptr); +#endif /* __SANITIZE_THREAD__ */ ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); if (sent == sizeof(ptr)) { @@ -218,6 +235,9 @@ namespace channel return true; } else { +#if __SANITIZE_THREAD__ + __tsan_acquire(ptr); +#endif /* __SANITIZE_THREAD__ */ if (errno == EINTR) { continue; } @@ -251,6 +271,9 @@ namespace channel T* obj{nullptr}; ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); if (got == sizeof(obj)) { +#if __SANITIZE_THREAD__ + __tsan_acquire(obj); +#endif /* __SANITIZE_THREAD__ */ return std::unique_ptr(obj, deleter); } else if (got == 0) { From eaf6fce1b139881ce73a1b6be3378c1583ae4e91 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 12 Dec 2022 10:06:56 +0100 Subject: [PATCH 268/909] channel: Fix formatting --- pdns/channel.hh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pdns/channel.hh b/pdns/channel.hh index b13b3f988150..9835ab68a2c8 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -35,8 +35,8 @@ #endif #if __SANITIZE_THREAD__ -extern "C" void __tsan_acquire(void *addr); -extern "C" void __tsan_release(void *addr); +extern "C" void __tsan_acquire(void* addr); +extern "C" void __tsan_release(void* addr); #endif namespace pdns @@ -236,7 +236,7 @@ namespace channel } else { #if __SANITIZE_THREAD__ - __tsan_acquire(ptr); + __tsan_acquire(ptr); #endif /* __SANITIZE_THREAD__ */ if (errno == EINTR) { continue; From 0a2f1e8b1fbfec18630edd3301bb4c5fe5ccdecf Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Dec 2022 15:45:49 +0100 Subject: [PATCH 269/909] dnsdist: TCPCrossProtocolResponse is a struct, not a class --- pdns/dnsdistdist/dnsdist-tcp-upstream.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh index 04a5ff4da682..b668c2f9eb7c 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh +++ b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh @@ -3,7 +3,7 @@ #include "dolog.hh" #include "dnsdist-tcp.hh" -class TCPCrossProtocolResponse; +struct TCPCrossProtocolResponse; class TCPClientThreadData { From 43ec3a214ff399857971bff1d074356a01bc8e26 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Dec 2022 15:46:34 +0100 Subject: [PATCH 270/909] channel: Cleaner handling of EOF when writing on the pipe --- pdns/channel.cc | 3 +++ pdns/channel.hh | 3 +++ 2 files changed, 6 insertions(+) diff --git a/pdns/channel.cc b/pdns/channel.cc index bebbdf4380b4..ce2f0ef60cca 100644 --- a/pdns/channel.cc +++ b/pdns/channel.cc @@ -37,6 +37,9 @@ namespace channel char data = 'a'; while (true) { auto sent = write(d_fd.getHandle(), &data, sizeof(data)); + if (sent == 0) { + throw std::runtime_error("Unable to write to channel notifier pipe: remote end has been closed"); + } if (sent != sizeof(data)) { if (errno == EINTR) { continue; diff --git a/pdns/channel.hh b/pdns/channel.hh index 9835ab68a2c8..ff34e9f990ea 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -234,6 +234,9 @@ namespace channel object.release(); return true; } + else if (sent == 0) { + throw std::runtime_error("Unable to write to channel: remote end has been closed"); + } else { #if __SANITIZE_THREAD__ __tsan_acquire(ptr); From c3be1471059aa00970eddb8c5745192ed0b13fbc Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Dec 2022 15:47:08 +0100 Subject: [PATCH 271/909] channel: Use the template deleter parameter --- pdns/channel.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/channel.hh b/pdns/channel.hh index ff34e9f990ea..9334f3b64db1 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -263,7 +263,7 @@ namespace channel template std::optional> Receiver::receive() { - return receive(std::default_delete()); + return receive(D()); } template From f6abb8aecb68fd7dad657ffd486a4ba7574e3539 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Dec 2022 15:47:46 +0100 Subject: [PATCH 272/909] channel: Rename the pointer to object 'objPtr' instead of 'obj' --- pdns/channel.hh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pdns/channel.hh b/pdns/channel.hh index 9334f3b64db1..6d26dc1b6a9e 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -271,13 +271,13 @@ namespace channel { while (true) { std::optional> result; - T* obj{nullptr}; - ssize_t got = read(d_fd.getHandle(), &obj, sizeof(obj)); - if (got == sizeof(obj)) { + T* objPtr{nullptr}; + ssize_t got = read(d_fd.getHandle(), &objPtr, sizeof(objPtr)); + if (got == sizeof(objPtr)) { #if __SANITIZE_THREAD__ - __tsan_acquire(obj); + __tsan_acquire(objPtr); #endif /* __SANITIZE_THREAD__ */ - return std::unique_ptr(obj, deleter); + return std::unique_ptr(objPtr, deleter); } else if (got == 0) { d_closed = true; From 1adbac7409ade150095f501ed8d94f72b549d644 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Sat, 17 Dec 2022 10:22:09 +0100 Subject: [PATCH 273/909] dnsdist: Fix invalid parameter name in the channel --- pdns/channel.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/channel.hh b/pdns/channel.hh index 6d26dc1b6a9e..e221e6b2672b 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -138,7 +138,7 @@ namespace channel * \throw runtime_error if the channel creation failed. */ template > - std::pair, Receiver> createObjectQueue(bool sendNonBlocking = true, bool writeNonBlocking = true, size_t pipeBufferSize = 0, bool throwOnEOF = true); + std::pair, Receiver> createObjectQueue(bool sendNonBlocking = true, bool receiveNonBlocking = true, size_t pipeBufferSize = 0, bool throwOnEOF = true); /** * The notifier's end of a channel used to communicate between threads. From cd93bea912fe3a5a7eaa99f314ab23a8ef667d79 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 19 Dec 2022 11:57:31 +0100 Subject: [PATCH 274/909] channel: Add unit tests --- pdns/Makefile.am | 2 + pdns/channel.cc | 3 +- pdns/channel.hh | 2 +- pdns/dnsdistdist/Makefile.am | 1 + pdns/dnsdistdist/test-channel.cc | 1 + pdns/test-channel.cc | 144 +++++++++++++++++++++++++++++++ 6 files changed, 151 insertions(+), 2 deletions(-) create mode 120000 pdns/dnsdistdist/test-channel.cc create mode 100644 pdns/test-channel.cc diff --git a/pdns/Makefile.am b/pdns/Makefile.am index f9e8c632cd24..a8fccbe782fa 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1337,6 +1337,7 @@ testrunner_SOURCES = \ base64.cc \ bindlexer.l \ bindparser.yy \ + channel.cc channel.hh \ credentials.cc credentials.hh \ dbdnsseckeeper.cc \ dns.cc \ @@ -1384,6 +1385,7 @@ testrunner_SOURCES = \ test-base32_cc.cc \ test-base64_cc.cc \ test-bindparser_cc.cc \ + test-channel.cc \ test-common.hh \ test-communicator_hh.cc \ test-credentials_cc.cc \ diff --git a/pdns/channel.cc b/pdns/channel.cc index ce2f0ef60cca..ae62d23693b1 100644 --- a/pdns/channel.cc +++ b/pdns/channel.cc @@ -60,13 +60,14 @@ namespace channel { } - void Waiter::clear() const + void Waiter::clear() { ssize_t got; do { char data; got = read(d_fd.getHandle(), &data, sizeof(data)); if (got == 0) { + d_closed = true; if (!d_throwOnEOF) { return; } diff --git a/pdns/channel.hh b/pdns/channel.hh index e221e6b2672b..d22004034168 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -187,7 +187,7 @@ namespace channel /** * \brief Clear all notifications queued on that channel, if any. */ - void clear() const; + void clear(); /** * \brief Get a descriptor that can be used with an I/O multiplexer to wait for a notification to arrive. * diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 44487953ffe0..3931c01ca8f5 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -306,6 +306,7 @@ testrunner_SOURCES = \ statnode.cc statnode.hh \ svc-records.cc svc-records.hh \ test-base64_cc.cc \ + test-channel.cc \ test-connectionmanagement_hh.cc \ test-credentials_cc.cc \ test-delaypipe_hh.cc \ diff --git a/pdns/dnsdistdist/test-channel.cc b/pdns/dnsdistdist/test-channel.cc new file mode 120000 index 000000000000..90f6b118d764 --- /dev/null +++ b/pdns/dnsdistdist/test-channel.cc @@ -0,0 +1 @@ +../test-channel.cc \ No newline at end of file diff --git a/pdns/test-channel.cc b/pdns/test-channel.cc new file mode 100644 index 000000000000..e97ddbe5ff78 --- /dev/null +++ b/pdns/test-channel.cc @@ -0,0 +1,144 @@ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_MAIN + +#include + +#include "channel.hh" + +struct MyObject +{ + uint64_t a{0}; +}; + +BOOST_AUTO_TEST_SUITE(test_channel) + +BOOST_AUTO_TEST_CASE(test_object_queue) { + auto [sender, receiver] = pdns::channel::createObjectQueue(); + + BOOST_CHECK(receiver.getDescriptor() != -1); + BOOST_CHECK_EQUAL(receiver.isClosed(), false); + + auto got = receiver.receive(); + BOOST_CHECK(!got); + + auto obj = std::make_unique(); + obj->a = 42U; + BOOST_CHECK_EQUAL(sender.send(std::move(obj)), true); + BOOST_CHECK(!obj); + got = receiver.receive(); + BOOST_CHECK(got != std::nullopt && *got); + BOOST_CHECK_EQUAL((*got)->a, 42U); +} + +BOOST_AUTO_TEST_CASE(test_object_queue_full) { + auto [sender, receiver] = pdns::channel::createObjectQueue(); + + { + auto got = receiver.receive(); + BOOST_CHECK(!got); + } + + /* add objects to the queue until it becomes full */ + bool blocked = false; + size_t queued = 0; + while (!blocked) { + auto obj = std::make_unique(); + obj->a = 42U; + blocked = sender.send(std::move(obj)) == false; + if (blocked) { + BOOST_CHECK(obj); + } + else { + BOOST_CHECK(!obj); + ++queued; + } + } + + BOOST_CHECK_GT(queued, 1U); + + /* clear the queue */ + blocked = false; + size_t received = 0; + while (!blocked) { + auto got = receiver.receive(); + if (got) { + ++received; + } + else { + blocked = true; + } + } + + BOOST_CHECK_EQUAL(queued, received); + + /* we should be able to write again */ + auto obj = std::make_unique(); + obj->a = 42U; + BOOST_CHECK(sender.send(std::move(obj))); +} + +BOOST_AUTO_TEST_CASE(test_object_queue_throw_on_eof) { + auto [sender, receiver] = pdns::channel::createObjectQueue(); + sender.close(); + BOOST_CHECK_THROW(receiver.receive(), std::runtime_error); + BOOST_CHECK_EQUAL(receiver.isClosed(), true); +} + +BOOST_AUTO_TEST_CASE(test_object_queue_do_not_throw_on_eof) { + auto [sender, receiver] = pdns::channel::createObjectQueue(true, true, 0U, false); + sender.close(); + auto got = receiver.receive(); + BOOST_CHECK(got == std::nullopt); + BOOST_CHECK_EQUAL(receiver.isClosed(), true); +} + +BOOST_AUTO_TEST_CASE(test_notification_queue_full) { + auto [notifier, waiter] = pdns::channel::createNotificationQueue(); + + BOOST_CHECK(waiter.getDescriptor() != -1); + BOOST_CHECK_EQUAL(waiter.isClosed(), false); + waiter.clear(); + + /* add notifications until the queue becomes full */ + bool blocked = false; + while (!blocked) + { + blocked = notifier.notify(); + } + + /* clear the queue */ + waiter.clear(); + + /* we should be able to write again */ + BOOST_CHECK(notifier.notify()); +} + +BOOST_AUTO_TEST_CASE(test_notification_queue_throw_on_eof) { + auto [notifier, waiter] = pdns::channel::createNotificationQueue(); + + BOOST_CHECK(waiter.getDescriptor() != -1); + BOOST_CHECK_EQUAL(waiter.isClosed(), false); + + BOOST_CHECK_EQUAL(notifier.notify(), true); + waiter.clear(); + + notifier = pdns::channel::Notifier(); + BOOST_CHECK_THROW(waiter.clear(), std::runtime_error); +} + +BOOST_AUTO_TEST_CASE(test_notification_queue_do_not_throw_on_eof) { + auto [notifier, waiter] = pdns::channel::createNotificationQueue(true, 0, false); + + BOOST_CHECK(waiter.getDescriptor() != -1); + BOOST_CHECK_EQUAL(waiter.isClosed(), false); + + BOOST_CHECK_EQUAL(notifier.notify(), true); + waiter.clear(); + + notifier = pdns::channel::Notifier(); + waiter.clear(); + BOOST_CHECK_EQUAL(waiter.isClosed(), true); +} + +BOOST_AUTO_TEST_SUITE_END() + From 3084c593328d2cbe0513ae30edbaf1c16c977260 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 19 Dec 2022 12:00:31 +0100 Subject: [PATCH 275/909] channel unit tests: Fix formatting --- pdns/test-channel.cc | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/pdns/test-channel.cc b/pdns/test-channel.cc index e97ddbe5ff78..500db1fb68f4 100644 --- a/pdns/test-channel.cc +++ b/pdns/test-channel.cc @@ -12,7 +12,8 @@ struct MyObject BOOST_AUTO_TEST_SUITE(test_channel) -BOOST_AUTO_TEST_CASE(test_object_queue) { +BOOST_AUTO_TEST_CASE(test_object_queue) +{ auto [sender, receiver] = pdns::channel::createObjectQueue(); BOOST_CHECK(receiver.getDescriptor() != -1); @@ -30,7 +31,8 @@ BOOST_AUTO_TEST_CASE(test_object_queue) { BOOST_CHECK_EQUAL((*got)->a, 42U); } -BOOST_AUTO_TEST_CASE(test_object_queue_full) { +BOOST_AUTO_TEST_CASE(test_object_queue_full) +{ auto [sender, receiver] = pdns::channel::createObjectQueue(); { @@ -77,14 +79,16 @@ BOOST_AUTO_TEST_CASE(test_object_queue_full) { BOOST_CHECK(sender.send(std::move(obj))); } -BOOST_AUTO_TEST_CASE(test_object_queue_throw_on_eof) { +BOOST_AUTO_TEST_CASE(test_object_queue_throw_on_eof) +{ auto [sender, receiver] = pdns::channel::createObjectQueue(); sender.close(); BOOST_CHECK_THROW(receiver.receive(), std::runtime_error); BOOST_CHECK_EQUAL(receiver.isClosed(), true); } -BOOST_AUTO_TEST_CASE(test_object_queue_do_not_throw_on_eof) { +BOOST_AUTO_TEST_CASE(test_object_queue_do_not_throw_on_eof) +{ auto [sender, receiver] = pdns::channel::createObjectQueue(true, true, 0U, false); sender.close(); auto got = receiver.receive(); @@ -92,7 +96,8 @@ BOOST_AUTO_TEST_CASE(test_object_queue_do_not_throw_on_eof) { BOOST_CHECK_EQUAL(receiver.isClosed(), true); } -BOOST_AUTO_TEST_CASE(test_notification_queue_full) { +BOOST_AUTO_TEST_CASE(test_notification_queue_full) +{ auto [notifier, waiter] = pdns::channel::createNotificationQueue(); BOOST_CHECK(waiter.getDescriptor() != -1); @@ -101,8 +106,7 @@ BOOST_AUTO_TEST_CASE(test_notification_queue_full) { /* add notifications until the queue becomes full */ bool blocked = false; - while (!blocked) - { + while (!blocked) { blocked = notifier.notify(); } @@ -113,7 +117,8 @@ BOOST_AUTO_TEST_CASE(test_notification_queue_full) { BOOST_CHECK(notifier.notify()); } -BOOST_AUTO_TEST_CASE(test_notification_queue_throw_on_eof) { +BOOST_AUTO_TEST_CASE(test_notification_queue_throw_on_eof) +{ auto [notifier, waiter] = pdns::channel::createNotificationQueue(); BOOST_CHECK(waiter.getDescriptor() != -1); @@ -126,7 +131,8 @@ BOOST_AUTO_TEST_CASE(test_notification_queue_throw_on_eof) { BOOST_CHECK_THROW(waiter.clear(), std::runtime_error); } -BOOST_AUTO_TEST_CASE(test_notification_queue_do_not_throw_on_eof) { +BOOST_AUTO_TEST_CASE(test_notification_queue_do_not_throw_on_eof) +{ auto [notifier, waiter] = pdns::channel::createNotificationQueue(true, 0, false); BOOST_CHECK(waiter.getDescriptor() != -1); @@ -141,4 +147,3 @@ BOOST_AUTO_TEST_CASE(test_notification_queue_do_not_throw_on_eof) { } BOOST_AUTO_TEST_SUITE_END() - From 465d1e15f1e511fe5eb80e426a18005297892bec Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 22 Dec 2022 10:25:00 +0100 Subject: [PATCH 276/909] channel: Transfer the object to a local pointer before sending it Even calling release() on the initial unique_ptr after sending the object could cause a use-after-free, as the unique_ptr might have been destroyed in the meantime. --- pdns/channel.hh | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/pdns/channel.hh b/pdns/channel.hh index d22004034168..119c1a24fbfb 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -220,8 +220,10 @@ namespace channel template bool Sender::send(std::unique_ptr&& object) const { - // we do not release right away because we might need the custom deleter later - auto ptr = object.get(); + /* we cannot touch the initial unique pointer after writing to the pipe, + not even to release it, so let's transfer it to a local object */ + auto localObj = std::move(object); + auto ptr = localObj.get(); static_assert(sizeof(ptr) <= PIPE_BUF, "Writes up to PIPE_BUF are guaranted not to interleaved and to either fully succeed or fail"); while (true) { #if __SANITIZE_THREAD__ @@ -230,11 +232,13 @@ namespace channel ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); if (sent == sizeof(ptr)) { - // we cannot touch it anymore - object.release(); + localObj.release(); return true; } else if (sent == 0) { +#if __SANITIZE_THREAD__ + __tsan_acquire(ptr); +#endif /* __SANITIZE_THREAD__ */ throw std::runtime_error("Unable to write to channel: remote end has been closed"); } else { @@ -245,6 +249,7 @@ namespace channel continue; } if (errno == EAGAIN || errno == EWOULDBLOCK) { + object = std::move(localObj); return false; } else { From 35b27ac8d18b43702a63e4078b68776c66f561ab Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 12 May 2023 17:42:27 +0200 Subject: [PATCH 277/909] dnsdist: Hopefully make clang-tidy happy --- pdns/channel.cc | 21 ++++------ pdns/dnsdistdist/dnsdist-nghttp2.cc | 64 ++++++++++++++++++++++++----- pdns/dnsdistdist/doh.cc | 6 +-- 3 files changed, 64 insertions(+), 27 deletions(-) diff --git a/pdns/channel.cc b/pdns/channel.cc index ae62d23693b1..262772b7f9e9 100644 --- a/pdns/channel.cc +++ b/pdns/channel.cc @@ -22,9 +22,7 @@ #include "channel.hh" -namespace pdns -{ -namespace channel +namespace pdns::channel { Notifier::Notifier(FDWrapper&& fd) : @@ -47,9 +45,7 @@ namespace channel if (errno == EAGAIN || errno == EWOULDBLOCK) { return false; } - else { - throw std::runtime_error("Unable to write to channel notifier pipe: " + stringerror()); - } + throw std::runtime_error("Unable to write to channel notifier pipe: " + stringerror()); } return true; } @@ -62,9 +58,9 @@ namespace channel void Waiter::clear() { - ssize_t got; + ssize_t got{0}; do { - char data; + char data{0}; got = read(d_fd.getHandle(), &data, sizeof(data)); if (got == 0) { d_closed = true; @@ -73,7 +69,7 @@ namespace channel } throw std::runtime_error("EOF while clearing channel notifier pipe"); } - else if (got == -1) { + if (got == -1) { if (errno == EINTR) { continue; } @@ -82,7 +78,7 @@ namespace channel } throw std::runtime_error("Error while clearing channel notifier pipe: " + stringerror()); } - } while (got); + } while (got > 0); } int Waiter::getDescriptor() const @@ -92,8 +88,8 @@ namespace channel std::pair createNotificationQueue(bool nonBlocking, size_t pipeBufferSize, bool throwOnEOF) { - int fds[2] = {-1, -1}; - if (pipe(fds) < 0) { + std::array fds = {-1, -1}; + if (pipe(fds.data()) < 0) { throw std::runtime_error("Error creating notification channel pipe: " + stringerror()); } @@ -117,4 +113,3 @@ namespace channel return std::pair(Notifier(std::move(sender)), Waiter(std::move(receiver), throwOnEOF)); } } -} diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 52403b9b048f..9c505cdcebe3 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -133,7 +133,11 @@ uint32_t DoHConnectionToBackend::getConcurrentStreamsCount() const void DoHConnectionToBackend::handleResponse(PendingRequest&& request) { - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; + gettimeofday(&now, nullptr); try { if (!d_healthCheckQuery) { @@ -175,7 +179,11 @@ void DoHConnectionToBackend::handleIOError() d_connectionDied = true; nghttp2_session_terminate_session(d_session.get(), NGHTTP2_PROTOCOL_ERROR); - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; + gettimeofday(&now, nullptr); for (auto& request : d_currentStreams) { handleResponseError(std::move(request.second), now); @@ -406,7 +414,11 @@ void DoHConnectionToBackend::handleReadableIOCallback(int fd, FDMultiplexer::fun throw std::runtime_error("Fatal error while passing received data to nghttp2: " + std::string(nghttp2_strerror((int)readlen))); } - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; + gettimeofday(&now, nullptr); conn->d_lastDataReceivedTime = now; @@ -496,7 +508,11 @@ void DoHConnectionToBackend::stopIO() void DoHConnectionToBackend::updateIO(IOState newState, FDMultiplexer::callbackfunc_t callback, bool noTTD) { - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; + gettimeofday(&now, nullptr); boost::optional ttd{boost::none}; if (!noTTD) { @@ -535,7 +551,11 @@ void DoHConnectionToBackend::watchForRemoteHostClosingConnection() void DoHConnectionToBackend::addToIOState(IOState state, FDMultiplexer::callbackfunc_t callback) { - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; + gettimeofday(&now, nullptr); boost::optional ttd{boost::none}; if (state == IOState::NeedRead) { @@ -649,7 +669,11 @@ int DoHConnectionToBackend::on_frame_recv_callback(nghttp2_session* session, con } else { vinfolog("HTTP response has a non-200 status code: %d", request.d_responseCode); - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; + gettimeofday(&now, nullptr); conn->handleResponseError(std::move(request), now); @@ -701,7 +725,11 @@ int DoHConnectionToBackend::on_data_chunk_recv_callback(nghttp2_session* session } else { vinfolog("HTTP response has a non-200 status code: %d", request.d_responseCode); - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; + gettimeofday(&now, nullptr); conn->handleResponseError(std::move(request), now); @@ -733,7 +761,11 @@ int DoHConnectionToBackend::on_stream_close_callback(nghttp2_session* session, i return 0; } - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; + gettimeofday(&now, nullptr); auto request = std::move(stream->second); conn->d_currentStreams.erase(stream->first); @@ -872,7 +904,10 @@ static void handleCrossProtocolQuery(int pipefd, FDMultiplexer::funcparam_t& par throw std::runtime_error("Error while reading from the DoH cross-protocol channel:" + std::string(e.what())); } - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; gettimeofday(&now, nullptr); std::shared_ptr tqs = cpq->getTCPQuerySender(); @@ -897,7 +932,11 @@ static void dohClientThread(pdns::channel::Receiver&& receiv DoHClientThreadData data(std::move(receiver)); data.mplexer->addReadFD(data.d_receiver.getDescriptor(), handleCrossProtocolQuery, &data); - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; + gettimeofday(&now, nullptr); time_t lastTimeoutScan = now.tv_sec; @@ -1088,7 +1127,10 @@ bool setupDoHClientProtocolNegotiation(std::shared_ptr& ctx) bool sendH2Query(const std::shared_ptr& ds, std::unique_ptr& mplexer, std::shared_ptr& sender, InternalQuery&& query, bool healthCheck) { #ifdef HAVE_NGHTTP2 - struct timeval now; + struct timeval now + { + .tv_sec = 0, .tv_usec = 0 + }; gettimeofday(&now, nullptr); if (healthCheck) { diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 57da686ee53f..4573addbab88 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -1272,7 +1272,7 @@ static void on_dnsdist(h2o_socket_t *listener, const char *err) for the CPU, the first thing we need to do is to send responses to free slots anyway, otherwise queries and responses are piling up in our pipes, consuming memory and likely coming up too late after the client has gone away */ - DOHServerConfig* dsc = reinterpret_cast(listener->data); + auto* dsc = static_cast(listener->data); while (true) { std::unique_ptr du{nullptr, DOHUnit::release}; try { @@ -1389,7 +1389,7 @@ static void on_accept(h2o_socket_t *listener, const char *err) static int create_listener(std::shared_ptr& dsc, int fd) { - auto sock = h2o_evloop_socket_create(dsc->h2o_ctx.loop, fd, H2O_SOCKET_FLAG_DONT_READ); + auto* sock = h2o_evloop_socket_create(dsc->h2o_ctx.loop, fd, H2O_SOCKET_FLAG_DONT_READ); sock->data = dsc.get(); h2o_socket_read_start(sock, on_accept); @@ -1617,7 +1617,7 @@ void dohThread(ClientState* cs) dsc->h2o_ctx.storage.entries[0].data = dsc.get(); ++dsc->h2o_ctx.storage.size; - auto sock = h2o_evloop_socket_create(dsc->h2o_ctx.loop, dsc->d_responseReceiver.getDescriptor(), H2O_SOCKET_FLAG_DONT_READ); + auto* sock = h2o_evloop_socket_create(dsc->h2o_ctx.loop, dsc->d_responseReceiver.getDescriptor(), H2O_SOCKET_FLAG_DONT_READ); sock->data = dsc.get(); // this listens to responses from dnsdist to turn into http responses From bf70d526029467cb3b245458711fa9c52c7a5e68 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 12 May 2023 17:56:05 +0200 Subject: [PATCH 278/909] dnsdist: Fix formatting in channel.cc --- pdns/channel.cc | 142 ++++++++++++++++++++++++------------------------ 1 file changed, 71 insertions(+), 71 deletions(-) diff --git a/pdns/channel.cc b/pdns/channel.cc index 262772b7f9e9..9b820437d53c 100644 --- a/pdns/channel.cc +++ b/pdns/channel.cc @@ -25,91 +25,91 @@ namespace pdns::channel { - Notifier::Notifier(FDWrapper&& fd) : - d_fd(std::move(fd)) - { - } +Notifier::Notifier(FDWrapper&& fd) : + d_fd(std::move(fd)) +{ +} - bool Notifier::notify() const - { - char data = 'a'; - while (true) { - auto sent = write(d_fd.getHandle(), &data, sizeof(data)); - if (sent == 0) { - throw std::runtime_error("Unable to write to channel notifier pipe: remote end has been closed"); +bool Notifier::notify() const +{ + char data = 'a'; + while (true) { + auto sent = write(d_fd.getHandle(), &data, sizeof(data)); + if (sent == 0) { + throw std::runtime_error("Unable to write to channel notifier pipe: remote end has been closed"); + } + if (sent != sizeof(data)) { + if (errno == EINTR) { + continue; } - if (sent != sizeof(data)) { - if (errno == EINTR) { - continue; - } - if (errno == EAGAIN || errno == EWOULDBLOCK) { - return false; - } - throw std::runtime_error("Unable to write to channel notifier pipe: " + stringerror()); + if (errno == EAGAIN || errno == EWOULDBLOCK) { + return false; } - return true; + throw std::runtime_error("Unable to write to channel notifier pipe: " + stringerror()); } + return true; } +} - Waiter::Waiter(FDWrapper&& fd, bool throwOnEOF) : - d_fd(std::move(fd)), d_throwOnEOF(throwOnEOF) - { - } +Waiter::Waiter(FDWrapper&& fd, bool throwOnEOF) : + d_fd(std::move(fd)), d_throwOnEOF(throwOnEOF) +{ +} - void Waiter::clear() - { - ssize_t got{0}; - do { - char data{0}; - got = read(d_fd.getHandle(), &data, sizeof(data)); - if (got == 0) { - d_closed = true; - if (!d_throwOnEOF) { - return; - } - throw std::runtime_error("EOF while clearing channel notifier pipe"); +void Waiter::clear() +{ + ssize_t got{0}; + do { + char data{0}; + got = read(d_fd.getHandle(), &data, sizeof(data)); + if (got == 0) { + d_closed = true; + if (!d_throwOnEOF) { + return; } - if (got == -1) { - if (errno == EINTR) { - continue; - } - if (errno == EAGAIN || errno == EWOULDBLOCK) { - break; - } - throw std::runtime_error("Error while clearing channel notifier pipe: " + stringerror()); + throw std::runtime_error("EOF while clearing channel notifier pipe"); + } + if (got == -1) { + if (errno == EINTR) { + continue; } - } while (got > 0); - } - - int Waiter::getDescriptor() const - { - return d_fd.getHandle(); - } - - std::pair createNotificationQueue(bool nonBlocking, size_t pipeBufferSize, bool throwOnEOF) - { - std::array fds = {-1, -1}; - if (pipe(fds.data()) < 0) { - throw std::runtime_error("Error creating notification channel pipe: " + stringerror()); + if (errno == EAGAIN || errno == EWOULDBLOCK) { + break; + } + throw std::runtime_error("Error while clearing channel notifier pipe: " + stringerror()); } + } while (got > 0); +} - FDWrapper sender(fds[1]); - FDWrapper receiver(fds[0]); +int Waiter::getDescriptor() const +{ + return d_fd.getHandle(); +} - if (nonBlocking && !setNonBlocking(receiver.getHandle())) { - int err = errno; - throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); - } +std::pair createNotificationQueue(bool nonBlocking, size_t pipeBufferSize, bool throwOnEOF) +{ + std::array fds = {-1, -1}; + if (pipe(fds.data()) < 0) { + throw std::runtime_error("Error creating notification channel pipe: " + stringerror()); + } - if (nonBlocking && !setNonBlocking(sender.getHandle())) { - int err = errno; - throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); - } + FDWrapper sender(fds[1]); + FDWrapper receiver(fds[0]); - if (pipeBufferSize > 0 && getPipeBufferSize(receiver.getHandle()) < pipeBufferSize) { - setPipeBufferSize(receiver.getHandle(), pipeBufferSize); - } + if (nonBlocking && !setNonBlocking(receiver.getHandle())) { + int err = errno; + throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); + } - return std::pair(Notifier(std::move(sender)), Waiter(std::move(receiver), throwOnEOF)); + if (nonBlocking && !setNonBlocking(sender.getHandle())) { + int err = errno; + throw std::runtime_error("Error making notification channel pipe non-blocking: " + stringerror(err)); } + + if (pipeBufferSize > 0 && getPipeBufferSize(receiver.getHandle()) < pipeBufferSize) { + setPipeBufferSize(receiver.getHandle(), pipeBufferSize); + } + + return std::pair(Notifier(std::move(sender)), Waiter(std::move(receiver), throwOnEOF)); +} } From 2c9b6e8915304b24996e9382ba1e8a36713b5da4 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 13 Jun 2023 10:02:45 +0200 Subject: [PATCH 279/909] dnsdist: Fix a boolean nit as suggested by Otto --- pdns/dnsdist.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index e2e123b7927a..fbe373cf71ab 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -1349,7 +1349,7 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders /* we do not record a miss for queries received over DoH and forwarded over TCP yet, as we will do a second-lookup */ - if (dq.ids.packetCache->get(dq, dq.getHeader()->id, &dq.ids.cacheKey, dq.ids.subnet, dq.ids.dnssecOK, forwardedOverUDP, allowExpired, false, true, (dq.ids.protocol != dnsdist::Protocol::DoH || forwardedOverUDP) ? true : false)) { + if (dq.ids.packetCache->get(dq, dq.getHeader()->id, &dq.ids.cacheKey, dq.ids.subnet, dq.ids.dnssecOK, forwardedOverUDP, allowExpired, false, true, dq.ids.protocol != dnsdist::Protocol::DoH || forwardedOverUDP)) { restoreFlags(dq.getHeader(), dq.ids.origFlags); From e65bc2837ce056901adada8e2cf677790b297f93 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 11 May 2023 15:22:25 +0200 Subject: [PATCH 280/909] dnsdist: Add the query ID to health-check log messages, fix nits --- pdns/dnsdistdist/dnsdist-healthchecks.cc | 42 +++++++++++++----------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index 213374020f15..9944fd4b4ab2 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -106,15 +106,13 @@ static bool handleResponse(std::shared_ptr& data) return false; } } - catch(const std::exception& e) - { + catch(const std::exception& e) { if (g_verboseHealthChecks) { infolog("Error checking the health of backend %s: %s", ds->getNameWithAddr(), e.what()); } return false; } - catch(...) - { + catch (...) { if (g_verboseHealthChecks) { infolog("Unknown exception while checking the health of backend %s", ds->getNameWithAddr()); } @@ -171,8 +169,9 @@ static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) data->d_buffer.resize(512); auto got = recvfrom(data->d_udpSocket.getHandle(), &data->d_buffer.at(0), data->d_buffer.size(), 0, reinterpret_cast(&from), &fromlen); if (got < 0) { + int savederrno = errno; if (g_verboseHealthChecks) { - infolog("Error receiving health check response from %s: %s", data->d_ds->d_config.remote.toStringWithPort(), stringerror()); + infolog("Error receiving health check response from %s: %s", data->d_ds->d_config.remote.toStringWithPort(), stringerror(savederrno)); } data->d_ds->submitHealthCheckResult(data->d_initial, false); return; @@ -263,8 +262,7 @@ static void healthCheckTCPCallback(int fd, FDMultiplexer::funcparam_t& param) bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared_ptr& ds, bool initialCheck) { - try - { + try { uint16_t queryID = dnsdist::getRandomDNSID(); DNSName checkName = ds->d_config.checkName; uint16_t checkType = ds->d_config.checkType.getCode(); @@ -345,7 +343,7 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared if (sent < 0) { int ret = errno; if (g_verboseHealthChecks) { - infolog("Error while sending a health check query to backend %s: %d", ds->getNameWithAddr(), ret); + infolog("Error while sending a health check query (ID %d) to backend %s: %d", queryID, ds->getNameWithAddr(), ret); } return false; } @@ -361,18 +359,18 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared } } else { - time_t now = time(nullptr); data->d_tcpHandler = std::make_unique(ds->d_config.d_tlsSubjectName, ds->d_config.d_tlsSubjectIsAddr, sock.releaseHandle(), timeval{ds->d_config.checkTimeout,0}, ds->d_tlsCtx); data->d_ioState = std::make_unique(*mplexer, data->d_tcpHandler->getDescriptor()); if (ds->d_tlsCtx) { try { + time_t now = time(nullptr); auto tlsSession = g_sessionCache.getSession(ds->getID(), now); if (tlsSession) { data->d_tcpHandler->setTLSSession(tlsSession); } } catch (const std::exception& e) { - vinfolog("Unable to restore a TLS session for the DoT healthcheck: %s", e.what()); + vinfolog("Unable to restore a TLS session for the DoT healthcheck for backend %s: %s", ds->getNameWithAddr(), e.what()); } } data->d_tcpHandler->tryConnect(ds->d_config.tcpFastOpen, ds->d_config.remote); @@ -394,15 +392,13 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared return true; } - catch (const std::exception& e) - { + catch (const std::exception& e) { if (g_verboseHealthChecks) { infolog("Error checking the health of backend %s: %s", ds->getNameWithAddr(), e.what()); } return false; } - catch (...) - { + catch (...) { if (g_verboseHealthChecks) { infolog("Unknown exception while checking the health of backend %s", ds->getNameWithAddr()); } @@ -421,6 +417,10 @@ void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial) } break; } + if (ret > 0) { + /* we got at least one event other than a timeout */ + continue; + } handleH2Timeouts(mplexer, now); @@ -432,6 +432,7 @@ void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial) auto data = boost::any_cast>(timeout.second); try { + /* UDP does not have an IO state, H2 is handled separately */ if (data->d_ioState) { data->d_ioState.reset(); } @@ -439,19 +440,19 @@ void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial) mplexer.removeReadFD(timeout.first); } if (g_verboseHealthChecks) { - infolog("Timeout while waiting for the health check response from backend %s", data->d_ds->getNameWithAddr()); + infolog("Timeout while waiting for the health check response (ID %d) from backend %s", data->d_queryID, data->d_ds->getNameWithAddr()); } data->d_ds->submitHealthCheckResult(initial, false); } catch (const std::exception& e) { if (g_verboseHealthChecks) { - infolog("Error while dealing with a timeout for the health check response from backend %s: %s", data->d_ds->getNameWithAddr(), e.what()); + infolog("Error while dealing with a timeout for the health check response (ID %d) from backend %s: %s", data->d_queryID, data->d_ds->getNameWithAddr(), e.what()); } } catch (...) { if (g_verboseHealthChecks) { - infolog("Error while dealing with a timeout for the health check response from backend %s", data->d_ds->getNameWithAddr()); + infolog("Error while dealing with a timeout for the health check response (ID %d) from backend %s", data->d_queryID, data->d_ds->getNameWithAddr()); } } } @@ -463,21 +464,22 @@ void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial) } auto data = boost::any_cast>(timeout.second); try { + /* UDP does not block while writing, H2 is handled separately */ data->d_ioState.reset(); if (g_verboseHealthChecks) { - infolog("Timeout while waiting for the health check response from backend %s", data->d_ds->getNameWithAddr()); + infolog("Timeout while waiting for the health check response (ID %d) from backend %s", data->d_queryID, data->d_ds->getNameWithAddr()); } data->d_ds->submitHealthCheckResult(initial, false); } catch (const std::exception& e) { if (g_verboseHealthChecks) { - infolog("Error while dealing with a timeout for the health check response from backend %s: %s", data->d_ds->getNameWithAddr(), e.what()); + infolog("Error while dealing with a timeout for the health check response (ID %d) from backend %s: %s", data->d_queryID, data->d_ds->getNameWithAddr(), e.what()); } } catch (...) { if (g_verboseHealthChecks) { - infolog("Error while dealing with a timeout for the health check response from backend %s", data->d_ds->getNameWithAddr()); + infolog("Error while dealing with a timeout for the health check response (ID %d) from backend %s", data->d_queryID, data->d_ds->getNameWithAddr()); } } } From ebd45edec62cd9df0ee21fda2213d48c0f222ebf Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 13 Jun 2023 10:52:33 +0200 Subject: [PATCH 281/909] channel: Fix clang-tidy warnings --- pdns/channel.cc | 2 +- pdns/test-channel.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/channel.cc b/pdns/channel.cc index 9b820437d53c..5892f9e0f881 100644 --- a/pdns/channel.cc +++ b/pdns/channel.cc @@ -110,6 +110,6 @@ std::pair createNotificationQueue(bool nonBlocking, size_t pip setPipeBufferSize(receiver.getHandle(), pipeBufferSize); } - return std::pair(Notifier(std::move(sender)), Waiter(std::move(receiver), throwOnEOF)); + return {Notifier(std::move(sender)), Waiter(std::move(receiver), throwOnEOF)}; } } diff --git a/pdns/test-channel.cc b/pdns/test-channel.cc index 500db1fb68f4..6965eecdbf67 100644 --- a/pdns/test-channel.cc +++ b/pdns/test-channel.cc @@ -46,7 +46,7 @@ BOOST_AUTO_TEST_CASE(test_object_queue_full) while (!blocked) { auto obj = std::make_unique(); obj->a = 42U; - blocked = sender.send(std::move(obj)) == false; + blocked = !sender.send(std::move(obj)); if (blocked) { BOOST_CHECK(obj); } From efaeb353a9375ddef62f3b03a69cbf776d164fae Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 11:35:20 +0200 Subject: [PATCH 282/909] Fix build of speedtest and make sure it gets built automatically to avoid bitrot --- pdns/Makefile.am | 4 +++- pdns/speedtest.cc | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 88229c32a741..3424cbc7c958 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1504,8 +1504,10 @@ pdns_control_LDFLAGS = \ $(AM_LDFLAGS) \ $(LIBCRYPTO_LDFLAGS) +noinst_PROGRAMS = speedtest + if UNIT_TESTS -noinst_PROGRAMS = testrunner +noinst_PROGRAMS += testrunner if HAVE_BOOST_GE_148 TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message SRCDIR='$(srcdir)' TESTS=testrunner diff --git a/pdns/speedtest.cc b/pdns/speedtest.cc index 9c7b5264a133..1447080f2c31 100644 --- a/pdns/speedtest.cc +++ b/pdns/speedtest.cc @@ -673,7 +673,7 @@ struct ParsePacketTest rr.qname=i->first.d_name; rr.ttl=i->first.d_ttl; - rr.content=i->first.d_content->getZoneRepresentation(); // this should be the serialised form + rr.content=i->first.getContent()->getZoneRepresentation(); // this should be the serialised form lwr.d_result.push_back(rr); } From 770bceb898be8377240f1a72bfe9b573cd020519 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 11:55:39 +0200 Subject: [PATCH 283/909] Add GGS_LIB to speedtest link if needed --- pdns/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 3424cbc7c958..0c73584470c6 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1444,6 +1444,7 @@ testrunner_LDADD = \ if GSS_TSIG testrunner_LDADD += $(GSS_LIBS) +speedtest_LDADD += $(GSS_LIBS) endif if PKCS11 From 03544d6f85a77b72705cd552f839daacd86ef3f5 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 10:49:45 +0200 Subject: [PATCH 284/909] Reformat --- .not-formatted | 3 - pdns/dns_random.cc | 193 +++++++++++++++++++------------------ pdns/dns_random.hh | 76 ++++++++------- pdns/test-dns_random_hh.cc | 104 ++++++++++---------- 4 files changed, 190 insertions(+), 186 deletions(-) diff --git a/.not-formatted b/.not-formatted index cbe3421eb765..f09ac66bca40 100644 --- a/.not-formatted +++ b/.not-formatted @@ -36,8 +36,6 @@ ./pdns/distributor.hh ./pdns/dns.cc ./pdns/dns.hh -./pdns/dns_random.cc -./pdns/dns_random.hh ./pdns/dnsbackend.cc ./pdns/dnsbackend.hh ./pdns/dnsbulktest.cc @@ -268,7 +266,6 @@ ./pdns/test-common.hh ./pdns/test-digests_hh.cc ./pdns/test-distributor_hh.cc -./pdns/test-dns_random_hh.cc ./pdns/test-dnscrypt_cc.cc ./pdns/test-dnsdist_cc.cc ./pdns/test-dnsdistpacketcache_cc.cc diff --git a/pdns/dns_random.cc b/pdns/dns_random.cc index 7f75b4908ce9..b53ba0e5a1e2 100644 --- a/pdns/dns_random.cc +++ b/pdns/dns_random.cc @@ -51,7 +51,8 @@ static enum DNS_RNG { RNG_ARC4RANDOM, RNG_URANDOM, RNG_KISS, -} chosen_rng = RNG_UNINITIALIZED; +} chosen_rng + = RNG_UNINITIALIZED; static int urandom_fd = -1; @@ -71,17 +72,17 @@ kiss_init(unsigned int seed) static unsigned int kiss_rand(void) { - kiss_z = 36969 * (kiss_z&65535) + (kiss_z>>16); - kiss_w = 18000 * (kiss_w&65535) + (kiss_w>>16); + kiss_z = 36969 * (kiss_z & 65535) + (kiss_z >> 16); + kiss_w = 18000 * (kiss_w & 65535) + (kiss_w >> 16); kiss_jcong = 69069 * kiss_jcong + 1234567; - kiss_jsr^=(kiss_jsr<<13); /* <<17, >>13 gives cycle length 2^28.2 max */ - kiss_jsr^=(kiss_jsr>>17); /* <<13, >>17 gives maximal cycle length */ - kiss_jsr^=(kiss_jsr<<5); - return (((kiss_z<<16) + kiss_w) ^ kiss_jcong) + kiss_jsr; + kiss_jsr ^= (kiss_jsr << 13); /* <<17, >>13 gives cycle length 2^28.2 max */ + kiss_jsr ^= (kiss_jsr >> 17); /* <<13, >>17 gives maximal cycle length */ + kiss_jsr ^= (kiss_jsr << 5); + return (((kiss_z << 16) + kiss_w) ^ kiss_jcong) + kiss_jsr; } #endif -static void dns_random_setup(bool force=false) +static void dns_random_setup(bool force = false) { string rdev; string rng; @@ -99,66 +100,73 @@ static void dns_random_setup(bool force=false) rng = ::arg()["rng"]; rdev = ::arg()["entropy-source"]; if (rng == "auto") { -# if defined(HAVE_GETRANDOM) +#if defined(HAVE_GETRANDOM) chosen_rng = RNG_GETRANDOM; -# elif defined(HAVE_ARC4RANDOM) +#elif defined(HAVE_ARC4RANDOM) chosen_rng = RNG_ARC4RANDOM; -# elif defined(HAVE_RANDOMBYTES_STIR) +#elif defined(HAVE_RANDOMBYTES_STIR) chosen_rng = RNG_SODIUM; -# elif defined(HAVE_RAND_BYTES) +#elif defined(HAVE_RAND_BYTES) chosen_rng = RNG_OPENSSL; -# else +#else chosen_rng = RNG_URANDOM; -# endif -# if defined(HAVE_RANDOMBYTES_STIR) - } else if (rng == "sodium") { +#endif +#if defined(HAVE_RANDOMBYTES_STIR) + } + else if (rng == "sodium") { chosen_rng = RNG_SODIUM; -# endif -# if defined(HAVE_RAND_BYTES) - } else if (rng == "openssl") { +#endif +#if defined(HAVE_RAND_BYTES) + } + else if (rng == "openssl") { chosen_rng = RNG_OPENSSL; -# endif -# if defined(HAVE_GETRANDOM) - } else if (rng == "getrandom") { +#endif +#if defined(HAVE_GETRANDOM) + } + else if (rng == "getrandom") { chosen_rng = RNG_GETRANDOM; -# endif -# if defined(HAVE_ARC4RANDOM) - } else if (rng == "arc4random") { +#endif +#if defined(HAVE_ARC4RANDOM) + } + else if (rng == "arc4random") { chosen_rng = RNG_ARC4RANDOM; -# endif - } else if (rng == "urandom") { +#endif + } + else if (rng == "urandom") { chosen_rng = RNG_URANDOM; #if defined(HAVE_KISS_RNG) - } else if (rng == "kiss") { + } + else if (rng == "kiss") { chosen_rng = RNG_KISS; - g_log<(__LINE__)); // cannot be reached case RNG_SODIUM: @@ -229,37 +236,35 @@ uint32_t dns_random(uint32_t upper_bound) { #endif /* RND_SODIUM */ case RNG_OPENSSL: { #if defined(HAVE_RAND_BYTES) && !defined(USE_URANDOM_ONLY) - uint32_t num = 0; - do { - if (RAND_bytes(reinterpret_cast(&num), sizeof(num)) < 1) - throw std::runtime_error("Openssl RNG was not seeded"); - } - while(num < min); + uint32_t num = 0; + do { + if (RAND_bytes(reinterpret_cast(&num), sizeof(num)) < 1) + throw std::runtime_error("Openssl RNG was not seeded"); + } while (num < min); - return num % upper_bound; + return num % upper_bound; #else - throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached + throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached #endif /* RNG_OPENSSL */ - } + } case RNG_GETRANDOM: { #if defined(HAVE_GETRANDOM) && !defined(USE_URANDOM_ONLY) - uint32_t num = 0; - do { - auto got = getrandom(&num, sizeof(num), 0); - if (got == -1 && errno == EINTR) { - continue; - } - if (got != sizeof(num)) { - throw std::runtime_error("getrandom() failed: " + stringerror()); - } + uint32_t num = 0; + do { + auto got = getrandom(&num, sizeof(num), 0); + if (got == -1 && errno == EINTR) { + continue; + } + if (got != sizeof(num)) { + throw std::runtime_error("getrandom() failed: " + stringerror()); } - while(num < min); + } while (num < min); - return num % upper_bound; + return num % upper_bound; #else - throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached + throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached #endif - } + } case RNG_ARC4RANDOM: #if defined(HAVE_ARC4RANDOM) && !defined(USE_URANDOM_ONLY) return arc4random_uniform(upper_bound); @@ -267,41 +272,39 @@ uint32_t dns_random(uint32_t upper_bound) { throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached #endif case RNG_URANDOM: { - uint32_t num = 0; - size_t attempts = 5; - do { - ssize_t got = read(urandom_fd, &num, sizeof(num)); - if (got < 0) { - if (errno == EINTR) { - continue; - } - - (void)close(urandom_fd); - throw std::runtime_error("Cannot read random device"); - } - else if (static_cast(got) != sizeof(num)) { - /* short read, let's retry */ - if (attempts == 0) { - throw std::runtime_error("Too many short reads on random device"); - } - attempts--; + uint32_t num = 0; + size_t attempts = 5; + do { + ssize_t got = read(urandom_fd, &num, sizeof(num)); + if (got < 0) { + if (errno == EINTR) { continue; } + + (void)close(urandom_fd); + throw std::runtime_error("Cannot read random device"); + } + else if (static_cast(got) != sizeof(num)) { + /* short read, let's retry */ + if (attempts == 0) { + throw std::runtime_error("Too many short reads on random device"); + } + attempts--; + continue; } - while(num < min); + } while (num < min); - return num % upper_bound; - } + return num % upper_bound; + } #if defined(HAVE_KISS_RNG) case RNG_KISS: { - uint32_t num = 0; - do { - num = kiss_rand(); - } - while(num < min); + uint32_t num = 0; + do { + num = kiss_rand(); + } while (num < min); - return num % upper_bound; - } + return num % upper_bound; + } #endif default: throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached diff --git a/pdns/dns_random.hh b/pdns/dns_random.hh index 5c5e44155580..09ed7f39f9fd 100644 --- a/pdns/dns_random.hh +++ b/pdns/dns_random.hh @@ -28,50 +28,52 @@ void dns_random_init(const std::string& data = "", bool force_reinit = false); uint32_t dns_random(uint32_t n); uint16_t dns_random_uint16(); -namespace pdns { - struct dns_random_engine { +namespace pdns +{ +struct dns_random_engine +{ - typedef uint32_t result_type; + typedef uint32_t result_type; - static constexpr result_type min() - { - return 0; - } - - static constexpr result_type max() - { - return std::numeric_limits::max() - 1; - } + static constexpr result_type min() + { + return 0; + } - result_type operator()() - { - return dns_random(std::numeric_limits::max()); - } - }; + static constexpr result_type max() + { + return std::numeric_limits::max() - 1; + } - /* minimum value that a PRNG should return for this upper bound to avoid a modulo bias */ - inline unsigned int random_minimum_acceptable_value(uint32_t upper_bound) + result_type operator()() { - /* Parts of this code come from arc4random_uniform */ - /* To avoid "modulo bias" for some methods, calculate - minimum acceptable value for random number to improve - uniformity. + return dns_random(std::numeric_limits::max()); + } +}; + +/* minimum value that a PRNG should return for this upper bound to avoid a modulo bias */ +inline unsigned int random_minimum_acceptable_value(uint32_t upper_bound) +{ + /* Parts of this code come from arc4random_uniform */ + /* To avoid "modulo bias" for some methods, calculate + minimum acceptable value for random number to improve + uniformity. - On applicable rngs, we loop until the rng spews out - value larger than min, and then take modulo out of that. - */ - unsigned int min; + On applicable rngs, we loop until the rng spews out + value larger than min, and then take modulo out of that. + */ + unsigned int min; #if (ULONG_MAX > 0xffffffffUL) - min = 0x100000000UL % upper_bound; + min = 0x100000000UL % upper_bound; #else - /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ - if (upper_bound > 0x80000000) - min = 1 + ~upper_bound; /* 2**32 - upper_bound */ - else { - /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ - min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound; - } -#endif - return min; + /* Calculate (2**32 % upper_bound) avoiding 64-bit math */ + if (upper_bound > 0x80000000) + min = 1 + ~upper_bound; /* 2**32 - upper_bound */ + else { + /* (2**32 - (x * 2)) % x == 2**32 % x when x <= 2**31 */ + min = ((0xffffffff - (upper_bound * 2)) + 1) % upper_bound; } +#endif + return min; +} } diff --git a/pdns/test-dns_random_hh.cc b/pdns/test-dns_random_hh.cc index 13a31597a535..2d3af18c7f8e 100644 --- a/pdns/test-dns_random_hh.cc +++ b/pdns/test-dns_random_hh.cc @@ -19,32 +19,27 @@ #include "dns_random.hh" #include "namespaces.hh" - using namespace boost; using namespace boost::accumulators; typedef accumulator_set< - double - , stats - > acc_t; - - + double, stats> + acc_t; BOOST_AUTO_TEST_SUITE(test_dns_random_hh) -BOOST_AUTO_TEST_CASE(test_dns_random_auto_average) { +BOOST_AUTO_TEST_CASE(test_dns_random_auto_average) +{ - ::arg().set("rng")="auto"; - ::arg().set("entropy-source")="/dev/urandom"; + ::arg().set("rng") = "auto"; + ::arg().set("entropy-source") = "/dev/urandom"; dns_random_init("", true); acc_t acc; - for(unsigned int n=0; n < 100000; ++n) { - acc(dns_random(100000)/100000.0); + for (unsigned int n = 0; n < 100000; ++n) { + acc(dns_random(100000) / 100000.0); } BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); @@ -52,17 +47,18 @@ BOOST_AUTO_TEST_CASE(test_dns_random_auto_average) { // please add covariance tests, chi-square, Kolmogorov-Smirnov } -BOOST_AUTO_TEST_CASE(test_dns_random_urandom_average) { +BOOST_AUTO_TEST_CASE(test_dns_random_urandom_average) +{ - ::arg().set("rng")="urandom"; - ::arg().set("entropy-source")="/dev/urandom"; + ::arg().set("rng") = "urandom"; + ::arg().set("entropy-source") = "/dev/urandom"; dns_random_init("", true); acc_t acc; - for(unsigned int n=0; n < 100000; ++n) { - acc(dns_random(100000)/100000.0); + for (unsigned int n = 0; n < 100000; ++n) { + acc(dns_random(100000) / 100000.0); } BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); @@ -70,22 +66,24 @@ BOOST_AUTO_TEST_CASE(test_dns_random_urandom_average) { // please add covariance tests, chi-square, Kolmogorov-Smirnov } -BOOST_AUTO_TEST_CASE(test_dns_random_garbage) { +BOOST_AUTO_TEST_CASE(test_dns_random_garbage) +{ - ::arg().set("rng")="garbage"; - ::arg().set("entropy-source")="/dev/urandom"; + ::arg().set("rng") = "garbage"; + ::arg().set("entropy-source") = "/dev/urandom"; BOOST_CHECK_THROW(dns_random_init("", true), std::runtime_error); } -BOOST_AUTO_TEST_CASE(test_dns_random_upper_bound) { - ::arg().set("rng")="auto"; - ::arg().set("entropy-source")="/dev/urandom"; +BOOST_AUTO_TEST_CASE(test_dns_random_upper_bound) +{ + ::arg().set("rng") = "auto"; + ::arg().set("entropy-source") = "/dev/urandom"; dns_random_init("", true); map seen; - for(unsigned int n=0; n < 100000; ++n) { + for (unsigned int n = 0; n < 100000; ++n) { seen[dns_random(10)] = true; } @@ -103,17 +101,18 @@ BOOST_AUTO_TEST_CASE(test_dns_random_upper_bound) { } #if defined(HAVE_GETRANDOM) -BOOST_AUTO_TEST_CASE(test_dns_random_getrandom_average) { +BOOST_AUTO_TEST_CASE(test_dns_random_getrandom_average) +{ - ::arg().set("rng")="getrandom"; - ::arg().set("entropy-source")="/dev/urandom"; + ::arg().set("rng") = "getrandom"; + ::arg().set("entropy-source") = "/dev/urandom"; dns_random_init("", true); acc_t acc; - for(unsigned int n=0; n < 100000; ++n) { - acc(dns_random(100000)/100000.0); + for (unsigned int n = 0; n < 100000; ++n) { + acc(dns_random(100000) / 100000.0); } BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); @@ -123,17 +122,18 @@ BOOST_AUTO_TEST_CASE(test_dns_random_getrandom_average) { #endif #if defined(HAVE_ARC4RANDOM) -BOOST_AUTO_TEST_CASE(test_dns_random_arc4random_average) { +BOOST_AUTO_TEST_CASE(test_dns_random_arc4random_average) +{ - ::arg().set("rng")="arc4random"; - ::arg().set("entropy-source")="/dev/urandom"; + ::arg().set("rng") = "arc4random"; + ::arg().set("entropy-source") = "/dev/urandom"; dns_random_init("", true); acc_t acc; - for(unsigned int n=0; n < 100000; ++n) { - acc(dns_random(100000)/100000.0); + for (unsigned int n = 0; n < 100000; ++n) { + acc(dns_random(100000) / 100000.0); } BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); @@ -143,17 +143,18 @@ BOOST_AUTO_TEST_CASE(test_dns_random_arc4random_average) { #endif #if defined(HAVE_RANDOMBYTES_STIR) -BOOST_AUTO_TEST_CASE(test_dns_random_sodium_average) { +BOOST_AUTO_TEST_CASE(test_dns_random_sodium_average) +{ - ::arg().set("rng")="sodium"; - ::arg().set("entropy-source")="/dev/urandom"; + ::arg().set("rng") = "sodium"; + ::arg().set("entropy-source") = "/dev/urandom"; dns_random_init("", true); acc_t acc; - for(unsigned int n=0; n < 100000; ++n) { - acc(dns_random(100000)/100000.0); + for (unsigned int n = 0; n < 100000; ++n) { + acc(dns_random(100000) / 100000.0); } BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); @@ -163,17 +164,18 @@ BOOST_AUTO_TEST_CASE(test_dns_random_sodium_average) { #endif #if defined(HAVE_RAND_BYTES) -BOOST_AUTO_TEST_CASE(test_dns_random_openssl_average) { +BOOST_AUTO_TEST_CASE(test_dns_random_openssl_average) +{ - ::arg().set("rng")="openssl"; - ::arg().set("entropy-source")="/dev/urandom"; + ::arg().set("rng") = "openssl"; + ::arg().set("entropy-source") = "/dev/urandom"; dns_random_init("", true); acc_t acc; - for(unsigned int n=0; n < 100000; ++n) { - acc(dns_random(100000)/100000.0); + for (unsigned int n = 0; n < 100000; ++n) { + acc(dns_random(100000) / 100000.0); } BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); @@ -183,17 +185,18 @@ BOOST_AUTO_TEST_CASE(test_dns_random_openssl_average) { #endif #if defined(HAVE_KISS_RNG) -BOOST_AUTO_TEST_CASE(test_dns_random_kiss_average) { +BOOST_AUTO_TEST_CASE(test_dns_random_kiss_average) +{ - ::arg().set("rng")="kiss"; - ::arg().set("entropy-source")="/dev/urandom"; + ::arg().set("rng") = "kiss"; + ::arg().set("entropy-source") = "/dev/urandom"; dns_random_init("", true); acc_t acc; - for(unsigned int n=0; n < 100000; ++n) { - acc(dns_random(100000)/100000.0); + for (unsigned int n = 0; n < 100000; ++n) { + acc(dns_random(100000) / 100000.0); } BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); @@ -202,7 +205,6 @@ BOOST_AUTO_TEST_CASE(test_dns_random_kiss_average) { } #endif - BOOST_AUTO_TEST_SUITE_END() #endif From f777e801530dd590193132bf033697c2dd3b9c79 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 10:58:49 +0200 Subject: [PATCH 285/909] delint --- pdns/dns_random.cc | 38 +++++++++++++++++++++++--------------- pdns/dns_random.hh | 6 +++--- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/pdns/dns_random.cc b/pdns/dns_random.cc index b53ba0e5a1e2..dc30ee8a15ee 100644 --- a/pdns/dns_random.cc +++ b/pdns/dns_random.cc @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include "dns_random.hh" #include "arguments.hh" @@ -87,8 +87,9 @@ static void dns_random_setup(bool force = false) string rdev; string rng; /* check if selection has been done */ - if (chosen_rng > RNG_UNINITIALIZED && !force) + if (chosen_rng > RNG_UNINITIALIZED && !force) { return; + } /* XXX: A horrible hack to allow using dns_random in places where arguments are not available. Forces /dev/urandom usage @@ -99,7 +100,7 @@ static void dns_random_setup(bool force = false) #else rng = ::arg()["rng"]; rdev = ::arg()["entropy-source"]; - if (rng == "auto") { + if (rng == "auto") { // NOLINT: I see no way to avoid repeating blocks reported bby clang-tidy #if defined(HAVE_GETRANDOM) chosen_rng = RNG_GETRANDOM; #elif defined(HAVE_ARC4RANDOM) @@ -147,8 +148,9 @@ static void dns_random_setup(bool force = false) #if defined(HAVE_RANDOMBYTES_STIR) if (chosen_rng == RNG_SODIUM) { - if (sodium_init() == -1) + if (sodium_init() == -1) { throw std::runtime_error("Unable to initialize sodium crypto library"); + } /* make sure it's set up */ randombytes_stir(); } @@ -156,10 +158,10 @@ static void dns_random_setup(bool force = false) #if defined(HAVE_GETRANDOM) if (chosen_rng == RNG_GETRANDOM) { - char buf[1]; + char buf; // some systems define getrandom but it does not really work, e.g. because it's // not present in kernel. - if (getrandom(buf, sizeof(buf), 0) == -1 && errno != EINTR) { + if (getrandom(&buf, sizeof(buf), 0) == -1 && errno != EINTR) { g_log << Logger::Warning << "getrandom() failed: " << stringerror() << ", falling back to " + rdev << std::endl; chosen_rng = RNG_URANDOM; } @@ -168,19 +170,22 @@ static void dns_random_setup(bool force = false) #if defined(HAVE_RAND_BYTES) if (chosen_rng == RNG_OPENSSL) { - int ret; - unsigned char buf[1]; - if ((ret = RAND_bytes(buf, sizeof(buf))) == -1) + int ret = 0; + unsigned char buf = 0; + if ((ret = RAND_bytes(&buf, sizeof(buf))) == -1) { throw std::runtime_error("RAND_bytes not supported by current SSL engine"); - if (ret == 0) + } + if (ret == 0) { throw std::runtime_error("Openssl RNG was not seeded"); + } } #endif #endif /* USE_URANDOM_ONLY */ if (chosen_rng == RNG_URANDOM) { urandom_fd = open(rdev.c_str(), O_RDONLY); - if (urandom_fd == -1) + if (urandom_fd == -1) { throw std::runtime_error("Cannot open " + rdev + ": " + stringerror()); + } } #if defined(HAVE_KISS_RNG) if (chosen_rng == RNG_KISS) { @@ -217,11 +222,13 @@ void dns_random_init(const string& data __attribute__((unused)), bool force) uint32_t dns_random(uint32_t upper_bound) { - if (chosen_rng == RNG_UNINITIALIZED) + if (chosen_rng == RNG_UNINITIALIZED) { dns_random_setup(); + } - if (upper_bound < 2) + if (upper_bound < 2) { return 0; + } unsigned int min = pdns::random_minimum_acceptable_value(upper_bound); @@ -238,8 +245,9 @@ uint32_t dns_random(uint32_t upper_bound) #if defined(HAVE_RAND_BYTES) && !defined(USE_URANDOM_ONLY) uint32_t num = 0; do { - if (RAND_bytes(reinterpret_cast(&num), sizeof(num)) < 1) + if (RAND_bytes(reinterpret_cast(&num), sizeof(num)) < 1) { // NOLINT: API throw std::runtime_error("Openssl RNG was not seeded"); + } } while (num < min); return num % upper_bound; @@ -284,7 +292,7 @@ uint32_t dns_random(uint32_t upper_bound) (void)close(urandom_fd); throw std::runtime_error("Cannot read random device"); } - else if (static_cast(got) != sizeof(num)) { + if (static_cast(got) != sizeof(num)) { /* short read, let's retry */ if (attempts == 0) { throw std::runtime_error("Too many short reads on random device"); diff --git a/pdns/dns_random.hh b/pdns/dns_random.hh index 09ed7f39f9fd..be93e68bcb95 100644 --- a/pdns/dns_random.hh +++ b/pdns/dns_random.hh @@ -25,7 +25,7 @@ #include void dns_random_init(const std::string& data = "", bool force_reinit = false); -uint32_t dns_random(uint32_t n); +uint32_t dns_random(uint32_t upper_bound); uint16_t dns_random_uint16(); namespace pdns @@ -33,7 +33,7 @@ namespace pdns struct dns_random_engine { - typedef uint32_t result_type; + using result_type = uint32_t; static constexpr result_type min() { @@ -62,7 +62,7 @@ inline unsigned int random_minimum_acceptable_value(uint32_t upper_bound) On applicable rngs, we loop until the rng spews out value larger than min, and then take modulo out of that. */ - unsigned int min; + unsigned int min = 0; #if (ULONG_MAX > 0xffffffffUL) min = 0x100000000UL % upper_bound; #else From e34d77314af485f16ed95f96adf135be95d27a19 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 11:02:59 +0200 Subject: [PATCH 286/909] Replace boost lexical casts, including the header produces a lot of warnings on some platforms for some time We now produce a string runtime, but since the to_string() call should never be executed, it does not matter. --- pdns/dns_random.cc | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pdns/dns_random.cc b/pdns/dns_random.cc index dc30ee8a15ee..4461de6413e6 100644 --- a/pdns/dns_random.cc +++ b/pdns/dns_random.cc @@ -31,7 +31,6 @@ #include "dns_random.hh" #include "arguments.hh" #include "logger.hh" -#include "boost/lexical_cast.hpp" #if defined(HAVE_RANDOMBYTES_STIR) #include @@ -234,12 +233,12 @@ uint32_t dns_random(uint32_t upper_bound) switch (chosen_rng) { case RNG_UNINITIALIZED: - throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached case RNG_SODIUM: #if defined(HAVE_RANDOMBYTES_STIR) && !defined(USE_URANDOM_ONLY) return randombytes_uniform(upper_bound); #else - throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached #endif /* RND_SODIUM */ case RNG_OPENSSL: { #if defined(HAVE_RAND_BYTES) && !defined(USE_URANDOM_ONLY) @@ -252,7 +251,7 @@ uint32_t dns_random(uint32_t upper_bound) return num % upper_bound; #else - throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached #endif /* RNG_OPENSSL */ } case RNG_GETRANDOM: { @@ -270,14 +269,14 @@ uint32_t dns_random(uint32_t upper_bound) return num % upper_bound; #else - throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached #endif } case RNG_ARC4RANDOM: #if defined(HAVE_ARC4RANDOM) && !defined(USE_URANDOM_ONLY) return arc4random_uniform(upper_bound); #else - throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached #endif case RNG_URANDOM: { uint32_t num = 0; @@ -315,7 +314,7 @@ uint32_t dns_random(uint32_t upper_bound) } #endif default: - throw std::runtime_error("Unreachable at " __FILE__ ":" + boost::lexical_cast(__LINE__)); // cannot be reached + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached }; } From 43159bf142d429a3458fa0ea07282a24db12a4f5 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 11:08:50 +0200 Subject: [PATCH 287/909] Introduce dns_random_uint32() To be used when a full 32 bits of randomness are needed, also avoiding the modulo dance --- pdns/dns_random.cc | 86 +++++++++++++++++++++++++++++++++++++++++++++- pdns/dns_random.hh | 5 +-- 2 files changed, 88 insertions(+), 3 deletions(-) diff --git a/pdns/dns_random.cc b/pdns/dns_random.cc index 4461de6413e6..9d3e34edc429 100644 --- a/pdns/dns_random.cc +++ b/pdns/dns_random.cc @@ -219,6 +219,90 @@ void dns_random_init(const string& data __attribute__((unused)), bool force) #endif } +uint32_t dns_random_uint32() +{ + if (chosen_rng == RNG_UNINITIALIZED) { + dns_random_setup(); + } + + switch (chosen_rng) { + case RNG_UNINITIALIZED: + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached + case RNG_SODIUM: +#if defined(HAVE_RANDOMBYTES_STIR) && !defined(USE_URANDOM_ONLY) + return randombytes_random(); +#else + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached +#endif /* RND_SODIUM */ + case RNG_OPENSSL: { +#if defined(HAVE_RAND_BYTES) && !defined(USE_URANDOM_ONLY) + uint32_t num = 0; + if (RAND_bytes(reinterpret_cast(&num), sizeof(num)) < 1) { // NOLINT: API + throw std::runtime_error("Openssl RNG was not seeded"); + } + return num; +#else + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached +#endif /* RNG_OPENSSL */ + } + case RNG_GETRANDOM: { +#if defined(HAVE_GETRANDOM) && !defined(USE_URANDOM_ONLY) + uint32_t num = 0; + do { + auto got = getrandom(&num, sizeof(num), 0); + if (got == -1 && errno == EINTR) { + continue; + } + if (got != sizeof(num)) { + throw std::runtime_error("getrandom() failed: " + stringerror()); + } + } while (true); + return num; +#else + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached +#endif + } + case RNG_ARC4RANDOM: +#if defined(HAVE_ARC4RANDOM) && !defined(USE_URANDOM_ONLY) + return arc4random(); +#else + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached +#endif + case RNG_URANDOM: { + uint32_t num = 0; + size_t attempts = 5; + ssize_t got = read(urandom_fd, &num, sizeof(num)); + do { + if (got < 0) { + if (errno == EINTR) { + continue; + } + + (void)close(urandom_fd); + throw std::runtime_error("Cannot read random device"); + } + if (static_cast(got) != sizeof(num)) { + /* short read, let's retry */ + if (attempts == 0) { + throw std::runtime_error("Too many short reads on random device"); + } + attempts--; + continue; + } + } while (true); + return num; + } +#if defined(HAVE_KISS_RNG) + case RNG_KISS: { + uint32_t num = kiss_rand(); + return num; + } +#endif + default: + throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached + }; +} + uint32_t dns_random(uint32_t upper_bound) { if (chosen_rng == RNG_UNINITIALIZED) { @@ -320,5 +404,5 @@ uint32_t dns_random(uint32_t upper_bound) uint16_t dns_random_uint16() { - return dns_random(0x10000); + return dns_random_uint32() & 0xffff; } diff --git a/pdns/dns_random.hh b/pdns/dns_random.hh index be93e68bcb95..634d233c1c39 100644 --- a/pdns/dns_random.hh +++ b/pdns/dns_random.hh @@ -26,6 +26,7 @@ void dns_random_init(const std::string& data = "", bool force_reinit = false); uint32_t dns_random(uint32_t upper_bound); +uint32_t dns_random_uint32(); uint16_t dns_random_uint16(); namespace pdns @@ -42,12 +43,12 @@ struct dns_random_engine static constexpr result_type max() { - return std::numeric_limits::max() - 1; + return std::numeric_limits::max(); } result_type operator()() { - return dns_random(std::numeric_limits::max()); + return dns_random_uint32(); } }; From 39b80bcc9898cc6f8d2858a5ac677aef1adf80df Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 11:17:45 +0200 Subject: [PATCH 288/909] Add basic test for dns_random_uint32 --- pdns/test-dns_random_hh.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/pdns/test-dns_random_hh.cc b/pdns/test-dns_random_hh.cc index 2d3af18c7f8e..e0211f720f25 100644 --- a/pdns/test-dns_random_hh.cc +++ b/pdns/test-dns_random_hh.cc @@ -28,6 +28,25 @@ typedef accumulator_set< BOOST_AUTO_TEST_SUITE(test_dns_random_hh) +BOOST_AUTO_TEST_CASE(test_dns_random_uint32_auto_average) +{ + + ::arg().set("rng") = "auto"; + ::arg().set("entropy-source") = "/dev/urandom"; + + dns_random_init("", true); + + acc_t acc; + + for (unsigned int n = 0; n < 100000; ++n) { + acc(dns_random_unint32() / static_cast(pdns::dns_random_engine::max() + 1)); + } + BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% + BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); + + // please add covariance tests, chi-square, Kolmogorov-Smirnov +} + BOOST_AUTO_TEST_CASE(test_dns_random_auto_average) { From 627eaf3b6433d6c9daa627cc6db31068853f51a9 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 12:58:12 +0200 Subject: [PATCH 289/909] Actually start testing this on !gcc and refactor --- pdns/test-dns_random_hh.cc | 168 ++++++++----------------------------- 1 file changed, 36 insertions(+), 132 deletions(-) diff --git a/pdns/test-dns_random_hh.cc b/pdns/test-dns_random_hh.cc index e0211f720f25..6a126c8a49cf 100644 --- a/pdns/test-dns_random_hh.cc +++ b/pdns/test-dns_random_hh.cc @@ -1,9 +1,6 @@ #define BOOST_TEST_DYN_LINK #define BOOST_TEST_NO_MAIN -// Disable this code for gcc 4.8 and lower -#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ > 8) || !__GNUC__ - #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -19,71 +16,32 @@ #include "dns_random.hh" #include "namespaces.hh" -using namespace boost; using namespace boost::accumulators; -typedef accumulator_set< - double, stats> - acc_t; +using acc_t = accumulator_set>; BOOST_AUTO_TEST_SUITE(test_dns_random_hh) -BOOST_AUTO_TEST_CASE(test_dns_random_uint32_auto_average) -{ - - ::arg().set("rng") = "auto"; - ::arg().set("entropy-source") = "/dev/urandom"; - - dns_random_init("", true); - - acc_t acc; - - for (unsigned int n = 0; n < 100000; ++n) { - acc(dns_random_unint32() / static_cast(pdns::dns_random_engine::max() + 1)); - } - BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% - BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); - - // please add covariance tests, chi-square, Kolmogorov-Smirnov -} - -BOOST_AUTO_TEST_CASE(test_dns_random_auto_average) -{ - - ::arg().set("rng") = "auto"; - ::arg().set("entropy-source") = "/dev/urandom"; - - dns_random_init("", true); - - acc_t acc; - - for (unsigned int n = 0; n < 100000; ++n) { - acc(dns_random(100000) / 100000.0); - } - BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% - BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); - - // please add covariance tests, chi-square, Kolmogorov-Smirnov -} - -BOOST_AUTO_TEST_CASE(test_dns_random_urandom_average) -{ - - ::arg().set("rng") = "urandom"; - ::arg().set("entropy-source") = "/dev/urandom"; - - dns_random_init("", true); - - acc_t acc; +const std::vector rndSources = { + "auto", + "urandom", +#if defined(HAVE_GETRANDOM) + "getrandom", +#endif + #if defined(HAVE_ARC4RANDOM) + "arc4random", + #endif +#if defined(HAVE_RANDOMBYTES_STIR) + "sodium", +#endif +#if defined(HAVE_RAND_BYTES) + "openssl", +#endif +#if defined(HAVE_KISS_RNG) + "kiss", +#endif +}; - for (unsigned int n = 0; n < 100000; ++n) { - acc(dns_random(100000) / 100000.0); - } - BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% - BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); - - // please add covariance tests, chi-square, Kolmogorov-Smirnov -} BOOST_AUTO_TEST_CASE(test_dns_random_garbage) { @@ -101,8 +59,8 @@ BOOST_AUTO_TEST_CASE(test_dns_random_upper_bound) dns_random_init("", true); - map seen; - for (unsigned int n = 0; n < 100000; ++n) { + map seen; + for (unsigned int iteration = 0; iteration < 100000; ++iteration) { seen[dns_random(10)] = true; } @@ -119,18 +77,16 @@ BOOST_AUTO_TEST_CASE(test_dns_random_upper_bound) BOOST_CHECK_EQUAL(seen[10], false); } -#if defined(HAVE_GETRANDOM) -BOOST_AUTO_TEST_CASE(test_dns_random_getrandom_average) +static void test_dns_random_avg(const string& source) { - - ::arg().set("rng") = "getrandom"; + ::arg().set("rng") = source; ::arg().set("entropy-source") = "/dev/urandom"; dns_random_init("", true); acc_t acc; - for (unsigned int n = 0; n < 100000; ++n) { + for (unsigned int iteration = 0; iteration < 100000; ++iteration) { acc(dns_random(100000) / 100000.0); } BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% @@ -138,92 +94,40 @@ BOOST_AUTO_TEST_CASE(test_dns_random_getrandom_average) // please add covariance tests, chi-square, Kolmogorov-Smirnov } -#endif -#if defined(HAVE_ARC4RANDOM) -BOOST_AUTO_TEST_CASE(test_dns_random_arc4random_average) +static void test_dns_random_uint32_avg(const string& source) { - - ::arg().set("rng") = "arc4random"; + ::arg().set("rng") = source; ::arg().set("entropy-source") = "/dev/urandom"; dns_random_init("", true); acc_t acc; - for (unsigned int n = 0; n < 100000; ++n) { - acc(dns_random(100000) / 100000.0); + for (unsigned int iteration = 0; iteration < 100000; ++iteration) { + acc(dns_random_uint32() / static_cast(pdns::dns_random_engine::max())); } BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); // please add covariance tests, chi-square, Kolmogorov-Smirnov } -#endif -#if defined(HAVE_RANDOMBYTES_STIR) -BOOST_AUTO_TEST_CASE(test_dns_random_sodium_average) +BOOST_AUTO_TEST_CASE(test_dns_random_average) { - - ::arg().set("rng") = "sodium"; - ::arg().set("entropy-source") = "/dev/urandom"; - - dns_random_init("", true); - - acc_t acc; - - for (unsigned int n = 0; n < 100000; ++n) { - acc(dns_random(100000) / 100000.0); + for (const auto& source : rndSources) { + test_dns_random_avg(source); } - BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% - BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); - - // please add covariance tests, chi-square, Kolmogorov-Smirnov } -#endif -#if defined(HAVE_RAND_BYTES) -BOOST_AUTO_TEST_CASE(test_dns_random_openssl_average) +BOOST_AUTO_TEST_CASE(test_dns_random_uint32_average) { - - ::arg().set("rng") = "openssl"; - ::arg().set("entropy-source") = "/dev/urandom"; - - dns_random_init("", true); - - acc_t acc; - - for (unsigned int n = 0; n < 100000; ++n) { - acc(dns_random(100000) / 100000.0); + for (const auto& source : rndSources) { + test_dns_random_uint32_avg(source); } - BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% - BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); - - // please add covariance tests, chi-square, Kolmogorov-Smirnov } -#endif - -#if defined(HAVE_KISS_RNG) -BOOST_AUTO_TEST_CASE(test_dns_random_kiss_average) -{ - ::arg().set("rng") = "kiss"; - ::arg().set("entropy-source") = "/dev/urandom"; - - dns_random_init("", true); - - acc_t acc; - - for (unsigned int n = 0; n < 100000; ++n) { - acc(dns_random(100000) / 100000.0); - } - BOOST_CHECK_CLOSE(0.5, median(acc), 2.0); // within 2% - BOOST_CHECK_CLOSE(0.5, mean(acc), 2.0); - - // please add covariance tests, chi-square, Kolmogorov-Smirnov -} -#endif BOOST_AUTO_TEST_SUITE_END() -#endif + From e59686d645ff5d1652f2fdef109fff5d98d70ea2 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 13 Jun 2023 14:08:56 +0200 Subject: [PATCH 290/909] dnsdist: Increment the "dyn blocked" counter for eBPF blocks as well Regular, userspace blocks increment the "dyn blocked" counter for every dropped query. The eBPF blocks are executed in kernelspace and thus do not increment that counter at all, which makes it challenging for reporting to do its job. On the other hand we want our eBPF code to be as efficient as possible since it is used when performance really matters. This commit updates the counter when a eBPF dynamic block is removed, which is a compromise between the performance impact and a slight reporting delay. --- pdns/dnsdistdist/dnsdist-dynblocks.cc | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-dynblocks.cc b/pdns/dnsdistdist/dnsdist-dynblocks.cc index ae9896ed273d..acf85243833b 100644 --- a/pdns/dnsdistdist/dnsdist-dynblocks.cc +++ b/pdns/dnsdistdist/dnsdist-dynblocks.cc @@ -429,6 +429,10 @@ void DynBlockRulesGroup::processResponseRules(counts_t& counts, StatNode& root, void DynBlockMaintenance::purgeExpired(const struct timespec& now) { + // we need to increase the dynBlocked counter when removing + // eBPF blocks, as otherwise it does not get incremented for these + // since the block happens in kernel space. + uint64_t bpfBlocked = 0; { auto blocks = g_dynblockNMG.getLocal(); std::vector toRemove; @@ -436,8 +440,15 @@ void DynBlockMaintenance::purgeExpired(const struct timespec& now) if (!(now < entry.second.until)) { toRemove.push_back(entry.first); if (g_defaultBPFFilter && entry.second.bpf) { + const auto& network = entry.first.getNetwork(); try { - g_defaultBPFFilter->unblock(entry.first.getNetwork()); + bpfBlocked += g_defaultBPFFilter->getHits(network); + } + catch (const std::exception& e) { + vinfolog("Error while getting block count before removing eBPF dynamic block for %s: %s", entry.first.toString(), e.what()); + } + try { + g_defaultBPFFilter->unblock(network); } catch (const std::exception& e) { vinfolog("Error while removing eBPF dynamic block for %s: %s", entry.first.toString(), e.what()); @@ -451,6 +462,7 @@ void DynBlockMaintenance::purgeExpired(const struct timespec& now) updated.erase(entry); } g_dynblockNMG.setState(std::move(updated)); + g_stats.dynBlocked += bpfBlocked; } } From 4add9e26d0e94927fd00863690e5df9220f75aa5 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 13:02:36 +0200 Subject: [PATCH 291/909] Fix loops --- pdns/dns_random.cc | 2 ++ pdns/test-dns_random_hh.cc | 10 +++------- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/pdns/dns_random.cc b/pdns/dns_random.cc index 9d3e34edc429..a8eb266c0cd0 100644 --- a/pdns/dns_random.cc +++ b/pdns/dns_random.cc @@ -256,6 +256,7 @@ uint32_t dns_random_uint32() if (got != sizeof(num)) { throw std::runtime_error("getrandom() failed: " + stringerror()); } + break; } while (true); return num; #else @@ -289,6 +290,7 @@ uint32_t dns_random_uint32() attempts--; continue; } + break; } while (true); return num; } diff --git a/pdns/test-dns_random_hh.cc b/pdns/test-dns_random_hh.cc index 6a126c8a49cf..db8a0eb0ab78 100644 --- a/pdns/test-dns_random_hh.cc +++ b/pdns/test-dns_random_hh.cc @@ -18,7 +18,7 @@ using namespace boost::accumulators; -using acc_t = accumulator_set>; +using acc_t = accumulator_set>; BOOST_AUTO_TEST_SUITE(test_dns_random_hh) @@ -28,9 +28,9 @@ const std::vector rndSources = { #if defined(HAVE_GETRANDOM) "getrandom", #endif - #if defined(HAVE_ARC4RANDOM) +#if defined(HAVE_ARC4RANDOM) "arc4random", - #endif +#endif #if defined(HAVE_RANDOMBYTES_STIR) "sodium", #endif @@ -42,7 +42,6 @@ const std::vector rndSources = { #endif }; - BOOST_AUTO_TEST_CASE(test_dns_random_garbage) { @@ -127,7 +126,4 @@ BOOST_AUTO_TEST_CASE(test_dns_random_uint32_average) } } - BOOST_AUTO_TEST_SUITE_END() - - From fa8766c59d2cdf05d86c2dd2ea21018524b35609 Mon Sep 17 00:00:00 2001 From: djonker Date: Wed, 14 Jun 2023 00:34:09 +0200 Subject: [PATCH 292/909] fixed the webserver config line? --- dockerdata/startup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dockerdata/startup.py b/dockerdata/startup.py index 8d738fd3e34d..320ef8ddf8d2 100755 --- a/dockerdata/startup.py +++ b/dockerdata/startup.py @@ -36,7 +36,7 @@ elif product == 'dnsdist': args = ['--supervised', '--disable-syslog'] apienvvar = 'DNSDIST_API_KEY' - apiconftemplate = """webserver("0.0.0.0:8083", '{{ apikey }}', '{{ apikey }}', {}, '0.0.0.0/0') + apiconftemplate = """webserver("0.0.0.0:8083") controlSocket('0.0.0.0:5199') setKey('{{ apikey }}') setConsoleACL('0.0.0.0/0') From afd96c15cc224aea6e2db92878e77fa7a7e5b557 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 14 Jun 2023 08:55:48 +0200 Subject: [PATCH 293/909] delint --- pdns/dns_random.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dns_random.cc b/pdns/dns_random.cc index a8eb266c0cd0..357bde31db66 100644 --- a/pdns/dns_random.cc +++ b/pdns/dns_random.cc @@ -157,7 +157,7 @@ static void dns_random_setup(bool force = false) #if defined(HAVE_GETRANDOM) if (chosen_rng == RNG_GETRANDOM) { - char buf; + char buf = 0; // some systems define getrandom but it does not really work, e.g. because it's // not present in kernel. if (getrandom(&buf, sizeof(buf), 0) == -1 && errno != EINTR) { From 1325b6a3fa189f09c8959deaf135c4ea6fd64725 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 15:40:08 +0200 Subject: [PATCH 294/909] rec: Upgrade regression tests to use pytest instead of nose One mysterious failure on Debian bookworm spotted: test_EDNS.py does not seem to set the right edns version on the outgoing query. To be investigated. --- regression-tests.recursor-dnssec/printlogs.py | 2 +- regression-tests.recursor-dnssec/requirements.txt | 2 +- regression-tests.recursor-dnssec/runtests | 4 ++-- regression-tests.recursor-dnssec/test_RecDnstap.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/regression-tests.recursor-dnssec/printlogs.py b/regression-tests.recursor-dnssec/printlogs.py index c4dde38d92f1..2c9065f7355f 100755 --- a/regression-tests.recursor-dnssec/printlogs.py +++ b/regression-tests.recursor-dnssec/printlogs.py @@ -5,7 +5,7 @@ import os.path import glob -e = xml.etree.ElementTree.parse('nosetests.xml') +e = xml.etree.ElementTree.parse('pysetest.xml') root = e.getroot() for child in root: diff --git a/regression-tests.recursor-dnssec/requirements.txt b/regression-tests.recursor-dnssec/requirements.txt index 3c15fe9ada80..1ec32b533fc0 100644 --- a/regression-tests.recursor-dnssec/requirements.txt +++ b/regression-tests.recursor-dnssec/requirements.txt @@ -1,5 +1,5 @@ dnspython>=1.11 -nose>=1.3.7 +pytest protobuf>=2.5; sys_platform != 'darwin' protobuf>=3.0; sys_platform == 'darwin' pyasn1==0.4.8 diff --git a/regression-tests.recursor-dnssec/runtests b/regression-tests.recursor-dnssec/runtests index 6741a638cf77..12b6946e7e0c 100755 --- a/regression-tests.recursor-dnssec/runtests +++ b/regression-tests.recursor-dnssec/runtests @@ -59,7 +59,7 @@ fi # LIBFAKETIME is only added to LD_PRELOAD by the pyton code when needed if [ "${LIBASAN}" != "" -o "${LIBAUTHBIND}" != "" ]; then -LD_PRELOAD="${LIBASAN} ${LIBAUTHBIND}" nosetests -I test_WellKnown.py --with-xunit $@ +LD_PRELOAD="${LIBASAN} ${LIBAUTHBIND}" pytest --ignore=test_WellKnown.py --junitxml=pytest.xml $@ else -nosetests -I test_WellKnown.py --with-xunit $@ +pytest --ignore=test_WellKnown.py --junitxml=pytest.xml $@ fi diff --git a/regression-tests.recursor-dnssec/test_RecDnstap.py b/regression-tests.recursor-dnssec/test_RecDnstap.py index 38dcd715d4c2..2cde8ee08674 100644 --- a/regression-tests.recursor-dnssec/test_RecDnstap.py +++ b/regression-tests.recursor-dnssec/test_RecDnstap.py @@ -5,7 +5,7 @@ import threading import dns import dnstap_pb2 -from nose import SkipTest +from unittest import SkipTest from recursortests import RecursorTest FSTRM_CONTROL_ACCEPT = 0x01 From 32d02dba4e567e1a6aebad5e7d9398942a1c7814 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 14 Jun 2023 09:06:23 +0200 Subject: [PATCH 295/909] Skip a test_EDNS.py test that hits a python 3.11 issue See https://github.com/PowerDNS/pdns/pull/12912 --- regression-tests.recursor-dnssec/printlogs.py | 2 +- regression-tests.recursor-dnssec/test_EDNS.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/regression-tests.recursor-dnssec/printlogs.py b/regression-tests.recursor-dnssec/printlogs.py index 2c9065f7355f..3058cd7ff8d2 100755 --- a/regression-tests.recursor-dnssec/printlogs.py +++ b/regression-tests.recursor-dnssec/printlogs.py @@ -5,7 +5,7 @@ import os.path import glob -e = xml.etree.ElementTree.parse('pysetest.xml') +e = xml.etree.ElementTree.parse('pytest.xml') root = e.getroot() for child in root: diff --git a/regression-tests.recursor-dnssec/test_EDNS.py b/regression-tests.recursor-dnssec/test_EDNS.py index aab178249246..172ab3980389 100644 --- a/regression-tests.recursor-dnssec/test_EDNS.py +++ b/regression-tests.recursor-dnssec/test_EDNS.py @@ -4,6 +4,8 @@ import struct import threading import time +import sys +from unittest import SkipTest from recursortests import RecursorTest from twisted.internet.protocol import DatagramProtocol @@ -35,6 +37,8 @@ def testEDNSBadVers(self): Ensure the rcode is BADVERS when we send an unsupported EDNS version and the query is not processed any further. """ + if sys.version_info >= (3, 11) and sys.version_info <= (3, 11, 3): + raise SkipTest("Test skipped, see https://github.com/PowerDNS/pdns/pull/12912") query = dns.message.make_query('version.bind.', 'TXT', 'CH', use_edns=5, payload=4096) response = self.sendUDPQuery(query) From b9e82a462fae4cf5979de3e13c68a9af2ca169c8 Mon Sep 17 00:00:00 2001 From: Houtworm <34796415+Houtworm@users.noreply.github.com> Date: Wed, 14 Jun 2023 10:09:15 +0200 Subject: [PATCH 296/909] Update dockerdata/startup.py Co-authored-by: Remi Gacogne --- dockerdata/startup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dockerdata/startup.py b/dockerdata/startup.py index 320ef8ddf8d2..e84055151a60 100755 --- a/dockerdata/startup.py +++ b/dockerdata/startup.py @@ -37,6 +37,7 @@ args = ['--supervised', '--disable-syslog'] apienvvar = 'DNSDIST_API_KEY' apiconftemplate = """webserver("0.0.0.0:8083") + setWebserverConfig({password='{{ apikey }}', apiKey='{{ apikey }}', acl='0.0.0.0/0'}) controlSocket('0.0.0.0:5199') setKey('{{ apikey }}') setConsoleACL('0.0.0.0/0') From a4d2d1167f0c01290fa55029fb556c70857b4dcd Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 14 Jun 2023 10:08:52 +0200 Subject: [PATCH 297/909] Fix deprecation warnings and dnstap exception on (expected) broken pipe --- regression-tests.recursor-dnssec/test_Lua.py | 2 +- regression-tests.recursor-dnssec/test_Notify.py | 4 ++-- regression-tests.recursor-dnssec/test_RecDnstap.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/regression-tests.recursor-dnssec/test_Lua.py b/regression-tests.recursor-dnssec/test_Lua.py index 222c9181c162..dad74051f5d6 100644 --- a/regression-tests.recursor-dnssec/test_Lua.py +++ b/regression-tests.recursor-dnssec/test_Lua.py @@ -1006,7 +1006,7 @@ def testDROP(self): """ postresolve_ffi: test that we can do a DROP for a name and type combo""" query = dns.message.make_query('example', 'TXT') res = self.sendUDPQuery(query) - self.assertEquals(res, None) + self.assertEqual(res, None) def testNXDOMAIN(self): """ postresolve_ffi: test that we can return a NXDOMAIN for a name and type combo""" diff --git a/regression-tests.recursor-dnssec/test_Notify.py b/regression-tests.recursor-dnssec/test_Notify.py index 689f346b7228..622ad37ec6c2 100644 --- a/regression-tests.recursor-dnssec/test_Notify.py +++ b/regression-tests.recursor-dnssec/test_Notify.py @@ -103,9 +103,9 @@ def testNotify(self): sender = getattr(self, method) res = sender(notify) self.assertRcodeEqual(res, dns.rcode.NOERROR) - self.assertEquals(res.opcode(), 4) + self.assertEqual(res.opcode(), 4) print(res) - self.assertEquals(res.question[0].to_text(), 'example. IN SOA') + self.assertEqual(res.question[0].to_text(), 'example. IN SOA') self.checkRecordCacheMetrics(3, 1) diff --git a/regression-tests.recursor-dnssec/test_RecDnstap.py b/regression-tests.recursor-dnssec/test_RecDnstap.py index 2cde8ee08674..8bd2845c45f3 100644 --- a/regression-tests.recursor-dnssec/test_RecDnstap.py +++ b/regression-tests.recursor-dnssec/test_RecDnstap.py @@ -186,7 +186,7 @@ def FrameStreamUnixListener(cls, conn, param): fstrm_handle_bidir_connection(conn, lambda data: \ param.queue.put(data, True, timeout=2.0)) except socket.error as e: - if e.errno == 9: + if e.errno == errno.EBADF or e.errno == errno.EPIPE: break sys.stderr.write("Unexpected socket error %s\n" % str(e)) sys.exit(1) From a1807bd46839323908d30b8d56b24d1f51fe4176 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 13 Jun 2023 10:30:39 +0200 Subject: [PATCH 298/909] Prep for rec-4.9.0-rc1 --- docs/secpoll.zone | 3 +- pdns/recursordist/docs/changelog/4.9.rst | 49 ++++++++++++++++++++++++ pdns/recursordist/docs/metrics.rst | 2 + pdns/recursordist/docs/upgrade.rst | 9 ++++- 4 files changed, 60 insertions(+), 3 deletions(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 8fe514f2cf6a..eaaaa7b20bcd 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023060201 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023061501 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -351,6 +351,7 @@ recursor-4.8.3.security-status 60 IN TXT "3 Upgrade now recursor-4.8.4.security-status 60 IN TXT "1 OK" recursor-4.9.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release" recursor-4.9.0-beta1.security-status 60 IN TXT "1 Unsupported pre-release" +recursor-4.9.0-rc1.security-status 60 IN TXT "1 Unsupported pre-release" ; Recursor Debian recursor-3.6.2-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/" diff --git a/pdns/recursordist/docs/changelog/4.9.rst b/pdns/recursordist/docs/changelog/4.9.rst index 40aa96987994..e6128ed64d68 100644 --- a/pdns/recursordist/docs/changelog/4.9.rst +++ b/pdns/recursordist/docs/changelog/4.9.rst @@ -1,5 +1,54 @@ Changelogs for 4.9.X ==================== +.. changelog:: + :version: 4.9.0-rc1 + :released: 15nd of June 2023 + + .. change:: + :tags: Improvements + :pullreq: 12906 + :tickets: 12468 + + Escape key names that are special in the systemd-journal structured logging backend. + + .. change:: + :tags: Improvements + :pullreq: 12893 + :tickets: 12890 + + Add feature to switch off unsupported DNSSEC algos, either automatically or manually. + + .. change:: + :tags: Bug Fixes + :pullreq: 12900 + + Prevent duplicate C/DNAMEs being included when doing serve-stale. + + .. change:: + :tags: Improvements + :pullreq: 12896 + :tickets: 12855 + + Expose NOD/UDR metrics. + + .. change:: + :tags: Improvements + :pullreq: 12883 + :tickets: 8232 + + Add SOA to RPZ modified answers if configured to do so. + + .. change:: + :tags: Improvements + :pullreq: 12898 + + Keep track of max depth reached and report it if !quiet. + .. change:: + :tags: Improvements + :pullreq: 12793,12904 + + Another set of fixes for clang-tidy reports. + .. changelog:: :version: 4.9.0-beta1 :released: 2nd of June 2023 diff --git a/pdns/recursordist/docs/metrics.rst b/pdns/recursordist/docs/metrics.rst index 3700652d9c41..a5ab35308f86 100644 --- a/pdns/recursordist/docs/metrics.rst +++ b/pdns/recursordist/docs/metrics.rst @@ -554,11 +554,13 @@ number of erroneous received packets nod-events ^^^^^^^^^^ .. versionadded:: 4.9.0 + Count of NOD events udr-events ^^^^^^^^^^ .. versionadded:: 4.9.0 + Count of UDR events nod-lookups-dropped-oversize diff --git a/pdns/recursordist/docs/upgrade.rst b/pdns/recursordist/docs/upgrade.rst index b8b25de0cd63..233a6ea95906 100644 --- a/pdns/recursordist/docs/upgrade.rst +++ b/pdns/recursordist/docs/upgrade.rst @@ -4,8 +4,8 @@ Upgrade Guide Before upgrading, it is advised to read the :doc:`changelog/index`. When upgrading several versions, please read **all** notes applying to the upgrade. -4.8.0 to master ---------------- +4.8.0 to 4.9.0 and master +------------------------- Metrics ^^^^^^^ @@ -21,6 +21,11 @@ New settings - The :ref:`setting-stack-cache-size` setting to control the number of allocated mthread stacks has been introduced. - The :ref:`setting-packetcache-shards` settings to control the number of shards in the packet cache has been introduced. - The :ref:`setting-aggressive-cache-min-nsec3-hit-ratio` setting to control which NSEC3 records are stored in the aggressive NSEC cache has been introduced. + This setting can be used to switch off aggressive caching for NSEC3 only. +- The :ref:`setting-dnssec-disabled-algorithms` has been introduced to not use DNSSEC algorithms disabled by the platform's security policy. + This applies specifically to Red Hat Enterprise Linux 9 and derivatives. + The default value (automatically determine the algorithms that are disabled) should work for many cases. +- The setting ``includeSOA`` was added to the :func:`rpzPrimary` and :func:`rpzFile` Lua functions to include the SOA of the RPZ the responses modified by the RPZ. Changed settings ~~~~~~~~~~~~~~~~ From b255fe8d5d42839037ca5d50be9e20541f035b6a Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 14 Jun 2023 11:12:44 +0200 Subject: [PATCH 299/909] Improve python style Co-authored-by: Chris Hofstaedtler --- regression-tests.recursor-dnssec/test_RecDnstap.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests.recursor-dnssec/test_RecDnstap.py b/regression-tests.recursor-dnssec/test_RecDnstap.py index 8bd2845c45f3..3f835a30dc60 100644 --- a/regression-tests.recursor-dnssec/test_RecDnstap.py +++ b/regression-tests.recursor-dnssec/test_RecDnstap.py @@ -186,7 +186,7 @@ def FrameStreamUnixListener(cls, conn, param): fstrm_handle_bidir_connection(conn, lambda data: \ param.queue.put(data, True, timeout=2.0)) except socket.error as e: - if e.errno == errno.EBADF or e.errno == errno.EPIPE: + if e.errno in (errno.EBADF, errno.EPIPE): break sys.stderr.write("Unexpected socket error %s\n" % str(e)) sys.exit(1) From b4fbe20d867d6f97f282f6e17d71e7e0a1346659 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Jun 2023 09:46:16 +0200 Subject: [PATCH 300/909] dnsdist: Automatically load Lua FFI inspection functions We used to do that for all Lua FFI functions except the ones used for inspecting StatNode objects. --- pdns/dnsdist-dynblocks.hh | 4 +- pdns/dnsdistdist/Makefile.am | 6 +-- pdns/dnsdistdist/dnsdist-lua-inspection-ffi.h | 46 ++++++++++++++++++ .../dnsdistdist/dnsdist-lua-inspection-ffi.hh | 47 ------------------- 4 files changed, 52 insertions(+), 51 deletions(-) create mode 100644 pdns/dnsdistdist/dnsdist-lua-inspection-ffi.h delete mode 100644 pdns/dnsdistdist/dnsdist-lua-inspection-ffi.hh diff --git a/pdns/dnsdist-dynblocks.hh b/pdns/dnsdist-dynblocks.hh index accaf6de2e33..a26e41530dd7 100644 --- a/pdns/dnsdist-dynblocks.hh +++ b/pdns/dnsdist-dynblocks.hh @@ -28,7 +28,9 @@ #include "dnsdist-rings.hh" #include "statnode.hh" -#include "dnsdist-lua-inspection-ffi.hh" +extern "C" { +#include "dnsdist-lua-inspection-ffi.h" +} // dnsdist_ffi_stat_node_t is a lightuserdata template<> diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 439ca398ab62..f11e4c4d19ce 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -34,9 +34,9 @@ htmlfiles.h: $(srcdir)/html/* $(srcdir)/incfiles $(AM_V_GEN)$(srcdir)/incfiles $(srcdir) > $@.tmp @mv $@.tmp $@ -dnsdist-lua-ffi-interface.inc: dnsdist-lua-ffi-interface.h +dnsdist-lua-ffi-interface.inc: dnsdist-lua-ffi-interface.h dnsdist-lua-inspection-ffi.h $(AM_V_GEN)echo 'R"FFIContent(' > $@ - @cat $< >> $@ + @cat $^ >> $@ @echo ')FFIContent"' >> $@ SRC_JS_FILES := $(wildcard src_js/*.js) MIN_JS_FILES := $(patsubst src_js/%.js,html/js/%.min.js,$(SRC_JS_FILES)) @@ -166,7 +166,7 @@ dnsdist_SOURCES = \ dnsdist-lua-bindings.cc \ dnsdist-lua-ffi-interface.h dnsdist-lua-ffi-interface.inc \ dnsdist-lua-ffi.cc dnsdist-lua-ffi.hh \ - dnsdist-lua-inspection-ffi.cc dnsdist-lua-inspection-ffi.hh \ + dnsdist-lua-inspection-ffi.cc \ dnsdist-lua-inspection.cc \ dnsdist-lua-network.cc dnsdist-lua-network.hh \ dnsdist-lua-rules.cc \ diff --git a/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.h b/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.h new file mode 100644 index 000000000000..ca70eedaffcb --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.h @@ -0,0 +1,46 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +typedef struct dnsdist_ffi_stat_node_t dnsdist_ffi_stat_node_t; + +uint64_t dnsdist_ffi_stat_node_get_queries_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_noerrors_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_nxdomains_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_servfails_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_drops_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_bytes(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_hits(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +unsigned int dnsdist_ffi_stat_node_get_labels_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_stat_node_get_full_name_raw(const dnsdist_ffi_stat_node_t* node, const char** name, size_t* nameSize) __attribute__ ((visibility ("default"))); + +unsigned int dnsdist_ffi_stat_node_get_children_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); + +uint64_t dnsdist_ffi_stat_node_get_children_queries_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_children_noerrors_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_children_nxdomains_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_children_servfails_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_children_drops_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_children_bytes_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); +uint64_t dnsdist_ffi_stat_node_get_children_hits(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); + +void dnsdist_ffi_state_node_set_reason(dnsdist_ffi_stat_node_t* node, const char* reason, size_t reasonSize) __attribute__ ((visibility ("default"))); + diff --git a/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.hh b/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.hh deleted file mode 100644 index f45a180dc676..000000000000 --- a/pdns/dnsdistdist/dnsdist-lua-inspection-ffi.hh +++ /dev/null @@ -1,47 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -extern "C" { - typedef struct dnsdist_ffi_stat_node_t dnsdist_ffi_stat_node_t; - - uint64_t dnsdist_ffi_stat_node_get_queries_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_noerrors_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_nxdomains_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_servfails_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_drops_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_bytes(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_hits(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - unsigned int dnsdist_ffi_stat_node_get_labels_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - void dnsdist_ffi_stat_node_get_full_name_raw(const dnsdist_ffi_stat_node_t* node, const char** name, size_t* nameSize) __attribute__ ((visibility ("default"))); - - unsigned int dnsdist_ffi_stat_node_get_children_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - - uint64_t dnsdist_ffi_stat_node_get_children_queries_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_children_noerrors_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_children_nxdomains_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_children_servfails_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_children_drops_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_children_bytes_count(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - uint64_t dnsdist_ffi_stat_node_get_children_hits(const dnsdist_ffi_stat_node_t* node) __attribute__ ((visibility ("default"))); - - void dnsdist_ffi_state_node_set_reason(dnsdist_ffi_stat_node_t* node, const char* reason, size_t reasonSize) __attribute__ ((visibility ("default"))); -} From f481e8d70059123c02a742d0a1232c871b5c89b7 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Jun 2023 10:14:21 +0200 Subject: [PATCH 301/909] dnsdist: Add a regression test for the Lua FFI raw tag interface --- regression-tests.dnsdist/test_LuaFFI.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/regression-tests.dnsdist/test_LuaFFI.py b/regression-tests.dnsdist/test_LuaFFI.py index 22d2deafb8ac..3fef2cdb1890 100644 --- a/regression-tests.dnsdist/test_LuaFFI.py +++ b/regression-tests.dnsdist/test_LuaFFI.py @@ -83,6 +83,16 @@ class TestAdvancedLuaFFI(DNSDistTest): print(ffi.string(tag)) return false end + + local raw_tag_buf_size = 255 + local raw_tag_buf = ffi.new("char [?]", raw_tag_buf_size) + local raw_tag_size = ffi.C.dnsdist_ffi_dnsquestion_get_tag_raw(dq, 'raw-tag', raw_tag_buf, raw_tag_buf_size) + if ffi.string(raw_tag_buf, raw_tag_size) ~= 'a\0b' then + print('invalid raw tag value') + print(ffi.string(raw_tag_buf, raw_tag_size)) + return false + end + return true end @@ -105,7 +115,14 @@ class TestAdvancedLuaFFI(DNSDistTest): return DNSAction.None end + function luaffiactionsettagraw(dq) + local value = "a\0b" + ffi.C.dnsdist_ffi_dnsquestion_set_tag_raw(dq, 'raw-tag', value, #value) + return DNSAction.None + end + addAction(AllRule(), LuaFFIAction(luaffiactionsettag)) + addAction(AllRule(), LuaFFIAction(luaffiactionsettagraw)) addAction(LuaFFIRule(luaffirulefunction), LuaFFIAction(luaffiactionfunction)) -- newServer{address="127.0.0.1:%s"} """ From 7724dc92f460cd28b9062e857bc3fa578f0de5b5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Jun 2023 15:35:53 +0200 Subject: [PATCH 302/909] dnsdist: Clarify the proxy protocol documentation - A proxy protocol payload is actually required from incoming clients configured with setProxyProtocolACL, not just allowed. - setProxyProtocolApplyACLToProxiedClients was wrongly documented as setProxyProtocolApplyACL --- pdns/dnsdistdist/docs/advanced/passing-source-address.rst | 3 ++- pdns/dnsdistdist/docs/reference/config.rst | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pdns/dnsdistdist/docs/advanced/passing-source-address.rst b/pdns/dnsdistdist/docs/advanced/passing-source-address.rst index 3473d01ed282..106c0dca85f1 100644 --- a/pdns/dnsdistdist/docs/advanced/passing-source-address.rst +++ b/pdns/dnsdistdist/docs/advanced/passing-source-address.rst @@ -70,7 +70,8 @@ It works by pre-pending a small header at the very beginning of a UDP datagram o In order to use it in dnsdist, the ``useProxyProtocol`` parameter can be used when creating a :func:`new server `. This parameter indicates whether a Proxy Protocol version 2 (binary) header should be prepended to the query before forwarding it to the backend, over UDP or TCP. -Such a Proxy Protocol header can also be passed from the client to dnsdist, using :func:`setProxyProtocolACL` to specify which clients to accept it from. +Such a Proxy Protocol header can also be passed from the client to dnsdist, using :func:`setProxyProtocolACL` to specify which clients to accept it from. Note that a proxy protocol payload will be required from these clients, regular DNS queries will no longer be accepted if they are not preceded by a proxy protocol payload. + If :func:`setProxyProtocolApplyACLToProxiedClients` is set (default is false), the general ACL will be applied to the source IP address as seen by dnsdist first, but also to the source IP address provided in the Proxy Protocol header. Custom values can be added to the header via :meth:`DNSQuestion:addProxyProtocolValue`, :meth:`DNSQuestion:setProxyProtocolValues`, :func:`SetAdditionalProxyProtocolValueAction` and :func:`SetProxyProtocolValuesAction`. diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 444a19c90112..b64893698688 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -469,11 +469,11 @@ Access Control Lists .. versionadded:: 1.6.0 - Set the list of netmasks from which a Proxy Protocol header will be accepted, over UDP, TCP and DNS over TLS. The default is empty. Note that, if :func:`setProxyProtocolApplyACLToProxiedClients` is set (default is false), the general ACL will be applied to the source IP address as seen by dnsdist first, but also to the source IP address provided in the Proxy Protocol header. + Set the list of netmasks from which a Proxy Protocol header will be required, over UDP, TCP and DNS over TLS. The default is empty. Note that a proxy protocol payload will be required from these clients, regular DNS queries will no longer be accepted if they are not preceded by a proxy protocol payload. Be also aware that, if :func:`setProxyProtocolApplyACLToProxiedClients` is set (default is false), the general ACL will be applied to the source IP address as seen by dnsdist first, but also to the source IP address provided in the Proxy Protocol header. :param {str} netmasks: A table of CIDR netmask, e.g. ``{"192.0.2.0/24", "2001:DB8:14::/56"}``. Without a subnetmask, only the specific address is allowed. -.. function:: setProxyProtocolApplyACL(apply) +.. function:: setProxyProtocolApplyACLToProxiedClients(apply) .. versionadded:: 1.6.0 From 5ca89a098b38e21be2c1f4cbb464b12efb3293ab Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 19 Jun 2023 11:23:05 +0200 Subject: [PATCH 303/909] Don't close the urandom file descriptor --- pdns/dns_random.cc | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/pdns/dns_random.cc b/pdns/dns_random.cc index 357bde31db66..a1991f438bd0 100644 --- a/pdns/dns_random.cc +++ b/pdns/dns_random.cc @@ -99,7 +99,7 @@ static void dns_random_setup(bool force = false) #else rng = ::arg()["rng"]; rdev = ::arg()["entropy-source"]; - if (rng == "auto") { // NOLINT: I see no way to avoid repeating blocks reported bby clang-tidy + if (rng == "auto") { // NOLINT: I see no way to avoid repeating blocks reported by clang-tidy #if defined(HAVE_GETRANDOM) chosen_rng = RNG_GETRANDOM; #elif defined(HAVE_ARC4RANDOM) @@ -188,16 +188,17 @@ static void dns_random_setup(bool force = false) } #if defined(HAVE_KISS_RNG) if (chosen_rng == RNG_KISS) { - unsigned int seed; - urandom_fd = open(rdev.c_str(), O_RDONLY); - if (urandom_fd == -1) + int fileDesc = open(rdev.c_str(), O_RDONLY); + if (fileDesc == -1) { throw std::runtime_error("Cannot open " + rdev + ": " + stringerror()); + } + unsigned int seed = 0; if (read(urandom_fd, &seed, sizeof(seed)) < 0) { - (void)close(urandom_fd); + (void)close(fileDesc); throw std::runtime_error("Cannot read random device"); } kiss_init(seed); - (void)close(urandom_fd); + (void)close(fileDesc); } #endif } @@ -278,8 +279,6 @@ uint32_t dns_random_uint32() if (errno == EINTR) { continue; } - - (void)close(urandom_fd); throw std::runtime_error("Cannot read random device"); } if (static_cast(got) != sizeof(num)) { @@ -373,8 +372,6 @@ uint32_t dns_random(uint32_t upper_bound) if (errno == EINTR) { continue; } - - (void)close(urandom_fd); throw std::runtime_error("Cannot read random device"); } if (static_cast(got) != sizeof(num)) { From e556776ddb3caf9bb37c481a77080539726f630f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 19 Jun 2023 11:33:02 +0200 Subject: [PATCH 304/909] Convert a couple of calls from dns_random() to dns_random_uint32() --- pdns/lua-base4.cc | 4 +++- pdns/opensslsigners.cc | 2 +- pdns/pdnsutil.cc | 2 +- pdns/recursordist/rec-main.cc | 2 +- pdns/tsigutils.cc | 2 +- 5 files changed, 7 insertions(+), 5 deletions(-) diff --git a/pdns/lua-base4.cc b/pdns/lua-base4.cc index a0fb5892d306..2eae10d9495e 100644 --- a/pdns/lua-base4.cc +++ b/pdns/lua-base4.cc @@ -239,7 +239,9 @@ void BaseLua4::prepareContext() { SLOG(g_log << (Logger::Urgency)loglevel.get_value_or(Logger::Warning) << msg<withName("lua")->info(static_cast(loglevel.get_value_or(Logr::Warning)), msg)); }); - d_lw->writeFunction("pdnsrandom", [](boost::optional maximum) { return dns_random(maximum.get_value_or(0xffffffff)); }); + d_lw->writeFunction("pdnsrandom", [](boost::optional maximum) { + return maximum ? dns_random(*maximum) : dns_random_uint32(); + }); // certain constants diff --git a/pdns/opensslsigners.cc b/pdns/opensslsigners.cc index a8ca7c071262..9b593aa2da7c 100644 --- a/pdns/opensslsigners.cc +++ b/pdns/opensslsigners.cc @@ -180,7 +180,7 @@ void openssl_seed() unsigned int r; for (int i = 0; i < 1024; i += 4) { - r = dns_random(0xffffffff); + r = dns_random_uint32(); entropy.append((const char*)&r, 4); } diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 6e0466a9705f..525b4636f43a 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -1852,7 +1852,7 @@ static void testSpeed(const DNSName& zone, const string& /* remote */, int cores DTime dt; dt.set(); for(unsigned int n=0; n < 100000; ++n) { - rnd = dns_random(UINT32_MAX); + rnd = dns_random_uint32(); snprintf(tmp, sizeof(tmp), "%d.%d.%d.%d", octets[0], octets[1], octets[2], octets[3]); rr.content=tmp; diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 1b54fa7fa938..5199df79c022 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1962,7 +1962,7 @@ static int serviceMain(Logr::log_t log) showProductVersion(); - g_disthashseed = dns_random(0xffffffff); + g_disthashseed = dns_random_uint32(); int ret = initNet(log); if (ret != 0) { diff --git a/pdns/tsigutils.cc b/pdns/tsigutils.cc index 40f49a9119c4..e81386bd8ff1 100644 --- a/pdns/tsigutils.cc +++ b/pdns/tsigutils.cc @@ -51,7 +51,7 @@ std::string makeTSIGKey(const DNSName& algorithm) { // Fill out the key for (size_t i = 0; i < klen; i += sizeof(uint32_t)) { - uint32_t t = dns_random(std::numeric_limits::max()); + uint32_t t = dns_random_uint32(); memcpy(&tmpkey.at(i), &t, sizeof(uint32_t)); } From 1365918f476d03d6f81b2f97367de592f586e87b Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 19 Jun 2023 13:19:22 +0200 Subject: [PATCH 305/909] rec: fix documentation of zoneToCache localAddress attribute Fixes #12919 --- pdns/recursordist/docs/lua-config/ztc.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/docs/lua-config/ztc.rst b/pdns/recursordist/docs/lua-config/ztc.rst index ee9dd62e674c..5d3c19c7b5e8 100644 --- a/pdns/recursordist/docs/lua-config/ztc.rst +++ b/pdns/recursordist/docs/lua-config/ztc.rst @@ -91,7 +91,8 @@ The default value of 0 means no restriction. localAddress ~~~~~~~~~~~~ The source IP address to use when transferring using the ``axfr`` or ``url`` methods. -When unset, :ref:`setting-query-local-address` is used. +For the ``axfr`` method :ref:`setting-query-local-address` is used by default. +The default used for ``url`` method is system dependent. zonemd ~~~~~~ From b8d3e62e682943e6df56b406c210d4c77375a8a7 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 09:01:21 +0200 Subject: [PATCH 306/909] rec: fix daemonize(), followup to #12836 Originally the code did not distinguish between parent return and error. --- pdns/recursordist/rec-main.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 5199df79c022..5d5b7c7c9b18 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -809,7 +809,13 @@ static void setupNODGlobal() static void daemonize(Logr::log_t log) { - if (fork() < 0) { + if (auto pid = fork(); pid != 0) { + if (pid < 0) { + int err = errno; + SLOG(g_log << Logger::Critical << "Fork failed: " << stringerror(err) << endl, + log->error(Logr::Critical, err, "Fork failed")); + exit(1); // NOLINT(concurrency-mt-unsafe + } exit(0); // NOLINT(concurrency-mt-unsafe } From a17a2838ee2a524cbadc0e46b31036f1d73e8e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20H=C3=B6schler?= Date: Tue, 20 Jun 2023 09:15:05 +0200 Subject: [PATCH 307/909] Fix wrong rfc number for zonemd record --- docs/appendices/types.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/appendices/types.rst b/docs/appendices/types.rst index 43119bccc318..d9ffd26cfbf4 100644 --- a/docs/appendices/types.rst +++ b/docs/appendices/types.rst @@ -372,7 +372,7 @@ mappings from hostnames to URIs. ZONEMD ------ -The ZONEMD record, specified in :rfc:`8796`, is used to validate zones. +The ZONEMD record, specified in :rfc:`8976`, is used to validate zones. Other types ----------- From aa87b287c52392ab25a2024f709a6d8378d10a44 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 09:24:50 +0200 Subject: [PATCH 308/909] Fix unused warnings coming from our own code. Some third party warning remain, mostly coming from boost. --- ext/lmdb-safe/lmdb-typed.hh | 6 +++--- modules/geoipbackend/geoipinterface-dat.cc | 2 +- modules/geoipbackend/geoipinterface-mmdb.cc | 2 +- modules/lmdbbackend/lmdbbackend.cc | 2 +- pdns/credentials.cc | 14 +++++++------- pdns/dnsdistdist/test-dnsdist-lua-ffi.cc | 4 ++-- pdns/dnsreplay.cc | 2 +- pdns/dynhandler.cc | 2 +- pdns/dynlistener.cc | 2 +- pdns/ednscookies.cc | 4 ++-- pdns/recursordist/rec-snmp.cc | 2 +- pdns/snmp-agent.cc | 2 +- pdns/speedtest.cc | 2 +- pdns/tcpiohandler.cc | 2 +- pdns/webserver.cc | 2 +- 15 files changed, 25 insertions(+), 25 deletions(-) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index ad5bb07c8a78..45da5e00b5e3 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -95,7 +95,7 @@ inline std::string keyConv(const T& t) namespace { - MDBOutVal getKeyFromCombinedKey(MDBInVal combined) { + inline MDBOutVal getKeyFromCombinedKey(MDBInVal combined) { if (combined.d_mdbval.mv_size < sizeof(uint32_t)) { throw std::runtime_error("combined key too short to get ID from"); } @@ -107,7 +107,7 @@ namespace { return ret; } - MDBOutVal getIDFromCombinedKey(MDBInVal combined) { + inline MDBOutVal getIDFromCombinedKey(MDBInVal combined) { if (combined.d_mdbval.mv_size < sizeof(uint32_t)) { throw std::runtime_error("combined key too short to get ID from"); } @@ -119,7 +119,7 @@ namespace { return ret; } - std::string makeCombinedKey(MDBInVal key, MDBInVal val) + inline std::string makeCombinedKey(MDBInVal key, MDBInVal val) { std::string lenprefix(sizeof(uint16_t), '\0'); std::string skey((char*) key.d_mdbval.mv_data, key.d_mdbval.mv_size); diff --git a/modules/geoipbackend/geoipinterface-dat.cc b/modules/geoipbackend/geoipinterface-dat.cc index 2a3f7596a801..198e60f08ab7 100644 --- a/modules/geoipbackend/geoipinterface-dat.cc +++ b/modules/geoipbackend/geoipinterface-dat.cc @@ -481,7 +481,7 @@ unique_ptr GeoIPInterface::makeDATInterface(const string& fname, #else -unique_ptr GeoIPInterface::makeDATInterface(const string& fname, const map& opts) +unique_ptr GeoIPInterface::makeDATInterface([[maybe_unused]] const string& fname, [[maybe_unused]] const map& opts) { throw PDNSException("libGeoIP support not compiled in"); } diff --git a/modules/geoipbackend/geoipinterface-mmdb.cc b/modules/geoipbackend/geoipinterface-mmdb.cc index fae7c44d2883..5866ae1a641d 100644 --- a/modules/geoipbackend/geoipinterface-mmdb.cc +++ b/modules/geoipbackend/geoipinterface-mmdb.cc @@ -288,7 +288,7 @@ unique_ptr GeoIPInterface::makeMMDBInterface(const string& fname #else -unique_ptr GeoIPInterface::makeMMDBInterface(const string& fname, const map& opts) +unique_ptr GeoIPInterface::makeMMDBInterface([[maybe_unused]] const string& fname, [[maybe_unused]] const map& opts) { throw PDNSException("libmaxminddb support not compiled in"); } diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index d6eb3ba0e80c..ada437db984b 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1189,7 +1189,7 @@ bool LMDBBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const Q return true; } -bool LMDBBackend::replaceComments(const uint32_t domain_id, const DNSName& qname, const QType& qt, const vector& comments) +bool LMDBBackend::replaceComments([[maybe_unused]] const uint32_t domain_id, [[maybe_unused]] const DNSName& qname, [[maybe_unused]] const QType& qt, const vector& comments) { // if the vector is empty, good, that's what we do here (LMDB does not store comments) // if it's not, report failure diff --git a/pdns/credentials.cc b/pdns/credentials.cc index 137f1b7f67a8..343c1205ecac 100644 --- a/pdns/credentials.cc +++ b/pdns/credentials.cc @@ -96,7 +96,7 @@ void SensitiveData::clear() d_data.clear(); } -static std::string hashPasswordInternal(const std::string& password, const std::string& salt, uint64_t workFactor, uint64_t parallelFactor, uint64_t blockSize) +static std::string hashPasswordInternal([[maybe_unused]] const std::string& password, [[maybe_unused]] const std::string& salt, [[maybe_unused]] uint64_t workFactor, [[maybe_unused]] uint64_t parallelFactor, [[maybe_unused]] uint64_t blockSize) { #if !defined(DISABLE_HASHED_CREDENTIALS) && defined(HAVE_EVP_PKEY_CTX_SET1_SCRYPT_SALT) auto pctx = std::unique_ptr(EVP_PKEY_CTX_new_id(EVP_PKEY_SCRYPT, nullptr), EVP_PKEY_CTX_free); @@ -165,7 +165,7 @@ static std::string generateRandomSalt() #endif } -std::string hashPassword(const std::string& password, uint64_t workFactor, uint64_t parallelFactor, uint64_t blockSize) +std::string hashPassword([[maybe_unused]] const std::string& password, [[maybe_unused]] uint64_t workFactor, [[maybe_unused]] uint64_t parallelFactor, [[maybe_unused]] uint64_t blockSize) { #if !defined(DISABLE_HASHED_CREDENTIALS) && defined(HAVE_EVP_PKEY_CTX_SET1_SCRYPT_SALT) if (workFactor == 0) { @@ -197,7 +197,7 @@ std::string hashPassword(const std::string& password, uint64_t workFactor, uint6 #endif } -std::string hashPassword(const std::string& password) +std::string hashPassword([[maybe_unused]] const std::string& password) { #if !defined(DISABLE_HASHED_CREDENTIALS) && defined(HAVE_EVP_PKEY_CTX_SET1_SCRYPT_SALT) return hashPassword(password, CredentialsHolder::s_defaultWorkFactor, CredentialsHolder::s_defaultParallelFactor, CredentialsHolder::s_defaultBlockSize); @@ -206,7 +206,7 @@ std::string hashPassword(const std::string& password) #endif } -bool verifyPassword(const std::string& binaryHash, const std::string& salt, uint64_t workFactor, uint64_t parallelFactor, uint64_t blockSize, const std::string& binaryPassword) +bool verifyPassword([[maybe_unused]] const std::string& binaryHash, [[maybe_unused]] const std::string& salt, [[maybe_unused]] uint64_t workFactor, [[maybe_unused]] uint64_t parallelFactor, [[maybe_unused]] uint64_t blockSize, [[maybe_unused]] const std::string& binaryPassword) { #if !defined(DISABLE_HASHED_CREDENTIALS) && defined(HAVE_EVP_PKEY_CTX_SET1_SCRYPT_SALT) auto expected = hashPasswordInternal(binaryPassword, salt, workFactor, parallelFactor, blockSize); @@ -217,7 +217,7 @@ bool verifyPassword(const std::string& binaryHash, const std::string& salt, uint } /* parse a hashed password in PHC string format */ -static void parseHashed(const std::string& hash, std::string& salt, std::string& hashedPassword, uint64_t& workFactor, uint64_t& parallelFactor, uint64_t& blockSize) +static void parseHashed([[maybe_unused]] const std::string& hash, [[maybe_unused]] std::string& salt, [[maybe_unused]] std::string& hashedPassword, [[maybe_unused]] uint64_t& workFactor, [[maybe_unused]] uint64_t& parallelFactor, [[maybe_unused]] uint64_t& blockSize) { #if !defined(DISABLE_HASHED_CREDENTIALS) && defined(HAVE_EVP_PKEY_CTX_SET1_SCRYPT_SALT) auto parametersEnd = hash.find('$', pwhash_prefix.size()); @@ -282,7 +282,7 @@ static void parseHashed(const std::string& hash, std::string& salt, std::string& #endif } -bool verifyPassword(const std::string& hash, const std::string& password) +bool verifyPassword(const std::string& hash, [[maybe_unused]] const std::string& password) { if (!isPasswordHashed(hash)) { return false; @@ -304,7 +304,7 @@ bool verifyPassword(const std::string& hash, const std::string& password) #endif } -bool isPasswordHashed(const std::string& password) +bool isPasswordHashed([[maybe_unused]] const std::string& password) { #if !defined(DISABLE_HASHED_CREDENTIALS) && defined(HAVE_EVP_PKEY_CTX_SET1_SCRYPT_SALT) if (password.size() < pwhash_prefix_size || password.size() > pwhash_max_size) { diff --git a/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc b/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc index d4367ea50e63..e6f0e1e21c23 100644 --- a/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc @@ -427,8 +427,8 @@ BOOST_AUTO_TEST_CASE(test_Server) BOOST_CHECK_EQUAL(dnsdist_ffi_server_is_up(&server), false); BOOST_CHECK_EQUAL(dnsdist_ffi_server_get_name(&server), ""); BOOST_CHECK_EQUAL(dnsdist_ffi_server_get_name_with_addr(&server), dsAddr.toStringWithPort()); - BOOST_CHECK_EQUAL(dnsdist_ffi_server_get_weight(&server), 1U); - BOOST_CHECK_EQUAL(dnsdist_ffi_server_get_order(&server), 1U); + BOOST_CHECK_EQUAL(dnsdist_ffi_server_get_weight(&server), 1); + BOOST_CHECK_EQUAL(dnsdist_ffi_server_get_order(&server), 1); BOOST_CHECK_EQUAL(dnsdist_ffi_server_get_latency(&server), 0.0); } diff --git a/pdns/dnsreplay.cc b/pdns/dnsreplay.cc index 588ca6602616..b270f45a43a8 100644 --- a/pdns/dnsreplay.cc +++ b/pdns/dnsreplay.cc @@ -595,7 +595,7 @@ static bool checkIPTransparentUsability() static bool g_rdSelector; static uint16_t g_pcapDnsPort; -static bool sendPacketFromPR(PcapPacketReader& pr, const ComboAddress& remote, int stamp, bool usePCAPSourceIP) +static bool sendPacketFromPR(PcapPacketReader& pr, const ComboAddress& remote, int stamp, [[maybe_unused]] bool usePCAPSourceIP) { bool sent=false; if (pr.d_len <= sizeof(dnsheader)) { diff --git a/pdns/dynhandler.cc b/pdns/dynhandler.cc index 730d324cdb75..b2b35a8338ec 100644 --- a/pdns/dynhandler.cc +++ b/pdns/dynhandler.cc @@ -410,7 +410,7 @@ string DLListZones(const vector& parts, Utility::pid_t /* ppid */) extern bool PKCS11ModuleSlotLogin(const std::string& module, const string& tokenId, const std::string& pin); #endif -string DLTokenLogin(const vector& parts, Utility::pid_t /* ppid */) +string DLTokenLogin([[maybe_unused]] const vector& parts, [[maybe_unused]] Utility::pid_t /* ppid */) { #ifndef HAVE_P11KIT1 return "PKCS#11 support not compiled in"; diff --git a/pdns/dynlistener.cc b/pdns/dynlistener.cc index a659de4fdd9e..456d62ba59d5 100644 --- a/pdns/dynlistener.cc +++ b/pdns/dynlistener.cc @@ -337,7 +337,7 @@ void DynListener::theListener() try { signal(SIGPIPE,SIG_IGN); - for(int n=0;;++n) { + for(;;) { string line=getLine(); boost::trim_right(line); diff --git a/pdns/ednscookies.cc b/pdns/ednscookies.cc index 5e57f04a8618..eefa0f43f76b 100644 --- a/pdns/ednscookies.cc +++ b/pdns/ednscookies.cc @@ -74,7 +74,7 @@ void EDNSCookiesOpt::getEDNSCookiesOptFromString(const char* option, unsigned in } } -bool EDNSCookiesOpt::isValid(const string& secret, const ComboAddress& source) const +bool EDNSCookiesOpt::isValid([[maybe_unused]] const string& secret, [[maybe_unused]] const ComboAddress& source) const { #ifdef HAVE_CRYPTO_SHORTHASH if (server.length() != 16 || client.length() != 8) { @@ -139,7 +139,7 @@ bool EDNSCookiesOpt::shouldRefresh() const return rfc1982LessThan(ts + 1800, now); } -bool EDNSCookiesOpt::makeServerCookie(const string& secret, const ComboAddress& source) +bool EDNSCookiesOpt::makeServerCookie([[maybe_unused]] const string& secret, [[maybe_unused]] const ComboAddress& source) { #ifdef HAVE_CRYPTO_SHORTHASH static_assert(EDNSCookieSecretSize == crypto_shorthash_KEYBYTES * 2, "The EDNSCookieSecretSize is not twice crypto_shorthash_KEYBYTES"); diff --git a/pdns/recursordist/rec-snmp.cc b/pdns/recursordist/rec-snmp.cc index 8773a158f1c5..d9c70071271d 100644 --- a/pdns/recursordist/rec-snmp.cc +++ b/pdns/recursordist/rec-snmp.cc @@ -249,7 +249,7 @@ static void registerCounter64Stat(const std::string& name, const oid statOID[], std::shared_ptr g_snmpAgent{nullptr}; -bool RecursorSNMPAgent::sendCustomTrap(const std::string& reason) +bool RecursorSNMPAgent::sendCustomTrap([[maybe_unused]] const std::string& reason) { #ifdef HAVE_NET_SNMP netsnmp_variable_list* varList = nullptr; diff --git a/pdns/snmp-agent.cc b/pdns/snmp-agent.cc index 18a088ea4353..da56e4a42315 100644 --- a/pdns/snmp-agent.cc +++ b/pdns/snmp-agent.cc @@ -161,7 +161,7 @@ void SNMPAgent::worker() #endif /* HAVE_NET_SNMP */ } -SNMPAgent::SNMPAgent(const std::string& name, const std::string& daemonSocket) +SNMPAgent::SNMPAgent([[maybe_unused]] const std::string& name, [[maybe_unused]] const std::string& daemonSocket) { #ifdef HAVE_NET_SNMP netsnmp_enable_subagent(); diff --git a/pdns/speedtest.cc b/pdns/speedtest.cc index 1447080f2c31..77bb60fb0741 100644 --- a/pdns/speedtest.cc +++ b/pdns/speedtest.cc @@ -1182,7 +1182,7 @@ struct SipHashTest }; #endif -int main(int argc, char** argv) +int main() try { reportAllTypes(); diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index 8f4d32123901..b75c3a97014e 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -1854,7 +1854,7 @@ bool TLSFrontend::setupTLS() return true; } -std::shared_ptr getTLSContext(const TLSContextParameters& params) +std::shared_ptr getTLSContext([[maybe_unused]] const TLSContextParameters& params) { #ifdef HAVE_DNS_OVER_TLS /* get the "best" available provider */ diff --git a/pdns/webserver.cc b/pdns/webserver.cc index 43cd180e8225..34577e70e577 100644 --- a/pdns/webserver.cc +++ b/pdns/webserver.cc @@ -378,7 +378,7 @@ std::string Logging::IterLoggable::to_stri } #endif -void WebServer::logRequest(const HttpRequest& req, const ComboAddress& remote) const { +void WebServer::logRequest(const HttpRequest& req, [[maybe_unused]] const ComboAddress& remote) const { if (d_loglevel >= WebServer::LogLevel::Detailed) { #ifdef RECURSOR if (!g_slogStructured) { From 72d2660a9ca80cfb0c75dbbe7c1bda5b79f4ec55 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 13:55:11 +0200 Subject: [PATCH 309/909] Avoid main() throwing an exception --- pdns/speedtest.cc | 217 +++++++++++++++++++++++----------------------- 1 file changed, 110 insertions(+), 107 deletions(-) diff --git a/pdns/speedtest.cc b/pdns/speedtest.cc index 77bb60fb0741..b8268d01d240 100644 --- a/pdns/speedtest.cc +++ b/pdns/speedtest.cc @@ -1183,165 +1183,168 @@ struct SipHashTest #endif int main() -try { - reportAllTypes(); + try { + reportAllTypes(); - doRun(NOPTest()); + doRun(NOPTest()); - doRun(IEqualsTest()); - doRun(MyIEqualsTest()); - doRun(StrcasecmpTest()); - doRun(Base64EncodeTest()); - doRun(B64DecodeTest()); + doRun(IEqualsTest()); + doRun(MyIEqualsTest()); + doRun(StrcasecmpTest()); + doRun(Base64EncodeTest()); + doRun(B64DecodeTest()); - doRun(StackMallocTest()); + doRun(StackMallocTest()); - doRun(EmptyQueryTest()); - doRun(TypicalRefTest()); - doRun(BigRefTest()); - doRun(BigDNSPacketRefTest()); + doRun(EmptyQueryTest()); + doRun(TypicalRefTest()); + doRun(BigRefTest()); + doRun(BigDNSPacketRefTest()); - auto packet = makeEmptyQuery(); - doRun(ParsePacketTest(packet, "empty-query")); + auto packet = makeEmptyQuery(); + doRun(ParsePacketTest(packet, "empty-query")); - packet = makeTypicalReferral(); - cerr<<"typical referral size: "< Date: Tue, 20 Jun 2023 14:56:29 +0200 Subject: [PATCH 310/909] Fix typos in comment Co-authored-by: Remi Gacogne --- pdns/recursordist/rec-main.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 5d5b7c7c9b18..225c72d80a0d 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -814,9 +814,9 @@ static void daemonize(Logr::log_t log) int err = errno; SLOG(g_log << Logger::Critical << "Fork failed: " << stringerror(err) << endl, log->error(Logr::Critical, err, "Fork failed")); - exit(1); // NOLINT(concurrency-mt-unsafe + exit(1); // NOLINT(concurrency-mt-unsafe) } - exit(0); // NOLINT(concurrency-mt-unsafe + exit(0); // NOLINT(concurrency-mt-unsafe) } setsid(); From d786e4d467ae591e14436d9a2d0f2be249a1dcd7 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Mon, 5 Jun 2023 22:38:34 +0200 Subject: [PATCH 311/909] auth: add startup warning about outgoing-axfr-expand-alias=ignore-errors --- pdns/auth-main.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index 65170674b222..12722088bb2a 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -742,6 +742,9 @@ static void mainthread() if (!PC.enabled() && ::arg().mustDo("log-dns-queries")) { g_log << Logger::Warning << "Packet cache disabled, logging queries without HIT/MISS" << endl; } + if (::arg()["outgoing-axfr-expand-alias"] == "ignore-errors") { + g_log << Logger::Error << "Ignoring ALIAS resolve failures on outgoing AXFR transfers, see option \"outgoing-axfr-expand-alias\"" << endl; + } stubParseResolveConf(); From 43bbbf845c5d1fd8c6133a0e2638fbc017b75c80 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Mon, 5 Jun 2023 22:51:59 +0200 Subject: [PATCH 312/909] auth: docs: warn more clearly about setting-outgoing-axfr-expand-alias=ignore-errors --- docs/guides/alias.rst | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) diff --git a/docs/guides/alias.rst b/docs/guides/alias.rst index b85762cbaa4a..48c74bd65c46 100644 --- a/docs/guides/alias.rst +++ b/docs/guides/alias.rst @@ -34,26 +34,29 @@ When the authoritative server receives a query for the A-record for ``example.net``, it will resolve the A record for ``mywebapp.paas-provider.net`` and serve an answer for ``example.net`` with that A record. -If the ALIAS target can not be resolved (SERVFAIL) or does not exist -(NXDOMAIN) the authoritative server will answer SERVFAIL. - -When a zone containing ALIAS records is transferred over AXFR, the -:ref:`setting-outgoing-axfr-expand-alias` -setting controls the behaviour of ALIAS records. When set to 'no' (the -default), ALIAS records are sent as-is (RRType 65401 and a DNSName in -the RDATA) in the AXFR. When set to 'yes', PowerDNS will lookup the A -and AAAA records of the name in the ALIAS-record and send the results in -the AXFR. -If the ALIAS target can not be resolved during AXFR the AXFR will fail. -To allow outgoing AXFR also if the ALIAS targets are broken you can set -:ref:`setting-outgoing-axfr-expand-alias` to 'ignore-errors', but -be warned, this will lead to inconsistent zones between the Primary and -Secondary name servers. - -Set ``outgoing-axfr-expand-alias`` to 'yes' if your slaves don't -understand ALIAS or should not look up the addresses themselves. Note -that slaves will not automatically follow changes in those A/AAAA -records unless you AXFR regularly. +If the ALIAS target cannot be resolved (SERVFAIL) or does not exist (NXDOMAIN) the authoritative server will answer SERVFAIL. + +.. _alias_axfr: + +AXFR Zone transfers +------------------- + +When a zone containing ALIAS records is transferred over AXFR, the :ref:`setting-outgoing-axfr-expand-alias` setting controls the behaviour of ALIAS records. + +When set to 'no' (the default), ALIAS records are sent as-is (RRType 65401 and a DNSName in the RDATA) in the AXFR. + +When set to 'yes', PowerDNS will look up the A and AAAA records of the name in the ALIAS-record and send the results in the AXFR. +This is useful when your secondary servers do not understand ALIAS, or should not look up the addresses themselves. +Note that secondaries will not automatically follow changes in those A/AAAA records unless you AXFR regularly. + +If the ALIAS target cannot be resolved, the AXFR will fail. +When set to 'ignore-errors', an unresolvable ALIAS target will be omitted from the outgoing transfer. + +.. warning:: + Setting ``setting-outgoing-axfr-expand-alias`` to 'ignore-errors', will allow an outgoing AXFR with a broken ALIAS target to complete, but the secondary server will receive an incomplete zone. + There is no standard mechanism for automatic re-transfer for zones broken in this way. + You should make sure this behaviour is acceptable in your use case, provide custom integration tooling to monitor such problems, and possibly fix them automatically. + .. note:: The ``expand-alias`` setting does not exist in PowerDNS From 5cf23dbaef3a62d8ef89cc62f8fc31d06ef6326a Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 7 Jun 2023 14:08:28 +0200 Subject: [PATCH 313/909] auth: ignore readability-function-cognitive-complexity for doAXFR for now --- pdns/tcpreceiver.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index b84053ea3f70..49a1b66f5dc8 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -582,7 +582,7 @@ namespace { /** do the actual zone transfer. Return 0 in case of error, 1 in case of success */ -int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr& q, int outsock) +int TCPNameserver::doAXFR(const DNSName &target, std::unique_ptr& q, int outsock) // NOLINT(readability-function-cognitive-complexity) { string logPrefix="AXFR-out zone '"+target.toLogString()+"', client '"+q->getRemoteString()+"', "; From 98769adca88b229cbdcba1e4b8fc2539d08759de Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 20 Jun 2023 18:47:36 +0200 Subject: [PATCH 314/909] channel: Rename 'fd' to 'descriptor' --- pdns/channel.cc | 8 ++++---- pdns/channel.hh | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pdns/channel.cc b/pdns/channel.cc index 5892f9e0f881..d6a30399f2d6 100644 --- a/pdns/channel.cc +++ b/pdns/channel.cc @@ -25,8 +25,8 @@ namespace pdns::channel { -Notifier::Notifier(FDWrapper&& fd) : - d_fd(std::move(fd)) +Notifier::Notifier(FDWrapper&& descriptor) : + d_fd(std::move(descriptor)) { } @@ -51,8 +51,8 @@ bool Notifier::notify() const } } -Waiter::Waiter(FDWrapper&& fd, bool throwOnEOF) : - d_fd(std::move(fd)), d_throwOnEOF(throwOnEOF) +Waiter::Waiter(FDWrapper&& descriptor, bool throwOnEOF) : + d_fd(std::move(descriptor)), d_throwOnEOF(throwOnEOF) { } diff --git a/pdns/channel.hh b/pdns/channel.hh index 119c1a24fbfb..e06d2583dc0e 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -55,8 +55,8 @@ namespace channel Sender() { } - Sender(FDWrapper&& fd) : - d_fd(std::move(fd)) + Sender(FDWrapper&& descriptor) : + d_fd(std::move(descriptor)) { } Sender(const Sender&) = delete; @@ -89,8 +89,8 @@ namespace channel Receiver() { } - Receiver(FDWrapper&& fd, bool throwOnEOF = true) : - d_fd(std::move(fd)), d_throwOnEOF(throwOnEOF) + Receiver(FDWrapper&& descriptor, bool throwOnEOF = true) : + d_fd(std::move(descriptor)), d_throwOnEOF(throwOnEOF) { } Receiver(const Receiver&) = delete; From 891f17371c4e1007f91abb4695c4b0e95c3f2995 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 21 Jun 2023 10:43:26 +0200 Subject: [PATCH 315/909] Followup to #12893: Rewrite and fix verifyOne() loop Previous version could return true if the first iteration succeeded, but the second one threw. Spotted by pt01 on IRC. --- pdns/dnssecinfra.cc | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index 04ce29193b0d..a07a9f1d8fc5 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -398,20 +398,28 @@ bool DNSCryptoKeyEngine::testVerify(unsigned int algo, maker_t* verifier) bool DNSCryptoKeyEngine::verifyOne(unsigned int algo) { - bool ret = false; - - for (auto* verifier : getAllMakers()[algo]) { + const auto& makers = getAllMakers(); + auto iter = makers.find(algo); + // No algo foound + if (iter == makers.cend()) { + return false; + } + // Algo found, but maker empty? Should not happen + if (iter->second.empty()) { + return false; + } + // Check that all maker->verify return true + return std::all_of(iter->second.begin(), iter->second.end(), [algo](maker_t* verifier) { try { - ret = testVerify(algo, verifier); + if (!testVerify(algo, verifier)) { + return false; + } } catch (std::exception& e) { - // Empty - } - if (!ret) { - break; + return false; } - } - return ret; + return true; + }); } void DNSCryptoKeyEngine::testMakers(unsigned int algo, maker_t* creator, maker_t* signer, maker_t* verifier) From da6a2d87c8d8cfe49dc6eda3481b82f8faf5a832 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 21 Jun 2023 13:17:01 +0200 Subject: [PATCH 316/909] Typo inc omment Co-authored-by: Remi Gacogne --- pdns/dnssecinfra.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index a07a9f1d8fc5..3e9056d71136 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -400,7 +400,7 @@ bool DNSCryptoKeyEngine::verifyOne(unsigned int algo) { const auto& makers = getAllMakers(); auto iter = makers.find(algo); - // No algo foound + // No algo found if (iter == makers.cend()) { return false; } From 9a3471825fc759742b53b38fe182a831c350a123 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 21 Jun 2023 14:25:03 +0200 Subject: [PATCH 317/909] rec: Silence Coverity 1462719 Unchecked return value from library. Call should not fail and it's a best effort anyway in this case --- pdns/recursordist/lwres.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/lwres.cc b/pdns/recursordist/lwres.cc index ad9bcbb81d5c..f6c6fa2479c9 100644 --- a/pdns/recursordist/lwres.cc +++ b/pdns/recursordist/lwres.cc @@ -486,7 +486,7 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma if (fstrmQEnabled || fstrmREnabled) { localip.sin4.sin_family = ip.sin4.sin_family; socklen_t slen = ip.getSocklen(); - getsockname(queryfd, reinterpret_cast(&localip), &slen); + (void)getsockname(queryfd, reinterpret_cast(&localip), &slen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)) } if (fstrmQEnabled) { logFstreamQuery(fstrmLoggers, queryTime, localip, ip, DnstapMessage::ProtocolType::DoUDP, context ? context->d_auth : boost::none, vpacket); From 9fcef4932c9323b085984f8a087045fef70103f5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 21 Jun 2023 14:58:15 +0200 Subject: [PATCH 318/909] Stop using the now deprecated ERR_load_CRYPTO_strings() to detect OpenSSL And move to BN_new() instead, which has been present since at least 0.9.6 and is still in 3.1. --- m4/pdns_check_libcrypto.m4 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/m4/pdns_check_libcrypto.m4 b/m4/pdns_check_libcrypto.m4 index 8e1219a3e75b..1fa4f23bda93 100644 --- a/m4/pdns_check_libcrypto.m4 +++ b/m4/pdns_check_libcrypto.m4 @@ -108,7 +108,7 @@ AC_DEFUN([PDNS_CHECK_LIBCRYPTO], [ LIBS="$LIBCRYPTO_LIBS $LIBS" CPPFLAGS="$LIBCRYPTO_INCLUDES $CPPFLAGS" AC_LINK_IFELSE( - [AC_LANG_PROGRAM([#include ], [ERR_load_CRYPTO_strings()])], + [AC_LANG_PROGRAM([#include ], [BN_new()])], [ AC_MSG_RESULT([yes]) AC_CHECK_FUNCS([RAND_bytes RAND_pseudo_bytes CRYPTO_memcmp OPENSSL_init_crypto EVP_MD_CTX_new EVP_MD_CTX_free RSA_get0_key]) From 5a7a3b67445af9cd1d2e8af2d842737a5a1ef398 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 22 Jun 2023 09:12:10 +0200 Subject: [PATCH 319/909] Fix coverity time_t related warnings Most are not *really* bad, as we convert tmioe_t or unsigned int, which is good for quite some time. One case of converting time_t to *signed* int spotted. --- modules/bindbackend/bindbackend2.cc | 1 + pdns/auth-zonecache.hh | 1 + pdns/dbdnsseckeeper.cc | 1 + pdns/ixplore.cc | 2 +- pdns/saxfr.cc | 1 + pdns/serialtweaker.cc | 2 ++ pdns/tkey.cc | 1 + pdns/ws-auth.cc | 1 + 8 files changed, 9 insertions(+), 1 deletion(-) diff --git a/modules/bindbackend/bindbackend2.cc b/modules/bindbackend/bindbackend2.cc index 931952d4e881..1a0b01a57886 100644 --- a/modules/bindbackend/bindbackend2.cc +++ b/modules/bindbackend/bindbackend2.cc @@ -430,6 +430,7 @@ void Bind2Backend::getUnfreshSlaveInfos(vector* unfreshDomains) catch (...) { } sd.serial = soadata.serial; + // coverity[store_truncates_time_t] if (sd.last_check + soadata.refresh < (unsigned int)time(nullptr)) unfreshDomains->push_back(std::move(sd)); } diff --git a/pdns/auth-zonecache.hh b/pdns/auth-zonecache.hh index c1b91d2b580a..c5b052a5378f 100644 --- a/pdns/auth-zonecache.hh +++ b/pdns/auth-zonecache.hh @@ -43,6 +43,7 @@ public: uint32_t getRefreshInterval() const { + // coverity[store_truncates_time_t] return d_refreshinterval; } diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index 9d7b85a332f9..514025292961 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -533,6 +533,7 @@ DNSSECKeeper::keyset_t DNSSECKeeper::getEntryPoints(const DNSName& zname) DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const DNSName& zone, bool useCache) { static int ttl = ::arg().asNum("dnssec-key-cache-ttl"); + // coverity[store_truncates_time_t] unsigned int now = time(nullptr); if(!((++s_ops) % 100000)) { diff --git a/pdns/ixplore.cc b/pdns/ixplore.cc index e6eedf42ce2a..620402ab0e56 100644 --- a/pdns/ixplore.cc +++ b/pdns/ixplore.cc @@ -180,7 +180,7 @@ int main(int argc, char** argv) { shared_ptr sr; uint32_t serial = getSerialFromMaster(master, zone, sr, tt); if(ourSerial == serial) { - time_t sleepTime = sr ? sr->d_st.refresh : 60; + unsigned int sleepTime = sr ? sr->d_st.refresh : 60; cout<<"still up to date, their serial is "<& tkey_out->d_error = 0; tkey_out->d_mode = tkey_in.d_mode; tkey_out->d_algo = tkey_in.d_algo; + // coverity[store_truncates_time_t] tkey_out->d_inception = inception; tkey_out->d_expiration = tkey_out->d_inception+15; diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 20d79875f682..fe7fb50b0c33 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -583,6 +583,7 @@ static void gatherComments(const Json& container, const DNSName& qname, const QT time_t now = time(nullptr); for (const auto& comment : container["comments"].array_items()) { + // FIXME this is converting to a *signed* int, 2036 issue c.modified_at = intFromJson(comment, "modified_at", now); c.content = stringFromJson(comment, "content"); c.account = stringFromJson(comment, "account"); From 46de63a6feb237e39b444c80ba82b57c4635ae52 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 22 Jun 2023 09:18:56 +0200 Subject: [PATCH 320/909] dnsdist: add dnsdist-lua-inspection-ffi.h to dist tarballs --- pdns/dnsdistdist/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index db85cb39119b..e9c7ca2086cd 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -167,7 +167,7 @@ dnsdist_SOURCES = \ dnsdist-lua-bindings.cc \ dnsdist-lua-ffi-interface.h dnsdist-lua-ffi-interface.inc \ dnsdist-lua-ffi.cc dnsdist-lua-ffi.hh \ - dnsdist-lua-inspection-ffi.cc \ + dnsdist-lua-inspection-ffi.cc dnsdist-lua-inspection-ffi.h \ dnsdist-lua-inspection.cc \ dnsdist-lua-network.cc dnsdist-lua-network.hh \ dnsdist-lua-rules.cc \ From d9b4683e38076cbf8a2bcd79ebf1f7c5da88ac00 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 22 Jun 2023 10:50:13 +0200 Subject: [PATCH 321/909] dnsdist: fix typo --- pdns/dnsdist.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index c1e2a0102551..a9af1a217d3c 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -2600,7 +2600,7 @@ int main(int argc, char** argv) cout<<"ipcipher "; #endif #ifdef HAVE_LIBEDIT - cout<<"libeditr "; + cout<<"libedit "; #endif #ifdef HAVE_LIBSODIUM cout<<"libsodium "; From 773cd53158e4fcfd0fcf66904126c644244f5b90 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 22 Jun 2023 11:09:44 +0200 Subject: [PATCH 322/909] channel: Add an annotation so Coverity does not think we leak --- pdns/channel.hh | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/channel.hh b/pdns/channel.hh index e06d2583dc0e..7beaa198d190 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -232,6 +232,7 @@ namespace channel ssize_t sent = write(d_fd.getHandle(), &ptr, sizeof(ptr)); if (sent == sizeof(ptr)) { + // coverity[leaked_storage] localObj.release(); return true; } From c92e6020a5a46b6a91a8e75f8e2bc5f83a88d29d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 22 Jun 2023 11:58:18 +0200 Subject: [PATCH 323/909] dnsdist: Apply performance suggestions from Coverity I don't expect these changes to actually make a difference in practice, because pretty much all of them impact configuration processing, where performance is not that critical. Still they should not hurt and a few of them might actually improve some edge cases. --- pdns/dnsdist-dynblocks.hh | 4 ++-- pdns/dnsdist-lbpolicies.hh | 4 ++-- pdns/dnsdist-lua-actions.cc | 18 +++++++++--------- pdns/dnsdist-lua-bindings-dnsquestion.cc | 2 +- pdns/dnsdist-lua-bindings.cc | 2 +- pdns/dnsdist-lua-inspection.cc | 8 ++++---- pdns/dnsdist-lua-rules.cc | 12 ++++++------ pdns/dnsdist-lua.cc | 18 +++++++++--------- pdns/dnsdist-web.cc | 2 +- pdns/dnsdistdist/dnsdist-discovery.cc | 2 +- .../dnsdist-lua-bindings-network.cc | 2 +- pdns/dnsdistdist/dnsdist-lua-network.cc | 2 +- pdns/dnsdistdist/dnsdist-rules.hh | 4 ++-- pdns/dnsdistdist/dnsdist-tcp.hh | 2 +- pdns/dnsparser.cc | 4 ++-- pdns/libssl.cc | 8 ++++---- pdns/libssl.hh | 5 +++-- pdns/mplexer.hh | 10 +++++----- pdns/tcpiohandler.cc | 6 +++--- 19 files changed, 58 insertions(+), 57 deletions(-) diff --git a/pdns/dnsdist-dynblocks.hh b/pdns/dnsdist-dynblocks.hh index a26e41530dd7..39c8bc7ec8ee 100644 --- a/pdns/dnsdist-dynblocks.hh +++ b/pdns/dnsdist-dynblocks.hh @@ -264,13 +264,13 @@ public: void setSuffixMatchRule(unsigned int seconds, const std::string& reason, unsigned int blockDuration, DNSAction::Action action, smtVisitor_t visitor) { d_suffixMatchRule = DynBlockRule(reason, blockDuration, 0, 0, seconds, action); - d_smtVisitor = visitor; + d_smtVisitor = std::move(visitor); } void setSuffixMatchRuleFFI(unsigned int seconds, const std::string& reason, unsigned int blockDuration, DNSAction::Action action, dnsdist_ffi_stat_node_visitor_t visitor) { d_suffixMatchRule = DynBlockRule(reason, blockDuration, 0, 0, seconds, action); - d_smtVisitorFFI = visitor; + d_smtVisitorFFI = std::move(visitor); } void setMasks(uint8_t v4, uint8_t v6, uint8_t port) diff --git a/pdns/dnsdist-lbpolicies.hh b/pdns/dnsdist-lbpolicies.hh index a1332c77297d..72443402d10f 100644 --- a/pdns/dnsdist-lbpolicies.hh +++ b/pdns/dnsdist-lbpolicies.hh @@ -37,11 +37,11 @@ public: typedef std::function(const NumberedServerVector& servers, const DNSQuestion*)> policyfunc_t; typedef std::function ffipolicyfunc_t; - ServerPolicy(const std::string& name_, policyfunc_t policy_, bool isLua_): d_name(name_), d_policy(policy_), d_isLua(isLua_) + ServerPolicy(const std::string& name_, policyfunc_t policy_, bool isLua_): d_name(name_), d_policy(std::move(policy_)), d_isLua(isLua_) { } - ServerPolicy(const std::string& name_, ffipolicyfunc_t policy_): d_name(name_), d_ffipolicy(policy_), d_isLua(true), d_isFFI(true) + ServerPolicy(const std::string& name_, ffipolicyfunc_t policy_): d_name(name_), d_ffipolicy(std::move(policy_)), d_isLua(true), d_isFFI(true) { } diff --git a/pdns/dnsdist-lua-actions.cc b/pdns/dnsdist-lua-actions.cc index a7ec4aea1aba..0f1d854a8fad 100644 --- a/pdns/dnsdist-lua-actions.cc +++ b/pdns/dnsdist-lua-actions.cc @@ -1453,7 +1453,7 @@ class DnstapLogAction : public DNSAction, public boost::noncopyable { public: // this action does not stop the processing - DnstapLogAction(const std::string& identity, std::shared_ptr& logger, boost::optional > alterFunc): d_identity(identity), d_logger(logger), d_alterFunc(alterFunc) + DnstapLogAction(const std::string& identity, std::shared_ptr& logger, boost::optional > alterFunc): d_identity(identity), d_logger(logger), d_alterFunc(std::move(alterFunc)) { } DNSAction::Action operator()(DNSQuestion* dq, std::string* ruleresult) const override @@ -1515,7 +1515,7 @@ class RemoteLogAction : public DNSAction, public boost::noncopyable { public: // this action does not stop the processing - RemoteLogAction(std::shared_ptr& logger, boost::optional > alterFunc, const std::string& serverID, const std::string& ipEncryptKey, std::vector>&& metas, std::optional>&& tagsToExport): d_tagsToExport(std::move(tagsToExport)), d_metas(std::move(metas)), d_logger(logger), d_alterFunc(alterFunc), d_serverID(serverID), d_ipEncryptKey(ipEncryptKey) + RemoteLogAction(std::shared_ptr& logger, boost::optional > alterFunc, const std::string& serverID, const std::string& ipEncryptKey, std::vector>&& metas, std::optional>&& tagsToExport): d_tagsToExport(std::move(tagsToExport)), d_metas(std::move(metas)), d_logger(logger), d_alterFunc(std::move(alterFunc)), d_serverID(serverID), d_ipEncryptKey(ipEncryptKey) { } @@ -1623,7 +1623,7 @@ class DnstapLogResponseAction : public DNSResponseAction, public boost::noncopya { public: // this action does not stop the processing - DnstapLogResponseAction(const std::string& identity, std::shared_ptr& logger, boost::optional > alterFunc): d_identity(identity), d_logger(logger), d_alterFunc(alterFunc) + DnstapLogResponseAction(const std::string& identity, std::shared_ptr& logger, boost::optional > alterFunc): d_identity(identity), d_logger(logger), d_alterFunc(std::move(alterFunc)) { } DNSResponseAction::Action operator()(DNSResponse* dr, std::string* ruleresult) const override @@ -1660,7 +1660,7 @@ class RemoteLogResponseAction : public DNSResponseAction, public boost::noncopya { public: // this action does not stop the processing - RemoteLogResponseAction(std::shared_ptr& logger, boost::optional > alterFunc, const std::string& serverID, const std::string& ipEncryptKey, bool includeCNAME, std::vector>&& metas, std::optional>&& tagsToExport): d_tagsToExport(std::move(tagsToExport)), d_metas(std::move(metas)), d_logger(logger), d_alterFunc(alterFunc), d_serverID(serverID), d_ipEncryptKey(ipEncryptKey), d_includeCNAME(includeCNAME) + RemoteLogResponseAction(std::shared_ptr& logger, boost::optional > alterFunc, const std::string& serverID, const std::string& ipEncryptKey, bool includeCNAME, std::vector>&& metas, std::optional>&& tagsToExport): d_tagsToExport(std::move(tagsToExport)), d_metas(std::move(metas)), d_logger(logger), d_alterFunc(std::move(alterFunc)), d_serverID(serverID), d_ipEncryptKey(ipEncryptKey), d_includeCNAME(includeCNAME) { } DNSResponseAction::Action operator()(DNSResponse* dr, std::string* ruleresult) const override @@ -2198,7 +2198,7 @@ void setupLuaActions(LuaContext& luaCtx) checkAllParametersConsumed("newRuleAction", params); auto rule = makeRule(dnsrule); - DNSDistRuleAction ra({std::move(rule), action, std::move(name), uuid, creationOrder}); + DNSDistRuleAction ra({std::move(rule), std::move(action), std::move(name), uuid, creationOrder}); return std::make_shared(ra); }); @@ -2538,7 +2538,7 @@ void setupLuaActions(LuaContext& luaCtx) checkAllParametersConsumed("RemoteLogAction", vars); - return std::shared_ptr(new RemoteLogAction(logger, alterFunc, serverID, ipEncryptKey, std::move(metaOptions), std::move(tagsToExport))); + return std::shared_ptr(new RemoteLogAction(logger, std::move(alterFunc), serverID, ipEncryptKey, std::move(metaOptions), std::move(tagsToExport))); }); luaCtx.writeFunction("RemoteLogResponseAction", [](std::shared_ptr logger, boost::optional > alterFunc, boost::optional includeCNAME, boost::optional> vars, boost::optional> metas) { @@ -2579,15 +2579,15 @@ void setupLuaActions(LuaContext& luaCtx) checkAllParametersConsumed("RemoteLogResponseAction", vars); - return std::shared_ptr(new RemoteLogResponseAction(logger, alterFunc, serverID, ipEncryptKey, includeCNAME ? *includeCNAME : false, std::move(metaOptions), std::move(tagsToExport))); + return std::shared_ptr(new RemoteLogResponseAction(logger, std::move(alterFunc), serverID, ipEncryptKey, includeCNAME ? *includeCNAME : false, std::move(metaOptions), std::move(tagsToExport))); }); luaCtx.writeFunction("DnstapLogAction", [](const std::string& identity, std::shared_ptr logger, boost::optional > alterFunc) { - return std::shared_ptr(new DnstapLogAction(identity, logger, alterFunc)); + return std::shared_ptr(new DnstapLogAction(identity, logger, std::move(alterFunc))); }); luaCtx.writeFunction("DnstapLogResponseAction", [](const std::string& identity, std::shared_ptr logger, boost::optional > alterFunc) { - return std::shared_ptr(new DnstapLogResponseAction(identity, logger, alterFunc)); + return std::shared_ptr(new DnstapLogResponseAction(identity, logger, std::move(alterFunc))); }); #endif /* DISABLE_PROTOBUF */ diff --git a/pdns/dnsdist-lua-bindings-dnsquestion.cc b/pdns/dnsdist-lua-bindings-dnsquestion.cc index 9d5da2c73600..a29c17c3ade0 100644 --- a/pdns/dnsdist-lua-bindings-dnsquestion.cc +++ b/pdns/dnsdist-lua-bindings-dnsquestion.cc @@ -187,7 +187,7 @@ void setupLuaBindingsDNSQuestion(LuaContext& luaCtx) dq.proxyProtocolValues = make_unique>(); } - dq.proxyProtocolValues->push_back({value, static_cast(type)}); + dq.proxyProtocolValues->push_back({std::move(value), static_cast(type)}); }); luaCtx.registerFunction(DNSQuestion::*)()>("getProxyProtocolValues", [](const DNSQuestion& dq) { diff --git a/pdns/dnsdist-lua-bindings.cc b/pdns/dnsdist-lua-bindings.cc index 5246e482142e..225f48b9556f 100644 --- a/pdns/dnsdist-lua-bindings.cc +++ b/pdns/dnsdist-lua-bindings.cc @@ -90,7 +90,7 @@ void setupLuaBindings(LuaContext& luaCtx, bool client) /* ServerPool */ luaCtx.registerFunction::*)(std::shared_ptr)>("setCache", [](std::shared_ptr pool, std::shared_ptr cache) { if (pool) { - pool->packetCache = cache; + pool->packetCache = std::move(cache); } }); luaCtx.registerFunction("getCache", &ServerPool::getCache); diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index fda2d1e8a092..d6755b00cd3b 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -148,7 +148,7 @@ static void statNodeRespRing(statvisitor_t visitor, uint64_t seconds) } StatNode::Stat node; - root.visit([visitor](const StatNode* node_, const StatNode::Stat& self, const StatNode::Stat& children) { + root.visit([visitor = std::move(visitor)](const StatNode* node_, const StatNode::Stat& self, const StatNode::Stat& children) { visitor(*node_, self, children);}, node); } @@ -832,7 +832,7 @@ void setupLuaInspection(LuaContext& luaCtx) luaCtx.registerMember("hits", &StatNode::Stat::hits); luaCtx.writeFunction("statNodeRespRing", [](statvisitor_t visitor, boost::optional seconds) { - statNodeRespRing(visitor, seconds ? *seconds : 0U); + statNodeRespRing(std::move(visitor), seconds ? *seconds : 0U); }); #endif /* DISABLE_DEPRECATED_DYNBLOCK */ @@ -850,12 +850,12 @@ void setupLuaInspection(LuaContext& luaCtx) }); luaCtx.registerFunction::*)(unsigned int, const std::string&, unsigned int, boost::optional, DynBlockRulesGroup::smtVisitor_t)>("setSuffixMatchRule", [](std::shared_ptr& group, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional action, DynBlockRulesGroup::smtVisitor_t visitor) { if (group) { - group->setSuffixMatchRule(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, visitor); + group->setSuffixMatchRule(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, std::move(visitor)); } }); luaCtx.registerFunction::*)(unsigned int, const std::string&, unsigned int, boost::optional, dnsdist_ffi_stat_node_visitor_t)>("setSuffixMatchRuleFFI", [](std::shared_ptr& group, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional action, dnsdist_ffi_stat_node_visitor_t visitor) { if (group) { - group->setSuffixMatchRuleFFI(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, visitor); + group->setSuffixMatchRuleFFI(seconds, reason, blockDuration, action ? *action : DNSAction::Action::None, std::move(visitor)); } }); luaCtx.registerFunction::*)(uint8_t, unsigned int, unsigned int, const std::string&, unsigned int, boost::optional, boost::optional)>("setRCodeRate", [](std::shared_ptr& group, uint8_t rcode, unsigned int rate, unsigned int seconds, const std::string& reason, unsigned int blockDuration, boost::optional action, boost::optional warningRate) { diff --git a/pdns/dnsdist-lua-rules.cc b/pdns/dnsdist-lua-rules.cc index ba8f465d2357..762e4e670db1 100644 --- a/pdns/dnsdist-lua-rules.cc +++ b/pdns/dnsdist-lua-rules.cc @@ -83,7 +83,7 @@ void parseRuleParams(boost::optional& params, boost::uuids::uui typedef LuaAssociativeTable > > ruleparams_t; template -static std::string rulesToString(const std::vector& rules, boost::optional vars) +static std::string rulesToString(const std::vector& rules, boost::optional& vars) { int num = 0; bool showUUIDs = false; @@ -116,7 +116,7 @@ static std::string rulesToString(const std::vector& rules, boost::optional -static void showRules(GlobalStateHolder > *someRuleActions, boost::optional vars) { +static void showRules(GlobalStateHolder > *someRuleActions, boost::optional& vars) { setLuaNoSideEffect(); auto rules = someRuleActions->getLocal(); @@ -124,7 +124,7 @@ static void showRules(GlobalStateHolder > *someRuleActions, boost::opt } template -static void rmRule(GlobalStateHolder > *someRuleActions, boost::variant id) { +static void rmRule(GlobalStateHolder > *someRuleActions, const boost::variant& id) { setLuaSideEffect(); auto rules = someRuleActions->getCopy(); if (auto str = boost::get(&id)) { @@ -592,7 +592,7 @@ void setupLuaRules(LuaContext& luaCtx) }); luaCtx.writeFunction("TagRule", [](const std::string& tag, boost::optional value) { - return std::shared_ptr(new TagRule(tag, value)); + return std::shared_ptr(new TagRule(tag, std::move(value))); }); luaCtx.writeFunction("TimedIPSetRule", []() { @@ -649,10 +649,10 @@ void setupLuaRules(LuaContext& luaCtx) }); luaCtx.writeFunction("LuaFFIPerThreadRule", [](const std::string& code) { - return std::shared_ptr(new LuaFFIPerThreadRule(code)); + return std::shared_ptr(new LuaFFIPerThreadRule(code)); }); luaCtx.writeFunction("ProxyProtocolValueRule", [](uint8_t type, boost::optional value) { - return std::shared_ptr(new ProxyProtocolValueRule(type, value)); + return std::shared_ptr(new ProxyProtocolValueRule(type, std::move(value))); }); } diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 9efa59dd2837..f0345ebf2ebf 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -128,7 +128,7 @@ static void parseLocalBindVars(boost::optional& vars, bool& reusePo } #if defined(HAVE_DNS_OVER_TLS) || defined(HAVE_DNS_OVER_HTTPS) -static bool loadTLSCertificateAndKeys(const std::string& context, std::vector& pairs, boost::variant, LuaArray, LuaArray>> certFiles, LuaTypeOrArrayOf keyFiles) +static bool loadTLSCertificateAndKeys(const std::string& context, std::vector& pairs, const boost::variant, LuaArray, LuaArray>>& certFiles, const LuaTypeOrArrayOf& keyFiles) { if (certFiles.type() == typeid(std::string) && keyFiles.type() == typeid(std::string)) { auto certFile = boost::get(certFiles); @@ -255,7 +255,7 @@ static void LuaThread(const std::string& code) // maybe offer more than `void` auto func = lua->readVariable data)>>>("threadmessage"); if (func) { - func.get()(cmd, data); + func.get()(std::move(cmd), std::move(data)); } else { errlog("Lua thread called submitToMainThread but no threadmessage receiver is defined"); @@ -1211,7 +1211,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) luaCtx.writeFunction("setQueryCount", [](bool enabled) { g_qcount.enabled = enabled; }); luaCtx.writeFunction("setQueryCountFilter", [](QueryCountFilter func) { - g_qcount.filter = func; + g_qcount.filter = std::move(func); }); luaCtx.writeFunction("makeKey", []() { @@ -1546,7 +1546,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) if (certFiles.type() == typeid(std::string) && keyFiles.type() == typeid(std::string)) { auto certFile = boost::get(certFiles); auto keyFile = boost::get(keyFiles); - certKeys.push_back({certFile, keyFile}); + certKeys.push_back({std::move(certFile), std::move(keyFile)}); } else if (certFiles.type() == typeid(LuaArray) && keyFiles.type() == typeid(LuaArray)) { auto certFilesVect = boost::get>(certFiles); @@ -1782,12 +1782,12 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) if (!checkConfigurationTime("setDefaultBPFFilter")) { return; } - g_defaultBPFFilter = bpf; + g_defaultBPFFilter = std::move(bpf); }); luaCtx.writeFunction("registerDynBPFFilter", [](std::shared_ptr dbpf) { if (dbpf) { - g_dynBPFFilters.push_back(dbpf); + g_dynBPFFilters.push_back(std::move(dbpf)); } }); @@ -2075,21 +2075,21 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) luaCtx.writeFunction("setPoolServerPolicy", [](ServerPolicy policy, const string& pool) { setLuaSideEffect(); auto localPools = g_pools.getCopy(); - setPoolPolicy(localPools, pool, std::make_shared(policy)); + setPoolPolicy(localPools, pool, std::make_shared(std::move(policy))); g_pools.setState(localPools); }); luaCtx.writeFunction("setPoolServerPolicyLua", [](const string& name, ServerPolicy::policyfunc_t policy, const string& pool) { setLuaSideEffect(); auto localPools = g_pools.getCopy(); - setPoolPolicy(localPools, pool, std::make_shared(ServerPolicy{name, policy, true})); + setPoolPolicy(localPools, pool, std::make_shared(ServerPolicy{name, std::move(policy), true})); g_pools.setState(localPools); }); luaCtx.writeFunction("setPoolServerPolicyLuaFFI", [](const string& name, ServerPolicy::ffipolicyfunc_t policy, const string& pool) { setLuaSideEffect(); auto localPools = g_pools.getCopy(); - setPoolPolicy(localPools, pool, std::make_shared(ServerPolicy{name, policy})); + setPoolPolicy(localPools, pool, std::make_shared(ServerPolicy{name, std::move(policy)})); g_pools.setState(localPools); }); diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index e8b51066b785..21cdfd05b3a7 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -1570,7 +1570,7 @@ void registerWebHandler(const std::string& endpoint, std::function handler) { - s_webHandlers[endpoint] = handler; + s_webHandlers[endpoint] = std::move(handler); } void clearWebHandlers() diff --git a/pdns/dnsdistdist/dnsdist-discovery.cc b/pdns/dnsdistdist/dnsdist-discovery.cc index 9d267ecded51..66ac1c070a65 100644 --- a/pdns/dnsdistdist/dnsdist-discovery.cc +++ b/pdns/dnsdistdist/dnsdist-discovery.cc @@ -38,7 +38,7 @@ const uint16_t ServiceDiscovery::s_defaultDoHSVCKey{7}; bool ServiceDiscovery::addUpgradeableServer(std::shared_ptr& server, uint32_t interval, std::string poolAfterUpgrade, uint16_t dohSVCKey, bool keepAfterUpgrade) { - s_upgradeableBackends.lock()->push_back(std::make_shared(UpgradeableBackend{server, poolAfterUpgrade, 0, interval, dohSVCKey, keepAfterUpgrade})); + s_upgradeableBackends.lock()->push_back(std::make_shared(UpgradeableBackend{server, std::move(poolAfterUpgrade), 0, interval, dohSVCKey, keepAfterUpgrade})); return true; } diff --git a/pdns/dnsdistdist/dnsdist-lua-bindings-network.cc b/pdns/dnsdistdist/dnsdist-lua-bindings-network.cc index 62dce3ba1147..75d8447b65fc 100644 --- a/pdns/dnsdistdist/dnsdist-lua-bindings-network.cc +++ b/pdns/dnsdistdist/dnsdist-lua-bindings-network.cc @@ -67,7 +67,7 @@ void setupLuaBindingsNetwork(LuaContext& luaCtx, bool client) return false; } - return listener->addUnixListeningEndpoint(path, endpointID, [cb](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) { + return listener->addUnixListeningEndpoint(path, endpointID, [cb = std::move(cb)](dnsdist::NetworkListener::EndpointID endpoint, std::string&& dgram, const std::string& from) { { auto lock = g_lua.lock(); cb(endpoint, dgram, from); diff --git a/pdns/dnsdistdist/dnsdist-lua-network.cc b/pdns/dnsdistdist/dnsdist-lua-network.cc index 68928880089f..ec477255ad41 100644 --- a/pdns/dnsdistdist/dnsdist-lua-network.cc +++ b/pdns/dnsdistdist/dnsdist-lua-network.cc @@ -113,7 +113,7 @@ bool NetworkListener::addUnixListeningEndpoint(const std::string& path, NetworkL auto cbData = std::make_shared(); cbData->d_endpoint = id; - cbData->d_cb = cb; + cbData->d_cb = std::move(cb); d_mplexer->addReadFD(sock.getHandle(), readCB, cbData); d_sockets.insert({path, std::move(sock)}); diff --git a/pdns/dnsdistdist/dnsdist-rules.hh b/pdns/dnsdistdist/dnsdist-rules.hh index 2457b2b56116..651911e4f800 100644 --- a/pdns/dnsdistdist/dnsdist-rules.hh +++ b/pdns/dnsdistdist/dnsdist-rules.hh @@ -1069,7 +1069,7 @@ private: class TagRule : public DNSRule { public: - TagRule(const std::string& tag, boost::optional value) : d_value(value), d_tag(tag) + TagRule(const std::string& tag, boost::optional value) : d_value(std::move(value)), d_tag(tag) { } bool matches(const DNSQuestion* dq) const override @@ -1318,7 +1318,7 @@ private: class ProxyProtocolValueRule : public DNSRule { public: - ProxyProtocolValueRule(uint8_t type, boost::optional value): d_value(value), d_type(type) + ProxyProtocolValueRule(uint8_t type, boost::optional value): d_value(std::move(value)), d_type(type) { } diff --git a/pdns/dnsdistdist/dnsdist-tcp.hh b/pdns/dnsdistdist/dnsdist-tcp.hh index 04fb37737413..ea25853e9c2e 100644 --- a/pdns/dnsdistdist/dnsdist-tcp.hh +++ b/pdns/dnsdistdist/dnsdist-tcp.hh @@ -122,7 +122,7 @@ struct TCPResponse : public TCPQuery } TCPResponse(PacketBuffer&& buffer, InternalQueryState&& state, std::shared_ptr conn, std::shared_ptr ds) : - TCPQuery(std::move(buffer), std::move(state)), d_connection(conn), d_ds(ds) + TCPQuery(std::move(buffer), std::move(state)), d_connection(std::move(conn)), d_ds(std::move(ds)) { if (d_buffer.size() >= sizeof(dnsheader)) { memcpy(&d_cleartextDH, reinterpret_cast(d_buffer.data()), sizeof(d_cleartextDH)); diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index 7f755793cedd..19fdb1663b1b 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -272,8 +272,8 @@ void MOADNSParser::init(bool query, const std::string_view& packet) dr.d_type=ah.d_type; dr.d_class=ah.d_class; - dr.d_name=name; - dr.d_clen=ah.d_clen; + dr.d_name = std::move(name); + dr.d_clen = ah.d_clen; if (query && !(d_qtype == QType::IXFR && dr.d_place == DNSResourceRecord::AUTHORITY && dr.d_type == QType::SOA) && // IXFR queries have a SOA in their AUTHORITY section diff --git a/pdns/libssl.cc b/pdns/libssl.cc index ea05a0278222..84610832a8d2 100644 --- a/pdns/libssl.cc +++ b/pdns/libssl.cc @@ -631,9 +631,9 @@ OpenSSLTLSTicketKeysRing::~OpenSSLTLSTicketKeysRing() { } -void OpenSSLTLSTicketKeysRing::addKey(std::shared_ptr newKey) +void OpenSSLTLSTicketKeysRing::addKey(std::shared_ptr&& newKey) { - d_ticketKeys.write_lock()->push_front(newKey); + d_ticketKeys.write_lock()->push_front(std::move(newKey)); } std::shared_ptr OpenSSLTLSTicketKeysRing::getEncryptionKey() @@ -665,7 +665,7 @@ void OpenSSLTLSTicketKeysRing::loadTicketsKeys(const std::string& keyFile) try { do { auto newKey = std::make_shared(file); - addKey(newKey); + addKey(std::move(newKey)); keyLoaded = true; } while (!file.fail()); @@ -683,7 +683,7 @@ void OpenSSLTLSTicketKeysRing::loadTicketsKeys(const std::string& keyFile) void OpenSSLTLSTicketKeysRing::rotateTicketsKey(time_t /* now */) { auto newKey = std::make_shared(); - addKey(newKey); + addKey(std::move(newKey)); } OpenSSLTLSTicketKey::OpenSSLTLSTicketKey() diff --git a/pdns/libssl.hh b/pdns/libssl.hh index fd5d90c0320d..a8c30bf25a6c 100644 --- a/pdns/libssl.hh +++ b/pdns/libssl.hh @@ -21,7 +21,7 @@ struct TLSCertKeyPair std::optional d_key; std::optional d_password; explicit TLSCertKeyPair(const std::string& cert, std::optional key = std::nullopt, std::optional password = std::nullopt): - d_cert(cert), d_key(key), d_password(password) { + d_cert(cert), d_key(std::move(key)), d_password(std::move(password)) { } }; @@ -113,7 +113,6 @@ class OpenSSLTLSTicketKeysRing public: OpenSSLTLSTicketKeysRing(size_t capacity); ~OpenSSLTLSTicketKeysRing(); - void addKey(std::shared_ptr newKey); std::shared_ptr getEncryptionKey(); std::shared_ptr getDecryptionKey(unsigned char name[TLS_TICKETS_KEY_NAME_SIZE], bool& activeKey); size_t getKeysCount(); @@ -121,6 +120,8 @@ public: void rotateTicketsKey(time_t now); private: + void addKey(std::shared_ptr&& newKey); + SharedLockGuarded > > d_ticketKeys; }; diff --git a/pdns/mplexer.hh b/pdns/mplexer.hh index 70b36d221f67..33f5066131de 100644 --- a/pdns/mplexer.hh +++ b/pdns/mplexer.hh @@ -106,7 +106,7 @@ public: } /* do the addition _after_ so the entry is not added if there is an error */ - accountingAddFD(d_readCallbacks, fd, toDo, parameter, ttd); + accountingAddFD(d_readCallbacks, fd, std::move(toDo), parameter, ttd); } //! Add an fd to the write watch list - currently an fd can only be on one list at a time! @@ -122,7 +122,7 @@ public: } /* do the addition _after_ so the entry is not added if there is an error */ - accountingAddFD(d_writeCallbacks, fd, toDo, parameter, ttd); + accountingAddFD(d_writeCallbacks, fd, std::move(toDo), parameter, ttd); } //! Remove an fd from the read watch list. You can't call this function on an fd that is closed already! @@ -185,14 +185,14 @@ public: { accountingRemoveFD(d_writeCallbacks, fd); this->alterFD(fd, EventKind::Write, EventKind::Read); - accountingAddFD(d_readCallbacks, fd, toDo, parameter, ttd); + accountingAddFD(d_readCallbacks, fd, std::move(toDo), parameter, ttd); } void alterFDToWrite(int fd, callbackfunc_t toDo, const funcparam_t& parameter = funcparam_t(), const struct timeval* ttd = nullptr) { accountingRemoveFD(d_readCallbacks, fd); this->alterFD(fd, EventKind::Read, EventKind::Write); - accountingAddFD(d_writeCallbacks, fd, toDo, parameter, ttd); + accountingAddFD(d_writeCallbacks, fd, std::move(toDo), parameter, ttd); } std::vector> getTimeouts(const struct timeval& tv, bool writes = false) @@ -282,7 +282,7 @@ protected: { Callback cb; cb.d_fd = fd; - cb.d_callback = toDo; + cb.d_callback = std::move(toDo); cb.d_parameter = parameter; memset(&cb.d_ttd, 0, sizeof(cb.d_ttd)); if (ttd) { diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index b75c3a97014e..64f330f464a3 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -79,7 +79,7 @@ class OpenSSLTLSConnection: public TLSConnection { public: /* server side connection */ - OpenSSLTLSConnection(int socket, const struct timeval& timeout, std::shared_ptr feContext): d_feContext(feContext), d_conn(std::unique_ptr(SSL_new(d_feContext->d_tlsCtx.get()), SSL_free)), d_timeout(timeout) + OpenSSLTLSConnection(int socket, const struct timeval& timeout, std::shared_ptr feContext): d_feContext(std::move(feContext)), d_conn(std::unique_ptr(SSL_new(d_feContext->d_tlsCtx.get()), SSL_free)), d_timeout(timeout) { d_socket = socket; @@ -1747,7 +1747,7 @@ class GnuTLSIOCtx: public TLSCtx auto newKey = std::make_shared(); { - *(d_ticketsKey.write_lock()) = newKey; + *(d_ticketsKey.write_lock()) = std::move(newKey); } if (d_ticketsKeyRotationDelay > 0) { @@ -1763,7 +1763,7 @@ class GnuTLSIOCtx: public TLSCtx auto newKey = std::make_shared(file); { - *(d_ticketsKey.write_lock()) = newKey; + *(d_ticketsKey.write_lock()) = std::move(newKey); } if (d_ticketsKeyRotationDelay > 0) { From ae71e4e236dd5e6f9bbd380a309442bf151746b9 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 22 Jun 2023 12:05:00 +0200 Subject: [PATCH 324/909] =?UTF-8?q?test-dnsname:=20Fix=20"unnecessary=20pa?= =?UTF-8?q?rentheses=20in=20declaration=20of=20=E2=80=98name5=E2=80=99"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pdns/test-dnsname_cc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/test-dnsname_cc.cc b/pdns/test-dnsname_cc.cc index 43c1b900ddf6..b3b442a46df6 100644 --- a/pdns/test-dnsname_cc.cc +++ b/pdns/test-dnsname_cc.cc @@ -1028,7 +1028,7 @@ BOOST_AUTO_TEST_CASE(test_getcommonlabels) { BOOST_CHECK_EQUAL(name3.getCommonLabels(name4), name3); BOOST_CHECK_EQUAL(name4.getCommonLabels(name3), name4); - const DNSName(name5); + const DNSName name5; BOOST_CHECK_EQUAL(name1.getCommonLabels(name5), DNSName()); BOOST_CHECK_EQUAL(name5.getCommonLabels(name1), DNSName()); } From d50646ca12820830929ae541e58b95cd2447fbef Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Wed, 21 Jun 2023 13:06:39 +0200 Subject: [PATCH 325/909] Print a message when clang-tidy fails --- .github/workflows/build-and-test-all.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 9c33fb83938c..7d2a75fd49e2 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -559,12 +559,15 @@ jobs: steps: - run: | if [ "x${{ needs.build-auth.outputs.clang-tidy-failed }}" != "x" -a "${{ needs.build-auth.outputs.clang-tidy-failed }}" != "0" ]; then + echo "::error::Auth clang-tidy failed" exit 1 fi - if [ "x${{ needs.build-dnsdist.outputs.clang-tidy-failed }}" != "x" -a "${{ needs.build-dnsdist.outputs.clang-tidy-failed }}" != "0" ]; then + if [ "x${{needs.build-recursor.outputs.clang-tidy-failed}}" != "x" -a "${{needs.build-recursor.outputs.clang-tidy-failed}}" != "0" ]; then + echo "::error::Rec clang-tidy failed" exit 1 fi - if [ "x${{needs.build-recursor.outputs.clang-tidy-failed}}" != "x" -a "${{needs.build-recursor.outputs.clang-tidy-failed}}" != "0" ]; then + if [ "x${{ needs.build-dnsdist.outputs.clang-tidy-failed }}" != "x" -a "${{ needs.build-dnsdist.outputs.clang-tidy-failed }}" != "0" ]; then + echo "::error::dnsdist clang-tidy failed" exit 1 fi From 302e630b412b3f5ae6aed9e20897f6ac24281a5b Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 22 Jun 2023 14:39:06 +0200 Subject: [PATCH 326/909] Fix clang-tidy-diff not finding module and ext files --- .github/scripts/git-filter.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/.github/scripts/git-filter.py b/.github/scripts/git-filter.py index 533111606d04..14033eb38eda 100755 --- a/.github/scripts/git-filter.py +++ b/.github/scripts/git-filter.py @@ -19,6 +19,8 @@ def main(): compdb = helpers.load_compdb("compile_commands.json") compdb = helpers.index_compdb(compdb) + pdns_path = os.path.join("pdns", "") + cwd = os.getcwd() root = helpers.get_repo_root() diff = sys.stdin.read() @@ -26,7 +28,29 @@ def main(): for patch in patch_set: path = os.path.join(root, patch.path) if path in compdb: + if not patch.path.startswith(pdns_path): + # If the file being diffed is not under the pdns/ directory, we + # need to reconstruct its filename in the patch adding extra + # paths that clang-tidy-diff will get rid of: this way + # clang-tidy can work with the correct file path. + # + # Example with a source file under modules/: + # patch.path = modules/foo/foo.cc + # path = /home/user/workspace/pdns/modules/foo/foo.cc + # cwd = /home/user/workspace/pdns/pdns/ + # relpath = ../modules/foo/foo.cc + # + # Then the patch filenames would be: + # patch.source_file = a/pdns/../modules/foo/foo.cc + # patch.target_file = b/pdns/../modules/foo/foo.cc + relpath = os.path.relpath(path, cwd) + if patch.source_file is not None: + patch.source_file = os.path.join("a", "pdns", relpath) + patch.target_file = os.path.join("b", "pdns", relpath) print(patch) + else: + msg = f"Skipping {path}: it is not in the compilation db" + print(msg, file=sys.stderr) return 0 From 38a9c77aa56da38599a003457d1b23dbcb4950fa Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 23 Jun 2023 15:01:05 +0200 Subject: [PATCH 327/909] dnsdist: Implement the AsynchronousHolder with the new channel feature --- pdns/channel.hh | 17 ++++---- pdns/dnsdistdist/dnsdist-async.cc | 67 ++++++------------------------- pdns/dnsdistdist/dnsdist-async.hh | 14 +++++-- 3 files changed, 32 insertions(+), 66 deletions(-) diff --git a/pdns/channel.hh b/pdns/channel.hh index 7beaa198d190..6947d3b26d4b 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -52,9 +52,7 @@ namespace channel class Sender { public: - Sender() - { - } + Sender() = default; Sender(FDWrapper&& descriptor) : d_fd(std::move(descriptor)) { @@ -63,6 +61,7 @@ namespace channel Sender& operator=(const Sender&) = delete; Sender(Sender&&) = default; Sender& operator=(Sender&&) = default; + ~Sender() = default; /** * \brief Try to send the supplied object to the other end of that channel. Might block if the channel was created in blocking mode. * @@ -86,9 +85,7 @@ namespace channel class Receiver { public: - Receiver() - { - } + Receiver() = default; Receiver(FDWrapper&& descriptor, bool throwOnEOF = true) : d_fd(std::move(descriptor)), d_throwOnEOF(throwOnEOF) { @@ -97,6 +94,7 @@ namespace channel Receiver& operator=(const Receiver&) = delete; Receiver(Receiver&&) = default; Receiver& operator=(Receiver&&) = default; + ~Receiver() = default; /** * \brief Try to read an object sent by the other end of that channel. Might block if the channel was created in blocking mode. * @@ -148,14 +146,13 @@ namespace channel class Notifier { public: - Notifier() - { - } + Notifier() = default; Notifier(FDWrapper&&); Notifier(const Notifier&) = delete; Notifier& operator=(const Notifier&) = delete; Notifier(Notifier&&) = default; Notifier& operator=(Notifier&&) = default; + ~Notifier() = default; /** * \brief Queue a notification to wake up the other end of the channel. @@ -178,11 +175,13 @@ namespace channel class Waiter { public: + Waiter() = default; Waiter(FDWrapper&&, bool throwOnEOF = true); Waiter(const Waiter&) = delete; Waiter& operator=(const Waiter&) = delete; Waiter(Waiter&&) = default; Waiter& operator=(Waiter&&) = default; + ~Waiter() = default; /** * \brief Clear all notifications queued on that channel, if any. diff --git a/pdns/dnsdistdist/dnsdist-async.cc b/pdns/dnsdistdist/dnsdist-async.cc index e1acef87a439..8c26b88449e1 100644 --- a/pdns/dnsdistdist/dnsdist-async.cc +++ b/pdns/dnsdistdist/dnsdist-async.cc @@ -27,28 +27,17 @@ namespace dnsdist { -AsynchronousHolder::AsynchronousHolder(bool failOpen) : - d_data(std::make_shared()) +AsynchronousHolder::Data::Data(bool failOpen) : + d_failOpen(failOpen) { - d_data->d_failOpen = failOpen; - - int fds[2] = {-1, -1}; - if (pipe(fds) < 0) { - throw std::runtime_error("Error creating the AsynchronousHolder pipe: " + stringerror()); - } - - for (size_t idx = 0; idx < (sizeof(fds) / sizeof(*fds)); idx++) { - if (!setNonBlocking(fds[idx])) { - int err = errno; - close(fds[0]); - close(fds[1]); - throw std::runtime_error("Error setting the AsynchronousHolder pipe non-blocking: " + stringerror(err)); - } - } - - d_data->d_notifyPipe = FDWrapper(fds[1]); - d_data->d_watchPipe = FDWrapper(fds[0]); + auto [notifier, waiter] = pdns::channel::createNotificationQueue(true); + d_waiter = std::move(waiter); + d_notifier = std::move(notifier); +} +AsynchronousHolder::AsynchronousHolder(bool failOpen) : + d_data(std::make_shared(failOpen)) +{ std::thread main([data = this->d_data] { mainThread(data); }); main.detach(); } @@ -64,25 +53,10 @@ AsynchronousHolder::~AsynchronousHolder() bool AsynchronousHolder::notify() const { - const char data = 0; - bool failed = false; - do { - auto written = write(d_data->d_notifyPipe.getHandle(), &data, sizeof(data)); - if (written == 0) { - break; - } - if (written > 0 && static_cast(written) == sizeof(data)) { - return true; - } - if (errno != EINTR) { - failed = true; - } - } while (!failed); - - return false; + return d_data->d_notifier.notify(); } -bool AsynchronousHolder::wait(const AsynchronousHolder::Data& data, FDMultiplexer& mplexer, std::vector& readyFDs, int atMostMs) +bool AsynchronousHolder::wait(AsynchronousHolder::Data& data, FDMultiplexer& mplexer, std::vector& readyFDs, int atMostMs) { readyFDs.clear(); mplexer.getAvailableFDs(readyFDs, atMostMs); @@ -91,22 +65,7 @@ bool AsynchronousHolder::wait(const AsynchronousHolder::Data& data, FDMultiplexe return true; } - while (true) { - /* we might have been notified several times, let's read - as much as possible before returning */ - char dummy = 0; - auto got = read(data.d_watchPipe.getHandle(), &dummy, sizeof(dummy)); - if (got == 0) { - break; - } - if (got > 0 && static_cast(got) != sizeof(dummy)) { - continue; - } - if (got == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) { - break; - } - } - + data.d_waiter.clear(); return false; } @@ -127,7 +86,7 @@ void AsynchronousHolder::mainThread(std::shared_ptr data) std::list>> expiredEvents; auto mplexer = std::unique_ptr(FDMultiplexer::getMultiplexerSilent(1)); - mplexer->addReadFD(data->d_watchPipe.getHandle(), [](int, FDMultiplexer::funcparam_t&) {}); + mplexer->addReadFD(data->d_waiter.getDescriptor(), [](int, FDMultiplexer::funcparam_t&) {}); std::vector readyFDs; while (true) { diff --git a/pdns/dnsdistdist/dnsdist-async.hh b/pdns/dnsdistdist/dnsdist-async.hh index 5a8c0908f59c..f6a0a97f0043 100644 --- a/pdns/dnsdistdist/dnsdist-async.hh +++ b/pdns/dnsdistdist/dnsdist-async.hh @@ -27,6 +27,7 @@ #include #include +#include "channel.hh" #include "dnsdist-tcp.hh" namespace dnsdist @@ -75,16 +76,23 @@ private: struct Data { + Data(bool failOpen); + Data(const Data&) = delete; + Data(Data&&) = delete; + Data& operator=(const Data&) = delete; + Data& operator=(Data&&) = delete; + ~Data() = default; + LockGuarded d_content; - FDWrapper d_notifyPipe; - FDWrapper d_watchPipe; + pdns::channel::Notifier d_notifier; + pdns::channel::Waiter d_waiter; bool d_failOpen{true}; bool d_done{false}; }; std::shared_ptr d_data{nullptr}; static void mainThread(std::shared_ptr data); - static bool wait(const Data& data, FDMultiplexer& mplexer, std::vector& readyFDs, int atMostMs); + static bool wait(Data& data, FDMultiplexer& mplexer, std::vector& readyFDs, int atMostMs); bool notify() const; }; From 13bdc4d9627dd28df025a5837ae84004f21cb023 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 23 Jun 2023 15:46:16 +0200 Subject: [PATCH 328/909] auth: Refactor the MultiThreadDistributor using pdns::channel --- pdns/distributor.hh | 120 +++++++++++++++++++++----------------------- 1 file changed, 58 insertions(+), 62 deletions(-) diff --git a/pdns/distributor.hh b/pdns/distributor.hh index 2f52454ac435..d021cfa0f71f 100644 --- a/pdns/distributor.hh +++ b/pdns/distributor.hh @@ -28,9 +28,10 @@ #include #include #include -#include #include "threadname.hh" #include + +#include "channel.hh" #include "logger.hh" #include "dns.hh" #include "dnsbackend.hh" @@ -117,15 +118,16 @@ public: } private: - int nextid; - time_t d_last_started; - unsigned int d_overloadQueueLength, d_maxQueueLength; - int d_num_threads; + std::vector> d_senders; + std::vector> d_receivers; + time_t d_last_started{0}; std::atomic d_queued{0}; - std::vector> d_pipes; + unsigned int d_overloadQueueLength{0}; + unsigned int d_maxQueueLength{0}; + int d_nextid{0}; + int d_num_threads{0}; }; -//template::nextid; template Distributor* Distributor::Create(int n) { if( n == 1 ) @@ -154,29 +156,24 @@ templateSingleThreadDistributorMultiThreadDistributor::MultiThreadDistributor(int n) +templateMultiThreadDistributor::MultiThreadDistributor(int numberOfThreads) : + d_last_started(time(nullptr)), d_overloadQueueLength(::arg().asNum("overload-queue-length")), d_maxQueueLength(::arg().asNum("max-queue-length")), d_num_threads(numberOfThreads) { - d_num_threads=n; - d_overloadQueueLength=::arg().asNum("overload-queue-length"); - d_maxQueueLength=::arg().asNum("max-queue-length"); - nextid=0; - d_last_started=time(0); - - for(int i=0; i < n; ++i) { - int fds[2]; - if(pipe(fds) < 0) - unixDie("Creating pipe"); - d_pipes.emplace_back(fds[0], fds[1]); - } - - if (n<1) { + if (numberOfThreads < 1) { g_log<(false, false); + d_senders.push_back(std::move(sender)); + d_receivers.push_back(std::move(receiver)); + } + + g_log<void MultiThreadDistributor setThreadName("pdns/distributo"); try { - std::unique_ptr b= make_unique(); // this will answer our questions - int queuetimeout=::arg().asNum("queue-limit"); + auto b = make_unique(); // this will answer our questions + int queuetimeout = ::arg().asNum("queue-limit"); + auto& receiver = d_receivers.at(ournum); - for(;;) { - - QuestionData* tempQD = nullptr; - if(read(d_pipes.at(ournum).first, &tempQD, sizeof(tempQD)) != sizeof(tempQD)) + for (;;) { + auto tempQD = receiver.receive(); + if (!tempQD) { unixDie("read"); + } --d_queued; - std::unique_ptr QD = std::unique_ptr(tempQD); - tempQD = nullptr; + auto questionData = std::move(*tempQD); std::unique_ptr a = nullptr; - - if(queuetimeout && QD->Q.d_dt.udiff()>queuetimeout*1000) { + if (queuetimeout && questionData->Q.d_dt.udiff() > queuetimeout * 1000) { S.inc("timedout-packets"); continue; - } + } - bool allowRetry=true; + bool allowRetry = true; retry: // this is the only point where we interact with the backend (synchronous) try { if (!b) { - allowRetry=false; - b=make_unique(); + allowRetry = false; + b = make_unique(); } - a=b->question(QD->Q); + a = b->question(questionData->Q); } - catch(const PDNSException &e) { + catch (const PDNSException &e) { b.reset(); if (!allowRetry) { g_log<Q.replyPacket(); + a = questionData->Q.replyPacket(); a->setRcode(RCode::ServFail); S.inc("servfail-packets"); - S.ringAccount("servfail-queries", QD->Q.qdomain, QD->Q.qtype); + S.ringAccount("servfail-queries", questionData->Q.qdomain, questionData->Q.qtype); } else { g_log<Q.replyPacket(); + g_log<Q.replyPacket(); a->setRcode(RCode::ServFail); S.inc("servfail-packets"); - S.ringAccount("servfail-queries", QD->Q.qdomain, QD->Q.qtype); + S.ringAccount("servfail-queries", questionData->Q.qdomain, questionData->Q.qtype); } else { - g_log<callback(a, QD->start); + questionData->callback(a, questionData->start); #ifdef ENABLE_GSS_TSIG if (g_doGssTSIG && a != nullptr) { - QD->Q.cleanupGSS(a->d.rcode); + questionData->Q.cleanupGSS(a->d.rcode); } #endif - QD.reset(); + questionData.reset(); } b.reset(); } - catch(const PDNSException &AE) { + catch (const PDNSException &AE) { g_log<setRcode(RCode::ServFail); S.inc("servfail-packets"); S.ringAccount("servfail-queries", q.qdomain, q.qtype); } else { - g_log<int MultiThreadDistributor::question(Question& q, callback_t callback) { // this is passed to other process over pipe and released there - auto QD=new QuestionData(q); - auto ret = QD->id = nextid++; // might be deleted after write! - QD->callback=callback; + auto questionData = std::make_unique(q); + auto ret = questionData->id = d_nextid++; // might be deleted after write! + questionData->callback = callback; ++d_queued; - if(write(d_pipes.at(QD->id % d_pipes.size()).second, &QD, sizeof(QD)) != sizeof(QD)) { + if (!d_senders.at(questionData->id % d_senders.size()).send(std::move(questionData))) { --d_queued; - delete QD; + questionData.reset(); unixDie("write"); } - if(d_queued > d_maxQueueLength) { + if (d_queued > d_maxQueueLength) { g_log< Date: Fri, 23 Jun 2023 16:18:56 +0200 Subject: [PATCH 329/909] dnsdist: Delint dnsdist-async.{cc,hh} --- pdns/dnsdistdist/dnsdist-async.cc | 83 ++++++++++++++++++------------- pdns/dnsdistdist/dnsdist-async.hh | 4 +- 2 files changed, 51 insertions(+), 36 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-async.cc b/pdns/dnsdistdist/dnsdist-async.cc index 8c26b88449e1..19426468df74 100644 --- a/pdns/dnsdistdist/dnsdist-async.cc +++ b/pdns/dnsdistdist/dnsdist-async.cc @@ -31,7 +31,9 @@ AsynchronousHolder::Data::Data(bool failOpen) : d_failOpen(failOpen) { auto [notifier, waiter] = pdns::channel::createNotificationQueue(true); + // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer): how I am supposed to do that? d_waiter = std::move(waiter); + // NOLINTNEXTLINE(cppcoreguidelines-prefer-member-initializer): how I am supposed to do that? d_notifier = std::move(notifier); } @@ -60,7 +62,7 @@ bool AsynchronousHolder::wait(AsynchronousHolder::Data& data, FDMultiplexer& mpl { readyFDs.clear(); mplexer.getAvailableFDs(readyFDs, atMostMs); - if (readyFDs.size() == 0) { + if (readyFDs.empty()) { /* timeout */ return true; } @@ -79,10 +81,13 @@ void AsynchronousHolder::stop() notify(); } +// NOLINTNEXTLINE(performance-unnecessary-value-param): this is a long-lived thread, and we want to make sure the reference count of the shared pointer has been increased void AsynchronousHolder::mainThread(std::shared_ptr data) { setThreadName("dnsdist/async"); - struct timeval now; + struct timeval now + { + }; std::list>> expiredEvents; auto mplexer = std::unique_ptr(FDMultiplexer::getMultiplexerSilent(1)); @@ -107,7 +112,7 @@ void AsynchronousHolder::mainThread(std::shared_ptr data) } else { auto remainingUsec = uSec(next - now); - timeout = std::round(remainingUsec / 1000.0); + timeout = static_cast(std::round(static_cast(remainingUsec) / 1000.0)); if (timeout == 0 && remainingUsec > 0) { /* if we have less than 1 ms, let's wait at least 1 ms */ timeout = 1; @@ -172,25 +177,27 @@ std::unique_ptr AsynchronousHolder::get(uint16_t asyncID, ui { /* no need to notify, worst case the thread wakes up for nothing because this was the next TTD */ auto content = d_data->d_content.lock(); - auto it = content->find(std::tie(queryID, asyncID)); - if (it == content->end()) { - struct timeval now; + auto contentIt = content->find(std::tie(queryID, asyncID)); + if (contentIt == content->end()) { + struct timeval now + { + }; gettimeofday(&now, nullptr); vinfolog("Asynchronous object %d not found at %d.%d", queryID, now.tv_sec, now.tv_usec); return nullptr; } - auto result = std::move(it->d_query); - content->erase(it); + auto result = std::move(contentIt->d_query); + content->erase(contentIt); return result; } void AsynchronousHolder::pickupExpired(content_t& content, const struct timeval& now, std::list>>& events) { auto& idx = content.get(); - for (auto it = idx.begin(); it != idx.end() && it->d_ttd < now;) { - events.emplace_back(it->d_queryID, std::move(it->d_query)); - it = idx.erase(it); + for (auto contentIt = idx.begin(); contentIt != idx.end() && contentIt->d_ttd < now;) { + events.emplace_back(contentIt->d_queryID, std::move(contentIt->d_query)); + contentIt = idx.erase(contentIt); } } @@ -212,10 +219,10 @@ static bool resumeResponse(std::unique_ptr&& response) { try { auto& ids = response->query.d_idstate; - DNSResponse dr = response->getDR(); + DNSResponse dnsResponse = response->getDR(); LocalHolders holders; - auto result = processResponseAfterRules(response->query.d_buffer, *holders.cacheInsertedRespRuleActions, dr, ids.cs->muted); + auto result = processResponseAfterRules(response->query.d_buffer, *holders.cacheInsertedRespRuleActions, dnsResponse, ids.cs->muted); if (!result) { /* easy */ return true; @@ -223,7 +230,9 @@ static bool resumeResponse(std::unique_ptr&& response) auto sender = response->getTCPQuerySender(); if (sender) { - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); TCPResponse resp(std::move(response->query.d_buffer), std::move(response->query.d_idstate), nullptr, response->downstream); @@ -274,43 +283,45 @@ bool resumeQuery(std::unique_ptr&& query) } auto& ids = query->query.d_idstate; - DNSQuestion dq = query->getDQ(); + DNSQuestion dnsQuestion = query->getDQ(); LocalHolders holders; - auto result = processQueryAfterRules(dq, holders, query->downstream); + auto result = processQueryAfterRules(dnsQuestion, holders, query->downstream); if (result == ProcessQueryResult::Drop) { /* easy */ return true; } - else if (result == ProcessQueryResult::PassToBackend) { + if (result == ProcessQueryResult::PassToBackend) { if (query->downstream == nullptr) { return false; } #ifdef HAVE_DNS_OVER_HTTPS - if (dq.ids.du != nullptr) { - dq.ids.du->downstream = query->downstream; + if (dnsQuestion.ids.du != nullptr) { + dnsQuestion.ids.du->downstream = query->downstream; } #endif - if (query->downstream->isTCPOnly() || !(dq.getProtocol().isUDP() || dq.getProtocol() == dnsdist::Protocol::DoH)) { + if (query->downstream->isTCPOnly() || !(dnsQuestion.getProtocol().isUDP() || dnsQuestion.getProtocol() == dnsdist::Protocol::DoH)) { query->downstream->passCrossProtocolQuery(std::move(query)); return true; } - auto queryID = dq.getHeader()->id; + auto queryID = dnsQuestion.getHeader()->id; /* at this point 'du', if it is not nullptr, is owned by the DoHCrossProtocolQuery which will stop existing when we return, so we need to increment the reference count */ - return assignOutgoingUDPQueryToBackend(query->downstream, queryID, dq, query->query.d_buffer, ids.origDest); + return assignOutgoingUDPQueryToBackend(query->downstream, queryID, dnsQuestion, query->query.d_buffer, ids.origDest); } - else if (result == ProcessQueryResult::SendAnswer) { + if (result == ProcessQueryResult::SendAnswer) { auto sender = query->getTCPQuerySender(); if (!sender) { return false; } - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); TCPResponse response(std::move(query->query.d_buffer), std::move(query->query.d_idstate), nullptr, query->downstream); @@ -326,7 +337,7 @@ bool resumeQuery(std::unique_ptr&& query) return false; } } - else if (result == ProcessQueryResult::Asynchronous) { + if (result == ProcessQueryResult::Asynchronous) { /* nope */ errlog("processQueryAfterRules returned 'asynchronous' while trying to resume an already asynchronous query"); return false; @@ -335,43 +346,47 @@ bool resumeQuery(std::unique_ptr&& query) return false; } -bool suspendQuery(DNSQuestion& dq, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) +bool suspendQuery(DNSQuestion& dnsQuestion, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) { if (!g_asyncHolder) { return false; } - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); struct timeval ttd = now; ttd.tv_sec += timeoutMs / 1000; - ttd.tv_usec += (timeoutMs % 1000) * 1000; + ttd.tv_usec += static_cast((timeoutMs % 1000) * 1000); normalizeTV(ttd); vinfolog("Suspending asynchronous query %d at %d.%d until %d.%d", queryID, now.tv_sec, now.tv_usec, ttd.tv_sec, ttd.tv_usec); - auto query = getInternalQueryFromDQ(dq, false); + auto query = getInternalQueryFromDQ(dnsQuestion, false); g_asyncHolder->push(asyncID, queryID, ttd, std::move(query)); return true; } -bool suspendResponse(DNSResponse& dr, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) +bool suspendResponse(DNSResponse& dnsResponse, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs) { if (!g_asyncHolder) { return false; } - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); struct timeval ttd = now; ttd.tv_sec += timeoutMs / 1000; - ttd.tv_usec += (timeoutMs % 1000) * 1000; + ttd.tv_usec += static_cast((timeoutMs % 1000) * 1000); normalizeTV(ttd); vinfolog("Suspending asynchronous response %d at %d.%d until %d.%d", queryID, now.tv_sec, now.tv_usec, ttd.tv_sec, ttd.tv_usec); - auto query = getInternalQueryFromDQ(dr, true); + auto query = getInternalQueryFromDQ(dnsResponse, true); query->d_isResponse = true; - query->downstream = dr.d_downstream; + query->downstream = dnsResponse.d_downstream; g_asyncHolder->push(asyncID, queryID, ttd, std::move(query)); return true; diff --git a/pdns/dnsdistdist/dnsdist-async.hh b/pdns/dnsdistdist/dnsdist-async.hh index f6a0a97f0043..c0b8453ae6be 100644 --- a/pdns/dnsdistdist/dnsdist-async.hh +++ b/pdns/dnsdistdist/dnsdist-async.hh @@ -96,8 +96,8 @@ private: bool notify() const; }; -bool suspendQuery(DNSQuestion& dq, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs); -bool suspendResponse(DNSResponse& dr, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs); +bool suspendQuery(DNSQuestion& dnsQuestion, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs); +bool suspendResponse(DNSResponse& dnsResponse, uint16_t asyncID, uint16_t queryID, uint32_t timeoutMs); bool queueQueryResumptionEvent(std::unique_ptr&& query); bool resumeQuery(std::unique_ptr&& query); void handleQueuedAsynchronousEvents(); From 6f2ca0713c031fae7ec897b292c19ca2760b69d5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 26 Jun 2023 10:36:11 +0200 Subject: [PATCH 330/909] dnsdist: Fix setRandomizedOutgoingSockets not showing up in the search Also add a link to it from newServer's 'sockets' parameter, which is related. --- pdns/dnsdistdist/docs/reference/config.rst | 2 +- pdns/dnsdistdist/docs/reference/tuning.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index b64893698688..03fb56b3820e 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -605,7 +605,7 @@ Servers -- "address@interface", e.g. "192.0.2.2@eth0" addXPF=NUM, -- Add the client's IP address and port to the query, along with the original destination address and port, -- using the experimental XPF record from `draft-bellis-dnsop-xpf `_ and the specified option code. Default is disabled (0). This is a deprecated feature that will be removed in the near future. - sockets=NUM, -- Number of UDP sockets (and thus source ports) used toward the backend server, defaults to a single one. Note that for backends which are multithreaded, this setting will have an effect on the number of cores that will be used to process traffic from dnsdist. For example you may want to set 'sockets' to a number somewhat higher than the number of worker threads configured in the backend, particularly if the Linux kernel is being used to distribute traffic to multiple threads listening on the same socket (via `reuseport`). + sockets=NUM, -- Number of UDP sockets (and thus source ports) used toward the backend server, defaults to a single one. Note that for backends which are multithreaded, this setting will have an effect on the number of cores that will be used to process traffic from dnsdist. For example you may want to set 'sockets' to a number somewhat higher than the number of worker threads configured in the backend, particularly if the Linux kernel is being used to distribute traffic to multiple threads listening on the same socket (via `reuseport`). See also :func:`setRandomizedOutgoingSockets`. disableZeroScope=BOOL, -- Disable the EDNS Client Subnet 'zero scope' feature, which does a cache lookup for an answer valid for all subnets (ECS scope of 0) before adding ECS information to the query and doing the regular lookup. This requires the ``parseECS`` option of the corresponding cache to be set to true rise=NUM, -- Require NUM consecutive successful checks before declaring the backend up, default: 1 useProxyProtocol=BOOL, -- Add a proxy protocol header to the query, passing along the client's IP address and port along with the original destination address and port. Default is disabled. diff --git a/pdns/dnsdistdist/docs/reference/tuning.rst b/pdns/dnsdistdist/docs/reference/tuning.rst index 1d7a90b2547e..d00b14feb073 100644 --- a/pdns/dnsdistdist/docs/reference/tuning.rst +++ b/pdns/dnsdistdist/docs/reference/tuning.rst @@ -134,7 +134,7 @@ Tuning related functions See also :func:`setRandomizedOutgoingSockets`. The default is to use a linearly increasing counter from 0 to 65535, wrapping back to 0 when necessary. -.. function:: setRandomizedOutgoingSockets(val): +.. function:: setRandomizedOutgoingSockets(val) .. versionadded:: 1.8.0 From 1527b7adef9d2970fbe2682027702a4fa6555ecd Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 27 Jun 2023 10:22:55 +0200 Subject: [PATCH 331/909] rec: give advice on a typical dnsdist-recursor setup with the new defaults --- pdns/recursordist/docs/performance.rst | 27 ++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/docs/performance.rst b/pdns/recursordist/docs/performance.rst index 3834a68eaf2b..5ab0ea07f366 100644 --- a/pdns/recursordist/docs/performance.rst +++ b/pdns/recursordist/docs/performance.rst @@ -32,9 +32,32 @@ This prevents a single thread from having to handle every incoming queries, but If ``SO_REUSEPORT`` support is available and :ref:`setting-reuseport` is set to ``yes``, which is the default since version 4.9.0, separate listening sockets are opened for each worker thread and the query distributions is handled by the kernel, avoiding any thundering herd issue as well as preventing the distributor thread from becoming the bottleneck. +The next section discusses how to determine if the mechanism is working properly. -On some systems setting :ref:`setting-reuseport` to ``yes`` does not have the desired effect. -If your systems shows imbalance in the number of queries processed per thread (as reported by the periodic statistics report), try switching :ref:`setting-reuseport` to ``no`` and/or setting :ref:`setting-pdns-distributes-queries` to ``yes``. +Imbalance +^^^^^^^^^ +Due to the nature of the distribution method used by the kernel imbalance with the new default settings of :ref:`setting-reuseport` and :ref:`setting-pdns-distributes-queries` may occur if you have very few clients. +Imbalance can be observed by reading the periodic statistics reported by :program:`Recursor`:: + + Jun 26 11:06:41 pepper pdns-recursor[10502]: msg="Queries handled by thread" subsystem="stats" level="0" prio="Info" tid="0" ts="1687770401.359" count="7" thread="0" + Jun 26 11:06:41 pepper pdns-recursor[10502]: msg="Queries handled by thread" subsystem=" stats" level="0" prio="Info" tid="0" ts="1687770401.359" count="535167" thread="1" + Jun 26 11:06:41 pepper pdns-recursor[10502]: msg="Queries handled by thread" subsystem=" stats" level="0" prio="Info" tid="0" ts="1687770401.359" count="5" thread="2" + +In the above log lines we see that almost all queries are processed by thread 1. +This can typically be observed when using ``dnsdist`` in front of :program:`Recursor`. + +When using ``dnsdist`` with a single ``newServer`` to a recursor instance in its configuration, the kernel will regard ``dnsdist`` as a single client unless you use the ``sockets`` parameter to ``newServer`` to increase the number of source ports used by ``dnsdist``. +The following guideline applies for the ``dnsdist`` case: + +- Be generous with the ``sockets`` setting of ``newServer``. + A starting points is to configure twice as many sockets as :program:`Recursor` threads. +- As long as the threads of the :program:`Recursor` as not overloaded, some imbalance will not impact performance significantly. +- If you want to reduce imbalance, increase the value of ``sockets`` even more. + +Non-Linux systems +^^^^^^^^^^^^^^^^^ +On some systems setting :ref:`setting-reuseport` to ``yes`` does not have the desired effect at all. +If your systems shows great imbalance in the number of queries processed per thread (as reported by the periodic statistics report), try switching :ref:`setting-reuseport` to ``no`` and/or setting :ref:`setting-pdns-distributes-queries` to ``yes``. .. versionadded:: 4.1.0 The :ref:`setting-cpu-map` parameter can be used to pin worker threads to specific CPUs, in order to keep caches as warm as possible and optimize memory access on NUMA systems. From 645b217bdf671b1841c6eb6a9f7146f65383a051 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 27 Jun 2023 11:08:20 +0200 Subject: [PATCH 332/909] rec: fix a set of move optimizations, as suggested by coverity --- pdns/recursordist/logging.cc | 6 +++--- pdns/recursordist/rec-main.hh | 4 ++-- pdns/recursordist/rec_channel_rec.cc | 22 +++++++++++----------- pdns/recursordist/reczones-helpers.cc | 6 +++--- pdns/recursordist/reczones.cc | 2 +- pdns/recursordist/syncres.cc | 12 ++++++------ pdns/recursordist/syncres.hh | 14 +++++++------- 7 files changed, 33 insertions(+), 33 deletions(-) diff --git a/pdns/recursordist/logging.cc b/pdns/recursordist/logging.cc index 5cfef1752c0d..42c1d2a20d33 100644 --- a/pdns/recursordist/logging.cc +++ b/pdns/recursordist/logging.cc @@ -49,7 +49,7 @@ void Logger::info(Logr::Priority p, const std::string& msg) const void Logger::logMessage(const std::string& msg, boost::optional err) const { - return logMessage(msg, Logr::Absent, err); + return logMessage(msg, Logr::Absent, std::move(err)); } void Logger::logMessage(const std::string& msg, Logr::Priority p, boost::optional err) const @@ -142,11 +142,11 @@ Logger::Logger(EntryLogger callback) : { } Logger::Logger(EntryLogger callback, boost::optional name) : - _callback(callback), _name(name) + _callback(callback), _name(std::move(name)) { } Logger::Logger(std::shared_ptr parent, boost::optional name, size_t verbosity, size_t lvl, EntryLogger callback) : - _parent(parent), _callback(callback), _name(name), _level(lvl), _verbosity(verbosity) + _parent(std::move(parent)), _callback(callback), _name(std::move(name)), _level(lvl), _verbosity(verbosity) { } diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index e84a89e9d508..303306837f51 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -54,12 +54,12 @@ extern std::shared_ptr g_slogudpin; struct DNSComboWriter { DNSComboWriter(const std::string& query, const struct timeval& now, shared_ptr luaContext) : - d_mdp(true, query), d_now(now), d_query(query), d_luaContext(luaContext) + d_mdp(true, query), d_now(now), d_query(query), d_luaContext(std::move(luaContext)) { } DNSComboWriter(const std::string& query, const struct timeval& now, std::unordered_set&& policyTags, shared_ptr luaContext, LuaContext::LuaObject&& data, std::vector&& records) : - d_mdp(true, query), d_now(now), d_query(query), d_policyTags(std::move(policyTags)), d_records(std::move(records)), d_luaContext(luaContext), d_data(std::move(data)) + d_mdp(true, query), d_now(now), d_query(query), d_policyTags(std::move(policyTags)), d_records(std::move(records)), d_luaContext(std::move(luaContext)), d_data(std::move(data)) { } diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index a91dea3cd8c6..34305559f546 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -117,12 +117,12 @@ static void addGetStat(const string& name, const pdns::stat_t* place) static void addGetStat(const string& name, std::function f) { - d_get64bitmembers[name] = f; + d_get64bitmembers[name] = std::move(f); } static void addGetStat(const string& name, std::function f) { - d_getmultimembers[name] = f; + d_getmultimembers[name] = std::move(f); } static std::string getPrometheusName(const std::string& arg) @@ -1094,7 +1094,7 @@ static StatsMap toStatsMap(const string& name, const pdns::Histogram& histogram) for (const auto& bucket : data) { snprintf(buf, sizeof(buf), "%g", bucket.d_boundary / 1e6); std::string pname = pbasename + "seconds_bucket{" + "le=\"" + (bucket.d_boundary == std::numeric_limits::max() ? "+Inf" : buf) + "\"}"; - entries.emplace(bucket.d_name, StatsMapEntry{pname, std::to_string(bucket.d_count)}); + entries.emplace(bucket.d_name, StatsMapEntry{std::move(pname), std::to_string(bucket.d_count)}); } snprintf(buf, sizeof(buf), "%g", histogram.getSum() / 1e6); @@ -1144,7 +1144,7 @@ static StatsMap toAuthRCodeStatsMap(const string& name) for (const auto& entry : rcodes) { const auto key = RCode::to_short_s(n); std::string pname = pbasename + "{rcode=\"" + key + "\"}"; - entries.emplace("auth-" + key + "-answers", StatsMapEntry{pname, std::to_string(entry)}); + entries.emplace("auth-" + key + "-answers", StatsMapEntry{std::move(pname), std::to_string(entry)}); n++; } return entries; @@ -1159,7 +1159,7 @@ static StatsMap toCPUStatsMap(const string& name) for (unsigned int n = 0; n < RecThreadInfo::numDistributors() + RecThreadInfo::numWorkers(); ++n) { uint64_t tm = doGetThreadCPUMsec(n); std::string pname = pbasename + "{thread=\"" + std::to_string(n) + "\"}"; - entries.emplace(name + "-thread-" + std::to_string(n), StatsMapEntry{pname, std::to_string(tm)}); + entries.emplace(name + "-thread-" + std::to_string(n), StatsMapEntry{std::move(pname), std::to_string(tm)}); } return entries; } @@ -1200,10 +1200,10 @@ static StatsMap toProxyMappingStatsMap(const string& name) auto keyname = pbasename + "{netmask=\"" + key.toString() + "\",count=\""; auto sname1 = name + "-n-" + std::to_string(count); auto pname1 = keyname + "netmaskmatches\"}"; - entries.emplace(sname1, StatsMapEntry{pname1, std::to_string(entry.netmaskMatches)}); + entries.emplace(sname1, StatsMapEntry{std::move(pname1), std::to_string(entry.netmaskMatches)}); auto sname2 = name + "-s-" + std::to_string(count); auto pname2 = keyname + "suffixmatches\"}"; - entries.emplace(sname2, StatsMapEntry{pname2, std::to_string(entry.suffixMatches)}); + entries.emplace(sname2, StatsMapEntry{std::move(pname2), std::to_string(entry.suffixMatches)}); count++; } return entries; @@ -1231,16 +1231,16 @@ static StatsMap toRemoteLoggerStatsMap(const string& name) auto keyname = pbasename + "{address=\"" + key + "\",type=\"" + type + "\",count=\""; auto sname1 = name + "-q-" + std::to_string(count); auto pname1 = keyname + "queued\"}"; - entries.emplace(sname1, StatsMapEntry{pname1, std::to_string(entry.d_queued)}); + entries.emplace(sname1, StatsMapEntry{std::move(pname1), std::to_string(entry.d_queued)}); auto sname2 = name + "-p-" + std::to_string(count); auto pname2 = keyname + "pipeFull\"}"; - entries.emplace(sname2, StatsMapEntry{pname2, std::to_string(entry.d_pipeFull)}); + entries.emplace(sname2, StatsMapEntry{std::move(pname2), std::to_string(entry.d_pipeFull)}); auto sname3 = name + "-t-" + std::to_string(count); auto pname3 = keyname + "tooLarge\"}"; - entries.emplace(sname3, StatsMapEntry{pname3, std::to_string(entry.d_tooLarge)}); + entries.emplace(sname3, StatsMapEntry{std::move(pname3), std::to_string(entry.d_tooLarge)}); auto sname4 = name + "-o-" + std::to_string(count); auto pname4 = keyname + "otherError\"}"; - entries.emplace(sname4, StatsMapEntry{pname4, std::to_string(entry.d_otherError)}); + entries.emplace(sname4, StatsMapEntry{std::move(pname4), std::to_string(entry.d_otherError)}); ++count; } } diff --git a/pdns/recursordist/reczones-helpers.cc b/pdns/recursordist/reczones-helpers.cc index 721a8d2e7db4..dd82ee3d034d 100644 --- a/pdns/recursordist/reczones-helpers.cc +++ b/pdns/recursordist/reczones-helpers.cc @@ -191,7 +191,7 @@ static SyncRes::AuthDomain makeSOAAndNSNodes(DNSRecord& dr, T content) static void addToDomainMap(SyncRes::domainmap_t& newMap, SyncRes::AuthDomain ad, - DNSName& name, + const DNSName& name, Logr::log_t log, const bool partial = false, const bool reverse = false) @@ -250,7 +250,7 @@ static void makeIPToNamesZone(SyncRes::domainmap_t& newMap, dr.setContent(DNSRecordContent::mastermake(QType::PTR, 1, DNSName(canonicalHostname).toString())); ad.d_records.insert(dr); - addToDomainMap(newMap, ad, dr.d_name, log, false, true); + addToDomainMap(newMap, std::move(ad), dr.d_name, log, false, true); } void makePartialIPZone(SyncRes::domainmap_t& newMap, @@ -266,7 +266,7 @@ void makePartialIPZone(SyncRes::domainmap_t& newMap, SyncRes::AuthDomain ad = makeSOAAndNSNodes(dr, DNSName("localhost.")); - addToDomainMap(newMap, ad, dr.d_name, log, true, true); + addToDomainMap(newMap, std::move(ad), dr.d_name, log, true, true); } void addForwardAndReverseLookupEntries(SyncRes::domainmap_t& newMap, diff --git a/pdns/recursordist/reczones.cc b/pdns/recursordist/reczones.cc index 389dcaee1c0e..907a89fbe4b0 100644 --- a/pdns/recursordist/reczones.cc +++ b/pdns/recursordist/reczones.cc @@ -100,7 +100,7 @@ static void convertServersForAD(const std::string& zone, const std::string& inpu static void* pleaseUseNewSDomainsMap(std::shared_ptr newmap) { - SyncRes::setDomainMap(newmap); + SyncRes::setDomainMap(std::move(newmap)); return 0; } diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 69584cd10140..2de8e592b8f3 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -324,7 +324,7 @@ static LockGuarded>> s_throttl struct SavedParentEntry { SavedParentEntry(const DNSName& name, map>&& nsAddresses, time_t ttd) : - d_domain(name), d_nsAddresses(nsAddresses), d_ttd(ttd) + d_domain(name), d_nsAddresses(std::move(nsAddresses)), d_ttd(ttd) { } DNSName d_domain; @@ -1779,7 +1779,7 @@ int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector& ret, shared_ptr pdl, Logr::log_t log) +int directResolve(const DNSName& qname, const QType qtype, const QClass qclass, vector& ret, const shared_ptr& pdl, Logr::log_t log) { return directResolve(qname, qtype, qclass, ret, pdl, SyncRes::s_qnameminimization, log); } -int directResolve(const DNSName& qname, const QType qtype, const QClass qclass, vector& ret, shared_ptr pdl, bool qm, Logr::log_t slog) +int directResolve(const DNSName& qname, const QType qtype, const QClass qclass, vector& ret, const shared_ptr& pdl, bool qnamemin, Logr::log_t slog) { auto log = slog->withValues("qname", Logging::Loggable(qname), "qtype", Logging::Loggable(qtype)); @@ -5848,7 +5848,7 @@ int directResolve(const DNSName& qname, const QType qtype, const QClass qclass, gettimeofday(&now, 0); SyncRes sr(now); - sr.setQNameMinimization(qm); + sr.setQNameMinimization(qnamemin); if (pdl) { sr.setLuaEngine(pdl); } @@ -5898,7 +5898,7 @@ int SyncRes::getRootNS(struct timeval now, asyncresolve_t asyncCallback, unsigne sr.setUpdatingRootNS(); sr.setDoDNSSEC(g_dnssecmode != DNSSECMode::Off); sr.setDNSSECValidationRequested(g_dnssecmode != DNSSECMode::Off && g_dnssecmode != DNSSECMode::ProcessNoValidate); - sr.setAsyncCallback(asyncCallback); + sr.setAsyncCallback(std::move(asyncCallback)); sr.setRefreshAlmostExpired(true); const string msg = "Failed to update . records"; diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 2b3a3082d112..38d823d686b8 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -282,7 +282,7 @@ public: static void setDomainMap(std::shared_ptr newMap) { - t_sstorage.domainmap = newMap; + t_sstorage.domainmap = std::move(newMap); } static const std::shared_ptr getDomainMap() { @@ -417,7 +417,7 @@ public: void setLuaEngine(shared_ptr pdl) { - d_pdl = pdl; + d_pdl = std::move(pdl); } bool wasVariable() const @@ -463,7 +463,7 @@ public: void setAsyncCallback(asyncresolve_t func) { - d_asyncResolve = func; + d_asyncResolve = std::move(func); } vState getValidationState() const @@ -873,8 +873,8 @@ private: class ImmediateServFailException { public: - ImmediateServFailException(string r) : - reason(r){}; + ImmediateServFailException(string reason_) : + reason(std::move(reason_)){}; string reason; //! Print this to tell the user what went wrong }; @@ -907,8 +907,8 @@ typedef std::function pipefunc_t; void broadcastFunction(const pipefunc_t& func); void distributeAsyncFunction(const std::string& question, const pipefunc_t& func); -int directResolve(const DNSName& qname, const QType qtype, const QClass qclass, vector& ret, shared_ptr pdl, Logr::log_t); -int directResolve(const DNSName& qname, const QType qtype, const QClass qclass, vector& ret, shared_ptr pdl, bool qm, Logr::log_t); +int directResolve(const DNSName& qname, QType qtype, QClass qclass, vector& ret, const shared_ptr& pdl, Logr::log_t); +int directResolve(const DNSName& qname, QType qtype, QClass qclass, vector& ret, const shared_ptr& pdl, bool qnamemin, Logr::log_t); int followCNAMERecords(std::vector& ret, const QType qtype, int oldret); int getFakeAAAARecords(const DNSName& qname, ComboAddress prefix, vector& ret); int getFakePTRRecords(const DNSName& qname, vector& ret); From b41140cf7520d472740988d59c755ffbc7b550a3 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 16 Feb 2023 11:26:42 +0100 Subject: [PATCH 333/909] Builder-dispatch: Generate provenance for built artifacts --- .github/workflows/builder-dispatch.yml | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/.github/workflows/builder-dispatch.yml b/.github/workflows/builder-dispatch.yml index 4db7f7e46f11..538e4e35111b 100644 --- a/.github/workflows/builder-dispatch.yml +++ b/.github/workflows/builder-dispatch.yml @@ -60,6 +60,8 @@ jobs: matrix: os: ${{fromJson(needs.prepare.outputs.oslist)}} fail-fast: false + outputs: + hashes: ${{ steps.hash.outputs.hashes }} steps: - uses: actions/checkout@v3 with: @@ -77,16 +79,33 @@ jobs: name: ${{ github.event.inputs.product }}-${{ matrix.os }}-${{ steps.getversion.outputs.version }} path: built_pkgs/ retention-days: 7 + - name: Generate hashes for provenance + shell: bash + id: hash + run: | + echo "hashes=$(sha256sum ./built_pkgs/*/*/* | base64 -w0)" >> $GITHUB_OUTPUT - name: Upload packages to downloads.powerdns.com env: SSHKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} RSYNCTARGET: ${{ secrets.DOWNLOADS_AUTOBUILT_RSYNCTARGET }} HOSTKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_HOSTKEY }} if: - "${{ env.SSHKEY != '' }}" + "${{ env.SSHKEY != '' }}" run: | mkdir -m 700 -p ~/.ssh echo "$SSHKEY" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 echo "$HOSTKEY" > ~/.ssh/known_hosts rsync -4rlptD built_pkgs/* "$RSYNCTARGET" + + provenance: + needs: build + name: Generate build provenance + permissions: + actions: read # To read the workflow path. + id-token: write # To sign the provenance. + contents: write # To be able to upload assets as release artifacts + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0 + with: + base64-subjects: "${{ needs.build.outputs.hashes }}" + upload-assets: false From cc6bf85ff036523c1b8a057393ed5293c1a44886 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 22 Feb 2023 11:24:17 +0100 Subject: [PATCH 334/909] builder-dispatch: Refactoring to get provenance for all targets Also include the list of installed packages during our package builds --- .github/workflows/builder-dispatch.yml | 51 ++++++++++++++++--- .../dockerfiles/Dockerfile.debbuild | 4 ++ .../dockerfiles/Dockerfile.rpmbuild | 18 +++++-- 3 files changed, 63 insertions(+), 10 deletions(-) diff --git a/.github/workflows/builder-dispatch.yml b/.github/workflows/builder-dispatch.yml index 538e4e35111b..9001c2c76c8b 100644 --- a/.github/workflows/builder-dispatch.yml +++ b/.github/workflows/builder-dispatch.yml @@ -61,7 +61,16 @@ jobs: os: ${{fromJson(needs.prepare.outputs.oslist)}} fail-fast: false outputs: - hashes: ${{ steps.hash.outputs.hashes }} + version: ${{ steps.getversion.outputs.version }} + pkghashes-el-7: ${{ steps.pkghashes.outputs.pkghashes-el-7 }} + pkghashes-el-8: ${{ steps.pkghashes.outputs.pkghashes-el-8 }} + pkghashes-el-9: ${{ steps.pkghashes.outputs.pkghashes-el-9 }} + pkghashes-debian-buster: ${{ steps.pkghashes.outputs.pkghashes-debian-buster }} + pkghashes-debian-bullseye: ${{ steps.pkghashes.outputs.pkghashes-debian-bullseye }} + pkghashes-ubuntu-bionic: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-bionic }} + pkghashes-ubuntu-focal: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-focal }} + pkghashes-ubuntu-jammy: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-jammy }} + srchashes: ${{ steps.srchashes.outputs.srchashes }} steps: - uses: actions/checkout@v3 with: @@ -79,11 +88,22 @@ jobs: name: ${{ github.event.inputs.product }}-${{ matrix.os }}-${{ steps.getversion.outputs.version }} path: built_pkgs/ retention-days: 7 - - name: Generate hashes for provenance + - name: Extract packages from the tarball + # so we get provenance for individual packages (and the JSON package manifests from the builder) + id: extract + run: | + mkdir -m 700 -p ./packages/ + tar xvf ./built_pkgs/*/*/${{ github.event.inputs.product }}-${{ steps.getversion.outputs.version }}-${{ matrix.os }}.tar.bz2 -C ./packages/ --transform='s/.*\///' + - name: Generate package hashes for provenance + shell: bash + id: pkghashes + run: | + echo "pkghashes-${{ matrix.os }}=$(sha256sum ./packages/*.rpm ./packages/*.deb ./packages/*.json | base64 -w0)" >> $GITHUB_OUTPUT + - name: Generate source hash for provenance shell: bash - id: hash + id: srchashes run: | - echo "hashes=$(sha256sum ./built_pkgs/*/*/* | base64 -w0)" >> $GITHUB_OUTPUT + echo "srchashes=$(sha256sum ./built_pkgs/*/*/${{ github.event.inputs.product }}-${{ steps.getversion.outputs.version }}.tar.bz2 ./packages/*.json | base64 -w0)" >> $GITHUB_OUTPUT - name: Upload packages to downloads.powerdns.com env: SSHKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} @@ -98,14 +118,31 @@ jobs: echo "$HOSTKEY" > ~/.ssh/known_hosts rsync -4rlptD built_pkgs/* "$RSYNCTARGET" - provenance: + provenance-pkgs: + needs: [prepare, build] + name: Generate provenance for ${{ github.event.inputs.product }} (${{ github.event.inputs.ref }}) for ${{ matrix.os }} + strategy: + matrix: + os: ${{fromJson(needs.prepare.outputs.oslist)}} + permissions: + actions: read # To read the workflow path. + id-token: write # To sign the provenance. + contents: write # To be able to upload assets as release artifacts + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0 + with: + base64-subjects: "${{ needs.build.outputs[format('pkghashes-{0}', matrix.os)] }}" + upload-assets: false + provenance-name: "${{ github.event.inputs.product }}-${{ needs.build.outputs.version }}-${{ matrix.os}}.intoto.jsonl" + + provenance-src: needs: build - name: Generate build provenance + name: Generate provenance for ${{ github.event.inputs.product }} (${{ github.event.inputs.ref }}) source tarball permissions: actions: read # To read the workflow path. id-token: write # To sign the provenance. contents: write # To be able to upload assets as release artifacts uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0 with: - base64-subjects: "${{ needs.build.outputs.hashes }}" + base64-subjects: "${{ needs.build.outputs.srchashes }}" upload-assets: false + provenance-name: "${{ github.event.inputs.product }}-${{ needs.build.outputs.version }}-src.intoto.jsonl" diff --git a/builder-support/dockerfiles/Dockerfile.debbuild b/builder-support/dockerfiles/Dockerfile.debbuild index 5b350d666ae2..46b315d74b0a 100644 --- a/builder-support/dockerfiles/Dockerfile.debbuild +++ b/builder-support/dockerfiles/Dockerfile.debbuild @@ -20,3 +20,7 @@ RUN builder/helpers/build-debs.sh dnsdist-${BUILDER_VERSION} RUN mv dnsdist*.deb /dist; mv dnsdist*.ddeb /dist || true @ENDIF + +# Generate provenance +RUN apt-get install -y python-apt || apt-get install -y python3-apt +@EVAL RUN python2 builder/helpers/generate-deb-provenance.py /dist/packages-${BUILDER_TARGET}.json || python3 builder/helpers/generate-deb-provenance.py /dist/packages-${BUILDER_TARGET}.json diff --git a/builder-support/dockerfiles/Dockerfile.rpmbuild b/builder-support/dockerfiles/Dockerfile.rpmbuild index b21923a43588..6ba2911557b1 100644 --- a/builder-support/dockerfiles/Dockerfile.rpmbuild +++ b/builder-support/dockerfiles/Dockerfile.rpmbuild @@ -1,7 +1,11 @@ FROM dist-base as package-builder -RUN touch /var/lib/rpm/* && \ - yum upgrade -y && \ - yum install -y rpm-build rpmdevtools python3 "@Development Tools" +RUN touch /var/lib/rpm/* && if $(grep -q 'release 7' /etc/redhat-release); then \ + yum upgrade -y && \ + yum install -y rpm-build rpmdevtools python2 python3 "@Development Tools"; \ + else \ + yum upgrade -y && \ + yum install -y rpm-build rpmdevtools python3 "@Development Tools"; \ + fi RUN mkdir /dist /pdns WORKDIR /pdns @@ -54,6 +58,14 @@ RUN touch /var/lib/rpm/* && if $(grep -q 'release 7' /etc/redhat-release); then fi @ENDIF +# Generate provenance +@IF [ ${BUILDER_TARGET} = el-7 ] +@EVAL RUN python builder/helpers/generate-yum-provenance.py /dist/packages-${BUILDER_TARGET}.json || python3 builder/helpers/generate-yum-provenance.py /dist/packages-${BUILDER_TARGET}.json +@ENDIF +@IF [ ${BUILDER_TARGET} != el-7 ] +@EVAL RUN python builder/helpers/generate-dnf-provenance.py /dist/packages-${BUILDER_TARGET}.json || python3 builder/helpers/generate-dnf-provenance.py /dist/packages-${BUILDER_TARGET}.json +@ENDIF + # mv across layers with overlay2 is buggy in some kernel versions (results in empty dirs) # See: https://github.com/moby/moby/issues/33733 #RUN mv /root/rpmbuild/RPMS/* /dist/ From e4023db1f91af5f112f48bec3b3501912dc79187 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 27 Jun 2023 13:46:35 +0200 Subject: [PATCH 335/909] builder-dispatch: Update the list of OS for pkghashes --- .github/workflows/builder-dispatch.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/builder-dispatch.yml b/.github/workflows/builder-dispatch.yml index 9001c2c76c8b..d2a43de736d7 100644 --- a/.github/workflows/builder-dispatch.yml +++ b/.github/workflows/builder-dispatch.yml @@ -14,6 +14,8 @@ on: os: description: OSes to build for, space separated type: string + # please remember to update the pkghashes below when you + # update this list default: > el-7 el-8 @@ -67,7 +69,7 @@ jobs: pkghashes-el-9: ${{ steps.pkghashes.outputs.pkghashes-el-9 }} pkghashes-debian-buster: ${{ steps.pkghashes.outputs.pkghashes-debian-buster }} pkghashes-debian-bullseye: ${{ steps.pkghashes.outputs.pkghashes-debian-bullseye }} - pkghashes-ubuntu-bionic: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-bionic }} + pkghashes-debian-bookworm: ${{ steps.pkghashes.outputs.pkghashes-debian-bookworm }} pkghashes-ubuntu-focal: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-focal }} pkghashes-ubuntu-jammy: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-jammy }} srchashes: ${{ steps.srchashes.outputs.srchashes }} From d5e055068355c7656b7dbe44f9414616162fb686 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 28 Mar 2023 14:13:58 +0200 Subject: [PATCH 336/909] Add a workflow to build packages when a tag is pushed --- .github/workflows/build-packages.yml | 152 +++++++++++++++++++++++++++ .github/workflows/build-tags.yml | 46 ++++++++ 2 files changed, 198 insertions(+) create mode 100644 .github/workflows/build-packages.yml create mode 100644 .github/workflows/build-tags.yml diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml new file mode 100644 index 000000000000..7d3bb7b28bda --- /dev/null +++ b/.github/workflows/build-packages.yml @@ -0,0 +1,152 @@ +--- +name: Build packages + +on: + workflow_call: + inputs: + product: + required: true + description: Product to build + type: string + os: + required: false + description: OSes to build for, space separated + type: string + default: > + el-7 + el-8 + el-9 + debian-buster + debian-bullseye + ubuntu-bionic + ubuntu-focal + ubuntu-jammy + ref: + description: git ref to checkout + type: string + default: master + required: false + is_release: + description: is this a release build? + type: string + required: false + default: 'NO' + secrets: + DOWNLOADS_AUTOBUILT_SECRET: + required: true + DOWNLOADS_AUTOBUILT_RSYNCTARGET: + required: true + DOWNLOADS_AUTOBUILT_HOSTKEY: + required: true + +permissions: # least privileges, see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions + contents: read + +jobs: + prepare: + name: generate OS list + runs-on: ubuntu-20.04 + outputs: + oslist: ${{ steps.get-oslist.outputs.oslist }} + steps: + # instead of jo, we could use jq here, which avoids running apt, and thus would be faster. + # but, as this whole workflow needs at least 30 minutes to run, I prefer spending a few seconds here + # so that the command remains readable, because jo is simpler to use. + - run: sudo apt-get update && sudo apt-get -y install jo + - id: get-oslist + run: echo "oslist=$(jo -a ${{ inputs.os }})" >> "$GITHUB_OUTPUT" + build: + needs: prepare + name: build ${{ inputs.product }} (${{ inputs.ref }}) for ${{ matrix.os }} + # on a ubuntu-20.04 VM + runs-on: ubuntu-20.04 + strategy: + matrix: + os: ${{fromJson(needs.prepare.outputs.oslist)}} + fail-fast: false + outputs: + version: ${{ steps.getversion.outputs.version }} + pkghashes-el-7: ${{ steps.pkghashes.outputs.pkghashes-el-7 }} + pkghashes-el-8: ${{ steps.pkghashes.outputs.pkghashes-el-8 }} + pkghashes-el-9: ${{ steps.pkghashes.outputs.pkghashes-el-9 }} + pkghashes-debian-buster: ${{ steps.pkghashes.outputs.pkghashes-debian-buster }} + pkghashes-debian-bullseye: ${{ steps.pkghashes.outputs.pkghashes-debian-bullseye }} + pkghashes-ubuntu-bionic: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-bionic }} + pkghashes-ubuntu-focal: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-focal }} + pkghashes-ubuntu-jammy: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-jammy }} + srchashes: ${{ steps.srchashes.outputs.srchashes }} + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 # for correct version numbers + submodules: recursive + ref: ${{ inputs.ref }} + # this builds packages and runs our unit tests (make check) + - run: IS_RELEASE=${{ inputs.is_release}} builder/build.sh -v -m ${{ inputs.product }} ${{ matrix.os }} + - name: Get version number + run: 'echo ::set-output name=version::$(readlink builder/tmp/latest)' + id: getversion + - name: Upload packages as GH artifacts + uses: actions/upload-artifact@v3 + with: + name: ${{ inputs.product }}-${{ matrix.os }}-${{ steps.getversion.outputs.version }} + path: built_pkgs/ + retention-days: 7 + - name: Extract packages from the tarball + # so we get provenance for individual packages (and the JSON package manifests from the builder) + id: extract + run: | + mkdir -m 700 -p ./packages/ + tar xvf ./built_pkgs/*/*/${{ inputs.product }}-${{ steps.getversion.outputs.version }}-${{ matrix.os }}.tar.bz2 -C ./packages/ --transform='s/.*\///' + - name: Generate package hashes for provenance + shell: bash + id: pkghashes + run: | + echo "pkghashes-${{ matrix.os }}=$(sha256sum ./packages/*.rpm ./packages/*.deb ./packages/*.json | base64 -w0)" >> $GITHUB_OUTPUT + - name: Generate source hash for provenance + shell: bash + id: srchashes + run: | + echo "srchashes=$(sha256sum ./built_pkgs/*/*/${{ inputs.product }}-${{ steps.getversion.outputs.version }}.tar.bz2 ./packages/*.json | base64 -w0)" >> $GITHUB_OUTPUT + - name: Upload packages to downloads.powerdns.com + env: + SSHKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} + RSYNCTARGET: ${{ secrets.DOWNLOADS_AUTOBUILT_RSYNCTARGET }} + HOSTKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_HOSTKEY }} + if: + "${{ env.SSHKEY != '' }}" + run: | + mkdir -m 700 -p ~/.ssh + echo "$SSHKEY" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + echo "$HOSTKEY" > ~/.ssh/known_hosts + rsync -4rlptD built_pkgs/* "$RSYNCTARGET" + + provenance-pkgs: + needs: [prepare, build] + name: Generate provenance for ${{ inputs.product }} (${{ inputs.ref }}) for ${{ matrix.os }} + strategy: + matrix: + os: ${{fromJson(needs.prepare.outputs.oslist)}} + permissions: + actions: read # To read the workflow path. + id-token: write # To sign the provenance. + contents: write # To be able to upload assets as release artifacts + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0 + with: + base64-subjects: "${{ needs.build.outputs[format('pkghashes-{0}', matrix.os)] }}" + upload-assets: false + provenance-name: "${{ inputs.product }}-${{ needs.build.outputs.version }}-${{ matrix.os}}.intoto.jsonl" + + provenance-src: + needs: build + name: Generate provenance for ${{ inputs.product }} (${{ inputs.ref }}) source tarball + permissions: + actions: read # To read the workflow path. + id-token: write # To sign the provenance. + contents: write # To be able to upload assets as release artifacts + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0 + with: + base64-subjects: "${{ needs.build.outputs.srchashes }}" + upload-assets: false + provenance-name: "${{ inputs.product }}-${{ needs.build.outputs.version }}-src.intoto.jsonl" diff --git a/.github/workflows/build-tags.yml b/.github/workflows/build-tags.yml new file mode 100644 index 000000000000..89e69a100adc --- /dev/null +++ b/.github/workflows/build-tags.yml @@ -0,0 +1,46 @@ +--- +name: Build packages for tags + +on: + push: + tags: + - 'auth-*' + - 'dnsdist-*' + - 'rec-*' + +jobs: + call-build-packages-auth: + uses: PowerDNS/pdns/.github/workflows/build-packages.yml@master + if: startsWith(github.ref_name, 'auth') + with: + is_release: 'YES' + product: 'auth' + ref: ${{ github.ref_name }} + secrets: + DOWNLOADS_AUTOBUILT_SECRET: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} + DOWNLOADS_AUTOBUILT_RSYNCTARGET: ${{ secrets.DOWNLOADS_AUTOBUILT_RSYNCTARGET }} + DOWNLOADS_AUTOBUILT_HOSTKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_HOSTKEY }} + + call-build-packages-dnsdist: + uses: PowerDNS/pdns/.github/workflows/build-packages.yml@master + if: startsWith(github.ref_name, 'dnsdist') + with: + is_release: 'YES' + product: 'dnsdist' + ref: ${{ github.ref_name }} + secrets: + DOWNLOADS_AUTOBUILT_SECRET: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} + DOWNLOADS_AUTOBUILT_RSYNCTARGET: ${{ secrets.DOWNLOADS_AUTOBUILT_RSYNCTARGET }} + DOWNLOADS_AUTOBUILT_HOSTKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_HOSTKEY }} + + call-build-packages-rec: + uses: PowerDNS/pdns/.github/workflows/build-packages.yml@master + if: startsWith(github.ref_name, 'rec') + with: + is_release: 'YES' + product: 'auth' + ref: ${{ github.ref_name }} + secrets: + DOWNLOADS_AUTOBUILT_SECRET: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} + DOWNLOADS_AUTOBUILT_RSYNCTARGET: ${{ secrets.DOWNLOADS_AUTOBUILT_RSYNCTARGET }} + DOWNLOADS_AUTOBUILT_HOSTKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_HOSTKEY }} From 3803aec5558d3bc88c4bc7674d15c99cbcd699c4 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 4 May 2023 14:40:45 +0200 Subject: [PATCH 337/909] builder-dispatch: Use the build-packages workflow --- .github/workflows/build-packages.yml | 4 +- .github/workflows/builder-dispatch.yml | 120 +++---------------------- 2 files changed, 12 insertions(+), 112 deletions(-) diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index 7d3bb7b28bda..1f7148b6947c 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -18,7 +18,7 @@ on: el-9 debian-buster debian-bullseye - ubuntu-bionic + debian-bookworm ubuntu-focal ubuntu-jammy ref: @@ -71,7 +71,7 @@ jobs: pkghashes-el-9: ${{ steps.pkghashes.outputs.pkghashes-el-9 }} pkghashes-debian-buster: ${{ steps.pkghashes.outputs.pkghashes-debian-buster }} pkghashes-debian-bullseye: ${{ steps.pkghashes.outputs.pkghashes-debian-bullseye }} - pkghashes-ubuntu-bionic: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-bionic }} + pkghashes-debian-bookworm: ${{ steps.pkghashes.outputs.pkghashes-debian-bookworm }} pkghashes-ubuntu-focal: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-focal }} pkghashes-ubuntu-jammy: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-jammy }} srchashes: ${{ steps.srchashes.outputs.srchashes }} diff --git a/.github/workflows/builder-dispatch.yml b/.github/workflows/builder-dispatch.yml index d2a43de736d7..b0a825c9aa5f 100644 --- a/.github/workflows/builder-dispatch.yml +++ b/.github/workflows/builder-dispatch.yml @@ -36,115 +36,15 @@ on: - 'NO' - 'YES' -permissions: # least privileges, see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions - contents: read - jobs: - prepare: - name: generate OS list - runs-on: ubuntu-20.04 - outputs: - oslist: ${{ steps.get-oslist.outputs.oslist }} - steps: - # instead of jo, we could use jq here, which avoids running apt, and thus would be faster. - # but, as this whole workflow needs at least 30 minutes to run, I prefer spending a few seconds here - # so that the command remains readable, because jo is simpler to use. - - run: sudo apt-get update && sudo apt-get -y install jo - - id: get-oslist - run: echo "oslist=$(jo -a ${{ github.event.inputs.os }})" >> "$GITHUB_OUTPUT" - - build: - needs: prepare - name: build ${{ github.event.inputs.product }} (${{ github.event.inputs.ref }}) for ${{ matrix.os }} - # on a ubuntu-20.04 VM - runs-on: ubuntu-20.04 - strategy: - matrix: - os: ${{fromJson(needs.prepare.outputs.oslist)}} - fail-fast: false - outputs: - version: ${{ steps.getversion.outputs.version }} - pkghashes-el-7: ${{ steps.pkghashes.outputs.pkghashes-el-7 }} - pkghashes-el-8: ${{ steps.pkghashes.outputs.pkghashes-el-8 }} - pkghashes-el-9: ${{ steps.pkghashes.outputs.pkghashes-el-9 }} - pkghashes-debian-buster: ${{ steps.pkghashes.outputs.pkghashes-debian-buster }} - pkghashes-debian-bullseye: ${{ steps.pkghashes.outputs.pkghashes-debian-bullseye }} - pkghashes-debian-bookworm: ${{ steps.pkghashes.outputs.pkghashes-debian-bookworm }} - pkghashes-ubuntu-focal: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-focal }} - pkghashes-ubuntu-jammy: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-jammy }} - srchashes: ${{ steps.srchashes.outputs.srchashes }} - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 # for correct version numbers - submodules: recursive - ref: ${{ github.event.inputs.ref }} - # this builds packages and runs our unit tests (make check) - - run: IS_RELEASE=${{ github.event.inputs.is_release}} builder/build.sh -v -m ${{ github.event.inputs.product }} ${{ matrix.os }} - - name: Get version number - run: 'echo ::set-output name=version::$(readlink builder/tmp/latest)' - id: getversion - - name: Upload packages as GH artifacts - uses: actions/upload-artifact@v3 - with: - name: ${{ github.event.inputs.product }}-${{ matrix.os }}-${{ steps.getversion.outputs.version }} - path: built_pkgs/ - retention-days: 7 - - name: Extract packages from the tarball - # so we get provenance for individual packages (and the JSON package manifests from the builder) - id: extract - run: | - mkdir -m 700 -p ./packages/ - tar xvf ./built_pkgs/*/*/${{ github.event.inputs.product }}-${{ steps.getversion.outputs.version }}-${{ matrix.os }}.tar.bz2 -C ./packages/ --transform='s/.*\///' - - name: Generate package hashes for provenance - shell: bash - id: pkghashes - run: | - echo "pkghashes-${{ matrix.os }}=$(sha256sum ./packages/*.rpm ./packages/*.deb ./packages/*.json | base64 -w0)" >> $GITHUB_OUTPUT - - name: Generate source hash for provenance - shell: bash - id: srchashes - run: | - echo "srchashes=$(sha256sum ./built_pkgs/*/*/${{ github.event.inputs.product }}-${{ steps.getversion.outputs.version }}.tar.bz2 ./packages/*.json | base64 -w0)" >> $GITHUB_OUTPUT - - name: Upload packages to downloads.powerdns.com - env: - SSHKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} - RSYNCTARGET: ${{ secrets.DOWNLOADS_AUTOBUILT_RSYNCTARGET }} - HOSTKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_HOSTKEY }} - if: - "${{ env.SSHKEY != '' }}" - run: | - mkdir -m 700 -p ~/.ssh - echo "$SSHKEY" > ~/.ssh/id_ed25519 - chmod 600 ~/.ssh/id_ed25519 - echo "$HOSTKEY" > ~/.ssh/known_hosts - rsync -4rlptD built_pkgs/* "$RSYNCTARGET" - - provenance-pkgs: - needs: [prepare, build] - name: Generate provenance for ${{ github.event.inputs.product }} (${{ github.event.inputs.ref }}) for ${{ matrix.os }} - strategy: - matrix: - os: ${{fromJson(needs.prepare.outputs.oslist)}} - permissions: - actions: read # To read the workflow path. - id-token: write # To sign the provenance. - contents: write # To be able to upload assets as release artifacts - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0 - with: - base64-subjects: "${{ needs.build.outputs[format('pkghashes-{0}', matrix.os)] }}" - upload-assets: false - provenance-name: "${{ github.event.inputs.product }}-${{ needs.build.outputs.version }}-${{ matrix.os}}.intoto.jsonl" - - provenance-src: - needs: build - name: Generate provenance for ${{ github.event.inputs.product }} (${{ github.event.inputs.ref }}) source tarball - permissions: - actions: read # To read the workflow path. - id-token: write # To sign the provenance. - contents: write # To be able to upload assets as release artifacts - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v1.4.0 + call-build-packages: + uses: PowerDNS/pdns/.github/workflows/build-packages.yml@master with: - base64-subjects: "${{ needs.build.outputs.srchashes }}" - upload-assets: false - provenance-name: "${{ github.event.inputs.product }}-${{ needs.build.outputs.version }}-src.intoto.jsonl" + product: ${{ github.event.inputs.product }} + os: ${{ github.event.inputs.os }} + ref: ${{ github.event.inputs.ref }} + is_release: ${{ github.event.inputs.is_release }} + secrets: + DOWNLOADS_AUTOBUILT_SECRET: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} + DOWNLOADS_AUTOBUILT_RSYNCTARGET: ${{ secrets.DOWNLOADS_AUTOBUILT_RSYNCTARGET }} + DOWNLOADS_AUTOBUILT_HOSTKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_HOSTKEY }} From 0aa570215fc2cc493ab47d62e0dae87b008a7fcf Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 27 Jun 2023 13:49:55 +0200 Subject: [PATCH 338/909] update docs builder workflow to ubuntu 22.04, get invoke from apt --- .github/workflows/documentation.yml | 2 +- build-scripts/gh-actions-setup-inv-no-dist-upgrade | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index c02b266a22fc..a03c005273ea 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -13,7 +13,7 @@ permissions: jobs: build-upload-docs: name: Build and upload docs - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: PowerDNS/pdns/set-ubuntu-mirror@meta - uses: actions/checkout@v3 diff --git a/build-scripts/gh-actions-setup-inv-no-dist-upgrade b/build-scripts/gh-actions-setup-inv-no-dist-upgrade index e2e18aa60f2b..49fe23a919f7 100755 --- a/build-scripts/gh-actions-setup-inv-no-dist-upgrade +++ b/build-scripts/gh-actions-setup-inv-no-dist-upgrade @@ -6,7 +6,6 @@ EOF " sudo chmod 755 /usr/sbin/policy-rc.d sudo apt-get update -sudo apt-get -qq -y --no-install-recommends install python3-pip -sudo pip3 install git+https://github.com/pyinvoke/invoke@faa5728a6f76199a3da1750ed952e7efee17c1da +sudo apt-get -qq -y --no-install-recommends install python3-pip python3-invoke sudo pip3 install gitpython sudo pip3 install unidiff From 894276d37b1376fa0e1369402e6e9f639f4f84b4 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 27 Jun 2023 13:37:52 +0200 Subject: [PATCH 339/909] auth docs: generate requirements.txt with package hashes --- .github/actions/spell-check/excludes.txt | 2 +- docs/requirements.in | 11 + docs/requirements.txt | 331 ++++++++++++++++++++++- 3 files changed, 335 insertions(+), 9 deletions(-) create mode 100644 docs/requirements.in diff --git a/.github/actions/spell-check/excludes.txt b/.github/actions/spell-check/excludes.txt index 0c60adc0136b..44460d1033ce 100644 --- a/.github/actions/spell-check/excludes.txt +++ b/.github/actions/spell-check/excludes.txt @@ -9,7 +9,7 @@ (?:^|/)m4/ (?:^|/)m4/ (?:^|/)package(?:-lock|)\.json$ -(?:^|/)requirements\.txt$ +(?:^|/)requirements\.(?:txt|in)$ (?:^|/)vendor/ /expected_result /test-base64_cc\.cc$ diff --git a/docs/requirements.in b/docs/requirements.in new file mode 100644 index 000000000000..6356425f0ffb --- /dev/null +++ b/docs/requirements.in @@ -0,0 +1,11 @@ +# To generate requirements.txt, run: +# pip-compile --generate-hashes requirements.in + +Sphinx>=1.5.0,!=1.8.0,<2.0 +https://github.com/PowerDNS/sphinxcontrib-openapi/archive/refs/heads/use-jsondomain-pdns-py3.10-noscm.zip +https://github.com/PowerDNS/sphinx-jsondomain/archive/refs/heads/no-type-links.zip +changelog>=0.5.6,<0.6 +sphinxcontrib-fulltoc +guzzle_sphinx_theme +docutils!=0.15,<0.18 +jinja2<3.1.0 diff --git a/docs/requirements.txt b/docs/requirements.txt index 8825a5ea9b3b..437cf275d528 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,8 +1,323 @@ -Sphinx>=1.5.0,!=1.8.0,<2.0 -git+https://github.com/PowerDNS/sphinxcontrib-openapi@use-jsondomain-pdns-py3.10 -git+https://github.com/PowerDNS/sphinx-jsondomain@no-type-links -changelog>=0.5.6,<0.6 -sphinxcontrib-fulltoc -guzzle_sphinx_theme -docutils!=0.15,<0.18 -jinja2<3.1.0 +# +# This file is autogenerated by pip-compile with Python 3.9 +# by the following command: +# +# pip-compile --generate-hashes requirements.in +# +alabaster==0.7.13 \ + --hash=sha256:1ee19aca801bbabb5ba3f5f258e4422dfa86f82f3e9cefb0859b283cdd7f62a3 \ + --hash=sha256:a27a4a084d5e690e16e01e03ad2b2e552c61a65469419b907243193de1a84ae2 + # via sphinx +attrs==23.1.0 \ + --hash=sha256:1f28b4522cdc2fb4256ac1a020c78acf9cba2c6b461ccd2c126f3aa8e8335d04 \ + --hash=sha256:6279836d581513a26f1bf235f9acd333bc9115683f14f7e8fae46c98fc50e015 + # via jsonschema +babel==2.12.1 \ + --hash=sha256:b4246fb7677d3b98f501a39d43396d3cafdc8eadb045f4a31be01863f655c610 \ + --hash=sha256:cc2d99999cd01d44420ae725a21c9e3711b3aadc7976d6147f622d8581963455 + # via sphinx +certifi==2023.5.7 \ + --hash=sha256:0f0d56dc5a6ad56fd4ba36484d6cc34451e1c6548c61daad8c320169f91eddc7 \ + --hash=sha256:c6c2e98f5c7869efca1f8916fed228dd91539f9f1b444c314c06eef02980c716 + # via requests +changelog==0.5.8 \ + --hash=sha256:43b21840874130666b7534b76b402bbb914f8c9c413d5ea9d45850ca4767dafb \ + --hash=sha256:cd67a8a30e1a38731ebc25568788fe499748113d27324a7e67ad8ee443509415 + # via -r requirements.in +charset-normalizer==3.1.0 \ + --hash=sha256:04afa6387e2b282cf78ff3dbce20f0cc071c12dc8f685bd40960cc68644cfea6 \ + --hash=sha256:04eefcee095f58eaabe6dc3cc2262f3bcd776d2c67005880894f447b3f2cb9c1 \ + --hash=sha256:0be65ccf618c1e7ac9b849c315cc2e8a8751d9cfdaa43027d4f6624bd587ab7e \ + --hash=sha256:0c95f12b74681e9ae127728f7e5409cbbef9cd914d5896ef238cc779b8152373 \ + --hash=sha256:0ca564606d2caafb0abe6d1b5311c2649e8071eb241b2d64e75a0d0065107e62 \ + --hash=sha256:10c93628d7497c81686e8e5e557aafa78f230cd9e77dd0c40032ef90c18f2230 \ + --hash=sha256:11d117e6c63e8f495412d37e7dc2e2fff09c34b2d09dbe2bee3c6229577818be \ + --hash=sha256:11d3bcb7be35e7b1bba2c23beedac81ee893ac9871d0ba79effc7fc01167db6c \ + --hash=sha256:12a2b561af122e3d94cdb97fe6fb2bb2b82cef0cdca131646fdb940a1eda04f0 \ + --hash=sha256:12d1a39aa6b8c6f6248bb54550efcc1c38ce0d8096a146638fd4738e42284448 \ + --hash=sha256:1435ae15108b1cb6fffbcea2af3d468683b7afed0169ad718451f8db5d1aff6f \ + --hash=sha256:1c60b9c202d00052183c9be85e5eaf18a4ada0a47d188a83c8f5c5b23252f649 \ + --hash=sha256:1e8fcdd8f672a1c4fc8d0bd3a2b576b152d2a349782d1eb0f6b8e52e9954731d \ + --hash=sha256:20064ead0717cf9a73a6d1e779b23d149b53daf971169289ed2ed43a71e8d3b0 \ + --hash=sha256:21fa558996782fc226b529fdd2ed7866c2c6ec91cee82735c98a197fae39f706 \ + --hash=sha256:22908891a380d50738e1f978667536f6c6b526a2064156203d418f4856d6e86a \ + --hash=sha256:3160a0fd9754aab7d47f95a6b63ab355388d890163eb03b2d2b87ab0a30cfa59 \ + --hash=sha256:322102cdf1ab682ecc7d9b1c5eed4ec59657a65e1c146a0da342b78f4112db23 \ + --hash=sha256:34e0a2f9c370eb95597aae63bf85eb5e96826d81e3dcf88b8886012906f509b5 \ + --hash=sha256:3573d376454d956553c356df45bb824262c397c6e26ce43e8203c4c540ee0acb \ + --hash=sha256:3747443b6a904001473370d7810aa19c3a180ccd52a7157aacc264a5ac79265e \ + --hash=sha256:38e812a197bf8e71a59fe55b757a84c1f946d0ac114acafaafaf21667a7e169e \ + --hash=sha256:3a06f32c9634a8705f4ca9946d667609f52cf130d5548881401f1eb2c39b1e2c \ + --hash=sha256:3a5fc78f9e3f501a1614a98f7c54d3969f3ad9bba8ba3d9b438c3bc5d047dd28 \ + --hash=sha256:3d9098b479e78c85080c98e1e35ff40b4a31d8953102bb0fd7d1b6f8a2111a3d \ + --hash=sha256:3dc5b6a8ecfdc5748a7e429782598e4f17ef378e3e272eeb1340ea57c9109f41 \ + --hash=sha256:4155b51ae05ed47199dc5b2a4e62abccb274cee6b01da5b895099b61b1982974 \ + --hash=sha256:49919f8400b5e49e961f320c735388ee686a62327e773fa5b3ce6721f7e785ce \ + --hash=sha256:53d0a3fa5f8af98a1e261de6a3943ca631c526635eb5817a87a59d9a57ebf48f \ + --hash=sha256:5f008525e02908b20e04707a4f704cd286d94718f48bb33edddc7d7b584dddc1 \ + --hash=sha256:628c985afb2c7d27a4800bfb609e03985aaecb42f955049957814e0491d4006d \ + --hash=sha256:65ed923f84a6844de5fd29726b888e58c62820e0769b76565480e1fdc3d062f8 \ + --hash=sha256:6734e606355834f13445b6adc38b53c0fd45f1a56a9ba06c2058f86893ae8017 \ + --hash=sha256:6baf0baf0d5d265fa7944feb9f7451cc316bfe30e8df1a61b1bb08577c554f31 \ + --hash=sha256:6f4f4668e1831850ebcc2fd0b1cd11721947b6dc7c00bf1c6bd3c929ae14f2c7 \ + --hash=sha256:6f5c2e7bc8a4bf7c426599765b1bd33217ec84023033672c1e9a8b35eaeaaaf8 \ + --hash=sha256:6f6c7a8a57e9405cad7485f4c9d3172ae486cfef1344b5ddd8e5239582d7355e \ + --hash=sha256:7381c66e0561c5757ffe616af869b916c8b4e42b367ab29fedc98481d1e74e14 \ + --hash=sha256:73dc03a6a7e30b7edc5b01b601e53e7fc924b04e1835e8e407c12c037e81adbd \ + --hash=sha256:74db0052d985cf37fa111828d0dd230776ac99c740e1a758ad99094be4f1803d \ + --hash=sha256:75f2568b4189dda1c567339b48cba4ac7384accb9c2a7ed655cd86b04055c795 \ + --hash=sha256:78cacd03e79d009d95635e7d6ff12c21eb89b894c354bd2b2ed0b4763373693b \ + --hash=sha256:80d1543d58bd3d6c271b66abf454d437a438dff01c3e62fdbcd68f2a11310d4b \ + --hash=sha256:830d2948a5ec37c386d3170c483063798d7879037492540f10a475e3fd6f244b \ + --hash=sha256:891cf9b48776b5c61c700b55a598621fdb7b1e301a550365571e9624f270c203 \ + --hash=sha256:8f25e17ab3039b05f762b0a55ae0b3632b2e073d9c8fc88e89aca31a6198e88f \ + --hash=sha256:9a3267620866c9d17b959a84dd0bd2d45719b817245e49371ead79ed4f710d19 \ + --hash=sha256:a04f86f41a8916fe45ac5024ec477f41f886b3c435da2d4e3d2709b22ab02af1 \ + --hash=sha256:aaf53a6cebad0eae578f062c7d462155eada9c172bd8c4d250b8c1d8eb7f916a \ + --hash=sha256:abc1185d79f47c0a7aaf7e2412a0eb2c03b724581139193d2d82b3ad8cbb00ac \ + --hash=sha256:ac0aa6cd53ab9a31d397f8303f92c42f534693528fafbdb997c82bae6e477ad9 \ + --hash=sha256:ac3775e3311661d4adace3697a52ac0bab17edd166087d493b52d4f4f553f9f0 \ + --hash=sha256:b06f0d3bf045158d2fb8837c5785fe9ff9b8c93358be64461a1089f5da983137 \ + --hash=sha256:b116502087ce8a6b7a5f1814568ccbd0e9f6cfd99948aa59b0e241dc57cf739f \ + --hash=sha256:b82fab78e0b1329e183a65260581de4375f619167478dddab510c6c6fb04d9b6 \ + --hash=sha256:bd7163182133c0c7701b25e604cf1611c0d87712e56e88e7ee5d72deab3e76b5 \ + --hash=sha256:c36bcbc0d5174a80d6cccf43a0ecaca44e81d25be4b7f90f0ed7bcfbb5a00909 \ + --hash=sha256:c3af8e0f07399d3176b179f2e2634c3ce9c1301379a6b8c9c9aeecd481da494f \ + --hash=sha256:c84132a54c750fda57729d1e2599bb598f5fa0344085dbde5003ba429a4798c0 \ + --hash=sha256:cb7b2ab0188829593b9de646545175547a70d9a6e2b63bf2cd87a0a391599324 \ + --hash=sha256:cca4def576f47a09a943666b8f829606bcb17e2bc2d5911a46c8f8da45f56755 \ + --hash=sha256:cf6511efa4801b9b38dc5546d7547d5b5c6ef4b081c60b23e4d941d0eba9cbeb \ + --hash=sha256:d16fd5252f883eb074ca55cb622bc0bee49b979ae4e8639fff6ca3ff44f9f854 \ + --hash=sha256:d2686f91611f9e17f4548dbf050e75b079bbc2a82be565832bc8ea9047b61c8c \ + --hash=sha256:d7fc3fca01da18fbabe4625d64bb612b533533ed10045a2ac3dd194bfa656b60 \ + --hash=sha256:dd5653e67b149503c68c4018bf07e42eeed6b4e956b24c00ccdf93ac79cdff84 \ + --hash=sha256:de5695a6f1d8340b12a5d6d4484290ee74d61e467c39ff03b39e30df62cf83a0 \ + --hash=sha256:e0ac8959c929593fee38da1c2b64ee9778733cdf03c482c9ff1d508b6b593b2b \ + --hash=sha256:e1b25e3ad6c909f398df8921780d6a3d120d8c09466720226fc621605b6f92b1 \ + --hash=sha256:e633940f28c1e913615fd624fcdd72fdba807bf53ea6925d6a588e84e1151531 \ + --hash=sha256:e89df2958e5159b811af9ff0f92614dabf4ff617c03a4c1c6ff53bf1c399e0e1 \ + --hash=sha256:ea9f9c6034ea2d93d9147818f17c2a0860d41b71c38b9ce4d55f21b6f9165a11 \ + --hash=sha256:f645caaf0008bacf349875a974220f1f1da349c5dbe7c4ec93048cdc785a3326 \ + --hash=sha256:f8303414c7b03f794347ad062c0516cee0e15f7a612abd0ce1e25caf6ceb47df \ + --hash=sha256:fca62a8301b605b954ad2e9c3666f9d97f63872aa4efcae5492baca2056b74ab + # via requests +docutils==0.17.1 \ + --hash=sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125 \ + --hash=sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61 + # via + # -r requirements.in + # sphinx +fake-factory==0.5.11 \ + --hash=sha256:24950d2cf028080f70830b79e8ceba8711cd2b9dccd99e3b6992dcf7da6e46cd \ + --hash=sha256:cc450de0e0e9f3f4f89fea715b772b38bb5ad9d458e594fd7fed0f8b934ba636 + # via sphinx-jsondomain +guzzle-sphinx-theme==0.7.11 \ + --hash=sha256:9b8c1639c343c02c3f3db7df660ddf6f533b5454ee92a5f7b02edaa573fed3e6 + # via -r requirements.in +idna==3.4 \ + --hash=sha256:814f528e8dead7d329833b91c5faa87d60bf71824cd12a7530b5526063d02cb4 \ + --hash=sha256:90b77e79eaa3eba6de819a0c442c0b4ceefc341a7a2ab77d7562bf49f425c5c2 + # via requests +imagesize==1.4.1 \ + --hash=sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b \ + --hash=sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a + # via sphinx +jinja2==3.0.3 \ + --hash=sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8 \ + --hash=sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7 + # via + # -r requirements.in + # sphinx +jsonschema==4.17.3 \ + --hash=sha256:0f864437ab8b6076ba6707453ef8f98a6a0d512a80e93f8abdb676f737ecb60d \ + --hash=sha256:a870ad254da1a8ca84b6a2905cac29d265f805acc57af304784962a2aa6508f6 + # via sphinxcontrib-openapi +markupsafe==2.1.3 \ + --hash=sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e \ + --hash=sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e \ + --hash=sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431 \ + --hash=sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686 \ + --hash=sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559 \ + --hash=sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc \ + --hash=sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c \ + --hash=sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0 \ + --hash=sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4 \ + --hash=sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9 \ + --hash=sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575 \ + --hash=sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba \ + --hash=sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d \ + --hash=sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3 \ + --hash=sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00 \ + --hash=sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155 \ + --hash=sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac \ + --hash=sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52 \ + --hash=sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f \ + --hash=sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8 \ + --hash=sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b \ + --hash=sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24 \ + --hash=sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea \ + --hash=sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198 \ + --hash=sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0 \ + --hash=sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee \ + --hash=sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be \ + --hash=sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2 \ + --hash=sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707 \ + --hash=sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6 \ + --hash=sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58 \ + --hash=sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779 \ + --hash=sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636 \ + --hash=sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c \ + --hash=sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad \ + --hash=sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee \ + --hash=sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc \ + --hash=sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2 \ + --hash=sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48 \ + --hash=sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7 \ + --hash=sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e \ + --hash=sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b \ + --hash=sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa \ + --hash=sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5 \ + --hash=sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e \ + --hash=sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb \ + --hash=sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9 \ + --hash=sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57 \ + --hash=sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc \ + --hash=sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2 + # via jinja2 +packaging==23.1 \ + --hash=sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61 \ + --hash=sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f + # via sphinx +pygments==2.15.1 \ + --hash=sha256:8ace4d3c1dd481894b2005f560ead0f9f19ee64fe983366be1a21e171d12775c \ + --hash=sha256:db2db3deb4b4179f399a09054b023b6a586b76499d36965813c71aa8ed7b5fd1 + # via sphinx +pyrsistent==0.19.3 \ + --hash=sha256:016ad1afadf318eb7911baa24b049909f7f3bb2c5b1ed7b6a8f21db21ea3faa8 \ + --hash=sha256:1a2994773706bbb4995c31a97bc94f1418314923bd1048c6d964837040376440 \ + --hash=sha256:20460ac0ea439a3e79caa1dbd560344b64ed75e85d8703943e0b66c2a6150e4a \ + --hash=sha256:3311cb4237a341aa52ab8448c27e3a9931e2ee09561ad150ba94e4cfd3fc888c \ + --hash=sha256:3a8cb235fa6d3fd7aae6a4f1429bbb1fec1577d978098da1252f0489937786f3 \ + --hash=sha256:3ab2204234c0ecd8b9368dbd6a53e83c3d4f3cab10ecaf6d0e772f456c442393 \ + --hash=sha256:42ac0b2f44607eb92ae88609eda931a4f0dfa03038c44c772e07f43e738bcac9 \ + --hash=sha256:49c32f216c17148695ca0e02a5c521e28a4ee6c5089f97e34fe24163113722da \ + --hash=sha256:4b774f9288dda8d425adb6544e5903f1fb6c273ab3128a355c6b972b7df39dcf \ + --hash=sha256:4c18264cb84b5e68e7085a43723f9e4c1fd1d935ab240ce02c0324a8e01ccb64 \ + --hash=sha256:5a474fb80f5e0d6c9394d8db0fc19e90fa540b82ee52dba7d246a7791712f74a \ + --hash=sha256:64220c429e42a7150f4bfd280f6f4bb2850f95956bde93c6fda1b70507af6ef3 \ + --hash=sha256:878433581fc23e906d947a6814336eee031a00e6defba224234169ae3d3d6a98 \ + --hash=sha256:99abb85579e2165bd8522f0c0138864da97847875ecbd45f3e7e2af569bfc6f2 \ + --hash=sha256:a2471f3f8693101975b1ff85ffd19bb7ca7dd7c38f8a81701f67d6b4f97b87d8 \ + --hash=sha256:aeda827381f5e5d65cced3024126529ddc4289d944f75e090572c77ceb19adbf \ + --hash=sha256:b735e538f74ec31378f5a1e3886a26d2ca6351106b4dfde376a26fc32a044edc \ + --hash=sha256:c147257a92374fde8498491f53ffa8f4822cd70c0d85037e09028e478cababb7 \ + --hash=sha256:c4db1bd596fefd66b296a3d5d943c94f4fac5bcd13e99bffe2ba6a759d959a28 \ + --hash=sha256:c74bed51f9b41c48366a286395c67f4e894374306b197e62810e0fdaf2364da2 \ + --hash=sha256:c9bb60a40a0ab9aba40a59f68214eed5a29c6274c83b2cc206a359c4a89fa41b \ + --hash=sha256:cc5d149f31706762c1f8bda2e8c4f8fead6e80312e3692619a75301d3dbb819a \ + --hash=sha256:ccf0d6bd208f8111179f0c26fdf84ed7c3891982f2edaeae7422575f47e66b64 \ + --hash=sha256:e42296a09e83028b3476f7073fcb69ffebac0e66dbbfd1bd847d61f74db30f19 \ + --hash=sha256:e8f2b814a3dc6225964fa03d8582c6e0b6650d68a232df41e3cc1b66a5d2f8d1 \ + --hash=sha256:f0774bf48631f3a20471dd7c5989657b639fd2d285b861237ea9e82c36a415a9 \ + --hash=sha256:f0e7c4b2f77593871e918be000b96c8107da48444d57005b6a6bc61fb4331b2c + # via jsonschema +python-dateutil==2.8.2 \ + --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ + --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 + # via fake-factory +pyyaml==6.0 \ + --hash=sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf \ + --hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \ + --hash=sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b \ + --hash=sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57 \ + --hash=sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b \ + --hash=sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4 \ + --hash=sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07 \ + --hash=sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba \ + --hash=sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9 \ + --hash=sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287 \ + --hash=sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513 \ + --hash=sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0 \ + --hash=sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782 \ + --hash=sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0 \ + --hash=sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92 \ + --hash=sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f \ + --hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2 \ + --hash=sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc \ + --hash=sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1 \ + --hash=sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c \ + --hash=sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86 \ + --hash=sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4 \ + --hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \ + --hash=sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34 \ + --hash=sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b \ + --hash=sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d \ + --hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \ + --hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \ + --hash=sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7 \ + --hash=sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737 \ + --hash=sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3 \ + --hash=sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d \ + --hash=sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358 \ + --hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \ + --hash=sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78 \ + --hash=sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803 \ + --hash=sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a \ + --hash=sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f \ + --hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \ + --hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5 + # via sphinxcontrib-openapi +requests==2.31.0 \ + --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ + --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 + # via sphinx +six==1.16.0 \ + --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ + --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 + # via + # fake-factory + # sphinx + # sphinxcontrib-httpdomain +snowballstemmer==2.2.0 \ + --hash=sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1 \ + --hash=sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a + # via sphinx +sphinx==1.8.6 \ + --hash=sha256:5973adbb19a5de30e15ab394ec8bc05700317fa83f122c349dd01804d983720f \ + --hash=sha256:e096b1b369dbb0fcb95a31ba8c9e1ae98c588e601f08eada032248e1696de4b1 + # via + # -r requirements.in + # guzzle-sphinx-theme + # sphinx-jsondomain + # sphinxcontrib-httpdomain +sphinx-jsondomain @ https://github.com/PowerDNS/sphinx-jsondomain/archive/refs/heads/no-type-links.zip \ + --hash=sha256:0df65f5b93902e9e4f03935f39d91ae2a6a782116078f8af99ec1e370f999257 + # via + # -r requirements.in + # sphinxcontrib-openapi +sphinxcontrib-fulltoc==1.2.0 \ + --hash=sha256:c845d62fc467f3135d4543e9f10e13ef91852683bd1c90fd19d07f9d36757cd9 + # via -r requirements.in +sphinxcontrib-httpdomain==1.8.1 \ + --hash=sha256:21eefe1270e4d9de8d717cc89ee92cc4871b8736774393bafc5e38a6bb77b1d5 \ + --hash=sha256:6c2dfe6ca282d75f66df333869bb0ce7331c01b475db6809ff9d107b7cdfe04b + # via sphinxcontrib-openapi +sphinxcontrib-openapi @ https://github.com/PowerDNS/sphinxcontrib-openapi/archive/refs/heads/use-jsondomain-pdns-py3.10-noscm.zip \ + --hash=sha256:7314b6a453d8c397d45a284255adbb55b7ba464f5f2ace32da4d08941ed76b2d + # via -r requirements.in +sphinxcontrib-serializinghtml==1.1.5 \ + --hash=sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd \ + --hash=sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952 + # via sphinxcontrib-websupport +sphinxcontrib-websupport==1.2.4 \ + --hash=sha256:4edf0223a0685a7c485ae5a156b6f529ba1ee481a1417817935b20bde1956232 \ + --hash=sha256:6fc9287dfc823fe9aa432463edd6cea47fa9ebbf488d7f289b322ffcfca075c7 + # via sphinx +urllib3==2.0.3 \ + --hash=sha256:48e7fafa40319d358848e1bc6809b208340fafe2096f1725d05d67443d0483d1 \ + --hash=sha256:bee28b5e56addb8226c96f7f13ac28cb4c301dd5ea8a6ca179c0b9835e032825 + # via requests + +# WARNING: The following packages were not pinned, but pip requires them to be +# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag. +# setuptools From 54c1bc22f3ae1af76253efa7ba859601d6d6c45e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 15 Jun 2023 14:17:03 +0200 Subject: [PATCH 340/909] dnsdist: Allow declaring custom metrics at runtime Also fixes a bug in the prometheus HELP and TYPE messages for custom metrics with labels, and adds a method to increment a counter by more than one. --- pdns/dnsdist-carbon.cc | 31 ++-- pdns/dnsdist-lua-inspection.cc | 26 +-- pdns/dnsdist-lua.cc | 75 +++++--- pdns/dnsdist-web.cc | 170 +++++++++--------- pdns/dnsdist.hh | 33 +++- pdns/dnsdistdist/dnsdist-lua-ffi-interface.h | 1 + pdns/dnsdistdist/dnsdist-lua-ffi.cc | 44 +++-- .../docs/reference/custommetrics.rst | 16 +- regression-tests.dnsdist/test_Advanced.py | 9 +- 9 files changed, 241 insertions(+), 164 deletions(-) diff --git a/pdns/dnsdist-carbon.cc b/pdns/dnsdist-carbon.cc index 90cdd5acbc8d..4280f05f3121 100644 --- a/pdns/dnsdist-carbon.cc +++ b/pdns/dnsdist-carbon.cc @@ -51,21 +51,24 @@ static bool doOneCarbonExport(const Carbon::Endpoint& endpoint) const time_t now = time(nullptr); - for (const auto& e : g_stats.entries) { - str << namespace_name << "." << hostname << "." << instance_name << "." << e.first << ' '; - if (const auto& val = boost::get(&e.second)) { - str << (*val)->load(); - } - else if (const auto& adval = boost::get*>(&e.second)) { - str << (*adval)->load(); - } - else if (const auto& dval = boost::get(&e.second)) { - str << **dval; - } - else if (const auto& func = boost::get(&e.second)) { - str << (*func)(e.first); + { + auto entries = g_stats.entries.read_lock(); + for (const auto& entry : *entries) { + str << namespace_name << "." << hostname << "." << instance_name << "." << entry.d_name << ' '; + if (const auto& val = boost::get(&entry.d_value)) { + str << (*val)->load(); + } + else if (const auto& adval = boost::get*>(&entry.d_value)) { + str << (*adval)->load(); + } + else if (const auto& dval = boost::get(&entry.d_value)) { + str << **dval; + } + else if (const auto& func = boost::get(&entry.d_value)) { + str << (*func)(entry.d_name); + } + str << ' ' << now << "\r\n"; } - str << ' ' << now << "\r\n"; } auto states = g_dstates.getLocal(); diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index d6755b00cd3b..27628c33eaa0 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -737,32 +737,32 @@ void setupLuaInspection(LuaContext& luaCtx) boost::format fmt("%-35s\t%+11s"); g_outputBuffer.clear(); - auto entries = g_stats.entries; + auto entries = *g_stats.entries.read_lock(); sort(entries.begin(), entries.end(), - [](const decltype(entries)::value_type& a, const decltype(entries)::value_type& b) { - return a.first < b.first; - }); + [](const decltype(entries)::value_type& a, const decltype(entries)::value_type& b) { + return a.d_name < b.d_name; + }); boost::format flt(" %9.1f"); - for (const auto& e : entries) { + for (const auto& entry : entries) { string second; - if (const auto& val = boost::get(&e.second)) { + if (const auto& val = boost::get(&entry.d_value)) { second = std::to_string((*val)->load()); } - else if (const auto& adval = boost::get*>(&e.second)) { + else if (const auto& adval = boost::get*>(&entry.d_value)) { second = (flt % (*adval)->load()).str(); } - else if (const auto& dval = boost::get(&e.second)) { + else if (const auto& dval = boost::get(&entry.d_value)) { second = (flt % (**dval)).str(); } - else if (const auto& func = boost::get(&e.second)) { - second = std::to_string((*func)(e.first)); + else if (const auto& func = boost::get(&entry.d_value)) { + second = std::to_string((*func)(entry.d_name)); } - if (leftcolumn.size() < g_stats.entries.size()/2) { - leftcolumn.push_back((fmt % e.first % second).str()); + if (leftcolumn.size() < entries.size() / 2) { + leftcolumn.push_back((fmt % entry.d_name % second).str()); } else { - rightcolumn.push_back((fmt % e.first % second).str()); + rightcolumn.push_back((fmt % entry.d_name % second).str()); } } diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index f0345ebf2ebf..0510d9a1afff 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -1828,9 +1828,14 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) luaCtx.writeFunction()>("getStatisticsCounters", []() { setLuaNoSideEffect(); std::unordered_map res; - for (const auto& entry : g_stats.entries) { - if (const auto& val = boost::get(&entry.second)) - res[entry.first] = (*val)->load(); + { + auto entries = g_stats.entries.read_lock(); + res.reserve(entries->size()); + for (const auto& entry : *entries) { + if (const auto& val = boost::get(&entry.d_value)) { + res[entry.d_name] = (*val)->load(); + } + } } return res; }); @@ -2909,25 +2914,24 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) }); luaCtx.writeFunction("declareMetric", [](const std::string& name, const std::string& type, const std::string& description, boost::optional customName) { - if (!checkConfigurationTime("declareMetric")) { - return false; - } if (!std::regex_match(name, std::regex("^[a-z0-9-]+$"))) { g_outputBuffer = "Unable to declare metric '" + name + "': invalid name\n"; errlog("Unable to declare metric '%s': invalid name", name); return false; } if (type == "counter") { - auto itp = g_stats.customCounters.emplace(name, 0); + auto customCounters = g_stats.customCounters.write_lock(); + auto itp = customCounters->insert({name, DNSDistStats::MutableCounter()}); if (itp.second) { - g_stats.entries.emplace_back(name, &g_stats.customCounters[name]); + g_stats.entries.write_lock()->emplace_back(DNSDistStats::EntryPair{name, &(*customCounters)[name].d_value}); addMetricDefinition(name, "counter", description, customName ? *customName : ""); } } else if (type == "gauge") { - auto itp = g_stats.customGauges.emplace(name, 0.); + auto customGauges = g_stats.customGauges.write_lock(); + auto itp = customGauges->insert({name, DNSDistStats::MutableGauge()}); if (itp.second) { - g_stats.entries.emplace_back(name, &g_stats.customGauges[name]); + g_stats.entries.write_lock()->emplace_back(DNSDistStats::EntryPair{name, &(*customGauges)[name].d_value}); addMetricDefinition(name, "gauge", description, customName ? *customName : ""); } } @@ -2938,43 +2942,56 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } return true; }); - luaCtx.writeFunction("incMetric", [](const std::string& name) { - auto metric = g_stats.customCounters.find(name); - if (metric != g_stats.customCounters.end()) { - return ++(metric->second); + luaCtx.writeFunction("incMetric", [](const std::string& name, boost::optional step) { + auto customCounters = g_stats.customCounters.read_lock(); + auto metric = customCounters->find(name); + if (metric != customCounters->end()) { + if (step) { + metric->second.d_value += *step; + return metric->second.d_value.load(); + } + return ++(metric->second.d_value); } g_outputBuffer = "incMetric no such metric '" + name + "'\n"; errlog("Unable to incMetric: no such name '%s'", name); return (uint64_t)0; }); luaCtx.writeFunction("decMetric", [](const std::string& name) { - auto metric = g_stats.customCounters.find(name); - if (metric != g_stats.customCounters.end()) { - return --(metric->second); + auto customCounters = g_stats.customCounters.read_lock(); + auto metric = customCounters->find(name); + if (metric != customCounters->end()) { + return --(metric->second.d_value); } g_outputBuffer = "decMetric no such metric '" + name + "'\n"; errlog("Unable to decMetric: no such name '%s'", name); return (uint64_t)0; }); - luaCtx.writeFunction("setMetric", [](const std::string& name, const double& value) { - auto metric = g_stats.customGauges.find(name); - if (metric != g_stats.customGauges.end()) { - metric->second = value; - return value; + luaCtx.writeFunction("setMetric", [](const std::string& name, const double value) -> double { + { + auto customGauges = g_stats.customGauges.read_lock(); + auto metric = customGauges->find(name); + if (metric != customGauges->end()) { + metric->second.d_value = value; + return value; + } } g_outputBuffer = "setMetric no such metric '" + name + "'\n"; errlog("Unable to setMetric: no such name '%s'", name); return 0.; }); luaCtx.writeFunction("getMetric", [](const std::string& name) { - auto counter = g_stats.customCounters.find(name); - if (counter != g_stats.customCounters.end()) { - return (double)counter->second.load(); + { + auto customCounters = g_stats.customCounters.read_lock(); + auto counter = customCounters->find(name); + if (counter != customCounters->end()) { + return (double)counter->second.d_value.load(); + } } - else { - auto gauge = g_stats.customGauges.find(name); - if (gauge != g_stats.customGauges.end()) { - return gauge->second.load(); + { + auto customGauges = g_stats.customGauges.read_lock(); + auto gauge = customGauges->find(name); + if (gauge != customGauges->end()) { + return gauge->second.d_value.load(); } } g_outputBuffer = "getMetric no such metric '" + name + "'\n"; diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index 21cdfd05b3a7..c7fd3812c23c 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -467,53 +467,58 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) std::ostringstream output; static const std::set metricBlacklist = { "special-memory-usage", "latency-count", "latency-sum" }; - for (const auto& e : g_stats.entries) { - const auto& metricName = std::get<0>(e); + { + auto entries = g_stats.entries.read_lock(); + for (const auto& entry : *entries) { + const auto& metricName = entry.d_name; - if (metricBlacklist.count(metricName) != 0) { - continue; - } + if (metricBlacklist.count(metricName) != 0) { + continue; + } - MetricDefinition metricDetails; - if (!s_metricDefinitions.getMetricDetails(metricName, metricDetails)) { - vinfolog("Do not have metric details for %s", metricName); - continue; - } + MetricDefinition metricDetails; + if (!s_metricDefinitions.getMetricDetails(metricName, metricDetails)) { + vinfolog("Do not have metric details for %s", metricName); + continue; + } - const std::string prometheusTypeName = s_metricDefinitions.getPrometheusStringMetricType(metricDetails.prometheusType); - if (prometheusTypeName.empty()) { - vinfolog("Unknown Prometheus type for %s", metricName); - continue; - } + const std::string prometheusTypeName = s_metricDefinitions.getPrometheusStringMetricType(metricDetails.prometheusType); + if (prometheusTypeName.empty()) { + vinfolog("Unknown Prometheus type for %s", metricName); + continue; + } - // Prometheus suggest using '_' instead of '-' - std::string prometheusMetricName; - if (metricDetails.customName.empty()) { - prometheusMetricName = "dnsdist_" + boost::replace_all_copy(metricName, "-", "_"); - } - else { - prometheusMetricName = metricDetails.customName; - } + // Prometheus suggest using '_' instead of '-' + std::string prometheusMetricName; + if (metricDetails.customName.empty()) { + prometheusMetricName = "dnsdist_" + boost::replace_all_copy(metricName, "-", "_"); + } + else { + prometheusMetricName = metricDetails.customName; + } - // for these we have the help and types encoded in the sources: - output << "# HELP " << prometheusMetricName << " " << metricDetails.description << "\n"; - output << "# TYPE " << prometheusMetricName << " " << prometheusTypeName << "\n"; - output << prometheusMetricName << " "; + // for these we have the help and types encoded in the sources + // but we need to be careful about labels in custom metrics + std::string helpName = prometheusMetricName.substr(0, prometheusMetricName.find('{')); + output << "# HELP " << helpName << " " << metricDetails.description << "\n"; + output << "# TYPE " << helpName << " " << prometheusTypeName << "\n"; + output << prometheusMetricName << " "; - if (const auto& val = boost::get(&std::get<1>(e))) { - output << (*val)->load(); - } - else if (const auto& adval = boost::get*>(&std::get<1>(e))) { - output << (*adval)->load(); - } - else if (const auto& dval = boost::get(&std::get<1>(e))) { - output << **dval; - } - else if (const auto& func = boost::get(&std::get<1>(e))) { - output << (*func)(std::get<0>(e)); - } + if (const auto& val = boost::get(&entry.d_value)) { + output << (*val)->load(); + } + else if (const auto& adval = boost::get*>(&entry.d_value)) { + output << (*adval)->load(); + } + else if (const auto& dval = boost::get(&entry.d_value)) { + output << **dval; + } + else if (const auto& func = boost::get(&entry.d_value)) { + output << (*func)(entry.d_name); + } - output << "\n"; + output << "\n"; + } } // Latency histogram buckets @@ -890,18 +895,19 @@ using namespace json11; static void addStatsToJSONObject(Json::object& obj) { - for (const auto& e : g_stats.entries) { - if (e.first == "special-memory-usage") { + auto entries = g_stats.entries.read_lock(); + for (const auto& entry : *entries) { + if (entry.d_name == "special-memory-usage") { continue; // Too expensive for get-all } - if (const auto& val = boost::get(&e.second)) { - obj.emplace(e.first, (double)(*val)->load()); - } else if (const auto& adval = boost::get*>(&e.second)) { - obj.emplace(e.first, (*adval)->load()); - } else if (const auto& dval = boost::get(&e.second)) { - obj.emplace(e.first, (**dval)); - } else if (const auto& func = boost::get(&e.second)) { - obj.emplace(e.first, (double)(*func)(e.first)); + if (const auto& val = boost::get(&entry.d_value)) { + obj.emplace(entry.d_name, (double)(*val)->load()); + } else if (const auto& adval = boost::get*>(&entry.d_value)) { + obj.emplace(entry.d_name, (*adval)->load()); + } else if (const auto& dval = boost::get(&entry.d_value)) { + obj.emplace(entry.d_name, (**dval)); + } else if (const auto& func = boost::get(&entry.d_value)) { + obj.emplace(entry.d_name, (double)(*func)(entry.d_name)); } } } @@ -1329,37 +1335,41 @@ static void handleStatsOnly(const YaHTTP::Request& req, YaHTTP::Response& resp) resp.status = 200; Json::array doc; - for(const auto& item : g_stats.entries) { - if (item.first == "special-memory-usage") - continue; // Too expensive for get-all + { + auto entries = g_stats.entries.read_lock(); + for (const auto& item : *entries) { + if (item.d_name == "special-memory-usage") { + continue; // Too expensive for get-all + } - if (const auto& val = boost::get(&item.second)) { - doc.push_back(Json::object { - { "type", "StatisticItem" }, - { "name", item.first }, - { "value", (double)(*val)->load() } - }); - } - else if (const auto& adval = boost::get*>(&item.second)) { - doc.push_back(Json::object { - { "type", "StatisticItem" }, - { "name", item.first }, - { "value", (*adval)->load() } - }); - } - else if (const auto& dval = boost::get(&item.second)) { - doc.push_back(Json::object { - { "type", "StatisticItem" }, - { "name", item.first }, - { "value", (**dval) } - }); - } - else if (const auto& func = boost::get(&item.second)) { - doc.push_back(Json::object { - { "type", "StatisticItem" }, - { "name", item.first }, - { "value", (double)(*func)(item.first) } - }); + if (const auto& val = boost::get(&item.d_value)) { + doc.push_back(Json::object { + { "type", "StatisticItem" }, + { "name", item.d_name }, + { "value", (double)(*val)->load() } + }); + } + else if (const auto& adval = boost::get*>(&item.d_value)) { + doc.push_back(Json::object { + { "type", "StatisticItem" }, + { "name", item.d_name }, + { "value", (*adval)->load() } + }); + } + else if (const auto& dval = boost::get(&item.d_value)) { + doc.push_back(Json::object { + { "type", "StatisticItem" }, + { "name", item.d_name }, + { "value", (**dval) } + }); + } + else if (const auto& func = boost::get(&item.d_value)) { + doc.push_back(Json::object { + { "type", "StatisticItem" }, + { "name", item.d_name }, + { "value", (double)(*func)(item.d_name) } + }); + } } } Json my_json = doc; diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index e55205599fb2..1f7b4e8704e2 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -369,10 +369,15 @@ struct DNSDistStats double latencyTCPAvg100{0}, latencyTCPAvg1000{0}, latencyTCPAvg10000{0}, latencyTCPAvg1000000{0}; double latencyDoTAvg100{0}, latencyDoTAvg1000{0}, latencyDoTAvg10000{0}, latencyDoTAvg1000000{0}; double latencyDoHAvg100{0}, latencyDoHAvg1000{0}, latencyDoHAvg10000{0}, latencyDoHAvg1000000{0}; - typedef std::function statfunction_t; - typedef boost::variant*, double*, statfunction_t> entry_t; + using statfunction_t = std::function; + using entry_t = boost::variant*, double*, statfunction_t>; + struct EntryPair + { + std::string d_name; + entry_t d_value; + }; - std::vector> entries{ + SharedLockGuarded> entries{std::vector{ {"responses", &responses}, {"servfail-responses", &servfailResponses}, {"queries", &queries}, @@ -450,9 +455,27 @@ struct DNSDistStats // Latency histogram {"latency-sum", &latencySum}, {"latency-count", &latencyCount}, + }}; + struct MutableCounter + { + MutableCounter() = default; + MutableCounter(MutableCounter&& rhs): d_value(rhs.d_value.load()) + { + } + + mutable stat_t d_value{0}; + }; + struct MutableGauge + { + MutableGauge() = default; + MutableGauge(MutableGauge&& rhs): d_value(rhs.d_value.load()) + { + } + + mutable pdns::stat_t_trait d_value{0}; }; - std::map> customCounters; - std::map, std::less<>> customGauges; + SharedLockGuarded>> customCounters; + SharedLockGuarded>> customGauges; }; extern struct DNSDistStats g_stats; diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h index c8d93978156f..5e393a7b948a 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h +++ b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h @@ -229,6 +229,7 @@ size_t dnsdist_ffi_dnspacket_get_name_at_offset_raw(const char* packet, size_t p void dnsdist_ffi_dnspacket_free(dnsdist_ffi_dnspacket_t*) __attribute__ ((visibility ("default"))); void dnsdist_ffi_metric_inc(const char* metricName, size_t metricNameLen) __attribute__ ((visibility ("default"))); +void dnsdist_ffi_metric_inc_by(const char* metricName, size_t metricNameLen, uint64_t value) __attribute__ ((visibility ("default"))); void dnsdist_ffi_metric_dec(const char* metricName, size_t metricNameLen) __attribute__ ((visibility ("default"))); void dnsdist_ffi_metric_set(const char* metricName, size_t metricNameLen, double value) __attribute__ ((visibility ("default"))); double dnsdist_ffi_metric_get(const char* metricName, size_t metricNameLen, bool isCounter) __attribute__ ((visibility ("default"))); diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index c9fa8407ef80..f42a01b6e10f 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -1603,25 +1603,37 @@ void dnsdist_ffi_dnspacket_free(dnsdist_ffi_dnspacket_t* packet) void dnsdist_ffi_metric_inc(const char* metricName, size_t metricNameLen) { - auto metric = g_stats.customCounters.find(std::string_view(metricName, metricNameLen)); - if (metric != g_stats.customCounters.end()) { - ++metric->second; + auto customCounters = g_stats.customCounters.read_lock(); + auto metric = customCounters->find(std::string_view(metricName, metricNameLen)); + if (metric != customCounters->end()) { + ++metric->second.d_value; + } +} + +void dnsdist_ffi_metric_inc_by(const char* metricName, size_t metricNameLen, uint64_t value) +{ + auto customCounters = g_stats.customCounters.write_lock(); + auto metric = customCounters->find(std::string_view(metricName, metricNameLen)); + if (metric != customCounters->end()) { + metric->second.d_value += value; } } void dnsdist_ffi_metric_dec(const char* metricName, size_t metricNameLen) { - auto metric = g_stats.customCounters.find(std::string_view(metricName, metricNameLen)); - if (metric != g_stats.customCounters.end()) { - --metric->second; + auto customCounters = g_stats.customCounters.read_lock(); + auto metric = customCounters->find(std::string_view(metricName, metricNameLen)); + if (metric != customCounters->end()) { + --metric->second.d_value; } } void dnsdist_ffi_metric_set(const char* metricName, size_t metricNameLen, double value) { - auto metric = g_stats.customGauges.find(std::string_view(metricName, metricNameLen)); - if (metric != g_stats.customGauges.end()) { - metric->second = value; + auto customGauges = g_stats.customGauges.read_lock(); + auto metric = customGauges->find(std::string_view(metricName, metricNameLen)); + if (metric != customGauges->end()) { + metric->second.d_value = value; } } @@ -1629,15 +1641,17 @@ double dnsdist_ffi_metric_get(const char* metricName, size_t metricNameLen, bool { auto name = std::string_view(metricName, metricNameLen); if (isCounter) { - auto counter = g_stats.customCounters.find(name); - if (counter != g_stats.customCounters.end()) { - return (double)counter->second.load(); + auto customCounters = g_stats.customCounters.read_lock(); + auto counter = customCounters->find(name); + if (counter != customCounters->end()) { + return (double)counter->second.d_value.load(); } } else { - auto gauge = g_stats.customGauges.find(name); - if (gauge != g_stats.customGauges.end()) { - return gauge->second.load(); + auto customGauges = g_stats.customGauges.read_lock(); + auto gauge = customGauges->find(name); + if (gauge != customGauges->end()) { + return gauge->second.d_value.load(); } } return 0.; diff --git a/pdns/dnsdistdist/docs/reference/custommetrics.rst b/pdns/dnsdistdist/docs/reference/custommetrics.rst index 7cf5fa1a6fc4..e0af5f51c277 100644 --- a/pdns/dnsdistdist/docs/reference/custommetrics.rst +++ b/pdns/dnsdistdist/docs/reference/custommetrics.rst @@ -1,9 +1,9 @@ Custom Metrics ===================================== -You can define at configuration time your own metrics that can be updated using Lua. +You can define at your own metrics that can be updated using Lua. -The first step is to declare a new metric using :func:`declareMetric`. +The first step is to declare a new metric using :func:`declareMetric`. In 1.8.0 the declaration had to be done at configuration time, but since 1.8.1 it can be done at any point. Then you can update those at runtime using the following functions, depending on the metric type: @@ -14,6 +14,9 @@ Then you can update those at runtime using the following functions, depending on .. versionadded:: 1.8.0 + .. versionchanged:: 1.8.1 + This function can now be used at runtime, instead of only at configuration time. + Return true if declaration was successful :param str name: The name of the metric, lowercase alphanumerical characters and dashes (-) only @@ -21,14 +24,18 @@ Then you can update those at runtime using the following functions, depending on :param str name: The description of the metric :param str prometheusName: The name to use in the prometheus metrics, if supplied. Otherwise the regular name will be used, prefixed with ``dnsdist_`` and ``-`` replaced by ``_``. -.. function:: incMetric(name) -> int +.. function:: incMetric(name [, step]) -> int .. versionadded:: 1.8.0 - Increment counter by one, will issue an error if the metric is not declared or not a ``counter`` + .. versionchanged:: 1.8.1 + Optional ``step`` parameter added. + + Increment counter by one (or more, see the ``step`` parameter), will issue an error if the metric is not declared or not a ``counter`` Return the new value :param str name: The name of the metric + :param int step: By how much the counter should be incremented, default to 1. .. function:: decMetric(name) -> int @@ -55,3 +62,4 @@ Then you can update those at runtime using the following functions, depending on Return the new value :param str name: The name of the metric + :param double value: The new value diff --git a/regression-tests.dnsdist/test_Advanced.py b/regression-tests.dnsdist/test_Advanced.py index 5c3efbb5016d..186138cbd510 100644 --- a/regression-tests.dnsdist/test_Advanced.py +++ b/regression-tests.dnsdist/test_Advanced.py @@ -597,18 +597,19 @@ class TestCustomMetrics(DNSDistTest): initialCounter = getMetric("my-custom-counter") initialGauge = getMetric("my-custom-counter") incMetric("my-custom-counter") + incMetric("my-custom-counter", 41) setMetric("my-custom-gauge", initialGauge + 1.3) - if getMetric("my-custom-counter") ~= (initialCounter + 1) or getMetric("my-custom-gauge") ~= (initialGauge + 1.3) then + if getMetric("my-custom-counter") ~= (initialCounter + 42) or getMetric("my-custom-gauge") ~= (initialGauge + 1.3) then return DNSAction.Spoof, '1.2.3.5' end return DNSAction.Spoof, '4.3.2.1' end function declareNewMetric(dq) - if declareMetric("new-runtime-metric", "counter", "Metric declaration at runtime should fail") then - return DNSAction.Spoof, '1.2.3.4' + if declareMetric("new-runtime-metric", "counter", "Metric declaration at runtime should work fine") then + return DNSAction.None end - return DNSAction.None + return DNSAction.Spoof, '1.2.3.4' end declareMetric("my-custom-counter", "counter", "Number of tests run") From 67cbba12a6e203d17f1286421d8acfc1b13559d1 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Jun 2023 13:39:16 +0200 Subject: [PATCH 341/909] dnsdist: Implement a FFI method to declare a new custom metric --- pdns/dnsdist-lua.cc | 99 +++++---------- pdns/dnsdistdist/Makefile.am | 2 + pdns/dnsdistdist/dnsdist-lua-ffi-interface.h | 1 + pdns/dnsdistdist/dnsdist-lua-ffi.cc | 60 +++++---- pdns/dnsdistdist/dnsdist-metrics.cc | 116 ++++++++++++++++++ pdns/dnsdistdist/dnsdist-metrics.hh | 39 ++++++ .../docs/reference/custommetrics.rst | 6 +- pdns/dnsdistdist/test-dnsdist-lua-ffi.cc | 5 + 8 files changed, 227 insertions(+), 101 deletions(-) create mode 100644 pdns/dnsdistdist/dnsdist-metrics.cc create mode 100644 pdns/dnsdistdist/dnsdist-metrics.hh diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 0510d9a1afff..aea5a1b66e40 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -47,6 +47,7 @@ #ifdef LUAJIT_VERSION #include "dnsdist-lua-ffi.hh" #endif /* LUAJIT_VERSION */ +#include "dnsdist-metrics.hh" #include "dnsdist-nghttp2.hh" #include "dnsdist-proxy-protocol.hh" #include "dnsdist-rings.hh" @@ -2914,89 +2915,49 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) }); luaCtx.writeFunction("declareMetric", [](const std::string& name, const std::string& type, const std::string& description, boost::optional customName) { - if (!std::regex_match(name, std::regex("^[a-z0-9-]+$"))) { - g_outputBuffer = "Unable to declare metric '" + name + "': invalid name\n"; - errlog("Unable to declare metric '%s': invalid name", name); - return false; - } - if (type == "counter") { - auto customCounters = g_stats.customCounters.write_lock(); - auto itp = customCounters->insert({name, DNSDistStats::MutableCounter()}); - if (itp.second) { - g_stats.entries.write_lock()->emplace_back(DNSDistStats::EntryPair{name, &(*customCounters)[name].d_value}); - addMetricDefinition(name, "counter", description, customName ? *customName : ""); - } - } - else if (type == "gauge") { - auto customGauges = g_stats.customGauges.write_lock(); - auto itp = customGauges->insert({name, DNSDistStats::MutableGauge()}); - if (itp.second) { - g_stats.entries.write_lock()->emplace_back(DNSDistStats::EntryPair{name, &(*customGauges)[name].d_value}); - addMetricDefinition(name, "gauge", description, customName ? *customName : ""); - } - } - else { - g_outputBuffer = "declareMetric unknown type '" + type + "'\n"; - errlog("Unable to declareMetric '%s': no such type '%s'", name, type); + auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName ? std::optional(*customName) : std::nullopt); + if (result) { + g_outputBuffer += *result + "\n"; + errlog("%s", *result); return false; } return true; }); luaCtx.writeFunction("incMetric", [](const std::string& name, boost::optional step) { - auto customCounters = g_stats.customCounters.read_lock(); - auto metric = customCounters->find(name); - if (metric != customCounters->end()) { - if (step) { - metric->second.d_value += *step; - return metric->second.d_value.load(); - } - return ++(metric->second.d_value); + auto result = dnsdist::metrics::incrementCustomCounter(name, step ? *step : 1); + if (const auto* errorStr = std::get_if(&result)) { + g_outputBuffer = *errorStr + "'\n"; + errlog("%s", *errorStr); + return static_cast(0); } - g_outputBuffer = "incMetric no such metric '" + name + "'\n"; - errlog("Unable to incMetric: no such name '%s'", name); - return (uint64_t)0; + return std::get(result); }); - luaCtx.writeFunction("decMetric", [](const std::string& name) { - auto customCounters = g_stats.customCounters.read_lock(); - auto metric = customCounters->find(name); - if (metric != customCounters->end()) { - return --(metric->second.d_value); + luaCtx.writeFunction("decMetric", [](const std::string& name, boost::optional step) { + auto result = dnsdist::metrics::decrementCustomCounter(name, step ? *step : 1); + if (const auto* errorStr = std::get_if(&result)) { + g_outputBuffer = *errorStr + "'\n"; + errlog("%s", *errorStr); + return static_cast(0); } - g_outputBuffer = "decMetric no such metric '" + name + "'\n"; - errlog("Unable to decMetric: no such name '%s'", name); - return (uint64_t)0; + return std::get(result); }); luaCtx.writeFunction("setMetric", [](const std::string& name, const double value) -> double { - { - auto customGauges = g_stats.customGauges.read_lock(); - auto metric = customGauges->find(name); - if (metric != customGauges->end()) { - metric->second.d_value = value; - return value; - } + auto result = dnsdist::metrics::setCustomGauge(name, value); + if (const auto* errorStr = std::get_if(&result)) { + g_outputBuffer = *errorStr + "'\n"; + errlog("%s", *errorStr); + return 0.; } - g_outputBuffer = "setMetric no such metric '" + name + "'\n"; - errlog("Unable to setMetric: no such name '%s'", name); - return 0.; + return std::get(result); }); luaCtx.writeFunction("getMetric", [](const std::string& name) { - { - auto customCounters = g_stats.customCounters.read_lock(); - auto counter = customCounters->find(name); - if (counter != customCounters->end()) { - return (double)counter->second.d_value.load(); - } - } - { - auto customGauges = g_stats.customGauges.read_lock(); - auto gauge = customGauges->find(name); - if (gauge != customGauges->end()) { - return gauge->second.d_value.load(); - } + auto result = dnsdist::metrics::getCustomMetric(name); + if (const auto* errorStr = std::get_if(&result)) { + g_outputBuffer = *errorStr + "'\n"; + errlog("%s", *errorStr); + return 0.; } - g_outputBuffer = "getMetric no such metric '" + name + "'\n"; - errlog("Unable to getMetric: no such name '%s'", name); - return 0.; + return std::get(result); }); } diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index e9c7ca2086cd..aaac2e206666 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -175,6 +175,7 @@ dnsdist_SOURCES = \ dnsdist-lua-web.cc \ dnsdist-lua.cc dnsdist-lua.hh \ dnsdist-mac-address.cc dnsdist-mac-address.hh \ + dnsdist-metrics.cc dnsdist-metrics.hh \ dnsdist-nghttp2.cc dnsdist-nghttp2.hh \ dnsdist-prometheus.hh \ dnsdist-protobuf.cc dnsdist-protobuf.hh \ @@ -269,6 +270,7 @@ testrunner_SOURCES = \ dnsdist-lua-network.cc dnsdist-lua-network.hh \ dnsdist-lua-vars.cc \ dnsdist-mac-address.cc dnsdist-mac-address.hh \ + dnsdist-metrics.cc dnsdist-metrics.hh \ dnsdist-nghttp2.cc dnsdist-nghttp2.hh \ dnsdist-protocols.cc dnsdist-protocols.hh \ dnsdist-proxy-protocol.cc dnsdist-proxy-protocol.hh \ diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h index 5e393a7b948a..e7cc8fe87333 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h +++ b/pdns/dnsdistdist/dnsdist-lua-ffi-interface.h @@ -228,6 +228,7 @@ uint16_t dnsdist_ffi_dnspacket_get_record_content_offset(const dnsdist_ffi_dnspa size_t dnsdist_ffi_dnspacket_get_name_at_offset_raw(const char* packet, size_t packetSize, size_t offset, char* name, size_t nameSize) __attribute__ ((visibility ("default"))); void dnsdist_ffi_dnspacket_free(dnsdist_ffi_dnspacket_t*) __attribute__ ((visibility ("default"))); +bool dnsdist_ffi_metric_declare(const char* name, size_t nameLen, const char* type, const char* description, const char* customName) __attribute__ ((visibility ("default"))); void dnsdist_ffi_metric_inc(const char* metricName, size_t metricNameLen) __attribute__ ((visibility ("default"))); void dnsdist_ffi_metric_inc_by(const char* metricName, size_t metricNameLen, uint64_t value) __attribute__ ((visibility ("default"))); void dnsdist_ffi_metric_dec(const char* metricName, size_t metricNameLen) __attribute__ ((visibility ("default"))); diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index f42a01b6e10f..bf46aadece44 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -25,6 +25,7 @@ #include "dnsdist-ecs.hh" #include "dnsdist-lua-ffi.hh" #include "dnsdist-mac-address.hh" +#include "dnsdist-metrics.hh" #include "dnsdist-lua-network.hh" #include "dnsdist-lua.hh" #include "dnsdist-ecs.hh" @@ -1601,60 +1602,57 @@ void dnsdist_ffi_dnspacket_free(dnsdist_ffi_dnspacket_t* packet) } } +bool dnsdist_ffi_metric_declare(const char* name, size_t nameLen, const char* type, const char* description, const char* customName) +{ + if (name == nullptr || nameLen == 0 || type == nullptr || description == nullptr) { + return false; + } + auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName ? std::optional(customName) : std::nullopt); + if (result) { + return false; + } + return true; +} + void dnsdist_ffi_metric_inc(const char* metricName, size_t metricNameLen) { - auto customCounters = g_stats.customCounters.read_lock(); - auto metric = customCounters->find(std::string_view(metricName, metricNameLen)); - if (metric != customCounters->end()) { - ++metric->second.d_value; + auto result = dnsdist::metrics::incrementCustomCounter(std::string_view(metricName, metricNameLen), 1U); + if (const auto* errorStr = std::get_if(&result)) { + return; } } void dnsdist_ffi_metric_inc_by(const char* metricName, size_t metricNameLen, uint64_t value) { - auto customCounters = g_stats.customCounters.write_lock(); - auto metric = customCounters->find(std::string_view(metricName, metricNameLen)); - if (metric != customCounters->end()) { - metric->second.d_value += value; + auto result = dnsdist::metrics::incrementCustomCounter(std::string_view(metricName, metricNameLen), value); + if (const auto* errorStr = std::get_if(&result)) { + return; } } void dnsdist_ffi_metric_dec(const char* metricName, size_t metricNameLen) { - auto customCounters = g_stats.customCounters.read_lock(); - auto metric = customCounters->find(std::string_view(metricName, metricNameLen)); - if (metric != customCounters->end()) { - --metric->second.d_value; + auto result = dnsdist::metrics::decrementCustomCounter(std::string_view(metricName, metricNameLen), 1U); + if (const auto* errorStr = std::get_if(&result)) { + return; } } void dnsdist_ffi_metric_set(const char* metricName, size_t metricNameLen, double value) { - auto customGauges = g_stats.customGauges.read_lock(); - auto metric = customGauges->find(std::string_view(metricName, metricNameLen)); - if (metric != customGauges->end()) { - metric->second.d_value = value; + auto result = dnsdist::metrics::setCustomGauge(std::string_view(metricName, metricNameLen), value); + if (const auto* errorStr = std::get_if(&result)) { + return; } } double dnsdist_ffi_metric_get(const char* metricName, size_t metricNameLen, bool isCounter) { - auto name = std::string_view(metricName, metricNameLen); - if (isCounter) { - auto customCounters = g_stats.customCounters.read_lock(); - auto counter = customCounters->find(name); - if (counter != customCounters->end()) { - return (double)counter->second.d_value.load(); - } - } - else { - auto customGauges = g_stats.customGauges.read_lock(); - auto gauge = customGauges->find(name); - if (gauge != customGauges->end()) { - return gauge->second.d_value.load(); - } + auto result = dnsdist::metrics::getCustomMetric(std::string_view(metricName, metricNameLen)); + if (const auto* errorStr = std::get_if(&result)) { + return 0.; } - return 0.; + return std::get(result); } const char* dnsdist_ffi_network_message_get_payload(const dnsdist_ffi_network_message_t* msg) diff --git a/pdns/dnsdistdist/dnsdist-metrics.cc b/pdns/dnsdistdist/dnsdist-metrics.cc new file mode 100644 index 000000000000..0eed93566aa4 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-metrics.cc @@ -0,0 +1,116 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include + +#include "dnsdist-metrics.hh" +#include "dnsdist.hh" +#include "dnsdist-web.hh" + +namespace dnsdist::metrics { + +std::optional declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional customName) +{ + if (!std::regex_match(name, std::regex("^[a-z0-9-]+$"))) { + return std::string("Unable to declare metric '") + std::string(name) + std::string("': invalid name\n"); + } + + if (type == "counter") { + auto customCounters = g_stats.customCounters.write_lock(); + auto itp = customCounters->insert({name, DNSDistStats::MutableCounter()}); + if (itp.second) { + g_stats.entries.write_lock()->emplace_back(DNSDistStats::EntryPair{name, &(*customCounters)[name].d_value}); + addMetricDefinition(name, "counter", description, customName ? *customName : ""); + } + } + else if (type == "gauge") { + auto customGauges = g_stats.customGauges.write_lock(); + auto itp = customGauges->insert({name, DNSDistStats::MutableGauge()}); + if (itp.second) { + g_stats.entries.write_lock()->emplace_back(DNSDistStats::EntryPair{name, &(*customGauges)[name].d_value}); + addMetricDefinition(name, "gauge", description, customName ? *customName : ""); + } + } + else { + return std::string("Unable to declare metric: unknown type '") + type + "'"; + } + return std::nullopt; +} + +std::variant incrementCustomCounter(const std::string_view& name, uint64_t step) +{ + auto customCounters = g_stats.customCounters.read_lock(); + auto metric = customCounters->find(name); + if (metric != customCounters->end()) { + if (step) { + metric->second.d_value += step; + return metric->second.d_value.load(); + } + return ++(metric->second.d_value); + } + return std::string("Unable to increment custom metric '") + std::string(name) + "': no such metric"; +} + +std::variant decrementCustomCounter(const std::string_view& name, uint64_t step) +{ + auto customCounters = g_stats.customCounters.read_lock(); + auto metric = customCounters->find(name); + if (metric != customCounters->end()) { + if (step) { + metric->second.d_value -= step; + return metric->second.d_value.load(); + } + return --(metric->second.d_value); + } + return std::string("Unable to decrement custom metric '") + std::string(name) + "': no such metric"; +} + +std::variant setCustomGauge(const std::string_view& name, const double value) +{ + auto customGauges = g_stats.customGauges.read_lock(); + auto metric = customGauges->find(name); + if (metric != customGauges->end()) { + metric->second.d_value = value; + return value; + } + + return std::string("Unable to set metric '") + std::string(name) + "': no such metric"; +} + +std::variant getCustomMetric(const std::string_view& name) +{ + { + auto customCounters = g_stats.customCounters.read_lock(); + auto counter = customCounters->find(name); + if (counter != customCounters->end()) { + return static_cast(counter->second.d_value.load()); + } + } + { + auto customGauges = g_stats.customGauges.read_lock(); + auto gauge = customGauges->find(name); + if (gauge != customGauges->end()) { + return gauge->second.d_value.load(); + } + } + return std::string("Unable to get metric '") + std::string(name) + "': no such metric"; +} +} diff --git a/pdns/dnsdistdist/dnsdist-metrics.hh b/pdns/dnsdistdist/dnsdist-metrics.hh new file mode 100644 index 000000000000..88a812ea8e5e --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-metrics.hh @@ -0,0 +1,39 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +#include +#include +#include +#include +#include + +namespace dnsdist::metrics +{ + using Error = std::string; + + [[nodiscard]] std::optional declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional customName); + [[nodiscard]] std::variant incrementCustomCounter(const std::string_view& name, uint64_t step); + [[nodiscard]] std::variant decrementCustomCounter(const std::string_view& name, uint64_t step); + [[nodiscard]] std::variant setCustomGauge(const std::string_view& name, const double value); + [[nodiscard]] std::variant getCustomMetric(const std::string_view& name); +} diff --git a/pdns/dnsdistdist/docs/reference/custommetrics.rst b/pdns/dnsdistdist/docs/reference/custommetrics.rst index e0af5f51c277..0f656b7f9c9e 100644 --- a/pdns/dnsdistdist/docs/reference/custommetrics.rst +++ b/pdns/dnsdistdist/docs/reference/custommetrics.rst @@ -41,10 +41,14 @@ Then you can update those at runtime using the following functions, depending on .. versionadded:: 1.8.0 - Decrement counter by one, will issue an error if the metric is not declared or not a ``counter`` + .. versionchanged:: 1.8.1 + Optional ``step`` parameter added. + + Decrement counter by one (or more, see the ``step`` parameter), will issue an error if the metric is not declared or not a ``counter`` Return the new value :param str name: The name of the metric + :param int step: By how much the counter should be decremented, default to 1. .. function:: getMetric(name) -> double diff --git a/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc b/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc index e6f0e1e21c23..8a5a06763bff 100644 --- a/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc @@ -29,6 +29,11 @@ #include "dnsparser.hh" #include "dnswriter.hh" +bool addMetricDefinition(const std::string& name, const std::string& type, const std::string& description, const std::string& customPrometheusName) +{ + return true; +} + BOOST_AUTO_TEST_SUITE(test_dnsdist_lua_ffi) BOOST_AUTO_TEST_CASE(test_Query) From 6ba8d6cacd8eb8ccc246ee2893c07fe3547d9e5c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Jun 2023 15:00:07 +0200 Subject: [PATCH 342/909] dnsdist: Move metrics to dnsdist-metrics.{cc,hh} This makes it possible to get more parts of the code out of the dnsdist.hh header, which ideally should go. --- pdns/dnsdist-carbon.cc | 11 +- pdns/dnsdist-dnscrypt.cc | 3 +- pdns/dnsdist-lua-inspection.cc | 10 +- pdns/dnsdist-lua.cc | 6 +- pdns/dnsdist-snmp.cc | 75 ++++++----- pdns/dnsdist-tcp.cc | 12 +- pdns/dnsdist-web.cc | 47 +++---- pdns/dnsdist.cc | 116 ++++++++-------- pdns/dnsdist.hh | 150 --------------------- pdns/dnsdistdist/dnsdist-backend.cc | 13 +- pdns/dnsdistdist/dnsdist-dynblocks.cc | 3 +- pdns/dnsdistdist/dnsdist-metrics.cc | 130 ++++++++++++++++-- pdns/dnsdistdist/dnsdist-metrics.hh | 71 +++++++++- pdns/dnsdistdist/dnsdist-nghttp2.cc | 2 +- pdns/dnsdistdist/dnsdist-proxy-protocol.cc | 9 +- pdns/dnsdistdist/dnsdist-secpoll.cc | 3 +- pdns/dnsdistdist/dnsdist-tcp.hh | 5 +- pdns/dnsdistdist/doh.cc | 15 ++- pdns/dnsdistdist/test-dnsdisttcp_cc.cc | 1 - 19 files changed, 353 insertions(+), 329 deletions(-) diff --git a/pdns/dnsdist-carbon.cc b/pdns/dnsdist-carbon.cc index 4280f05f3121..65f739721e87 100644 --- a/pdns/dnsdist-carbon.cc +++ b/pdns/dnsdist-carbon.cc @@ -25,6 +25,7 @@ #include "dnsdist-carbon.hh" #include "dnsdist.hh" +#include "dnsdist-metrics.hh" #ifndef DISABLE_CARBON #include "dolog.hh" @@ -52,19 +53,19 @@ static bool doOneCarbonExport(const Carbon::Endpoint& endpoint) const time_t now = time(nullptr); { - auto entries = g_stats.entries.read_lock(); + auto entries = dnsdist::metrics::g_stats.entries.read_lock(); for (const auto& entry : *entries) { str << namespace_name << "." << hostname << "." << instance_name << "." << entry.d_name << ' '; - if (const auto& val = boost::get(&entry.d_value)) { + if (const auto& val = std::get_if(&entry.d_value)) { str << (*val)->load(); } - else if (const auto& adval = boost::get*>(&entry.d_value)) { + else if (const auto& adval = std::get_if*>(&entry.d_value)) { str << (*adval)->load(); } - else if (const auto& dval = boost::get(&entry.d_value)) { + else if (const auto& dval = std::get_if(&entry.d_value)) { str << **dval; } - else if (const auto& func = boost::get(&entry.d_value)) { + else if (const auto& func = std::get_if(&entry.d_value)) { str << (*func)(entry.d_name); } str << ' ' << now << "\r\n"; diff --git a/pdns/dnsdist-dnscrypt.cc b/pdns/dnsdist-dnscrypt.cc index 99301445c3f7..8f02910aaa8a 100644 --- a/pdns/dnsdist-dnscrypt.cc +++ b/pdns/dnsdist-dnscrypt.cc @@ -21,6 +21,7 @@ */ #include "dolog.hh" #include "dnsdist.hh" +#include "dnsdist-metrics.hh" #include "dnscrypt.hh" #ifdef HAVE_DNSCRYPT @@ -40,7 +41,7 @@ int handleDNSCryptQuery(PacketBuffer& packet, DNSCryptQuery& query, bool tcp, ti } if (packet.size() < static_cast(sizeof(struct dnsheader))) { - ++g_stats.nonCompliantQueries; + ++dnsdist::metrics::g_stats.nonCompliantQueries; return false; } diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index 27628c33eaa0..66200df0eaa5 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -737,7 +737,7 @@ void setupLuaInspection(LuaContext& luaCtx) boost::format fmt("%-35s\t%+11s"); g_outputBuffer.clear(); - auto entries = *g_stats.entries.read_lock(); + auto entries = *dnsdist::metrics::g_stats.entries.read_lock(); sort(entries.begin(), entries.end(), [](const decltype(entries)::value_type& a, const decltype(entries)::value_type& b) { return a.d_name < b.d_name; @@ -745,16 +745,16 @@ void setupLuaInspection(LuaContext& luaCtx) boost::format flt(" %9.1f"); for (const auto& entry : entries) { string second; - if (const auto& val = boost::get(&entry.d_value)) { + if (const auto& val = std::get_if(&entry.d_value)) { second = std::to_string((*val)->load()); } - else if (const auto& adval = boost::get*>(&entry.d_value)) { + else if (const auto& adval = std::get_if*>(&entry.d_value)) { second = (flt % (*adval)->load()).str(); } - else if (const auto& dval = boost::get(&entry.d_value)) { + else if (const auto& dval = std::get_if(&entry.d_value)) { second = (flt % (**dval)).str(); } - else if (const auto& func = boost::get(&entry.d_value)) { + else if (const auto& func = std::get_if(&entry.d_value)) { second = std::to_string((*func)(entry.d_name)); } diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index aea5a1b66e40..dcd7a5c3f5c4 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -1830,10 +1830,10 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) setLuaNoSideEffect(); std::unordered_map res; { - auto entries = g_stats.entries.read_lock(); + auto entries = dnsdist::metrics::g_stats.entries.read_lock(); res.reserve(entries->size()); for (const auto& entry : *entries) { - if (const auto& val = boost::get(&entry.d_value)) { + if (const auto& val = std::get_if(&entry.d_value)) { res[entry.d_name] = (*val)->load(); } } @@ -2221,7 +2221,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) #ifndef DISABLE_SECPOLL luaCtx.writeFunction("showSecurityStatus", []() { setLuaNoSideEffect(); - g_outputBuffer = std::to_string(g_stats.securityStatus) + "\n"; + g_outputBuffer = std::to_string(dnsdist::metrics::g_stats.securityStatus) + "\n"; }); luaCtx.writeFunction("setSecurityPollSuffix", [](const std::string& suffix) { diff --git a/pdns/dnsdist-snmp.cc b/pdns/dnsdist-snmp.cc index 149acbc511bb..181561a39c72 100644 --- a/pdns/dnsdist-snmp.cc +++ b/pdns/dnsdist-snmp.cc @@ -1,5 +1,6 @@ #include "dnsdist-snmp.hh" +#include "dnsdist-metrics.hh" #include "dolog.hh" bool g_snmpEnabled{false}; @@ -55,7 +56,7 @@ static const oid securityStatusOID[] = { DNSDIST_STATS_OID, 38 }; static const oid specialMemoryUsageOID[] = { DNSDIST_STATS_OID, 39 }; static const oid ruleTruncatedOID[] = { DNSDIST_STATS_OID, 40 }; -static std::unordered_map s_statsMap; +static std::unordered_map s_statsMap; /* We are never called for a GETNEXT if it's registered as a "instance", as it's "magically" handled for us. */ @@ -80,7 +81,7 @@ static int handleCounter64Stats(netsnmp_mib_handler* handler, return SNMP_ERR_GENERR; } - if (const auto& val = boost::get(&it->second)) { + if (const auto& val = std::get_if(&it->second)) { return DNSDistSNMPAgent::setCounter64Value(requests, (*val)->load()); } @@ -125,7 +126,7 @@ static int handleFloatStats(netsnmp_mib_handler* handler, return SNMP_ERR_GENERR; } - if (const auto& val = boost::get(&it->second)) { + if (const auto& val = std::get_if(&it->second)) { std::string str(std::to_string(**val)); snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, @@ -176,11 +177,11 @@ static int handleGauge64Stats(netsnmp_mib_handler* handler, } std::string str; - uint64_t value = (*boost::get(&it->second))(str); + uint64_t value = (*std::get_if(&it->second))(str); return DNSDistSNMPAgent::setCounter64Value(requests, value); } -static void registerGauge64Stat(const char* name, const oid statOID[], size_t statOIDLength, DNSDistStats::statfunction_t ptr) +static void registerGauge64Stat(const char* name, const oid statOID[], size_t statOIDLength, dnsdist::metrics::Stats::statfunction_t ptr) { if (statOIDLength != OID_LENGTH(queriesOID)) { errlog("Invalid OID for SNMP Gauge64 statistic %s", name); @@ -552,44 +553,44 @@ DNSDistSNMPAgent::DNSDistSNMPAgent(const std::string& name, const std::string& d { #ifdef HAVE_NET_SNMP - registerCounter64Stat("queries", queriesOID, OID_LENGTH(queriesOID), &g_stats.queries); - registerCounter64Stat("responses", responsesOID, OID_LENGTH(responsesOID), &g_stats.responses); - registerCounter64Stat("servfailResponses", servfailResponsesOID, OID_LENGTH(servfailResponsesOID), &g_stats.servfailResponses); - registerCounter64Stat("aclDrops", aclDropsOID, OID_LENGTH(aclDropsOID), &g_stats.aclDrops); - registerCounter64Stat("ruleDrop", ruleDropOID, OID_LENGTH(ruleDropOID), &g_stats.ruleDrop); - registerCounter64Stat("ruleNXDomain", ruleNXDomainOID, OID_LENGTH(ruleNXDomainOID), &g_stats.ruleNXDomain); - registerCounter64Stat("ruleRefused", ruleRefusedOID, OID_LENGTH(ruleRefusedOID), &g_stats.ruleRefused); - registerCounter64Stat("ruleServFail", ruleServFailOID, OID_LENGTH(ruleServFailOID), &g_stats.ruleServFail); - registerCounter64Stat("ruleTruncated", ruleTruncatedOID, OID_LENGTH(ruleTruncatedOID), &g_stats.ruleTruncated); - registerCounter64Stat("selfAnswered", selfAnsweredOID, OID_LENGTH(selfAnsweredOID), &g_stats.selfAnswered); - registerCounter64Stat("downstreamTimeouts", downstreamTimeoutsOID, OID_LENGTH(downstreamTimeoutsOID), &g_stats.downstreamTimeouts); - registerCounter64Stat("downstreamSendErrors", downstreamSendErrorsOID, OID_LENGTH(downstreamSendErrorsOID), &g_stats.downstreamSendErrors); - registerCounter64Stat("truncFail", truncFailOID, OID_LENGTH(truncFailOID), &g_stats.truncFail); - registerCounter64Stat("noPolicy", noPolicyOID, OID_LENGTH(noPolicyOID), &g_stats.noPolicy); - registerCounter64Stat("latency0_1", latency0_1OID, OID_LENGTH(latency0_1OID), &g_stats.latency0_1); - registerCounter64Stat("latency1_10", latency1_10OID, OID_LENGTH(latency1_10OID), &g_stats.latency1_10); - registerCounter64Stat("latency10_50", latency10_50OID, OID_LENGTH(latency10_50OID), &g_stats.latency10_50); - registerCounter64Stat("latency50_100", latency50_100OID, OID_LENGTH(latency50_100OID), &g_stats.latency50_100); - registerCounter64Stat("latency100_1000", latency100_1000OID, OID_LENGTH(latency100_1000OID), &g_stats.latency100_1000); - registerCounter64Stat("latencySlow", latencySlowOID, OID_LENGTH(latencySlowOID), &g_stats.latencySlow); - registerCounter64Stat("nonCompliantQueries", nonCompliantQueriesOID, OID_LENGTH(nonCompliantQueriesOID), &g_stats.nonCompliantQueries); - registerCounter64Stat("nonCompliantResponses", nonCompliantResponsesOID, OID_LENGTH(nonCompliantResponsesOID), &g_stats.nonCompliantResponses); - registerCounter64Stat("rdQueries", rdQueriesOID, OID_LENGTH(rdQueriesOID), &g_stats.rdQueries); - registerCounter64Stat("emptyQueries", emptyQueriesOID, OID_LENGTH(emptyQueriesOID), &g_stats.emptyQueries); - registerCounter64Stat("cacheHits", cacheHitsOID, OID_LENGTH(cacheHitsOID), &g_stats.cacheHits); - registerCounter64Stat("cacheMisses", cacheMissesOID, OID_LENGTH(cacheMissesOID), &g_stats.cacheMisses); - registerCounter64Stat("dynBlocked", dynBlockedOID, OID_LENGTH(dynBlockedOID), &g_stats.dynBlocked); - registerFloatStat("latencyAvg100", latencyAvg100OID, OID_LENGTH(latencyAvg100OID), &g_stats.latencyAvg100); - registerFloatStat("latencyAvg1000", latencyAvg1000OID, OID_LENGTH(latencyAvg1000OID), &g_stats.latencyAvg1000); - registerFloatStat("latencyAvg10000", latencyAvg10000OID, OID_LENGTH(latencyAvg10000OID), &g_stats.latencyAvg10000); - registerFloatStat("latencyAvg1000000", latencyAvg1000000OID, OID_LENGTH(latencyAvg1000000OID), &g_stats.latencyAvg1000000); + registerCounter64Stat("queries", queriesOID, OID_LENGTH(queriesOID), &dnsdist::metrics::g_stats.queries); + registerCounter64Stat("responses", responsesOID, OID_LENGTH(responsesOID), &dnsdist::metrics::g_stats.responses); + registerCounter64Stat("servfailResponses", servfailResponsesOID, OID_LENGTH(servfailResponsesOID), &dnsdist::metrics::g_stats.servfailResponses); + registerCounter64Stat("aclDrops", aclDropsOID, OID_LENGTH(aclDropsOID), &dnsdist::metrics::g_stats.aclDrops); + registerCounter64Stat("ruleDrop", ruleDropOID, OID_LENGTH(ruleDropOID), &dnsdist::metrics::g_stats.ruleDrop); + registerCounter64Stat("ruleNXDomain", ruleNXDomainOID, OID_LENGTH(ruleNXDomainOID), &dnsdist::metrics::g_stats.ruleNXDomain); + registerCounter64Stat("ruleRefused", ruleRefusedOID, OID_LENGTH(ruleRefusedOID), &dnsdist::metrics::g_stats.ruleRefused); + registerCounter64Stat("ruleServFail", ruleServFailOID, OID_LENGTH(ruleServFailOID), &dnsdist::metrics::g_stats.ruleServFail); + registerCounter64Stat("ruleTruncated", ruleTruncatedOID, OID_LENGTH(ruleTruncatedOID), &dnsdist::metrics::g_stats.ruleTruncated); + registerCounter64Stat("selfAnswered", selfAnsweredOID, OID_LENGTH(selfAnsweredOID), &dnsdist::metrics::g_stats.selfAnswered); + registerCounter64Stat("downstreamTimeouts", downstreamTimeoutsOID, OID_LENGTH(downstreamTimeoutsOID), &dnsdist::metrics::g_stats.downstreamTimeouts); + registerCounter64Stat("downstreamSendErrors", downstreamSendErrorsOID, OID_LENGTH(downstreamSendErrorsOID), &dnsdist::metrics::g_stats.downstreamSendErrors); + registerCounter64Stat("truncFail", truncFailOID, OID_LENGTH(truncFailOID), &dnsdist::metrics::g_stats.truncFail); + registerCounter64Stat("noPolicy", noPolicyOID, OID_LENGTH(noPolicyOID), &dnsdist::metrics::g_stats.noPolicy); + registerCounter64Stat("latency0_1", latency0_1OID, OID_LENGTH(latency0_1OID), &dnsdist::metrics::g_stats.latency0_1); + registerCounter64Stat("latency1_10", latency1_10OID, OID_LENGTH(latency1_10OID), &dnsdist::metrics::g_stats.latency1_10); + registerCounter64Stat("latency10_50", latency10_50OID, OID_LENGTH(latency10_50OID), &dnsdist::metrics::g_stats.latency10_50); + registerCounter64Stat("latency50_100", latency50_100OID, OID_LENGTH(latency50_100OID), &dnsdist::metrics::g_stats.latency50_100); + registerCounter64Stat("latency100_1000", latency100_1000OID, OID_LENGTH(latency100_1000OID), &dnsdist::metrics::g_stats.latency100_1000); + registerCounter64Stat("latencySlow", latencySlowOID, OID_LENGTH(latencySlowOID), &dnsdist::metrics::g_stats.latencySlow); + registerCounter64Stat("nonCompliantQueries", nonCompliantQueriesOID, OID_LENGTH(nonCompliantQueriesOID), &dnsdist::metrics::g_stats.nonCompliantQueries); + registerCounter64Stat("nonCompliantResponses", nonCompliantResponsesOID, OID_LENGTH(nonCompliantResponsesOID), &dnsdist::metrics::g_stats.nonCompliantResponses); + registerCounter64Stat("rdQueries", rdQueriesOID, OID_LENGTH(rdQueriesOID), &dnsdist::metrics::g_stats.rdQueries); + registerCounter64Stat("emptyQueries", emptyQueriesOID, OID_LENGTH(emptyQueriesOID), &dnsdist::metrics::g_stats.emptyQueries); + registerCounter64Stat("cacheHits", cacheHitsOID, OID_LENGTH(cacheHitsOID), &dnsdist::metrics::g_stats.cacheHits); + registerCounter64Stat("cacheMisses", cacheMissesOID, OID_LENGTH(cacheMissesOID), &dnsdist::metrics::g_stats.cacheMisses); + registerCounter64Stat("dynBlocked", dynBlockedOID, OID_LENGTH(dynBlockedOID), &dnsdist::metrics::g_stats.dynBlocked); + registerFloatStat("latencyAvg100", latencyAvg100OID, OID_LENGTH(latencyAvg100OID), &dnsdist::metrics::g_stats.latencyAvg100); + registerFloatStat("latencyAvg1000", latencyAvg1000OID, OID_LENGTH(latencyAvg1000OID), &dnsdist::metrics::g_stats.latencyAvg1000); + registerFloatStat("latencyAvg10000", latencyAvg10000OID, OID_LENGTH(latencyAvg10000OID), &dnsdist::metrics::g_stats.latencyAvg10000); + registerFloatStat("latencyAvg1000000", latencyAvg1000000OID, OID_LENGTH(latencyAvg1000000OID), &dnsdist::metrics::g_stats.latencyAvg1000000); registerGauge64Stat("uptime", uptimeOID, OID_LENGTH(uptimeOID), &uptimeOfProcess); registerGauge64Stat("specialMemoryUsage", specialMemoryUsageOID, OID_LENGTH(specialMemoryUsageOID), &getSpecialMemoryUsage); registerGauge64Stat("cpuUserMSec", cpuUserMSecOID, OID_LENGTH(cpuUserMSecOID), &getCPUTimeUser); registerGauge64Stat("cpuSysMSec", cpuSysMSecOID, OID_LENGTH(cpuSysMSecOID), &getCPUTimeSystem); registerGauge64Stat("fdUsage", fdUsageOID, OID_LENGTH(fdUsageOID), &getOpenFileDescriptors); registerGauge64Stat("dynBlockedNMGSize", dynBlockedNMGSizeOID, OID_LENGTH(dynBlockedNMGSizeOID), [](const std::string&) { return g_dynblockNMG.getLocal()->size(); }); - registerGauge64Stat("securityStatus", securityStatusOID, OID_LENGTH(securityStatusOID), [](const std::string&) { return g_stats.securityStatus.load(); }); + registerGauge64Stat("securityStatus", securityStatusOID, OID_LENGTH(securityStatusOID), [](const std::string&) { return dnsdist::metrics::g_stats.securityStatus.load(); }); registerGauge64Stat("realMemoryUsage", realMemoryUsageOID, OID_LENGTH(realMemoryUsageOID), &getRealMemoryUsage); diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index b72f0e0f5f9e..7b99f6be7d1e 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -507,7 +507,7 @@ void IncomingTCPConnectionState::handleResponse(const struct timeval& now, TCPRe } } - ++g_stats.responses; + ++dnsdist::metrics::g_stats.responses; ++state->d_ci.cs->responses; queueResponse(state, now, std::move(response)); @@ -578,7 +578,7 @@ void IncomingTCPConnectionState::handleCrossProtocolResponse(const struct timeva try { auto ptr = std::make_unique(std::move(response), state, now); if (!state->d_threadData.crossProtocolResponseSender.send(std::move(ptr))) { - ++g_stats.tcpCrossProtocolResponsePipeFull; + ++dnsdist::metrics::g_stats.tcpCrossProtocolResponsePipeFull; vinfolog("Unable to pass a cross-protocol response to the TCP worker thread because the pipe is full"); } } @@ -590,7 +590,7 @@ void IncomingTCPConnectionState::handleCrossProtocolResponse(const struct timeva static void handleQuery(std::shared_ptr& state, const struct timeval& now) { if (state->d_querySize < sizeof(dnsheader)) { - ++g_stats.nonCompliantQueries; + ++dnsdist::metrics::g_stats.nonCompliantQueries; ++state->d_ci.cs->nonCompliantQueries; state->terminateClientConnection(); return; @@ -598,7 +598,7 @@ static void handleQuery(std::shared_ptr& state, cons ++state->d_queriesCount; ++state->d_ci.cs->queries; - ++g_stats.queries; + ++dnsdist::metrics::g_stats.queries; if (state->d_handler.isTLS()) { auto tlsVersion = state->d_handler.getTLSVersion(); @@ -837,7 +837,7 @@ void IncomingTCPConnectionState::handleIO(std::shared_ptrd_buffer); if (remaining == 0) { vinfolog("Unable to consume proxy protocol header in packet from TCP client %s", state->d_ci.remote.toStringWithPort()); - ++g_stats.proxyProtocolInvalid; + ++dnsdist::metrics::g_stats.proxyProtocolInvalid; break; } else if (remaining < 0) { @@ -1358,7 +1358,7 @@ static void acceptNewConnection(const TCPAcceptorParam& param, TCPClientThreadDa } if (!acl->match(remote)) { - ++g_stats.aclDrops; + ++dnsdist::metrics::g_stats.aclDrops; vinfolog("Dropped TCP connection from %s because of ACL", remote.toStringWithPort()); return; } diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index c7fd3812c23c..dfb9718b3bf4 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -34,6 +34,7 @@ #include "dnsdist.hh" #include "dnsdist-dynblocks.hh" #include "dnsdist-healthchecks.hh" +#include "dnsdist-metrics.hh" #include "dnsdist-prometheus.hh" #include "dnsdist-web.hh" #include "dolog.hh" @@ -468,7 +469,7 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) std::ostringstream output; static const std::set metricBlacklist = { "special-memory-usage", "latency-count", "latency-sum" }; { - auto entries = g_stats.entries.read_lock(); + auto entries = dnsdist::metrics::g_stats.entries.read_lock(); for (const auto& entry : *entries) { const auto& metricName = entry.d_name; @@ -504,16 +505,16 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) output << "# TYPE " << helpName << " " << prometheusTypeName << "\n"; output << prometheusMetricName << " "; - if (const auto& val = boost::get(&entry.d_value)) { + if (const auto& val = std::get_if(&entry.d_value)) { output << (*val)->load(); } - else if (const auto& adval = boost::get*>(&entry.d_value)) { + else if (const auto& adval = std::get_if*>(&entry.d_value)) { output << (*adval)->load(); } - else if (const auto& dval = boost::get(&entry.d_value)) { + else if (const auto& dval = std::get_if(&entry.d_value)) { output << **dval; } - else if (const auto& func = boost::get(&entry.d_value)) { + else if (const auto& func = std::get_if(&entry.d_value)) { output << (*func)(entry.d_name); } @@ -524,20 +525,20 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) // Latency histogram buckets output << "# HELP dnsdist_latency Histogram of responses by latency (in milliseconds)\n"; output << "# TYPE dnsdist_latency histogram\n"; - uint64_t latency_amounts = g_stats.latency0_1; + uint64_t latency_amounts = dnsdist::metrics::g_stats.latency0_1; output << "dnsdist_latency_bucket{le=\"1\"} " << latency_amounts << "\n"; - latency_amounts += g_stats.latency1_10; + latency_amounts += dnsdist::metrics::g_stats.latency1_10; output << "dnsdist_latency_bucket{le=\"10\"} " << latency_amounts << "\n"; - latency_amounts += g_stats.latency10_50; + latency_amounts += dnsdist::metrics::g_stats.latency10_50; output << "dnsdist_latency_bucket{le=\"50\"} " << latency_amounts << "\n"; - latency_amounts += g_stats.latency50_100; + latency_amounts += dnsdist::metrics::g_stats.latency50_100; output << "dnsdist_latency_bucket{le=\"100\"} " << latency_amounts << "\n"; - latency_amounts += g_stats.latency100_1000; + latency_amounts += dnsdist::metrics::g_stats.latency100_1000; output << "dnsdist_latency_bucket{le=\"1000\"} " << latency_amounts << "\n"; - latency_amounts += g_stats.latencySlow; // Should be the same as latency_count + latency_amounts += dnsdist::metrics::g_stats.latencySlow; // Should be the same as latency_count output << "dnsdist_latency_bucket{le=\"+Inf\"} " << latency_amounts << "\n"; - output << "dnsdist_latency_sum " << g_stats.latencySum << "\n"; - output << "dnsdist_latency_count " << g_stats.latencyCount << "\n"; + output << "dnsdist_latency_sum " << dnsdist::metrics::g_stats.latencySum << "\n"; + output << "dnsdist_latency_count " << dnsdist::metrics::g_stats.latencyCount << "\n"; auto states = g_dstates.getLocal(); const string statesbase = "dnsdist_server_"; @@ -895,18 +896,18 @@ using namespace json11; static void addStatsToJSONObject(Json::object& obj) { - auto entries = g_stats.entries.read_lock(); + auto entries = dnsdist::metrics::g_stats.entries.read_lock(); for (const auto& entry : *entries) { if (entry.d_name == "special-memory-usage") { continue; // Too expensive for get-all } - if (const auto& val = boost::get(&entry.d_value)) { + if (const auto& val = std::get_if(&entry.d_value)) { obj.emplace(entry.d_name, (double)(*val)->load()); - } else if (const auto& adval = boost::get*>(&entry.d_value)) { + } else if (const auto& adval = std::get_if*>(&entry.d_value)) { obj.emplace(entry.d_name, (*adval)->load()); - } else if (const auto& dval = boost::get(&entry.d_value)) { + } else if (const auto& dval = std::get_if(&entry.d_value)) { obj.emplace(entry.d_name, (**dval)); - } else if (const auto& func = boost::get(&entry.d_value)) { + } else if (const auto& func = std::get_if(&entry.d_value)) { obj.emplace(entry.d_name, (double)(*func)(entry.d_name)); } } @@ -1336,34 +1337,34 @@ static void handleStatsOnly(const YaHTTP::Request& req, YaHTTP::Response& resp) Json::array doc; { - auto entries = g_stats.entries.read_lock(); + auto entries = dnsdist::metrics::g_stats.entries.read_lock(); for (const auto& item : *entries) { if (item.d_name == "special-memory-usage") { continue; // Too expensive for get-all } - if (const auto& val = boost::get(&item.d_value)) { + if (const auto& val = std::get_if(&item.d_value)) { doc.push_back(Json::object { { "type", "StatisticItem" }, { "name", item.d_name }, { "value", (double)(*val)->load() } }); } - else if (const auto& adval = boost::get*>(&item.d_value)) { + else if (const auto& adval = std::get_if*>(&item.d_value)) { doc.push_back(Json::object { { "type", "StatisticItem" }, { "name", item.d_name }, { "value", (*adval)->load() } }); } - else if (const auto& dval = boost::get(&item.d_value)) { + else if (const auto& dval = std::get_if(&item.d_value)) { doc.push_back(Json::object { { "type", "StatisticItem" }, { "name", item.d_name }, { "value", (**dval) } }); } - else if (const auto& func = boost::get(&item.d_value)) { + else if (const auto& func = std::get_if(&item.d_value)) { doc.push_back(Json::object { { "type", "StatisticItem" }, { "name", item.d_name }, diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index a9af1a217d3c..62fef05a2e3c 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -96,8 +96,6 @@ using std::thread; bool g_verbose; std::optional g_verboseStream{std::nullopt}; -struct DNSDistStats g_stats; - uint16_t g_maxOutstanding{std::numeric_limits::max()}; uint32_t g_staleCacheEntriesTTL{0}; bool g_syslog{true}; @@ -205,7 +203,7 @@ static void truncateTC(PacketBuffer& packet, size_t maximumSize, unsigned int qn } catch(...) { - ++g_stats.truncFail; + ++dnsdist::metrics::g_stats.truncFail; } } @@ -258,49 +256,49 @@ static void doLatencyStats(dnsdist::Protocol protocol, double udiff) if (protocol == dnsdist::Protocol::DoUDP || protocol == dnsdist::Protocol::DNSCryptUDP) { if (udiff < 1000) { - ++g_stats.latency0_1; + ++dnsdist::metrics::g_stats.latency0_1; } else if (udiff < 10000) { - ++g_stats.latency1_10; + ++dnsdist::metrics::g_stats.latency1_10; } else if (udiff < 50000) { - ++g_stats.latency10_50; + ++dnsdist::metrics::g_stats.latency10_50; } else if (udiff < 100000) { - ++g_stats.latency50_100; + ++dnsdist::metrics::g_stats.latency50_100; } else if (udiff < 1000000) { - ++g_stats.latency100_1000; + ++dnsdist::metrics::g_stats.latency100_1000; } else { - ++g_stats.latencySlow; + ++dnsdist::metrics::g_stats.latencySlow; } - g_stats.latencySum += udiff / 1000; - ++g_stats.latencyCount; + dnsdist::metrics::g_stats.latencySum += udiff / 1000; + ++dnsdist::metrics::g_stats.latencyCount; - doAvg(g_stats.latencyAvg100, udiff, 100); - doAvg(g_stats.latencyAvg1000, udiff, 1000); - doAvg(g_stats.latencyAvg10000, udiff, 10000); - doAvg(g_stats.latencyAvg1000000, udiff, 1000000); + doAvg(dnsdist::metrics::g_stats.latencyAvg100, udiff, 100); + doAvg(dnsdist::metrics::g_stats.latencyAvg1000, udiff, 1000); + doAvg(dnsdist::metrics::g_stats.latencyAvg10000, udiff, 10000); + doAvg(dnsdist::metrics::g_stats.latencyAvg1000000, udiff, 1000000); } else if (protocol == dnsdist::Protocol::DoTCP || protocol == dnsdist::Protocol::DNSCryptTCP) { - doAvg(g_stats.latencyTCPAvg100, udiff, 100); - doAvg(g_stats.latencyTCPAvg1000, udiff, 1000); - doAvg(g_stats.latencyTCPAvg10000, udiff, 10000); - doAvg(g_stats.latencyTCPAvg1000000, udiff, 1000000); + doAvg(dnsdist::metrics::g_stats.latencyTCPAvg100, udiff, 100); + doAvg(dnsdist::metrics::g_stats.latencyTCPAvg1000, udiff, 1000); + doAvg(dnsdist::metrics::g_stats.latencyTCPAvg10000, udiff, 10000); + doAvg(dnsdist::metrics::g_stats.latencyTCPAvg1000000, udiff, 1000000); } else if (protocol == dnsdist::Protocol::DoT) { - doAvg(g_stats.latencyDoTAvg100, udiff, 100); - doAvg(g_stats.latencyDoTAvg1000, udiff, 1000); - doAvg(g_stats.latencyDoTAvg10000, udiff, 10000); - doAvg(g_stats.latencyDoTAvg1000000, udiff, 1000000); + doAvg(dnsdist::metrics::g_stats.latencyDoTAvg100, udiff, 100); + doAvg(dnsdist::metrics::g_stats.latencyDoTAvg1000, udiff, 1000); + doAvg(dnsdist::metrics::g_stats.latencyDoTAvg10000, udiff, 10000); + doAvg(dnsdist::metrics::g_stats.latencyDoTAvg1000000, udiff, 1000000); } else if (protocol == dnsdist::Protocol::DoH) { - doAvg(g_stats.latencyDoHAvg100, udiff, 100); - doAvg(g_stats.latencyDoHAvg1000, udiff, 1000); - doAvg(g_stats.latencyDoHAvg10000, udiff, 10000); - doAvg(g_stats.latencyDoHAvg1000000, udiff, 1000000); + doAvg(dnsdist::metrics::g_stats.latencyDoHAvg100, udiff, 100); + doAvg(dnsdist::metrics::g_stats.latencyDoHAvg1000, udiff, 1000); + doAvg(dnsdist::metrics::g_stats.latencyDoHAvg10000, udiff, 10000); + doAvg(dnsdist::metrics::g_stats.latencyDoHAvg1000000, udiff, 1000000); } } @@ -312,7 +310,7 @@ bool responseContentMatches(const PacketBuffer& response, const DNSName& qname, const struct dnsheader* dh = reinterpret_cast(response.data()); if (dh->qr == 0) { - ++g_stats.nonCompliantResponses; + ++dnsdist::metrics::g_stats.nonCompliantResponses; if (remote) { ++remote->nonCompliantResponses; } @@ -324,7 +322,7 @@ bool responseContentMatches(const PacketBuffer& response, const DNSName& qname, return true; } else { - ++g_stats.nonCompliantResponses; + ++dnsdist::metrics::g_stats.nonCompliantResponses; if (remote) { ++remote->nonCompliantResponses; } @@ -341,7 +339,7 @@ bool responseContentMatches(const PacketBuffer& response, const DNSName& qname, if (remote && response.size() > 0 && static_cast(response.size()) > sizeof(dnsheader)) { infolog("Backend %s sent us a response with id %d that did not parse: %s", remote->d_config.remote.toStringWithPort(), ntohs(dh->id), e.what()); } - ++g_stats.nonCompliantResponses; + ++dnsdist::metrics::g_stats.nonCompliantResponses; if (remote) { ++remote->nonCompliantResponses; } @@ -636,16 +634,16 @@ void handleResponseSent(const DNSName& qname, const QType& qtype, double udiff, switch (cleartextDH.rcode) { case RCode::NXDomain: - ++g_stats.frontendNXDomain; + ++dnsdist::metrics::g_stats.frontendNXDomain; break; case RCode::ServFail: if (fromBackend) { - ++g_stats.servfailResponses; + ++dnsdist::metrics::g_stats.servfailResponses; } - ++g_stats.frontendServFail; + ++dnsdist::metrics::g_stats.frontendServFail; break; case RCode::NoError: - ++g_stats.frontendNoError; + ++dnsdist::metrics::g_stats.frontendNoError; break; } @@ -680,7 +678,7 @@ static void handleResponseForUDPClient(InternalQueryState& ids, PacketBuffer& re } } - ++g_stats.responses; + ++dnsdist::metrics::g_stats.responses; if (ids.cs) { ++ids.cs->responses; } @@ -873,7 +871,7 @@ bool processRulesResult(const DNSAction::Action& action, DNSQuestion& dq, std::s return true; break; case DNSAction::Action::Drop: - ++g_stats.ruleDrop; + ++dnsdist::metrics::g_stats.ruleDrop; drop = true; return true; break; @@ -911,7 +909,7 @@ bool processRulesResult(const DNSAction::Action& action, DNSQuestion& dq, std::s dq.getHeader()->ra = dq.getHeader()->rd; dq.getHeader()->aa = false; dq.getHeader()->ad = false; - ++g_stats.ruleTruncated; + ++dnsdist::metrics::g_stats.ruleTruncated; return true; } break; @@ -970,7 +968,7 @@ static bool applyRulesToQuery(LocalHolders& holders, DNSQuestion& dq, const stru /* the Dynamic Block mechanism supports address and port ranges, so we need to pass the full address and port */ if (auto got = holders.dynNMGBlock->lookup(AddressAndPortRange(dq.ids.origRemote, dq.ids.origRemote.isIPv4() ? 32 : 128, 16))) { auto updateBlockStats = [&got]() { - ++g_stats.dynBlocked; + ++dnsdist::metrics::g_stats.dynBlocked; got->second.blocks++; }; @@ -1030,7 +1028,7 @@ static bool applyRulesToQuery(LocalHolders& holders, DNSQuestion& dq, const stru if (auto got = holders.dynSMTBlock->lookup(dq.ids.qname)) { auto updateBlockStats = [&got]() { - ++g_stats.dynBlocked; + ++dnsdist::metrics::g_stats.dynBlocked; got->blocks++; }; @@ -1147,14 +1145,14 @@ static bool isUDPQueryAcceptable(ClientState& cs, LocalHolders& holders, const s /* message was too large for our buffer */ vinfolog("Dropping message too large for our buffer"); ++cs.nonCompliantQueries; - ++g_stats.nonCompliantQueries; + ++dnsdist::metrics::g_stats.nonCompliantQueries; return false; } expectProxyProtocol = expectProxyProtocolFrom(remote); if (!holders.acl->match(remote) && !expectProxyProtocol) { vinfolog("Query from %s dropped because of ACL", remote.toStringWithPort()); - ++g_stats.aclDrops; + ++dnsdist::metrics::g_stats.aclDrops; return false; } @@ -1184,7 +1182,7 @@ static bool isUDPQueryAcceptable(ClientState& cs, LocalHolders& holders, const s } ++cs.queries; - ++g_stats.queries; + ++dnsdist::metrics::g_stats.queries; return true; } @@ -1213,20 +1211,20 @@ bool checkDNSCryptQuery(const ClientState& cs, PacketBuffer& query, std::unique_ bool checkQueryHeaders(const struct dnsheader* dh, ClientState& cs) { if (dh->qr) { // don't respond to responses - ++g_stats.nonCompliantQueries; + ++dnsdist::metrics::g_stats.nonCompliantQueries; ++cs.nonCompliantQueries; return false; } if (dh->qdcount == 0) { - ++g_stats.emptyQueries; + ++dnsdist::metrics::g_stats.emptyQueries; if (g_dropEmptyQueries) { return false; } } if (dh->rd) { - ++g_stats.rdQueries; + ++dnsdist::metrics::g_stats.rdQueries; } return true; @@ -1268,7 +1266,7 @@ static bool prepareOutgoingResponse(LocalHolders& holders, const ClientState& cs } if (cacheHit) { - ++g_stats.cacheHits; + ++dnsdist::metrics::g_stats.cacheHits; } if (dr.isAsynchronous()) { @@ -1300,16 +1298,16 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders const auto rcode = dq.getHeader()->rcode; if (rcode == RCode::NXDomain) { - ++g_stats.ruleNXDomain; + ++dnsdist::metrics::g_stats.ruleNXDomain; } else if (rcode == RCode::Refused) { - ++g_stats.ruleRefused; + ++dnsdist::metrics::g_stats.ruleRefused; } else if (rcode == RCode::ServFail) { - ++g_stats.ruleServFail; + ++dnsdist::metrics::g_stats.ruleServFail; } - ++g_stats.selfAnswered; + ++dnsdist::metrics::g_stats.selfAnswered; ++dq.ids.cs->responses; return ProcessQueryResult::SendAnswer; } @@ -1340,7 +1338,7 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders return ProcessQueryResult::Drop; } - ++g_stats.responses; + ++dnsdist::metrics::g_stats.responses; ++dq.ids.cs->responses; return ProcessQueryResult::SendAnswer; } @@ -1375,7 +1373,7 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders return ProcessQueryResult::Drop; } - ++g_stats.responses; + ++dnsdist::metrics::g_stats.responses; ++dq.ids.cs->responses; return ProcessQueryResult::SendAnswer; } @@ -1386,7 +1384,7 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders return ProcessQueryResult::Drop; } - ++g_stats.responses; + ++dnsdist::metrics::g_stats.responses; ++dq.ids.cs->responses; return ProcessQueryResult::SendAnswer; } @@ -1394,11 +1392,11 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders vinfolog("Packet cache miss for query for %s|%s from %s (%s, %d bytes)", dq.ids.qname.toLogString(), QType(dq.ids.qtype).toString(), dq.ids.origRemote.toStringWithPort(), dq.ids.protocol.toString(), dq.getData().size()); - ++g_stats.cacheMisses; + ++dnsdist::metrics::g_stats.cacheMisses; } if (!selectedBackend) { - ++g_stats.noPolicy; + ++dnsdist::metrics::g_stats.noPolicy; vinfolog("%s query for %s|%s from %s, no downstream server available", g_servFailOnNoPolicy ? "ServFailed" : "Dropped", dq.ids.qname.toLogString(), QType(dq.ids.qtype).toString(), dq.ids.origRemote.toStringWithPort()); if (g_servFailOnNoPolicy) { @@ -1410,7 +1408,7 @@ ProcessQueryResult processQueryAfterRules(DNSQuestion& dq, LocalHolders& holders if (!prepareOutgoingResponse(holders, *dq.ids.cs, dq, false)) { return ProcessQueryResult::Drop; } - ++g_stats.responses; + ++dnsdist::metrics::g_stats.responses; ++dq.ids.cs->responses; // no response-only statistics counter to update. return ProcessQueryResult::SendAnswer; @@ -1591,7 +1589,7 @@ bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint1 dq.ids.du->status_code = 502; } } - ++g_stats.downstreamSendErrors; + ++dnsdist::metrics::g_stats.downstreamSendErrors; ++ds->sendErrors; return false; } @@ -1795,7 +1793,7 @@ static void MultipleMessagesUDPClientThread(ClientState* cs, LocalHolders& holde const ComboAddress& remote = recvData[msgIdx].remote; if (static_cast(got) < sizeof(struct dnsheader)) { - ++g_stats.nonCompliantQueries; + ++dnsdist::metrics::g_stats.nonCompliantQueries; ++cs->nonCompliantQueries; continue; } @@ -1862,7 +1860,7 @@ static void udpClientThread(std::vector states) ssize_t got = recvmsg(param.socket, &msgh, 0); if (got < 0 || static_cast(got) < sizeof(struct dnsheader)) { - ++g_stats.nonCompliantQueries; + ++dnsdist::metrics::g_stats.nonCompliantQueries; ++param.cs->nonCompliantQueries; return; } diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 1f7b4e8704e2..fca2e3c4dbdd 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -330,156 +330,6 @@ extern vector > g_confDelta; using pdns::stat_t; -struct DNSDistStats -{ - stat_t responses{0}; - stat_t servfailResponses{0}; - stat_t queries{0}; - stat_t frontendNXDomain{0}; - stat_t frontendServFail{0}; - stat_t frontendNoError{0}; - stat_t nonCompliantQueries{0}; - stat_t nonCompliantResponses{0}; - stat_t rdQueries{0}; - stat_t emptyQueries{0}; - stat_t aclDrops{0}; - stat_t dynBlocked{0}; - stat_t ruleDrop{0}; - stat_t ruleNXDomain{0}; - stat_t ruleRefused{0}; - stat_t ruleServFail{0}; - stat_t ruleTruncated{0}; - stat_t selfAnswered{0}; - stat_t downstreamTimeouts{0}; - stat_t downstreamSendErrors{0}; - stat_t truncFail{0}; - stat_t noPolicy{0}; - stat_t cacheHits{0}; - stat_t cacheMisses{0}; - stat_t latency0_1{0}, latency1_10{0}, latency10_50{0}, latency50_100{0}, latency100_1000{0}, latencySlow{0}, latencySum{0}, latencyCount{0}; - stat_t securityStatus{0}; - stat_t dohQueryPipeFull{0}; - stat_t dohResponsePipeFull{0}; - stat_t outgoingDoHQueryPipeFull{0}; - stat_t proxyProtocolInvalid{0}; - stat_t tcpQueryPipeFull{0}; - stat_t tcpCrossProtocolQueryPipeFull{0}; - stat_t tcpCrossProtocolResponsePipeFull{0}; - double latencyAvg100{0}, latencyAvg1000{0}, latencyAvg10000{0}, latencyAvg1000000{0}; - double latencyTCPAvg100{0}, latencyTCPAvg1000{0}, latencyTCPAvg10000{0}, latencyTCPAvg1000000{0}; - double latencyDoTAvg100{0}, latencyDoTAvg1000{0}, latencyDoTAvg10000{0}, latencyDoTAvg1000000{0}; - double latencyDoHAvg100{0}, latencyDoHAvg1000{0}, latencyDoHAvg10000{0}, latencyDoHAvg1000000{0}; - using statfunction_t = std::function; - using entry_t = boost::variant*, double*, statfunction_t>; - struct EntryPair - { - std::string d_name; - entry_t d_value; - }; - - SharedLockGuarded> entries{std::vector{ - {"responses", &responses}, - {"servfail-responses", &servfailResponses}, - {"queries", &queries}, - {"frontend-nxdomain", &frontendNXDomain}, - {"frontend-servfail", &frontendServFail}, - {"frontend-noerror", &frontendNoError}, - {"acl-drops", &aclDrops}, - {"rule-drop", &ruleDrop}, - {"rule-nxdomain", &ruleNXDomain}, - {"rule-refused", &ruleRefused}, - {"rule-servfail", &ruleServFail}, - {"rule-truncated", &ruleTruncated}, - {"self-answered", &selfAnswered}, - {"downstream-timeouts", &downstreamTimeouts}, - {"downstream-send-errors", &downstreamSendErrors}, - {"trunc-failures", &truncFail}, - {"no-policy", &noPolicy}, - {"latency0-1", &latency0_1}, - {"latency1-10", &latency1_10}, - {"latency10-50", &latency10_50}, - {"latency50-100", &latency50_100}, - {"latency100-1000", &latency100_1000}, - {"latency-slow", &latencySlow}, - {"latency-avg100", &latencyAvg100}, - {"latency-avg1000", &latencyAvg1000}, - {"latency-avg10000", &latencyAvg10000}, - {"latency-avg1000000", &latencyAvg1000000}, - {"latency-tcp-avg100", &latencyTCPAvg100}, - {"latency-tcp-avg1000", &latencyTCPAvg1000}, - {"latency-tcp-avg10000", &latencyTCPAvg10000}, - {"latency-tcp-avg1000000", &latencyTCPAvg1000000}, - {"latency-dot-avg100", &latencyDoTAvg100}, - {"latency-dot-avg1000", &latencyDoTAvg1000}, - {"latency-dot-avg10000", &latencyDoTAvg10000}, - {"latency-dot-avg1000000", &latencyDoTAvg1000000}, - {"latency-doh-avg100", &latencyDoHAvg100}, - {"latency-doh-avg1000", &latencyDoHAvg1000}, - {"latency-doh-avg10000", &latencyDoHAvg10000}, - {"latency-doh-avg1000000", &latencyDoHAvg1000000}, - {"uptime", uptimeOfProcess}, - {"real-memory-usage", getRealMemoryUsage}, - {"special-memory-usage", getSpecialMemoryUsage}, - {"udp-in-errors", std::bind(udpErrorStats, "udp-in-errors")}, - {"udp-noport-errors", std::bind(udpErrorStats, "udp-noport-errors")}, - {"udp-recvbuf-errors", std::bind(udpErrorStats, "udp-recvbuf-errors")}, - {"udp-sndbuf-errors", std::bind(udpErrorStats, "udp-sndbuf-errors")}, - {"udp-in-csum-errors", std::bind(udpErrorStats, "udp-in-csum-errors")}, - {"udp6-in-errors", std::bind(udp6ErrorStats, "udp6-in-errors")}, - {"udp6-recvbuf-errors", std::bind(udp6ErrorStats, "udp6-recvbuf-errors")}, - {"udp6-sndbuf-errors", std::bind(udp6ErrorStats, "udp6-sndbuf-errors")}, - {"udp6-noport-errors", std::bind(udp6ErrorStats, "udp6-noport-errors")}, - {"udp6-in-csum-errors", std::bind(udp6ErrorStats, "udp6-in-csum-errors")}, - {"tcp-listen-overflows", std::bind(tcpErrorStats, "ListenOverflows")}, - {"noncompliant-queries", &nonCompliantQueries}, - {"noncompliant-responses", &nonCompliantResponses}, - {"proxy-protocol-invalid", &proxyProtocolInvalid}, - {"rdqueries", &rdQueries}, - {"empty-queries", &emptyQueries}, - {"cache-hits", &cacheHits}, - {"cache-misses", &cacheMisses}, - {"cpu-iowait", getCPUIOWait}, - {"cpu-steal", getCPUSteal}, - {"cpu-sys-msec", getCPUTimeSystem}, - {"cpu-user-msec", getCPUTimeUser}, - {"fd-usage", getOpenFileDescriptors}, - {"dyn-blocked", &dynBlocked}, - {"dyn-block-nmg-size", [](const std::string&) { return g_dynblockNMG.getLocal()->size(); }}, - {"security-status", &securityStatus}, - {"doh-query-pipe-full", &dohQueryPipeFull}, - {"doh-response-pipe-full", &dohResponsePipeFull}, - {"outgoing-doh-query-pipe-full", &outgoingDoHQueryPipeFull}, - {"tcp-query-pipe-full", &tcpQueryPipeFull}, - {"tcp-cross-protocol-query-pipe-full", &tcpCrossProtocolQueryPipeFull}, - {"tcp-cross-protocol-response-pipe-full", &tcpCrossProtocolResponsePipeFull}, - // Latency histogram - {"latency-sum", &latencySum}, - {"latency-count", &latencyCount}, - }}; - struct MutableCounter - { - MutableCounter() = default; - MutableCounter(MutableCounter&& rhs): d_value(rhs.d_value.load()) - { - } - - mutable stat_t d_value{0}; - }; - struct MutableGauge - { - MutableGauge() = default; - MutableGauge(MutableGauge&& rhs): d_value(rhs.d_value.load()) - { - } - - mutable pdns::stat_t_trait d_value{0}; - }; - SharedLockGuarded>> customCounters; - SharedLockGuarded>> customGauges; -}; - -extern struct DNSDistStats g_stats; - class BasicQPSLimiter { public: diff --git a/pdns/dnsdistdist/dnsdist-backend.cc b/pdns/dnsdistdist/dnsdist-backend.cc index 97cd0e46ec5c..87326c93a59f 100644 --- a/pdns/dnsdistdist/dnsdist-backend.cc +++ b/pdns/dnsdistdist/dnsdist-backend.cc @@ -21,6 +21,7 @@ */ #include "dnsdist.hh" +#include "dnsdist-metrics.hh" #include "dnsdist-nghttp2.hh" #include "dnsdist-random.hh" #include "dnsdist-rings.hh" @@ -362,7 +363,7 @@ void DownstreamState::handleUDPTimeout(IDState& ids) handleDOHTimeout(std::move(ids.internal.du)); ++reuseds; --outstanding; - ++g_stats.downstreamTimeouts; // this is an 'actively' discovered timeout + ++dnsdist::metrics::g_stats.downstreamTimeouts; // this is an 'actively' discovered timeout vinfolog("Had a downstream timeout from %s (%s) for query for %s|%s from %s", d_config.remote.toStringWithPort(), getName(), ids.internal.qname.toLogString(), QType(ids.internal.qtype).toString(), ids.internal.origRemote.toStringWithPort()); @@ -461,7 +462,7 @@ uint16_t DownstreamState::saveState(InternalQueryState&& state) auto oldDU = std::move(it->second.internal.du); ++reuseds; - ++g_stats.downstreamTimeouts; + ++dnsdist::metrics::g_stats.downstreamTimeouts; handleDOHTimeout(std::move(oldDU)); } else { @@ -488,7 +489,7 @@ uint16_t DownstreamState::saveState(InternalQueryState&& state) to handle it because it's about to be overwritten. */ auto oldDU = std::move(ids.internal.du); ++reuseds; - ++g_stats.downstreamTimeouts; + ++dnsdist::metrics::g_stats.downstreamTimeouts; handleDOHTimeout(std::move(oldDU)); } else { @@ -511,7 +512,7 @@ void DownstreamState::restoreState(uint16_t id, InternalQueryState&& state) if (!inserted) { /* already used */ ++reuseds; - ++g_stats.downstreamTimeouts; + ++dnsdist::metrics::g_stats.downstreamTimeouts; handleDOHTimeout(std::move(state.du)); } else { @@ -526,14 +527,14 @@ void DownstreamState::restoreState(uint16_t id, InternalQueryState&& state) if (!guard) { /* already used */ ++reuseds; - ++g_stats.downstreamTimeouts; + ++dnsdist::metrics::g_stats.downstreamTimeouts; handleDOHTimeout(std::move(state.du)); return; } if (ids.isInUse()) { /* already used */ ++reuseds; - ++g_stats.downstreamTimeouts; + ++dnsdist::metrics::g_stats.downstreamTimeouts; handleDOHTimeout(std::move(state.du)); return; } diff --git a/pdns/dnsdistdist/dnsdist-dynblocks.cc b/pdns/dnsdistdist/dnsdist-dynblocks.cc index acf85243833b..9b7bee8ae3bd 100644 --- a/pdns/dnsdistdist/dnsdist-dynblocks.cc +++ b/pdns/dnsdistdist/dnsdist-dynblocks.cc @@ -1,6 +1,7 @@ #include "dnsdist.hh" #include "dnsdist-dynblocks.hh" +#include "dnsdist-metrics.hh" GlobalStateHolder> g_dynblockNMG; GlobalStateHolder> g_dynblockSMT; @@ -462,7 +463,7 @@ void DynBlockMaintenance::purgeExpired(const struct timespec& now) updated.erase(entry); } g_dynblockNMG.setState(std::move(updated)); - g_stats.dynBlocked += bpfBlocked; + dnsdist::metrics::g_stats.dynBlocked += bpfBlocked; } } diff --git a/pdns/dnsdistdist/dnsdist-metrics.cc b/pdns/dnsdistdist/dnsdist-metrics.cc index 0eed93566aa4..18b4e8330647 100644 --- a/pdns/dnsdistdist/dnsdist-metrics.cc +++ b/pdns/dnsdistdist/dnsdist-metrics.cc @@ -27,6 +27,113 @@ namespace dnsdist::metrics { +struct MutableCounter +{ + MutableCounter() = default; + MutableCounter(MutableCounter&& rhs): d_value(rhs.d_value.load()) + { + } + + mutable stat_t d_value{0}; +}; + +struct MutableGauge +{ + MutableGauge() = default; + MutableGauge(MutableGauge&& rhs): d_value(rhs.d_value.load()) + { + } + + mutable pdns::stat_t_trait d_value{0}; +}; + +static SharedLockGuarded>> s_customCounters; +static SharedLockGuarded>> s_customGauges; + +Stats::Stats(): entries{std::vector{ + {"responses", &responses}, + {"servfail-responses", &servfailResponses}, + {"queries", &queries}, + {"frontend-nxdomain", &frontendNXDomain}, + {"frontend-servfail", &frontendServFail}, + {"frontend-noerror", &frontendNoError}, + {"acl-drops", &aclDrops}, + {"rule-drop", &ruleDrop}, + {"rule-nxdomain", &ruleNXDomain}, + {"rule-refused", &ruleRefused}, + {"rule-servfail", &ruleServFail}, + {"rule-truncated", &ruleTruncated}, + {"self-answered", &selfAnswered}, + {"downstream-timeouts", &downstreamTimeouts}, + {"downstream-send-errors", &downstreamSendErrors}, + {"trunc-failures", &truncFail}, + {"no-policy", &noPolicy}, + {"latency0-1", &latency0_1}, + {"latency1-10", &latency1_10}, + {"latency10-50", &latency10_50}, + {"latency50-100", &latency50_100}, + {"latency100-1000", &latency100_1000}, + {"latency-slow", &latencySlow}, + {"latency-avg100", &latencyAvg100}, + {"latency-avg1000", &latencyAvg1000}, + {"latency-avg10000", &latencyAvg10000}, + {"latency-avg1000000", &latencyAvg1000000}, + {"latency-tcp-avg100", &latencyTCPAvg100}, + {"latency-tcp-avg1000", &latencyTCPAvg1000}, + {"latency-tcp-avg10000", &latencyTCPAvg10000}, + {"latency-tcp-avg1000000", &latencyTCPAvg1000000}, + {"latency-dot-avg100", &latencyDoTAvg100}, + {"latency-dot-avg1000", &latencyDoTAvg1000}, + {"latency-dot-avg10000", &latencyDoTAvg10000}, + {"latency-dot-avg1000000", &latencyDoTAvg1000000}, + {"latency-doh-avg100", &latencyDoHAvg100}, + {"latency-doh-avg1000", &latencyDoHAvg1000}, + {"latency-doh-avg10000", &latencyDoHAvg10000}, + {"latency-doh-avg1000000", &latencyDoHAvg1000000}, + {"uptime", uptimeOfProcess}, + {"real-memory-usage", getRealMemoryUsage}, + {"special-memory-usage", getSpecialMemoryUsage}, + {"udp-in-errors", std::bind(udpErrorStats, "udp-in-errors")}, + {"udp-noport-errors", std::bind(udpErrorStats, "udp-noport-errors")}, + {"udp-recvbuf-errors", std::bind(udpErrorStats, "udp-recvbuf-errors")}, + {"udp-sndbuf-errors", std::bind(udpErrorStats, "udp-sndbuf-errors")}, + {"udp-in-csum-errors", std::bind(udpErrorStats, "udp-in-csum-errors")}, + {"udp6-in-errors", std::bind(udp6ErrorStats, "udp6-in-errors")}, + {"udp6-recvbuf-errors", std::bind(udp6ErrorStats, "udp6-recvbuf-errors")}, + {"udp6-sndbuf-errors", std::bind(udp6ErrorStats, "udp6-sndbuf-errors")}, + {"udp6-noport-errors", std::bind(udp6ErrorStats, "udp6-noport-errors")}, + {"udp6-in-csum-errors", std::bind(udp6ErrorStats, "udp6-in-csum-errors")}, + {"tcp-listen-overflows", std::bind(tcpErrorStats, "ListenOverflows")}, + {"noncompliant-queries", &nonCompliantQueries}, + {"noncompliant-responses", &nonCompliantResponses}, + {"proxy-protocol-invalid", &proxyProtocolInvalid}, + {"rdqueries", &rdQueries}, + {"empty-queries", &emptyQueries}, + {"cache-hits", &cacheHits}, + {"cache-misses", &cacheMisses}, + {"cpu-iowait", getCPUIOWait}, + {"cpu-steal", getCPUSteal}, + {"cpu-sys-msec", getCPUTimeSystem}, + {"cpu-user-msec", getCPUTimeUser}, + {"fd-usage", getOpenFileDescriptors}, + {"dyn-blocked", &dynBlocked}, + {"dyn-block-nmg-size", [](const std::string&) { return g_dynblockNMG.getLocal()->size(); }}, + {"security-status", &securityStatus}, + {"doh-query-pipe-full", &dohQueryPipeFull}, + {"doh-response-pipe-full", &dohResponsePipeFull}, + {"outgoing-doh-query-pipe-full", &outgoingDoHQueryPipeFull}, + {"tcp-query-pipe-full", &tcpQueryPipeFull}, + {"tcp-cross-protocol-query-pipe-full", &tcpCrossProtocolQueryPipeFull}, + {"tcp-cross-protocol-response-pipe-full", &tcpCrossProtocolResponsePipeFull}, + // Latency histogram + {"latency-sum", &latencySum}, + {"latency-count", &latencyCount}, + }} +{ +} + +struct Stats g_stats; + std::optional declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional customName) { if (!std::regex_match(name, std::regex("^[a-z0-9-]+$"))) { @@ -34,18 +141,18 @@ std::optional declareCustomMetric(const std::string& name, const st } if (type == "counter") { - auto customCounters = g_stats.customCounters.write_lock(); - auto itp = customCounters->insert({name, DNSDistStats::MutableCounter()}); + auto customCounters = s_customCounters.write_lock(); + auto itp = customCounters->insert({name, MutableCounter()}); if (itp.second) { - g_stats.entries.write_lock()->emplace_back(DNSDistStats::EntryPair{name, &(*customCounters)[name].d_value}); + g_stats.entries.write_lock()->emplace_back(Stats::EntryPair{name, &(*customCounters)[name].d_value}); addMetricDefinition(name, "counter", description, customName ? *customName : ""); } } else if (type == "gauge") { - auto customGauges = g_stats.customGauges.write_lock(); - auto itp = customGauges->insert({name, DNSDistStats::MutableGauge()}); + auto customGauges = s_customGauges.write_lock(); + auto itp = customGauges->insert({name, MutableGauge()}); if (itp.second) { - g_stats.entries.write_lock()->emplace_back(DNSDistStats::EntryPair{name, &(*customGauges)[name].d_value}); + g_stats.entries.write_lock()->emplace_back(Stats::EntryPair{name, &(*customGauges)[name].d_value}); addMetricDefinition(name, "gauge", description, customName ? *customName : ""); } } @@ -57,7 +164,7 @@ std::optional declareCustomMetric(const std::string& name, const st std::variant incrementCustomCounter(const std::string_view& name, uint64_t step) { - auto customCounters = g_stats.customCounters.read_lock(); + auto customCounters = s_customCounters.read_lock(); auto metric = customCounters->find(name); if (metric != customCounters->end()) { if (step) { @@ -71,7 +178,7 @@ std::variant incrementCustomCounter(const std::string_view& nam std::variant decrementCustomCounter(const std::string_view& name, uint64_t step) { - auto customCounters = g_stats.customCounters.read_lock(); + auto customCounters = s_customCounters.read_lock(); auto metric = customCounters->find(name); if (metric != customCounters->end()) { if (step) { @@ -85,7 +192,7 @@ std::variant decrementCustomCounter(const std::string_view& nam std::variant setCustomGauge(const std::string_view& name, const double value) { - auto customGauges = g_stats.customGauges.read_lock(); + auto customGauges = s_customGauges.read_lock(); auto metric = customGauges->find(name); if (metric != customGauges->end()) { metric->second.d_value = value; @@ -98,14 +205,14 @@ std::variant setCustomGauge(const std::string_view& name, const d std::variant getCustomMetric(const std::string_view& name) { { - auto customCounters = g_stats.customCounters.read_lock(); + auto customCounters = s_customCounters.read_lock(); auto counter = customCounters->find(name); if (counter != customCounters->end()) { return static_cast(counter->second.d_value.load()); } } { - auto customGauges = g_stats.customGauges.read_lock(); + auto customGauges = s_customGauges.read_lock(); auto gauge = customGauges->find(name); if (gauge != customGauges->end()) { return gauge->second.d_value.load(); @@ -113,4 +220,5 @@ std::variant getCustomMetric(const std::string_view& name) } return std::string("Unable to get metric '") + std::string(name) + "': no such metric"; } + } diff --git a/pdns/dnsdistdist/dnsdist-metrics.hh b/pdns/dnsdistdist/dnsdist-metrics.hh index 88a812ea8e5e..a44c3c0c646e 100644 --- a/pdns/dnsdistdist/dnsdist-metrics.hh +++ b/pdns/dnsdistdist/dnsdist-metrics.hh @@ -27,13 +27,72 @@ #include #include +#include "lock.hh" +#include "stat_t.hh" + namespace dnsdist::metrics { - using Error = std::string; +using Error = std::string; + +[[nodiscard]] std::optional declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional customName); +[[nodiscard]] std::variant incrementCustomCounter(const std::string_view& name, uint64_t step); +[[nodiscard]] std::variant decrementCustomCounter(const std::string_view& name, uint64_t step); +[[nodiscard]] std::variant setCustomGauge(const std::string_view& name, const double value); +[[nodiscard]] std::variant getCustomMetric(const std::string_view& name); + +using pdns::stat_t; + +struct Stats +{ + Stats(); + + stat_t responses{0}; + stat_t servfailResponses{0}; + stat_t queries{0}; + stat_t frontendNXDomain{0}; + stat_t frontendServFail{0}; + stat_t frontendNoError{0}; + stat_t nonCompliantQueries{0}; + stat_t nonCompliantResponses{0}; + stat_t rdQueries{0}; + stat_t emptyQueries{0}; + stat_t aclDrops{0}; + stat_t dynBlocked{0}; + stat_t ruleDrop{0}; + stat_t ruleNXDomain{0}; + stat_t ruleRefused{0}; + stat_t ruleServFail{0}; + stat_t ruleTruncated{0}; + stat_t selfAnswered{0}; + stat_t downstreamTimeouts{0}; + stat_t downstreamSendErrors{0}; + stat_t truncFail{0}; + stat_t noPolicy{0}; + stat_t cacheHits{0}; + stat_t cacheMisses{0}; + stat_t latency0_1{0}, latency1_10{0}, latency10_50{0}, latency50_100{0}, latency100_1000{0}, latencySlow{0}, latencySum{0}, latencyCount{0}; + stat_t securityStatus{0}; + stat_t dohQueryPipeFull{0}; + stat_t dohResponsePipeFull{0}; + stat_t outgoingDoHQueryPipeFull{0}; + stat_t proxyProtocolInvalid{0}; + stat_t tcpQueryPipeFull{0}; + stat_t tcpCrossProtocolQueryPipeFull{0}; + stat_t tcpCrossProtocolResponsePipeFull{0}; + double latencyAvg100{0}, latencyAvg1000{0}, latencyAvg10000{0}, latencyAvg1000000{0}; + double latencyTCPAvg100{0}, latencyTCPAvg1000{0}, latencyTCPAvg10000{0}, latencyTCPAvg1000000{0}; + double latencyDoTAvg100{0}, latencyDoTAvg1000{0}, latencyDoTAvg10000{0}, latencyDoTAvg1000000{0}; + double latencyDoHAvg100{0}, latencyDoHAvg1000{0}, latencyDoHAvg10000{0}, latencyDoHAvg1000000{0}; + using statfunction_t = std::function; + using entry_t = std::variant*, double*, statfunction_t>; + struct EntryPair + { + std::string d_name; + entry_t d_value; + }; + + SharedLockGuarded> entries; +}; - [[nodiscard]] std::optional declareCustomMetric(const std::string& name, const std::string& type, const std::string& description, std::optional customName); - [[nodiscard]] std::variant incrementCustomCounter(const std::string_view& name, uint64_t step); - [[nodiscard]] std::variant decrementCustomCounter(const std::string_view& name, uint64_t step); - [[nodiscard]] std::variant setCustomGauge(const std::string_view& name, const double value); - [[nodiscard]] std::variant getCustomMetric(const std::string_view& name); +extern struct Stats g_stats; } diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 9c505cdcebe3..fdc3d7a294c2 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -1043,7 +1043,7 @@ bool DoHClientCollection::passCrossProtocolQueryToThread(std::unique_ptr(used) > g_proxyProtocolMaximumSize) { vinfolog("Proxy protocol header in %s packet from %s is larger than proxy-protocol-maximum-size (%d), dropping", (isTCP ? "TCP" : "UDP"), remote.toStringWithPort(), used); - ++g_stats.proxyProtocolInvalid; + ++dnsdist::metrics::g_stats.proxyProtocolInvalid; return false; } @@ -95,14 +96,14 @@ bool handleProxyProtocol(const ComboAddress& remote, bool isTCP, const NetmaskGr /* on TCP we have not read the actual query yet */ if (!isTCP && query.size() < sizeof(struct dnsheader)) { - ++g_stats.nonCompliantQueries; + ++dnsdist::metrics::g_stats.nonCompliantQueries; return false; } if (proxyProto && g_applyACLToProxiedClients) { if (!acl.match(realRemote)) { vinfolog("Query from %s dropped because of ACL", realRemote.toStringWithPort()); - ++g_stats.aclDrops; + ++dnsdist::metrics::g_stats.aclDrops; return false; } } diff --git a/pdns/dnsdistdist/dnsdist-secpoll.cc b/pdns/dnsdistdist/dnsdist-secpoll.cc index eb38d356c65e..7964d1490b0c 100644 --- a/pdns/dnsdistdist/dnsdist-secpoll.cc +++ b/pdns/dnsdistdist/dnsdist-secpoll.cc @@ -36,6 +36,7 @@ #include "sstuff.hh" #include "dnsdist.hh" +#include "dnsdist-metrics.hh" #include "dnsdist-random.hh" #ifndef PACKAGEVERSION @@ -220,7 +221,7 @@ void doSecPoll(const std::string& suffix) errlog("PowerDNS DNSDist Security Update Mandatory: %s", securityMessage); } - g_stats.securityStatus = securityStatus; + dnsdist::metrics::g_stats.securityStatus = securityStatus; g_secPollDone = true; return; } diff --git a/pdns/dnsdistdist/dnsdist-tcp.hh b/pdns/dnsdistdist/dnsdist-tcp.hh index ea25853e9c2e..d5f2edb0d1e8 100644 --- a/pdns/dnsdistdist/dnsdist-tcp.hh +++ b/pdns/dnsdistdist/dnsdist-tcp.hh @@ -25,6 +25,7 @@ #include "channel.hh" #include "iputils.hh" #include "dnsdist.hh" +#include "dnsdist-metrics.hh" struct ConnectionInfo { @@ -220,7 +221,7 @@ public: ++d_queued; if (!d_tcpclientthreads.at(pos % d_numthreads).d_querySender.send(std::move(conn))) { --d_queued; - ++g_stats.tcpQueryPipeFull; + ++dnsdist::metrics::g_stats.tcpQueryPipeFull; return false; } @@ -235,7 +236,7 @@ public: uint64_t pos = d_pos++; if (!d_tcpclientthreads.at(pos % d_numthreads).d_crossProtocolQuerySender.send(std::move(cpq))) { - ++g_stats.tcpCrossProtocolQueryPipeFull; + ++dnsdist::metrics::g_stats.tcpCrossProtocolQueryPipeFull; return false; } diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 4573addbab88..4959039ffed6 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -26,6 +26,7 @@ #include "dolog.hh" #include "dnsdist-concurrent-connections.hh" #include "dnsdist-ecs.hh" +#include "dnsdist-metrics.hh" #include "dnsdist-proxy-protocol.hh" #include "dnsdist-rules.hh" #include "dnsdist-xpf.hh" @@ -223,7 +224,7 @@ static void sendDoHUnitToTheMainThread(DOHUnitUniquePtr&& du, const char* descri } try { if (!du->responseSender->send(std::move(du))) { - ++g_stats.dohResponsePipeFull; + ++dnsdist::metrics::g_stats.dohResponsePipeFull; vinfolog("Unable to pass a %s to the DoH worker thread because the pipe is full", description); } } catch (const std::exception& e) { @@ -463,7 +464,7 @@ class DoHTCPCrossQuerySender : public TCPQuerySender handleResponseSent(du->ids, udiff, du->ids.origRemote, du->downstream->d_config.remote, du->response.size(), cleartextDH, backendProtocol, true); } - ++g_stats.responses; + ++dnsdist::metrics::g_stats.responses; if (du->ids.cs) { ++du->ids.cs->responses; } @@ -643,7 +644,7 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) ClientState& cs = *dsc->cs; if (du->query.size() < sizeof(dnsheader)) { - ++g_stats.nonCompliantQueries; + ++dnsdist::metrics::g_stats.nonCompliantQueries; ++cs.nonCompliantQueries; du->status_code = 400; handleImmediateResponse(std::move(du), "DoH non-compliant query"); @@ -651,7 +652,7 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) } ++cs.queries; - ++g_stats.queries; + ++dnsdist::metrics::g_stats.queries; du->ids.queryRealTime.start(); { @@ -872,7 +873,7 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re #else /* USE_SINGLE_ACCEPTOR_THREAD */ try { if (!dsc->d_querySender.send(std::move(du))) { - ++g_stats.dohQueryPipeFull; + ++dnsdist::metrics::g_stats.dohQueryPipeFull; vinfolog("Unable to pass a DoH query to the DoH worker thread because the pipe is full"); h2o_send_error_500(req, "Internal Server Error", "Internal Server Error", 0); } @@ -976,7 +977,7 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) auto& holders = dsc->holders; if (!holders.acl->match(conn.d_remote)) { - ++g_stats.aclDrops; + ++dnsdist::metrics::g_stats.aclDrops; vinfolog("Query from %s (DoH) dropped because of ACL", conn.d_remote.toStringWithPort()); h2o_send_error_403(req, "Forbidden", "dns query not allowed because of ACL", 0); return 0; @@ -1688,7 +1689,7 @@ void handleUDPResponseForDoH(DOHUnitUniquePtr&& du, PacketBuffer&& udpResponse, handleResponseSent(du->ids, udiff, dr.ids.origRemote, du->downstream->d_config.remote, du->response.size(), cleartextDH, du->downstream->getProtocol(), true); - ++g_stats.responses; + ++dnsdist::metrics::g_stats.responses; if (du->ids.cs) { ++du->ids.cs->responses; } diff --git a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc index 0904441da6fe..2aa5adbe2063 100644 --- a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc +++ b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc @@ -31,7 +31,6 @@ #include "dnsdist-tcp-downstream.hh" #include "dnsdist-tcp-upstream.hh" -struct DNSDistStats g_stats; GlobalStateHolder g_ACL; GlobalStateHolder > g_ruleactions; GlobalStateHolder > g_respruleactions; From 2b6d77185ca4382de8b37ea7f01c51c0c8960b28 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Jun 2023 15:12:57 +0200 Subject: [PATCH 343/909] dnsdist: Fix formatting in dnsdist-metrics.{cc,hh} --- pdns/dnsdistdist/dnsdist-metrics.cc | 12 ++++++++---- pdns/dnsdistdist/dnsdist-metrics.hh | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-metrics.cc b/pdns/dnsdistdist/dnsdist-metrics.cc index 18b4e8330647..b4c537aaddc6 100644 --- a/pdns/dnsdistdist/dnsdist-metrics.cc +++ b/pdns/dnsdistdist/dnsdist-metrics.cc @@ -25,12 +25,14 @@ #include "dnsdist.hh" #include "dnsdist-web.hh" -namespace dnsdist::metrics { +namespace dnsdist::metrics +{ struct MutableCounter { MutableCounter() = default; - MutableCounter(MutableCounter&& rhs): d_value(rhs.d_value.load()) + MutableCounter(MutableCounter&& rhs) : + d_value(rhs.d_value.load()) { } @@ -40,7 +42,8 @@ struct MutableCounter struct MutableGauge { MutableGauge() = default; - MutableGauge(MutableGauge&& rhs): d_value(rhs.d_value.load()) + MutableGauge(MutableGauge&& rhs) : + d_value(rhs.d_value.load()) { } @@ -50,7 +53,8 @@ struct MutableGauge static SharedLockGuarded>> s_customCounters; static SharedLockGuarded>> s_customGauges; -Stats::Stats(): entries{std::vector{ +Stats::Stats() : + entries{std::vector{ {"responses", &responses}, {"servfail-responses", &servfailResponses}, {"queries", &queries}, diff --git a/pdns/dnsdistdist/dnsdist-metrics.hh b/pdns/dnsdistdist/dnsdist-metrics.hh index a44c3c0c646e..b14cb804ef30 100644 --- a/pdns/dnsdistdist/dnsdist-metrics.hh +++ b/pdns/dnsdistdist/dnsdist-metrics.hh @@ -83,7 +83,7 @@ struct Stats double latencyTCPAvg100{0}, latencyTCPAvg1000{0}, latencyTCPAvg10000{0}, latencyTCPAvg1000000{0}; double latencyDoTAvg100{0}, latencyDoTAvg1000{0}, latencyDoTAvg10000{0}, latencyDoTAvg1000000{0}; double latencyDoHAvg100{0}, latencyDoHAvg1000{0}, latencyDoHAvg10000{0}, latencyDoHAvg1000000{0}; - using statfunction_t = std::function; + using statfunction_t = std::function; using entry_t = std::variant*, double*, statfunction_t>; struct EntryPair { From f0040aaeee838a855c76453867bb68a1107ae5e4 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 16 Jun 2023 16:55:37 +0200 Subject: [PATCH 344/909] dnsdist: Apply clang-tidy's suggestions --- pdns/dnsdist-web.cc | 4 +- pdns/dnsdistdist/dnsdist-lua-ffi.cc | 7 +-- pdns/dnsdistdist/dnsdist-metrics.cc | 62 ++++++++++++++---------- pdns/dnsdistdist/dnsdist-prometheus.hh | 17 +++++-- pdns/dnsdistdist/dnsdist-web.hh | 5 +- pdns/dnsdistdist/test-dnsdist-lua-ffi.cc | 3 +- 6 files changed, 60 insertions(+), 38 deletions(-) diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index dfb9718b3bf4..d47f33cd6331 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -213,9 +213,9 @@ std::map MetricDefinitionStorage::metrics{ }; #endif /* DISABLE_PROMETHEUS */ -bool addMetricDefinition(const std::string& name, const std::string& type, const std::string& description, const std::string& customName) { +bool addMetricDefinition(const dnsdist::prometheus::PrometheusMetricDefinition& def) { #ifndef DISABLE_PROMETHEUS - return MetricDefinitionStorage::addMetricDefinition(name, type, description, customName); + return MetricDefinitionStorage::addMetricDefinition(def); #else return true; #endif /* DISABLE_PROMETHEUS */ diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index bf46aadece44..33e13b534fb7 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -1607,11 +1607,8 @@ bool dnsdist_ffi_metric_declare(const char* name, size_t nameLen, const char* ty if (name == nullptr || nameLen == 0 || type == nullptr || description == nullptr) { return false; } - auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName ? std::optional(customName) : std::nullopt); - if (result) { - return false; - } - return true; + auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName != nullptr ? std::optional(customName) : std::nullopt); + return !result; } void dnsdist_ffi_metric_inc(const char* metricName, size_t metricNameLen) diff --git a/pdns/dnsdistdist/dnsdist-metrics.cc b/pdns/dnsdistdist/dnsdist-metrics.cc index b4c537aaddc6..e86439c89e98 100644 --- a/pdns/dnsdistdist/dnsdist-metrics.cc +++ b/pdns/dnsdistdist/dnsdist-metrics.cc @@ -31,10 +31,18 @@ namespace dnsdist::metrics struct MutableCounter { MutableCounter() = default; - MutableCounter(MutableCounter&& rhs) : + MutableCounter(const MutableCounter&) = delete; + MutableCounter(MutableCounter&& rhs) noexcept : d_value(rhs.d_value.load()) { } + MutableCounter& operator=(const MutableCounter&) = delete; + MutableCounter& operator=(MutableCounter&& rhs) noexcept + { + d_value = rhs.d_value.load(); + return *this; + } + ~MutableCounter() = default; mutable stat_t d_value{0}; }; @@ -42,10 +50,18 @@ struct MutableCounter struct MutableGauge { MutableGauge() = default; - MutableGauge(MutableGauge&& rhs) : + MutableGauge(const MutableGauge&) = delete; + MutableGauge(MutableGauge&& rhs) noexcept : d_value(rhs.d_value.load()) { } + MutableGauge& operator=(const MutableGauge&) = delete; + MutableGauge& operator=(MutableGauge&& rhs) noexcept + { + d_value = rhs.d_value.load(); + return *this; + } + ~MutableGauge() = default; mutable pdns::stat_t_trait d_value{0}; }; @@ -97,17 +113,17 @@ Stats::Stats() : {"uptime", uptimeOfProcess}, {"real-memory-usage", getRealMemoryUsage}, {"special-memory-usage", getSpecialMemoryUsage}, - {"udp-in-errors", std::bind(udpErrorStats, "udp-in-errors")}, - {"udp-noport-errors", std::bind(udpErrorStats, "udp-noport-errors")}, - {"udp-recvbuf-errors", std::bind(udpErrorStats, "udp-recvbuf-errors")}, - {"udp-sndbuf-errors", std::bind(udpErrorStats, "udp-sndbuf-errors")}, - {"udp-in-csum-errors", std::bind(udpErrorStats, "udp-in-csum-errors")}, - {"udp6-in-errors", std::bind(udp6ErrorStats, "udp6-in-errors")}, - {"udp6-recvbuf-errors", std::bind(udp6ErrorStats, "udp6-recvbuf-errors")}, - {"udp6-sndbuf-errors", std::bind(udp6ErrorStats, "udp6-sndbuf-errors")}, - {"udp6-noport-errors", std::bind(udp6ErrorStats, "udp6-noport-errors")}, - {"udp6-in-csum-errors", std::bind(udp6ErrorStats, "udp6-in-csum-errors")}, - {"tcp-listen-overflows", std::bind(tcpErrorStats, "ListenOverflows")}, + {"udp-in-errors", [](const std::string&) { return udpErrorStats("udp-in-errors"); }}, + {"udp-noport-errors", [](const std::string&) { return udpErrorStats("udp-noport-errors"); }}, + {"udp-recvbuf-errors", [](const std::string&) { return udpErrorStats("udp-recvbuf-errors"); }}, + {"udp-sndbuf-errors", [](const std::string&) { return udpErrorStats("udp-sndbuf-errors"); }}, + {"udp-in-csum-errors", [](const std::string&) { return udpErrorStats("udp-in-csum-errors"); }}, + {"udp6-in-errors", [](const std::string&) { return udp6ErrorStats("udp6-in-errors"); }}, + {"udp6-recvbuf-errors", [](const std::string&) { return udp6ErrorStats("udp6-recvbuf-errors"); }}, + {"udp6-sndbuf-errors", [](const std::string&) { return udp6ErrorStats("udp6-sndbuf-errors"); }}, + {"udp6-noport-errors", [](const std::string&) { return udp6ErrorStats("udp6-noport-errors"); }}, + {"udp6-in-csum-errors", [](const std::string&) { return udp6ErrorStats("udp6-in-csum-errors"); }}, + {"tcp-listen-overflows", [](const std::string&) { return tcpErrorStats("ListenOverflows"); }}, {"noncompliant-queries", &nonCompliantQueries}, {"noncompliant-responses", &nonCompliantResponses}, {"proxy-protocol-invalid", &proxyProtocolInvalid}, @@ -149,7 +165,8 @@ std::optional declareCustomMetric(const std::string& name, const st auto itp = customCounters->insert({name, MutableCounter()}); if (itp.second) { g_stats.entries.write_lock()->emplace_back(Stats::EntryPair{name, &(*customCounters)[name].d_value}); - addMetricDefinition(name, "counter", description, customName ? *customName : ""); + dnsdist::prometheus::PrometheusMetricDefinition def{name, "counter", description, customName ? *customName : ""}; + addMetricDefinition(def); } } else if (type == "gauge") { @@ -157,7 +174,8 @@ std::optional declareCustomMetric(const std::string& name, const st auto itp = customGauges->insert({name, MutableGauge()}); if (itp.second) { g_stats.entries.write_lock()->emplace_back(Stats::EntryPair{name, &(*customGauges)[name].d_value}); - addMetricDefinition(name, "gauge", description, customName ? *customName : ""); + dnsdist::prometheus::PrometheusMetricDefinition def{name, "gauge", description, customName ? *customName : ""}; + addMetricDefinition(def); } } else { @@ -171,11 +189,8 @@ std::variant incrementCustomCounter(const std::string_view& nam auto customCounters = s_customCounters.read_lock(); auto metric = customCounters->find(name); if (metric != customCounters->end()) { - if (step) { - metric->second.d_value += step; - return metric->second.d_value.load(); - } - return ++(metric->second.d_value); + metric->second.d_value += step; + return metric->second.d_value.load(); } return std::string("Unable to increment custom metric '") + std::string(name) + "': no such metric"; } @@ -185,11 +200,8 @@ std::variant decrementCustomCounter(const std::string_view& nam auto customCounters = s_customCounters.read_lock(); auto metric = customCounters->find(name); if (metric != customCounters->end()) { - if (step) { - metric->second.d_value -= step; - return metric->second.d_value.load(); - } - return --(metric->second.d_value); + metric->second.d_value -= step; + return metric->second.d_value.load(); } return std::string("Unable to decrement custom metric '") + std::string(name) + "': no such metric"; } diff --git a/pdns/dnsdistdist/dnsdist-prometheus.hh b/pdns/dnsdistdist/dnsdist-prometheus.hh index 15567bff0448..011053d32e29 100644 --- a/pdns/dnsdistdist/dnsdist-prometheus.hh +++ b/pdns/dnsdistdist/dnsdist-prometheus.hh @@ -21,6 +21,17 @@ */ #pragma once +namespace dnsdist::prometheus +{ +struct PrometheusMetricDefinition +{ + const std::string& name; + const std::string& type; + const std::string& description; + const std::string& customName; +}; +} + #ifndef DISABLE_PROMETHEUS // Metric types for Prometheus enum class PrometheusMetricType: uint8_t { @@ -56,16 +67,16 @@ struct MetricDefinitionStorage { return true; }; - static bool addMetricDefinition(const std::string& name, const std::string& type, const std::string& description, const std::string& customName) { + static bool addMetricDefinition(const dnsdist::prometheus::PrometheusMetricDefinition& def) { static const std::map namesToTypes = { {"counter", PrometheusMetricType::counter}, {"gauge", PrometheusMetricType::gauge}, }; - auto realtype = namesToTypes.find(type); + auto realtype = namesToTypes.find(def.type); if (realtype == namesToTypes.end()) { return false; } - metrics.emplace(name, MetricDefinition{realtype->second, description, customName}); + metrics.emplace(def.name, MetricDefinition{realtype->second, def.description, def.customName}); return true; } diff --git a/pdns/dnsdistdist/dnsdist-web.hh b/pdns/dnsdistdist/dnsdist-web.hh index 3497d65a96b2..7325025823d7 100644 --- a/pdns/dnsdistdist/dnsdist-web.hh +++ b/pdns/dnsdistdist/dnsdist-web.hh @@ -1,6 +1,7 @@ #pragma once #include "credentials.hh" +#include "dnsdist-prometheus.hh" void setWebserverAPIKey(std::unique_ptr&& apiKey); void setWebserverPassword(std::unique_ptr&& password); @@ -16,6 +17,6 @@ void dnsdistWebserverThread(int sock, const ComboAddress& local); void registerBuiltInWebHandlers(); void clearWebHandlers(); -bool addMetricDefinition(const std::string& name, const std::string& type, const std::string& description, const std::string& customPrometheusName); - std::string getWebserverConfig(); + +bool addMetricDefinition(const dnsdist::prometheus::PrometheusMetricDefinition& def); diff --git a/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc b/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc index 8a5a06763bff..81897a340d1c 100644 --- a/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/test-dnsdist-lua-ffi.cc @@ -26,10 +26,11 @@ #include "dnsdist-lua-ffi.hh" #include "dnsdist-rings.hh" +#include "dnsdist-web.hh" #include "dnsparser.hh" #include "dnswriter.hh" -bool addMetricDefinition(const std::string& name, const std::string& type, const std::string& description, const std::string& customPrometheusName) +bool addMetricDefinition(const dnsdist::prometheus::PrometheusMetricDefinition& def) { return true; } From 55361195cb8d1f6c4a6e32e2504996bec67a23b4 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 27 Jun 2023 16:18:04 +0200 Subject: [PATCH 345/909] dnsdist: Fix the initial value of the custom gauge in our tests Thanks Otto! --- regression-tests.dnsdist/test_Advanced.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests.dnsdist/test_Advanced.py b/regression-tests.dnsdist/test_Advanced.py index 186138cbd510..530bf0190af7 100644 --- a/regression-tests.dnsdist/test_Advanced.py +++ b/regression-tests.dnsdist/test_Advanced.py @@ -595,7 +595,7 @@ class TestCustomMetrics(DNSDistTest): _config_template = """ function custommetrics(dq) initialCounter = getMetric("my-custom-counter") - initialGauge = getMetric("my-custom-counter") + initialGauge = getMetric("my-custom-gauge") incMetric("my-custom-counter") incMetric("my-custom-counter", 41) setMetric("my-custom-gauge", initialGauge + 1.3) From d432e73f05fa848894e8de7a85604b65a1ee3285 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 27 Jun 2023 16:18:39 +0200 Subject: [PATCH 346/909] dnsdist: Fix a typo spotted by Otto in the docs --- pdns/dnsdistdist/docs/reference/custommetrics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/reference/custommetrics.rst b/pdns/dnsdistdist/docs/reference/custommetrics.rst index 0f656b7f9c9e..46cb5b8ddbd7 100644 --- a/pdns/dnsdistdist/docs/reference/custommetrics.rst +++ b/pdns/dnsdistdist/docs/reference/custommetrics.rst @@ -1,7 +1,7 @@ Custom Metrics ===================================== -You can define at your own metrics that can be updated using Lua. +You can define your own metrics that can be updated using Lua. The first step is to declare a new metric using :func:`declareMetric`. In 1.8.0 the declaration had to be done at configuration time, but since 1.8.1 it can be done at any point. From 01c93591def0738f036e965e48048b84656cb34f Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 27 Jun 2023 14:38:50 +0200 Subject: [PATCH 347/909] build-packages: Upload the provenance artifacts to downloads.powerdns.com --- .github/workflows/build-packages.yml | 34 ++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index 1f7148b6947c..ea3c456f7486 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -150,3 +150,37 @@ jobs: base64-subjects: "${{ needs.build.outputs.srchashes }}" upload-assets: false provenance-name: "${{ inputs.product }}-${{ needs.build.outputs.version }}-src.intoto.jsonl" + + upload-provenance: + needs: [prepare, build, provenance-src, provenance-pkgs] + name: Upload the provenance artifacts to downloads.powerdns.com + runs-on: ubuntu-20.04 + strategy: + matrix: + os: ${{fromJson(needs.prepare.outputs.oslist)}} + steps: + - name: Download source tarball provenance for ${{ inputs.product }} (${{ inputs.ref }}) + id: download-src-provenance + uses: actions/download-artifact@v3 + with: + name: "${{ inputs.product }}-${{ needs.build.outputs.version }}-src.intoto.jsonl" + - name: Download provenance for ${{ inputs.product }} (${{ inputs.ref }}) for ${{ matrix.os }} + id: download-provenance + uses: actions/download-artifact@v3 + with: + name: "${{ inputs.product }}-${{ needs.build.outputs.version }}-${{ matrix.os}}.intoto.jsonl" + - name: Upload provenance artifacts to downloads.powerdns.com + id: upload-provenance + env: + SSHKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} + RSYNCTARGET: ${{ secrets.DOWNLOADS_AUTOBUILT_RSYNCTARGET }} + HOSTKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_HOSTKEY }} + if: + "${{ env.SSHKEY != '' }}" + shell: bash + run: | + mkdir -m 700 -p ~/.ssh + echo "$SSHKEY" > ~/.ssh/id_ed25519 + chmod 600 ~/.ssh/id_ed25519 + echo "$HOSTKEY" > ~/.ssh/known_hosts + rsync -4rlptD ${{steps.download-src-provenance.outputs.download-path}}/*.jsonl ${{steps.download-provenance.outputs.download-path}}/*.jsonl "${RSYNCTARGET}/${{ inputs.product }}/${{ needs.build.outputs.version }}/" From f48129f9c8d1e1af8a4eb496481f08e1442b5971 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 27 Jun 2023 16:55:42 +0200 Subject: [PATCH 348/909] Warn about the duplicated content in builder-dispatch and build-packages --- .github/workflows/build-packages.yml | 2 ++ .github/workflows/builder-dispatch.yml | 3 +-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index ea3c456f7486..b6dc27a97bfd 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -12,6 +12,8 @@ on: required: false description: OSes to build for, space separated type: string + # please remember to update the pkghashes below when you + # update this list, as well as the one in builder-dispatch.yml default: > el-7 el-8 diff --git a/.github/workflows/builder-dispatch.yml b/.github/workflows/builder-dispatch.yml index b0a825c9aa5f..456af0af244f 100644 --- a/.github/workflows/builder-dispatch.yml +++ b/.github/workflows/builder-dispatch.yml @@ -14,8 +14,7 @@ on: os: description: OSes to build for, space separated type: string - # please remember to update the pkghashes below when you - # update this list + # please remember to update build-packages.yml as well default: > el-7 el-8 From 3b904a7f92e88943148b87fe27f731c63178a129 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 27 Jun 2023 17:16:15 +0200 Subject: [PATCH 349/909] generate-repo-files: don't crash when the process errors --- build-scripts/docker/repo-test/generate-repo-files.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-scripts/docker/repo-test/generate-repo-files.py b/build-scripts/docker/repo-test/generate-repo-files.py index 956695c79474..7ebe25bd3f4d 100755 --- a/build-scripts/docker/repo-test/generate-repo-files.py +++ b/build-scripts/docker/repo-test/generate-repo-files.py @@ -224,7 +224,7 @@ def run (tag): if cp.returncode != 0 and cp.returncode != 99: # FIXME write failed output to log print('Error running {}: {}'.format(tag, repr(cp.returncode))) - return cp.returncode + return cp.returncode, None if version and version.group(2): return cp.returncode, version.group(2) else: From 71cfa23993ce7a551a5489e553accf022f015032 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 27 Jun 2023 18:09:09 +0200 Subject: [PATCH 350/909] dnsdist: Fix the rendering of some Lua configuration examples --- pdns/dnsdistdist/docs/advanced/passing-source-address.rst | 2 ++ pdns/dnsdistdist/docs/guides/dns-over-https.rst | 2 ++ pdns/dnsdistdist/docs/guides/dns-over-tls.rst | 1 + 3 files changed, 5 insertions(+) diff --git a/pdns/dnsdistdist/docs/advanced/passing-source-address.rst b/pdns/dnsdistdist/docs/advanced/passing-source-address.rst index 106c0dca85f1..4e8445fd21a7 100644 --- a/pdns/dnsdistdist/docs/advanced/passing-source-address.rst +++ b/pdns/dnsdistdist/docs/advanced/passing-source-address.rst @@ -60,6 +60,8 @@ This parameter indicates whether an XPF record shall be added to the query. Sinc If the incoming request already contains a XPF record, it will not be overwritten. Instead a new one will be added to the query and the existing one will be preserved. That might be an issue by allowing clients to spoof their source address by adding a forged XPF record to their query. That can be prevented by using a rule to drop incoming queries containing a XPF record (in that example the 65280 option code has been assigned to XPF): +.. code-block:: lua + addAction(RecordsTypeCountRule(DNSSection.Additional, 65280, 1, 65535), DropAction()) Proxy Protocol diff --git a/pdns/dnsdistdist/docs/guides/dns-over-https.rst b/pdns/dnsdistdist/docs/guides/dns-over-https.rst index 78be8b0e31ae..5df4d7f05352 100644 --- a/pdns/dnsdistdist/docs/guides/dns-over-https.rst +++ b/pdns/dnsdistdist/docs/guides/dns-over-https.rst @@ -85,6 +85,8 @@ Outgoing Support for securing the exchanges between dnsdist and the backend will be implemented in 1.7.0, and will lead to all queries, regardless of whether they were initially received by dnsdist over UDP, TCP, DoT or DoH, being forwarded over a secure DNS over HTTPS channel. That support can be enabled via the ``dohPath`` parameter of the :func:`newServer` command. Additional parameters control the TLS provider used (``tls``), the validation of the certificate presented by the backend (``caStore``, ``validateCertificates``), the actual TLS ciphers used (``ciphers``, ``ciphersTLS13``) and the SNI value sent (``subjectName``). +.. code-block:: lua + newServer({address="[2001:DB8::1]:443", tls="openssl", subjectName="doh.powerdns.com", dohPath="/dns-query", validateCertificates=true}) diff --git a/pdns/dnsdistdist/docs/guides/dns-over-tls.rst b/pdns/dnsdistdist/docs/guides/dns-over-tls.rst index 91d95a5d22cd..62362adebad2 100644 --- a/pdns/dnsdistdist/docs/guides/dns-over-tls.rst +++ b/pdns/dnsdistdist/docs/guides/dns-over-tls.rst @@ -30,6 +30,7 @@ Outgoing Support for securing the exchanges between dnsdist and the backend will be implemented in 1.7.0, and will lead to all queries, regardless of whether they were initially received by dnsdist over UDP, TCP, DoT or DoH, being forwarded over a secure DNS over TLS channel. That support can be enabled via the ``tls`` parameter of the :func:`newServer` command. Additional parameters control the validation of the certificate presented by the backend (``caStore``, ``validateCertificates``), the actual TLS ciphers used (``ciphers``, ``ciphersTLS13``) and the SNI value sent (``subjectName``). +.. code-block:: lua newServer({address="[2001:DB8::1]:853", tls="openssl", subjectName="dot.powerdns.com", validateCertificates=true}) From d7f3ac0f3260c642d425fb2cc25aed18bb1d48a3 Mon Sep 17 00:00:00 2001 From: Doug Freed Date: Wed, 28 Jun 2023 00:13:51 -0500 Subject: [PATCH 351/909] rec: include qname when logging skip of step 4 of qname minimization --- pdns/recursordist/syncres.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 2de8e592b8f3..056825cf6445 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1746,7 +1746,7 @@ int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector Date: Wed, 28 Jun 2023 15:23:35 +0200 Subject: [PATCH 352/909] Work around Red Hat 8 pooping the bed in OpenSSL's headers The openssl/kdf.h header on EL8 is invalid because someone backported a work-in-progress feature to an older OpenSSL branch and did not bother to backport the fixes that were added later. Red Hat declined to fix their mess and helpfully suggested we do the work instead in https://bugzilla.redhat.com/show_bug.cgi?id=2215856 --- m4/pdns_check_libcrypto.m4 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/m4/pdns_check_libcrypto.m4 b/m4/pdns_check_libcrypto.m4 index 1fa4f23bda93..4ca3c702eaba 100644 --- a/m4/pdns_check_libcrypto.m4 +++ b/m4/pdns_check_libcrypto.m4 @@ -112,7 +112,15 @@ AC_DEFUN([PDNS_CHECK_LIBCRYPTO], [ [ AC_MSG_RESULT([yes]) AC_CHECK_FUNCS([RAND_bytes RAND_pseudo_bytes CRYPTO_memcmp OPENSSL_init_crypto EVP_MD_CTX_new EVP_MD_CTX_free RSA_get0_key]) - AC_CHECK_DECL(EVP_PKEY_CTX_set1_scrypt_salt, [AC_DEFINE([HAVE_EVP_PKEY_CTX_SET1_SCRYPT_SALT], [1], [Define to 1 if you have EVP_PKEY_CTX_set1_scrypt_salt])], [], [#include ]) + # you might be wondering why the stdarg.h and stddef.h includes, + # in which case please have a look at https://github.com/PowerDNS/pdns/issues/12926 + # and weep, yelling at Red Hat + AC_CHECK_DECL(EVP_PKEY_CTX_set1_scrypt_salt, + [AC_DEFINE([HAVE_EVP_PKEY_CTX_SET1_SCRYPT_SALT], [1], [Define to 1 if you have EVP_PKEY_CTX_set1_scrypt_salt])], + [], + [#include + #include + #include ]) $1 ], [ AC_MSG_RESULT([no]) From c456c93734fd74a489bb761ef4290ab325811617 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 29 Jun 2023 09:09:22 +0200 Subject: [PATCH 353/909] coverity: bump to ubuntu 22.04 --- .github/workflows/misc-dailies.yml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/misc-dailies.yml b/.github/workflows/misc-dailies.yml index 1b12ce6cf03f..60d66abe821a 100644 --- a/.github/workflows/misc-dailies.yml +++ b/.github/workflows/misc-dailies.yml @@ -42,7 +42,7 @@ jobs: coverity-auth: name: coverity scan of the auth if: ${{ vars.SCHEDULED_MISC_DAILIES }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: COVERITY_TOKEN: ${{ secrets.coverity_auth_token }} FUZZING_TARGETS: no @@ -54,7 +54,7 @@ jobs: with: fetch-depth: 5 submodules: recursive - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade + - run: build-scripts/gh-actions-setup-inv-no-dist-upgrade - run: inv install-clang - run: inv install-auth-build-deps - run: inv install-coverity-tools PowerDNS @@ -68,7 +68,7 @@ jobs: coverity-dnsdist: name: coverity scan of dnsdist if: ${{ vars.SCHEDULED_MISC_DAILIES }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: COVERITY_TOKEN: ${{ secrets.coverity_dnsdist_token }} SANITIZERS: @@ -79,7 +79,7 @@ jobs: with: fetch-depth: 5 submodules: recursive - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade + - run: build-scripts/gh-actions-setup-inv-no-dist-upgrade - run: inv install-clang - run: inv install-dnsdist-build-deps - run: inv install-coverity-tools dnsdist @@ -98,7 +98,7 @@ jobs: coverity-rec: name: coverity scan of the rec if: ${{ vars.SCHEDULED_MISC_DAILIES }} - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 env: COVERITY_TOKEN: ${{ secrets.coverity_rec_token }} SANITIZERS: @@ -109,7 +109,7 @@ jobs: with: fetch-depth: 5 submodules: recursive - - run: build-scripts/gh-actions-setup-inv # this runs apt update+upgrade + - run: build-scripts/gh-actions-setup-inv-no-dist-upgrade - run: inv install-clang - run: inv install-rec-build-deps - run: inv install-coverity-tools 'PowerDNS+Recursor' From 44885b257a71de368bfff88fe080fd83d85cc344 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 29 Jun 2023 12:26:05 +0200 Subject: [PATCH 354/909] workaround: recognise centos-7 target name too in provenance generation --- builder-support/dockerfiles/Dockerfile.rpmbuild | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder-support/dockerfiles/Dockerfile.rpmbuild b/builder-support/dockerfiles/Dockerfile.rpmbuild index 6ba2911557b1..c18859c2609c 100644 --- a/builder-support/dockerfiles/Dockerfile.rpmbuild +++ b/builder-support/dockerfiles/Dockerfile.rpmbuild @@ -59,10 +59,10 @@ RUN touch /var/lib/rpm/* && if $(grep -q 'release 7' /etc/redhat-release); then @ENDIF # Generate provenance -@IF [ ${BUILDER_TARGET} = el-7 ] +@IF [ ${BUILDER_TARGET} = el-7 || ${BUILDER_TARGET} = centos-7 ] @EVAL RUN python builder/helpers/generate-yum-provenance.py /dist/packages-${BUILDER_TARGET}.json || python3 builder/helpers/generate-yum-provenance.py /dist/packages-${BUILDER_TARGET}.json @ENDIF -@IF [ ${BUILDER_TARGET} != el-7 ] +@IF [ ${BUILDER_TARGET} != el-7 && ${BUILDET_TARGET} != centos-7 ] @EVAL RUN python builder/helpers/generate-dnf-provenance.py /dist/packages-${BUILDER_TARGET}.json || python3 builder/helpers/generate-dnf-provenance.py /dist/packages-${BUILDER_TARGET}.json @ENDIF From 7b9450932da11f34a8a729b7b7e47202276fff5f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 29 Jun 2023 09:31:46 +0200 Subject: [PATCH 355/909] rec: fix qname length getting out-of-sync with qname-minimization iteration count Approach two: fall back to non-QM mode if loop detected Fixes #12956 --- pdns/recursordist/syncres.cc | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 056825cf6445..c36aebb07b38 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1599,7 +1599,12 @@ static unsigned int qmStepLen(unsigned int labels, unsigned int qnamelen, unsign return targetlen; } -int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, set& beenthere, Context& context) +static string resToString(int res) +{ + return res >= 0 ? RCode::to_s(res) : std::to_string(res); +} + +int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector& ret, unsigned int depth, set& beenthere, Context& context) // NOLINT(readability-function-cognitive-complexity) { auto prefix = getPrefix(depth); auto luaconfsLocal = g_luaconfs.getLocal(); @@ -1733,21 +1738,24 @@ int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector= 0 ? RCode::to_s(res) : std::to_string(res)) << "/" << ret.size() << endl); + LOG(prefix << qname << ": Step3 Final resolve: " << resToString(res) << "/" << ret.size() << endl); return res; } - // If we have seen this child during resolution already; just skip it. We tried to QM it already or otherwise broken. - bool skipStep4 = false; + // If we have seen this child during resolution already; we tried to QM it already or otherwise broken. + // fall back to no-QM + bool qmLoopDetected = false; for (const auto& visitedNS : beenthere) { if (visitedNS.qname == child) { - skipStep4 = true; + qmLoopDetected = true; break; } } - if (skipStep4) { - LOG(prefix << qname << ": Step4 Being skipped as visited this child name already" << endl); - continue; + if (qmLoopDetected) { + LOG(prefix << qname << ": Step4 loop detected as visited this child name already, fallback to no QM" << endl); + res = doResolveNoQNameMinimization(qname, qtype, ret, depth, beenthere, context); + LOG(prefix << qname << ": Step4 Final resolve: " << resToString(res) << "/" << ret.size() << endl); + return res; } // Step 4 @@ -1783,7 +1791,7 @@ int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector Date: Wed, 17 May 2023 15:36:44 +0200 Subject: [PATCH 356/909] Delint pdns_recursor.cc --- pdns/dns.hh | 10 +- pdns/recursordist/lwres.hh | 8 +- pdns/recursordist/pdns_recursor.cc | 1293 ++++++++++++++-------------- pdns/recursordist/rec-main.cc | 10 +- pdns/recursordist/rec-main.hh | 10 +- pdns/recursordist/rec-tcp.cc | 29 +- pdns/recursordist/syncres.hh | 4 +- 7 files changed, 687 insertions(+), 677 deletions(-) diff --git a/pdns/dns.hh b/pdns/dns.hh index 7ceda1eeecc7..bb7c842cfa0b 100644 --- a/pdns/dns.hh +++ b/pdns/dns.hh @@ -193,8 +193,8 @@ class dnsheader_aligned public: dnsheader_aligned(const void* mem) { - if (reinterpret_cast(mem) % sizeof(uint32_t) == 0) { - d_p = reinterpret_cast(mem); + if (reinterpret_cast(mem) % sizeof(uint32_t) == 0) { // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + d_p = reinterpret_cast(mem); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) } else { memcpy(&d_h, mem, sizeof(dnsheader)); @@ -202,14 +202,14 @@ public: } } - const dnsheader* get() const + [[nodiscard]] const dnsheader* get() const { return d_p; } private: - dnsheader d_h; - const dnsheader *d_p; + dnsheader d_h{}; + const dnsheader *d_p{}; }; inline uint16_t * getFlagsFromDNSHeader(struct dnsheader * dh) diff --git a/pdns/recursordist/lwres.hh b/pdns/recursordist/lwres.hh index 52ed30ec1ad5..688c86cb009f 100644 --- a/pdns/recursordist/lwres.hh +++ b/pdns/recursordist/lwres.hh @@ -83,9 +83,9 @@ public: bool d_haveEDNS{false}; }; -LWResult::Result asendto(const char* data, size_t len, int flags, const ComboAddress& ip, uint16_t id, - const DNSName& domain, uint16_t qtype, bool ecs, int* fd); -LWResult::Result arecvfrom(PacketBuffer& packet, int flags, const ComboAddress& ip, size_t& len, uint16_t id, - const DNSName& domain, uint16_t qtype, int fd, const struct timeval& now); +LWResult::Result asendto(const char* data, size_t len, int flags, const ComboAddress& toAddress, uint16_t qid, + const DNSName& domain, uint16_t qtype, bool ecs, int* fileDesc); +LWResult::Result arecvfrom(PacketBuffer& packet, int flags, const ComboAddress& fromAddr, size_t& len, uint16_t qid, + const DNSName& domain, uint16_t qtype, int fileDesc, const struct timeval& now); LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, const std::shared_ptr>>& outgoingLoggers, const std::shared_ptr>>& fstrmLoggers, const std::set& exportTypes, LWResult* res, bool* chained); diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 7d3340669105..f56375739717 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -46,7 +46,7 @@ thread_local FDWrapper t_tracefd = -1; thread_local ProtobufServersInfo t_protobufServers; thread_local ProtobufServersInfo t_outgoingProtobufServers; -thread_local std::unique_ptr MT; // the big MTasker +thread_local std::unique_ptr g_multiTasker; // the big MTasker std::unique_ptr g_recCache; std::unique_ptr g_negCache; std::unique_ptr g_packetCache; @@ -59,7 +59,7 @@ thread_local std::shared_ptr t_allowNotifyFrom; thread_local std::shared_ptr t_allowNotifyFor; __thread struct timeval g_now; // timestamp, updated (too) frequently -typedef map listenSocketsAddresses_t; // is shared across all threads right now +using listenSocketsAddresses_t = map; // is shared across all threads right now static listenSocketsAddresses_t g_listenSocketsAddresses; // is shared across all threads right now static set g_fromtosockets; // listen sockets that use 'sendfromto()' mechanism (without actually using sendfromto()) @@ -97,17 +97,17 @@ GlobalStateHolder g_dontThrottleNetmasks; GlobalStateHolder g_DoTToAuthNames; uint64_t g_latencyStatSize; -LWResult::Result UDPClientSocks::getSocket(const ComboAddress& toaddr, int* fd) +LWResult::Result UDPClientSocks::getSocket(const ComboAddress& toaddr, int* fileDesc) { - *fd = makeClientSocket(toaddr.sin4.sin_family); - if (*fd < 0) { // temporary error - receive exception otherwise + *fileDesc = makeClientSocket(toaddr.sin4.sin_family); + if (*fileDesc < 0) { // temporary error - receive exception otherwise return LWResult::Result::OSLimitError; } - if (connect(*fd, (struct sockaddr*)(&toaddr), toaddr.getSocklen()) < 0) { + if (connect(*fileDesc, reinterpret_cast(&toaddr), toaddr.getSocklen()) < 0) { // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)) int err = errno; try { - closesocket(*fd); + closesocket(*fileDesc); } catch (const PDNSException& e) { SLOG(g_log << Logger::Error << "Error closing UDP socket after connect() failed: " << e.reason << endl, @@ -126,17 +126,17 @@ LWResult::Result UDPClientSocks::getSocket(const ComboAddress& toaddr, int* fd) } // return a socket to the pool, or simply erase it -void UDPClientSocks::returnSocket(int fd) +void UDPClientSocks::returnSocket(int fileDesc) { try { - t_fdm->removeReadFD(fd); + t_fdm->removeReadFD(fileDesc); } catch (const FDMultiplexerException& e) { // we sometimes return a socket that has not yet been assigned to t_fdm } try { - closesocket(fd); + closesocket(fileDesc); } catch (const PDNSException& e) { SLOG(g_log << Logger::Error << "Error closing returned UDP socket: " << e.reason << endl, @@ -168,7 +168,7 @@ int UDPClientSocks::makeClientSocket(int family) #endif ComboAddress sin; while (--tries != 0) { - in_port_t port; + in_port_t port = 0; if (tries == 1) { // last iteration: fall back to kernel 'random' port = 0; @@ -180,7 +180,7 @@ int UDPClientSocks::makeClientSocket(int family) } sin = pdns::getQueryLocalAddress(family, port); // does htons for us - if (::bind(ret, reinterpret_cast(&sin), sin.getSocklen()) >= 0) { + if (::bind(ret, reinterpret_cast(&sin), sin.getSocklen()) >= 0) { // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) break; } } @@ -203,53 +203,53 @@ int UDPClientSocks::makeClientSocket(int family) return ret; } -static void handleGenUDPQueryResponse(int fd, FDMultiplexer::funcparam_t& var) +static void handleGenUDPQueryResponse(int fileDesc, FDMultiplexer::funcparam_t& var) { - std::shared_ptr pident = boost::any_cast>(var); + auto pident = boost::any_cast>(var); PacketBuffer resp; resp.resize(512); ComboAddress fromaddr; socklen_t addrlen = sizeof(fromaddr); - ssize_t ret = recvfrom(fd, resp.data(), resp.size(), 0, (sockaddr*)&fromaddr, &addrlen); + ssize_t ret = recvfrom(fileDesc, resp.data(), resp.size(), 0, reinterpret_cast(&fromaddr), &addrlen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) if (fromaddr != pident->remote) { SLOG(g_log << Logger::Notice << "Response received from the wrong remote host (" << fromaddr.toStringWithPort() << " instead of " << pident->remote.toStringWithPort() << "), discarding" << endl, g_slog->withName("lua")->info(Logr::Notice, "Response received from the wrong remote host. discarding", "method", Logging::Loggable("GenUDPQueryResponse"), "fromaddr", Logging::Loggable(fromaddr), "expected", Logging::Loggable(pident->remote))); } - t_fdm->removeReadFD(fd); + t_fdm->removeReadFD(fileDesc); if (ret >= 0) { resp.resize(ret); - MT->sendEvent(pident, &resp); + g_multiTasker->sendEvent(pident, &resp); } else { PacketBuffer empty; - MT->sendEvent(pident, &empty); + g_multiTasker->sendEvent(pident, &empty); // cerr<<"Had some kind of error: "< pident = std::make_shared(); - pident->fd = s.getHandle(); + pident->fd = socket.getHandle(); pident->remote = dest; pident->type = 0; - t_fdm->addReadFD(s.getHandle(), handleGenUDPQueryResponse, pident); + t_fdm->addReadFD(socket.getHandle(), handleGenUDPQueryResponse, pident); PacketBuffer data; - int ret = MT->waitEvent(pident, &data, g_networkTimeoutMsec); + int ret = g_multiTasker->waitEvent(pident, &data, g_networkTimeoutMsec); - if (!ret || ret == -1) { // timeout - t_fdm->removeReadFD(s.getHandle()); + if (ret == 0 || ret == -1) { // timeout + t_fdm->removeReadFD(socket.getHandle()); } else if (data.empty()) { // error, EOF or other // we could special case this @@ -258,18 +258,18 @@ PacketBuffer GenUDPQueryResponse(const ComboAddress& dest, const string& query) return data; } -static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t&); +static void handleUDPServerResponse(int fileDesc, FDMultiplexer::funcparam_t& var); thread_local std::unique_ptr t_udpclientsocks; /* these two functions are used by LWRes */ LWResult::Result asendto(const char* data, size_t len, int /* flags */, - const ComboAddress& toaddr, uint16_t id, const DNSName& domain, uint16_t qtype, bool ecs, int* fd) + const ComboAddress& toAddress, uint16_t qid, const DNSName& domain, uint16_t qtype, bool ecs, int* fileDesc) { auto pident = std::make_shared(); pident->domain = domain; - pident->remote = toaddr; + pident->remote = toAddress; pident->type = qtype; // We cannot merge ECS-enabled queries based on the ECS source only, as the scope @@ -279,35 +279,35 @@ LWResult::Result asendto(const char* data, size_t len, int /* flags */, // See if there is an existing outstanding request we can chain on to, using partial equivalence // function looking for the same query (qname and qtype) to the same host, but with a different // message ID. - auto chain = MT->d_waiters.equal_range(pident, PacketIDBirthdayCompare()); + auto chain = g_multiTasker->d_waiters.equal_range(pident, PacketIDBirthdayCompare()); for (; chain.first != chain.second; chain.first++) { // Line below detected an issue with the two ways of ordering PacketIDs (birthday and non-birthday) - assert(chain.first->key->domain == pident->domain); + assert(chain.first->key->domain == pident->domain); // NOLINT // don't chain onto existing chained waiter or a chain already processed if (chain.first->key->fd > -1 && !chain.first->key->closed) { - chain.first->key->chain.insert(id); // we can chain - *fd = -1; // gets used in waitEvent / sendEvent later on + chain.first->key->chain.insert(qid); // we can chain + *fileDesc = -1; // gets used in waitEvent / sendEvent later on return LWResult::Result::Success; } } } - auto ret = t_udpclientsocks->getSocket(toaddr, fd); + auto ret = t_udpclientsocks->getSocket(toAddress, fileDesc); if (ret != LWResult::Result::Success) { return ret; } - pident->fd = *fd; - pident->id = id; + pident->fd = *fileDesc; + pident->id = qid; - t_fdm->addReadFD(*fd, handleUDPServerResponse, pident); - ssize_t sent = send(*fd, data, len, 0); + t_fdm->addReadFD(*fileDesc, handleUDPServerResponse, pident); + ssize_t sent = send(*fileDesc, data, len, 0); int tmp = errno; if (sent < 0) { - t_udpclientsocks->returnSocket(*fd); + t_udpclientsocks->returnSocket(*fileDesc); errno = tmp; // this is for logging purposes only return LWResult::Result::PermanentError; } @@ -315,19 +315,19 @@ LWResult::Result asendto(const char* data, size_t len, int /* flags */, return LWResult::Result::Success; } -LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAddress& fromaddr, size_t& len, - uint16_t id, const DNSName& domain, uint16_t qtype, int fd, const struct timeval& now) +LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAddress& fromAddr, size_t& len, + uint16_t qid, const DNSName& domain, uint16_t qtype, int fileDesc, const struct timeval& now) { static const unsigned int nearMissLimit = ::arg().asNum("spoof-nearmiss-max"); auto pident = std::make_shared(); - pident->fd = fd; - pident->id = id; + pident->fd = fileDesc; + pident->id = qid; pident->domain = domain; pident->type = qtype; - pident->remote = fromaddr; + pident->remote = fromAddr; - int ret = MT->waitEvent(pident, &packet, g_networkTimeoutMsec, &now); + int ret = g_multiTasker->waitEvent(pident, &packet, g_networkTimeoutMsec, &now); len = 0; /* -1 means error, 0 means timeout, 1 means a result from handleUDPServerResponse() which might still be an error */ @@ -342,23 +342,21 @@ LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAdd if (nearMissLimit > 0 && pident->nearMisses > nearMissLimit) { /* we have received more than nearMissLimit answers on the right IP and port, from the right source (we are using connected sockets), for the correct qname and qtype, but with an unexpected message ID. That looks like a spoofing attempt. */ - SLOG(g_log << Logger::Error << "Too many (" << pident->nearMisses << " > " << nearMissLimit << ") answers with a wrong message ID for '" << domain << "' from " << fromaddr.toString() << ", assuming spoof attempt." << endl, + SLOG(g_log << Logger::Error << "Too many (" << pident->nearMisses << " > " << nearMissLimit << ") answers with a wrong message ID for '" << domain << "' from " << fromAddr.toString() << ", assuming spoof attempt." << endl, g_slogudpin->info(Logr::Error, "Too many answers with a wrong message ID, assuming spoofing attempt", "nearmisses", Logging::Loggable(pident->nearMisses), "nearmisslimit", Logging::Loggable(nearMissLimit), "qname", Logging::Loggable(domain), - "from", Logging::Loggable(fromaddr))); + "from", Logging::Loggable(fromAddr))); t_Counters.at(rec::Counter::spoofCount)++; return LWResult::Result::Spoofed; } return LWResult::Result::Success; } - else { - /* getting there means error or timeout, it's up to us to close the socket */ - if (fd >= 0) { - t_udpclientsocks->returnSocket(fd); - } + /* getting there means error or timeout, it's up to us to close the socket */ + if (fileDesc >= 0) { + t_udpclientsocks->returnSocket(fileDesc); } return ret == 0 ? LWResult::Result::Timeout : LWResult::Result::PermanentError; @@ -367,14 +365,16 @@ LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAdd // the idea is, only do things that depend on the *response* here. Incoming accounting is on incoming. static void updateResponseStats(int res, const ComboAddress& remote, unsigned int packetsize, const DNSName* query, uint16_t qtype) { - if (packetsize > 1000 && t_largeanswerremotes) + if (packetsize > 1000 && t_largeanswerremotes) { t_largeanswerremotes->push_back(remote); + } switch (res) { case RCode::ServFail: if (t_servfailremotes) { t_servfailremotes->push_back(remote); - if (query && t_servfailqueryring) // packet cache + if (query != nullptr && t_servfailqueryring) { // packet cache t_servfailqueryring->push_back({*query, qtype}); + } } ++t_Counters.at(rec::Counter::servFails); break; @@ -387,9 +387,9 @@ static void updateResponseStats(int res, const ComboAddress& remote, unsigned in } } -static string makeLoginfo(const std::unique_ptr& dc) +static string makeLoginfo(const std::unique_ptr& comboWriter) try { - return "(" + dc->d_mdp.d_qname.toLogString() + "/" + DNSRecordContent::NumberToType(dc->d_mdp.d_qtype) + " from " + (dc->getRemote()) + ")"; + return "(" + comboWriter->d_mdp.d_qname.toLogString() + "/" + DNSRecordContent::NumberToType(comboWriter->d_mdp.d_qtype) + " from " + (comboWriter->getRemote()) + ")"; } catch (...) { return "Exception making error message for exception"; @@ -404,40 +404,41 @@ catch (...) { * @param res: An integer that will contain the RCODE of the lookup we do * @param ret: A vector of DNSRecords where the result of the CNAME chase should be appended to */ -static void handleRPZCustom(const DNSRecord& spoofed, const QType& qtype, SyncRes& sr, int& res, vector& ret) +static void handleRPZCustom(const DNSRecord& spoofed, const QType& qtype, SyncRes& resolver, int& res, vector& ret) { if (spoofed.d_type == QType::CNAME) { - bool oldWantsRPZ = sr.getWantsRPZ(); - sr.setWantsRPZ(false); + bool oldWantsRPZ = resolver.getWantsRPZ(); + resolver.setWantsRPZ(false); vector ans; - res = sr.beginResolve(DNSName(spoofed.getContent()->getZoneRepresentation()), qtype, QClass::IN, ans); + res = resolver.beginResolve(DNSName(spoofed.getContent()->getZoneRepresentation()), qtype, QClass::IN, ans); for (const auto& rec : ans) { if (rec.d_place == DNSResourceRecord::ANSWER) { ret.push_back(rec); } } // Reset the RPZ state of the SyncRes - sr.setWantsRPZ(oldWantsRPZ); + resolver.setWantsRPZ(oldWantsRPZ); } } -static bool addRecordToPacket(DNSPacketWriter& pw, const DNSRecord& rec, uint32_t& minTTL, uint32_t ttlCap, const uint16_t maxAnswerSize, bool& seenAuthSOA) +static bool addRecordToPacket(DNSPacketWriter& packetWritewr, const DNSRecord& rec, uint32_t& minTTL, uint32_t ttlCap, const uint16_t maxAnswerSize, bool& seenAuthSOA) { - pw.startRecord(rec.d_name, rec.d_type, (rec.d_ttl > ttlCap ? ttlCap : rec.d_ttl), rec.d_class, rec.d_place); + packetWritewr.startRecord(rec.d_name, rec.d_type, (rec.d_ttl > ttlCap ? ttlCap : rec.d_ttl), rec.d_class, rec.d_place); if (rec.d_type == QType::SOA && rec.d_place == DNSResourceRecord::AUTHORITY) { seenAuthSOA = true; } - if (rec.d_type != QType::OPT) // their TTL ain't real + if (rec.d_type != QType::OPT) { // their TTL ain't real minTTL = min(minTTL, rec.d_ttl); + } - rec.getContent()->toPacket(pw); - if (pw.size() > static_cast(maxAnswerSize)) { - pw.rollback(); + rec.getContent()->toPacket(packetWritewr); + if (packetWritewr.size() > static_cast(maxAnswerSize)) { + packetWritewr.rollback(); if (rec.d_place != DNSResourceRecord::ADDITIONAL) { - pw.getHeader()->tc = 1; - pw.truncate(); + packetWritewr.getHeader()->tc = 1; + packetWritewr.truncate(); } return false; } @@ -454,8 +455,12 @@ static bool addRecordToPacket(DNSPacketWriter& pw, const DNSRecord& rec, uint32_ class RunningResolveGuard { public: - RunningResolveGuard(std::unique_ptr& dc) : - d_dc(dc) + RunningResolveGuard(const RunningResolveGuard&) = default; + RunningResolveGuard(RunningResolveGuard&&) = delete; + RunningResolveGuard& operator=(const RunningResolveGuard&) = delete; + RunningResolveGuard& operator=(RunningResolveGuard&&) = delete; + RunningResolveGuard(std::unique_ptr& comboWriter) : + d_dc(comboWriter) { if (d_dc->d_tcp && !d_dc->d_tcpConnection) { throw std::runtime_error("incoming TCP case without TCP connection"); @@ -494,22 +499,22 @@ enum class PolicyResult : uint8_t Drop }; -static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy, const std::unique_ptr& dc, SyncRes& sr, int& res, vector& ret, DNSPacketWriter& pw, RunningResolveGuard& tcpGuard) +static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy, const std::unique_ptr& comboWriter, SyncRes& resolver, int& res, vector& ret, DNSPacketWriter& packetWriter, RunningResolveGuard& tcpGuard) { /* don't account truncate actions for TCP queries, since they are not applied */ - if (appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::Truncate || !dc->d_tcp) { + if (appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::Truncate || !comboWriter->d_tcp) { ++t_Counters.at(rec::PolicyHistogram::policy).at(appliedPolicy.d_kind); ++t_Counters.at(rec::PolicyNameHits::policyName).counts[appliedPolicy.getName()]; } - if (sr.doLog() && appliedPolicy.d_type != DNSFilterEngine::PolicyType::None) { - SLOG(g_log << Logger::Warning << dc->d_mdp.d_qname << "|" << QType(dc->d_mdp.d_qtype) << appliedPolicy.getLogString() << endl, - appliedPolicy.info(Logr::Warning, sr.d_slog)); + if (resolver.doLog() && appliedPolicy.d_type != DNSFilterEngine::PolicyType::None) { + SLOG(g_log << Logger::Warning << comboWriter->d_mdp.d_qname << "|" << QType(comboWriter->d_mdp.d_qtype) << appliedPolicy.getLogString() << endl, + appliedPolicy.info(Logr::Warning, resolver.d_slog)); } if (appliedPolicy.d_zoneData && appliedPolicy.d_zoneData->d_extendedErrorCode) { - dc->d_extendedErrorCode = *appliedPolicy.d_zoneData->d_extendedErrorCode; - dc->d_extendedErrorExtra = appliedPolicy.d_zoneData->d_extendedErrorExtra; + comboWriter->d_extendedErrorCode = *appliedPolicy.d_zoneData->d_extendedErrorCode; + comboWriter->d_extendedErrorExtra = appliedPolicy.d_zoneData->d_extendedErrorExtra; } switch (appliedPolicy.d_kind) { @@ -535,11 +540,11 @@ static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy return PolicyResult::HaveAnswer; case DNSFilterEngine::PolicyKind::Truncate: - if (!dc->d_tcp) { + if (!comboWriter->d_tcp) { ret.clear(); appliedPolicy.addSOAtoRPZResult(ret); res = RCode::NoError; - pw.getHeader()->tc = 1; + packetWriter.getHeader()->tc = 1; return PolicyResult::HaveAnswer; } return PolicyResult::NoAction; @@ -547,16 +552,16 @@ static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy case DNSFilterEngine::PolicyKind::Custom: res = RCode::NoError; { - auto spoofed = appliedPolicy.getCustomRecords(dc->d_mdp.d_qname, dc->d_mdp.d_qtype); - for (auto& dr : spoofed) { - ret.push_back(dr); + auto spoofed = appliedPolicy.getCustomRecords(comboWriter->d_mdp.d_qname, comboWriter->d_mdp.d_qtype); + for (auto& record : spoofed) { + ret.push_back(record); try { - handleRPZCustom(dr, QType(dc->d_mdp.d_qtype), sr, res, ret); + handleRPZCustom(record, QType(comboWriter->d_mdp.d_qtype), resolver, res, ret); } catch (const ImmediateServFailException& e) { if (g_logCommonErrors) { - SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << dc->getRemote() << " during resolve of the custom filter policy '" << appliedPolicy.getName() << "' while resolving '" << dc->d_mdp.d_qname << "' because: " << e.reason << endl, - sr.d_slog->error(Logr::Notice, e.reason, "Sending SERVFAIL during resolve of the custom filter policy", + SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << comboWriter->getRemote() << " during resolve of the custom filter policy '" << appliedPolicy.getName() << "' while resolving '" << comboWriter->d_mdp.d_qname << "' because: " << e.reason << endl, + resolver.d_slog->error(Logr::Notice, e.reason, "Sending SERVFAIL during resolve of the custom filter policy", "policyName", Logging::Loggable(appliedPolicy.getName()), "exception", Logging::Loggable("ImmediateServFailException"))); } res = RCode::ServFail; @@ -564,8 +569,8 @@ static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy } catch (const PolicyHitException& e) { if (g_logCommonErrors) { - SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << dc->getRemote() << " during resolve of the custom filter policy '" << appliedPolicy.getName() << "' while resolving '" << dc->d_mdp.d_qname << "' because another RPZ policy was hit" << endl, - sr.d_slog->info(Logr::Notice, "Sending SERVFAIL during resolve of the custom filter policy because another RPZ policy was hit", + SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << comboWriter->getRemote() << " during resolve of the custom filter policy '" << appliedPolicy.getName() << "' while resolving '" << comboWriter->d_mdp.d_qname << "' because another RPZ policy was hit" << endl, + resolver.d_slog->info(Logr::Notice, "Sending SERVFAIL during resolve of the custom filter policy because another RPZ policy was hit", "policyName", Logging::Loggable(appliedPolicy.getName()), "exception", Logging::Loggable("PolicyHitException"))); } res = RCode::ServFail; @@ -627,9 +632,9 @@ static bool udrCheckUniqueDNSRecord(Logr::log_t nodlogger, const DNSName& dname, bool ret = false; if (record.d_place == DNSResourceRecord::ANSWER || record.d_place == DNSResourceRecord::ADDITIONAL) { // Create a string that represent a triplet of (qname, qtype and RR[type, name, content]) - std::stringstream ss; - ss << dname.toDNSStringLC() << ":" << qtype << ":" << qtype << ":" << record.d_type << ":" << record.d_name.toDNSStringLC() << ":" << record.getContent()->getZoneRepresentation(); - if (t_udrDBp && t_udrDBp->isUniqueResponse(ss.str())) { + std::stringstream strStream; + strStream << dname.toDNSStringLC() << ":" << qtype << ":" << qtype << ":" << record.d_type << ":" << record.d_name.toDNSStringLC() << ":" << record.getContent()->getZoneRepresentation(); + if (t_udrDBp && t_udrDBp->isUniqueResponse(strStream.str())) { if (g_udrLog) { // This should also probably log to a dedicated file. SLOG(g_log << Logger::Notice << "Unique response observed: qname=" << dname << " qtype=" << QType(qtype) << " rrtype=" << QType(record.d_type) << " rrname=" << record.d_name << " rrcontent=" << record.getContent()->getZoneRepresentation() << endl, @@ -653,9 +658,9 @@ int followCNAMERecords(vector& ret, const QType qtype, int rcode) { vector resolved; DNSName target; - for (const DNSRecord& rr : ret) { - if (rr.d_type == QType::CNAME) { - auto rec = getRR(rr); + for (const DNSRecord& record : ret) { + if (record.d_type == QType::CNAME) { + auto rec = getRR(record); if (rec) { target = rec->getTarget(); break; @@ -674,9 +679,9 @@ int followCNAMERecords(vector& ret, const QType qtype, int rcode) rcode = getFakeAAAARecords(target, *g_dns64Prefix, resolved); } - for (DNSRecord& rr : resolved) { - if (rr.d_place == DNSResourceRecord::ANSWER) { - ret.push_back(std::move(rr)); + for (DNSRecord& record : resolved) { + if (record.d_place == DNSResourceRecord::ANSWER) { + ret.push_back(std::move(record)); } } return rcode; @@ -701,9 +706,9 @@ int getFakeAAAARecords(const DNSName& qname, ComboAddress prefix, vector(rr); + [&seenCNAMEs](DNSRecord& record) { + if (record.d_type == QType::CNAME) { + auto target = getRR(record); if (target == nullptr) { return false; } @@ -718,13 +723,13 @@ int getFakeAAAARecords(const DNSName& qname, ComboAddress prefix, vector(rr)) { + for (DNSRecord& record : ret) { + if (record.d_type == QType::A && record.d_place == DNSResourceRecord::ANSWER) { + if (auto rec = getRR(record)) { ComboAddress ipv4(rec->getCA()); memcpy(&prefix.sin6.sin6_addr.s6_addr[12], &ipv4.sin4.sin_addr.s_addr, sizeof(ipv4.sin4.sin_addr.s_addr)); - rr.setContent(std::make_shared(prefix)); - rr.d_type = QType::AAAA; + record.setContent(std::make_shared(prefix)); + record.d_type = QType::AAAA; } seenA = true; } @@ -736,8 +741,8 @@ int getFakeAAAARecords(const DNSName& qname, ComboAddress prefix, vector& ret) } string newquery; - for (int n = 0; n < 4; ++n) { - newquery += std::to_string(stoll(parts[n * 2], 0, 16) + 16 * stoll(parts[n * 2 + 1], 0, 16)); + for (size_t octet = 0; octet < 4; ++octet) { + newquery += std::to_string(stoll(parts[octet * 2], nullptr, 16) + 16 * stoll(parts[octet * 2 + 1], nullptr, 16)); newquery.append(1, '.'); } newquery += "in-addr.arpa."; - DNSRecord rr; - rr.d_name = qname; - rr.d_type = QType::CNAME; - rr.setContent(std::make_shared(newquery)); - ret.push_back(rr); + DNSRecord record; + record.d_name = qname; + record.d_type = QType::CNAME; + record.setContent(std::make_shared(newquery)); + ret.push_back(record); auto log = g_slog->withName("dns64")->withValues("method", Logging::Loggable("getPTR")); int rcode = directResolve(DNSName(newquery), QType::PTR, QClass::IN, ret, t_pdl, log); @@ -813,8 +818,9 @@ bool isAllowNotifyForZone(DNSName qname) notifyset_t::const_iterator ret; do { ret = t_allowNotifyFor->find(qname); - if (ret != t_allowNotifyFor->end()) + if (ret != t_allowNotifyFor->end()) { return true; + } } while (qname.chopOff()); return false; } @@ -872,13 +878,13 @@ static void dumpTrace(const string& trace, const timeval& timev) close(traceFd); return; } - std::array timebuf; + std::array timebuf{}; isoDateTimeMillis(timev, timebuf.data(), timebuf.size()); fprintf(filep.get(), " us === START OF TRACE %s ===\n", timebuf.data()); fprintf(filep.get(), "%s", trace.c_str()); isoDateTimeMillis(now, timebuf.data(), timebuf.size()); fprintf(filep.get(), "=== END OF TRACE %s ===\n", timebuf.data()); - if (ferror(filep.get())) { + if (ferror(filep.get()) != 0) { int err = errno; SLOG(g_log << Logger::Error << "Problems writing to trace file: " << stringerror(err) << endl, g_slog->withName("trace")->error(Logr::Error, err, "Problems writing to trace file")); @@ -900,18 +906,19 @@ static uint32_t capPacketCacheTTL(const struct dnsheader& hdr, uint32_t ttl, boo return ttl; } -void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 +void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 { - auto dc = std::unique_ptr(reinterpret_cast(p)); - SyncRes sr(dc->d_now); + auto comboWriter = std::unique_ptr(reinterpret_cast(arg)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + SyncRes resolver(comboWriter->d_now); try { - if (t_queryring) - t_queryring->push_back({dc->d_mdp.d_qname, dc->d_mdp.d_qtype}); + if (t_queryring) { + t_queryring->push_back({comboWriter->d_mdp.d_qname, comboWriter->d_mdp.d_qtype}); + } - uint16_t maxanswersize = dc->d_tcp ? 65535 : min(static_cast(512), g_udpTruncationThreshold); + uint16_t maxanswersize = comboWriter->d_tcp ? 65535 : min(static_cast(512), g_udpTruncationThreshold); EDNSOpts edo; std::vector> ednsOpts; - bool variableAnswer = dc->d_variable; + bool variableAnswer = comboWriter->d_variable; bool haveEDNS = false; bool paddingAllowed = false; bool addPaddingToResponse = false; @@ -919,18 +926,18 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity bool hasUDR = false; std::shared_ptr nodlogger{nullptr}; if (g_udrEnabled || g_nodEnabled) { - nodlogger = g_slog->withName("nod")->v(1)->withValues("qname", Logging::Loggable(dc->d_mdp.d_qname)); + nodlogger = g_slog->withName("nod")->v(1)->withValues("qname", Logging::Loggable(comboWriter->d_mdp.d_qname)); } #endif /* NOD_ENABLED */ DNSPacketWriter::optvect_t returnedEdnsOptions; // Here we stuff all the options for the return packet uint8_t ednsExtRCode = 0; - if (getEDNSOpts(dc->d_mdp, &edo)) { + if (getEDNSOpts(comboWriter->d_mdp, &edo)) { haveEDNS = true; if (edo.d_version != 0) { ednsExtRCode = ERCode::BADVERS; } - if (!dc->d_tcp) { + if (!comboWriter->d_tcp) { /* rfc6891 6.2.3: "Values lower than 512 MUST be treated as equal to 512." */ @@ -939,18 +946,18 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity ednsOpts = edo.d_options; maxanswersize -= 11; // EDNS header size - if (!dc->d_responsePaddingDisabled && g_paddingFrom.match(dc->d_remote)) { + if (!comboWriter->d_responsePaddingDisabled && g_paddingFrom.match(comboWriter->d_remote)) { paddingAllowed = true; if (g_paddingMode == PaddingMode::Always) { addPaddingToResponse = true; } } - for (const auto& o : edo.d_options) { - if (o.first == EDNSOptionCode::ECS && g_useIncomingECS && !dc->d_ecsParsed) { - dc->d_ecsFound = getEDNSSubnetOptsFromString(o.second, &dc->d_ednssubnet); + for (const auto& option : edo.d_options) { + if (option.first == EDNSOptionCode::ECS && g_useIncomingECS && !comboWriter->d_ecsParsed) { + comboWriter->d_ecsFound = getEDNSSubnetOptsFromString(option.second, &comboWriter->d_ednssubnet); } - else if (o.first == EDNSOptionCode::NSID) { + else if (option.first == EDNSOptionCode::NSID) { const static string mode_server_id = ::arg()["server-id"]; if (mode_server_id != "disabled" && !mode_server_id.empty() && maxanswersize > (EDNSOptionCodeSize + EDNSOptionLengthSize + mode_server_id.size())) { returnedEdnsOptions.emplace_back(EDNSOptionCode::NSID, mode_server_id); @@ -958,7 +965,7 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity maxanswersize -= EDNSOptionCodeSize + EDNSOptionLengthSize + mode_server_id.size(); } } - else if (paddingAllowed && !addPaddingToResponse && g_paddingMode == PaddingMode::PaddedQueries && o.first == EDNSOptionCode::PADDING) { + else if (paddingAllowed && !addPaddingToResponse && g_paddingMode == PaddingMode::PaddedQueries && option.first == EDNSOptionCode::PADDING) { addPaddingToResponse = true; } } @@ -967,12 +974,12 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity /* the lookup will be done _before_ knowing whether the query actually has a padding option, so we need to use the separate tag even when the query does not have padding, as long as it is from an allowed source */ - if (paddingAllowed && dc->d_tag == 0) { - dc->d_tag = g_paddingTag; + if (paddingAllowed && comboWriter->d_tag == 0) { + comboWriter->d_tag = g_paddingTag; } /* perhaps there was no EDNS or no ECS but by now we looked */ - dc->d_ecsParsed = true; + comboWriter->d_ecsParsed = true; vector ret; vector packet; @@ -983,7 +990,7 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity pdns::ProtoZero::RecMessage pbMessage; if (checkProtobufExport(luaconfsLocal)) { pbMessage.reserve(128, 128); // It's a bit of a guess... - pbMessage.setResponse(dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass); + pbMessage.setResponse(comboWriter->d_mdp.d_qname, comboWriter->d_mdp.d_qtype, comboWriter->d_mdp.d_qclass); pbMessage.setServerIdentity(SyncRes::s_serverID); // RRSets added below @@ -994,46 +1001,46 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity checkFrameStreamExport(luaconfsLocal, luaconfsLocal->nodFrameStreamExportConfig, t_nodFrameStreamServersInfo); #endif - DNSPacketWriter pw(packet, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_mdp.d_qclass, dc->d_mdp.d_header.opcode); + DNSPacketWriter packetWriter(packet, comboWriter->d_mdp.d_qname, comboWriter->d_mdp.d_qtype, comboWriter->d_mdp.d_qclass, comboWriter->d_mdp.d_header.opcode); - pw.getHeader()->aa = 0; - pw.getHeader()->ra = 1; - pw.getHeader()->qr = 1; - pw.getHeader()->tc = 0; - pw.getHeader()->id = dc->d_mdp.d_header.id; - pw.getHeader()->rd = dc->d_mdp.d_header.rd; - pw.getHeader()->cd = dc->d_mdp.d_header.cd; + packetWriter.getHeader()->aa = 0; + packetWriter.getHeader()->ra = 1; + packetWriter.getHeader()->qr = 1; + packetWriter.getHeader()->tc = 0; + packetWriter.getHeader()->id = comboWriter->d_mdp.d_header.id; + packetWriter.getHeader()->rd = comboWriter->d_mdp.d_header.rd; + packetWriter.getHeader()->cd = comboWriter->d_mdp.d_header.cd; /* This is the lowest TTL seen in the records of the response, so we can't cache it for longer than this value. If we have a TTL cap, this value can't be larger than the cap no matter what. */ - uint32_t minTTL = dc->d_ttlCap; + uint32_t minTTL = comboWriter->d_ttlCap; bool seenAuthSOA = false; - sr.d_eventTrace = std::move(dc->d_eventTrace); - sr.setId(MT->getTid()); + resolver.d_eventTrace = std::move(comboWriter->d_eventTrace); + resolver.setId(g_multiTasker->getTid()); bool DNSSECOK = false; - if (dc->d_luaContext) { - sr.setLuaEngine(dc->d_luaContext); + if (comboWriter->d_luaContext) { + resolver.setLuaEngine(comboWriter->d_luaContext); } if (g_dnssecmode != DNSSECMode::Off) { - sr.setDoDNSSEC(true); + resolver.setDoDNSSEC(true); // Does the requestor want DNSSEC records? - if (edo.d_extFlags & EDNSOpts::DNSSECOK) { + if ((edo.d_extFlags & EDNSOpts::DNSSECOK) != 0) { DNSSECOK = true; t_Counters.at(rec::Counter::dnssecQueries)++; } - if (dc->d_mdp.d_header.cd) { + if (comboWriter->d_mdp.d_header.cd) { /* Per rfc6840 section 5.9, "When processing a request with the Checking Disabled (CD) bit set, a resolver SHOULD attempt to return all response data, even data that has failed DNSSEC validation. */ ++t_Counters.at(rec::Counter::dnssecCheckDisabledQueries); } - if (dc->d_mdp.d_header.ad) { + if (comboWriter->d_mdp.d_header.ad) { /* Per rfc6840 section 5.7, "the AD bit in a query as a signal indicating that the requester understands and is interested in the value of the AD bit in the response. This allows a requester to @@ -1044,37 +1051,37 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } else { // Ignore the client-set CD flag - pw.getHeader()->cd = 0; + packetWriter.getHeader()->cd = 0; } - sr.setDNSSECValidationRequested(g_dnssecmode == DNSSECMode::ValidateAll || g_dnssecmode == DNSSECMode::ValidateForLog || ((dc->d_mdp.d_header.ad || DNSSECOK) && g_dnssecmode == DNSSECMode::Process)); + resolver.setDNSSECValidationRequested(g_dnssecmode == DNSSECMode::ValidateAll || g_dnssecmode == DNSSECMode::ValidateForLog || ((comboWriter->d_mdp.d_header.ad || DNSSECOK) && g_dnssecmode == DNSSECMode::Process)); - sr.setInitialRequestId(dc->d_uuid); - sr.setOutgoingProtobufServers(t_outgoingProtobufServers.servers); + resolver.setInitialRequestId(comboWriter->d_uuid); + resolver.setOutgoingProtobufServers(t_outgoingProtobufServers.servers); #ifdef HAVE_FSTRM - sr.setFrameStreamServers(t_frameStreamServersInfo.servers); + resolver.setFrameStreamServers(t_frameStreamServersInfo.servers); #endif bool useMapped = true; // If proxy by table is active and had a match, we only want to use the mapped address if it also has a domain match // (if a domain suffix match table is present in the config) - if (t_proxyMapping && dc->d_source != dc->d_mappedSource) { - if (auto it = t_proxyMapping->lookup(dc->d_source)) { - if (it->second.suffixMatchNode) { - if (!it->second.suffixMatchNode->check(dc->d_mdp.d_qname)) { + if (t_proxyMapping && comboWriter->d_source != comboWriter->d_mappedSource) { + if (const auto* iter = t_proxyMapping->lookup(comboWriter->d_source)) { + if (iter->second.suffixMatchNode) { + if (!iter->second.suffixMatchNode->check(comboWriter->d_mdp.d_qname)) { // No match in domains, use original source useMapped = false; } else { - ++it->second.stats.suffixMatches; + ++iter->second.stats.suffixMatches; } } // No suffix match node defined, use mapped address } // lookup failing cannot happen as dc->d_source != dc->d_mappedSource } - sr.setQuerySource(useMapped ? dc->d_mappedSource : dc->d_source, g_useIncomingECS && !dc->d_ednssubnet.source.empty() ? boost::optional(dc->d_ednssubnet) : boost::none); + resolver.setQuerySource(useMapped ? comboWriter->d_mappedSource : comboWriter->d_source, g_useIncomingECS && !comboWriter->d_ednssubnet.source.empty() ? boost::optional(comboWriter->d_ednssubnet) : boost::none); - sr.setQueryReceivedOverTCP(dc->d_tcp); + resolver.setQueryReceivedOverTCP(comboWriter->d_tcp); bool tracedQuery = false; // we could consider letting Lua know about this too bool shouldNotValidate = false; @@ -1083,82 +1090,82 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity int res = RCode::NoError; DNSFilterEngine::Policy appliedPolicy; - RecursorLua4::DNSQuestion dq(dc->d_source, dc->d_destination, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, dc->d_tcp, variableAnswer, wantsRPZ, dc->d_logResponse, addPaddingToResponse, (g_useKernelTimestamp && dc->d_kernelTimestamp.tv_sec != 0) ? dc->d_kernelTimestamp : dc->d_now); - dq.ednsFlags = &edo.d_extFlags; - dq.ednsOptions = &ednsOpts; - dq.tag = dc->d_tag; - dq.discardedPolicies = &sr.d_discardedPolicies; - dq.policyTags = &dc->d_policyTags; - dq.appliedPolicy = &appliedPolicy; - dq.currentRecords = &ret; - dq.dh = &dc->d_mdp.d_header; - dq.data = dc->d_data; - dq.requestorId = dc->d_requestorId; - dq.deviceId = dc->d_deviceId; - dq.deviceName = dc->d_deviceName; - dq.proxyProtocolValues = &dc->d_proxyProtocolValues; - dq.extendedErrorCode = &dc->d_extendedErrorCode; - dq.extendedErrorExtra = &dc->d_extendedErrorExtra; - dq.meta = std::move(dc->d_meta); - dq.fromAuthIP = &sr.d_fromAuthIP; - - sr.d_slog = sr.d_slog->withValues("qname", Logging::Loggable(dc->d_mdp.d_qname), - "qtype", Logging::Loggable(QType(dc->d_mdp.d_qtype)), - "remote", Logging::Loggable(dc->getRemote()), - "proto", Logging::Loggable(dc->d_tcp ? "tcp" : "udp"), - "ecs", Logging::Loggable(dc->d_ednssubnet.source.empty() ? "" : dc->d_ednssubnet.source.toString()), - "mtid", Logging::Loggable(MT->getTid())); - RunningResolveGuard tcpGuard(dc); - - if (ednsExtRCode != 0 || dc->d_mdp.d_header.opcode == Opcode::Notify) { - goto sendit; - } - - if (dc->d_mdp.d_qtype == QType::ANY && !dc->d_tcp && g_anyToTcp) { - pw.getHeader()->tc = 1; + RecursorLua4::DNSQuestion dnsQuestion(comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mdp.d_qname, comboWriter->d_mdp.d_qtype, comboWriter->d_tcp, variableAnswer, wantsRPZ, comboWriter->d_logResponse, addPaddingToResponse, (g_useKernelTimestamp && comboWriter->d_kernelTimestamp.tv_sec != 0) ? comboWriter->d_kernelTimestamp : comboWriter->d_now); + dnsQuestion.ednsFlags = &edo.d_extFlags; + dnsQuestion.ednsOptions = &ednsOpts; + dnsQuestion.tag = comboWriter->d_tag; + dnsQuestion.discardedPolicies = &resolver.d_discardedPolicies; + dnsQuestion.policyTags = &comboWriter->d_policyTags; + dnsQuestion.appliedPolicy = &appliedPolicy; + dnsQuestion.currentRecords = &ret; + dnsQuestion.dh = &comboWriter->d_mdp.d_header; + dnsQuestion.data = comboWriter->d_data; + dnsQuestion.requestorId = comboWriter->d_requestorId; + dnsQuestion.deviceId = comboWriter->d_deviceId; + dnsQuestion.deviceName = comboWriter->d_deviceName; + dnsQuestion.proxyProtocolValues = &comboWriter->d_proxyProtocolValues; + dnsQuestion.extendedErrorCode = &comboWriter->d_extendedErrorCode; + dnsQuestion.extendedErrorExtra = &comboWriter->d_extendedErrorExtra; + dnsQuestion.meta = std::move(comboWriter->d_meta); + dnsQuestion.fromAuthIP = &resolver.d_fromAuthIP; + + resolver.d_slog = resolver.d_slog->withValues("qname", Logging::Loggable(comboWriter->d_mdp.d_qname), + "qtype", Logging::Loggable(QType(comboWriter->d_mdp.d_qtype)), + "remote", Logging::Loggable(comboWriter->getRemote()), + "proto", Logging::Loggable(comboWriter->d_tcp ? "tcp" : "udp"), + "ecs", Logging::Loggable(comboWriter->d_ednssubnet.source.empty() ? "" : comboWriter->d_ednssubnet.source.toString()), + "mtid", Logging::Loggable(g_multiTasker->getTid())); + RunningResolveGuard tcpGuard(comboWriter); + + if (ednsExtRCode != 0 || comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { + goto sendit; // NOLINT(cppcoreguidelines-avoid-goto) + } + + if (comboWriter->d_mdp.d_qtype == QType::ANY && !comboWriter->d_tcp && g_anyToTcp) { + packetWriter.getHeader()->tc = 1; res = 0; variableAnswer = true; - goto sendit; + goto sendit; // NOLINT(cppcoreguidelines-avoid-goto) } - if (t_traceRegex && t_traceRegex->match(dc->d_mdp.d_qname.toString())) { - sr.setLogMode(SyncRes::Store); + if (t_traceRegex && t_traceRegex->match(comboWriter->d_mdp.d_qname.toString())) { + resolver.setLogMode(SyncRes::Store); tracedQuery = true; } if (!g_quiet || tracedQuery) { if (!g_slogStructured) { - g_log << Logger::Warning << RecThreadInfo::id() << " [" << MT->getTid() << "/" << MT->numProcesses() << "] " << (dc->d_tcp ? "TCP " : "") << "question for '" << dc->d_mdp.d_qname << "|" - << QType(dc->d_mdp.d_qtype) << "' from " << dc->getRemote(); - if (!dc->d_ednssubnet.source.empty()) { - g_log << " (ecs " << dc->d_ednssubnet.source.toString() << ")"; + g_log << Logger::Warning << RecThreadInfo::id() << " [" << g_multiTasker->getTid() << "/" << g_multiTasker->numProcesses() << "] " << (comboWriter->d_tcp ? "TCP " : "") << "question for '" << comboWriter->d_mdp.d_qname << "|" + << QType(comboWriter->d_mdp.d_qtype) << "' from " << comboWriter->getRemote(); + if (!comboWriter->d_ednssubnet.source.empty()) { + g_log << " (ecs " << comboWriter->d_ednssubnet.source.toString() << ")"; } g_log << endl; } else { - sr.d_slog->info(Logr::Info, "Question"); + resolver.d_slog->info(Logr::Info, "Question"); } } - if (!dc->d_mdp.d_header.rd) { - sr.setCacheOnly(); + if (!comboWriter->d_mdp.d_header.rd) { + resolver.setCacheOnly(); } - if (dc->d_luaContext) { - dc->d_luaContext->prerpz(dq, res, sr.d_eventTrace); + if (comboWriter->d_luaContext) { + comboWriter->d_luaContext->prerpz(dnsQuestion, res, resolver.d_eventTrace); } // Check if the client has a policy attached to it if (wantsRPZ && !appliedPolicy.wasHit()) { - if (luaconfsLocal->dfe.getClientPolicy(dc->d_source, sr.d_discardedPolicies, appliedPolicy)) { - mergePolicyTags(dc->d_policyTags, appliedPolicy.getTags()); + if (luaconfsLocal->dfe.getClientPolicy(comboWriter->d_source, resolver.d_discardedPolicies, appliedPolicy)) { + mergePolicyTags(comboWriter->d_policyTags, appliedPolicy.getTags()); } } /* If we already have an answer generated from gettag_ffi, let's see if the filtering policies should be applied to it */ - if (dc->d_rcode != boost::none) { + if (comboWriter->d_rcode != boost::none) { bool policyOverride = false; /* Unless we already matched on the client IP, time to check the qname. @@ -1169,9 +1176,9 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } else { // no match on the client IP, check the qname - if (luaconfsLocal->dfe.getQueryPolicy(dc->d_mdp.d_qname, sr.d_discardedPolicies, appliedPolicy)) { + if (luaconfsLocal->dfe.getQueryPolicy(comboWriter->d_mdp.d_qname, resolver.d_discardedPolicies, appliedPolicy)) { // got a match - mergePolicyTags(dc->d_policyTags, appliedPolicy.getTags()); + mergePolicyTags(comboWriter->d_policyTags, appliedPolicy.getTags()); } } @@ -1182,39 +1189,39 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity if (!policyOverride) { /* No RPZ or gettag overrides it anyway */ - ret = std::move(dc->d_records); - res = *dc->d_rcode; - if (res == RCode::NoError && dc->d_followCNAMERecords) { - res = followCNAMERecords(ret, QType(dc->d_mdp.d_qtype), res); + ret = std::move(comboWriter->d_records); + res = *comboWriter->d_rcode; + if (res == RCode::NoError && comboWriter->d_followCNAMERecords) { + res = followCNAMERecords(ret, QType(comboWriter->d_mdp.d_qtype), res); } - goto haveAnswer; + goto haveAnswer; // NOLINT(cppcoreguidelines-avoid-goto) } } // if there is a RecursorLua active, and it 'took' the query in preResolve, we don't launch beginResolve - if (!dc->d_luaContext || !dc->d_luaContext->preresolve(dq, res, sr.d_eventTrace)) { + if (!comboWriter->d_luaContext || !comboWriter->d_luaContext->preresolve(dnsQuestion, res, resolver.d_eventTrace)) { - if (!g_dns64PrefixReverse.empty() && dq.qtype == QType::PTR && dq.qname.isPartOf(g_dns64PrefixReverse)) { - res = getFakePTRRecords(dq.qname, ret); - goto haveAnswer; + if (!g_dns64PrefixReverse.empty() && dnsQuestion.qtype == QType::PTR && dnsQuestion.qname.isPartOf(g_dns64PrefixReverse)) { + res = getFakePTRRecords(dnsQuestion.qname, ret); + goto haveAnswer; // NOLINT(cppcoreguidelines-avoid-goto) } - sr.setWantsRPZ(wantsRPZ); + resolver.setWantsRPZ(wantsRPZ); if (wantsRPZ && appliedPolicy.d_kind != DNSFilterEngine::PolicyKind::NoAction) { - if (dc->d_luaContext && dc->d_luaContext->policyHitEventFilter(dc->d_source, dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_tcp, appliedPolicy, dc->d_policyTags, sr.d_discardedPolicies)) { + if (comboWriter->d_luaContext && comboWriter->d_luaContext->policyHitEventFilter(comboWriter->d_source, comboWriter->d_mdp.d_qname, QType(comboWriter->d_mdp.d_qtype), comboWriter->d_tcp, appliedPolicy, comboWriter->d_policyTags, resolver.d_discardedPolicies)) { /* reset to no match */ appliedPolicy = DNSFilterEngine::Policy(); } else { - auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw, tcpGuard); + auto policyResult = handlePolicyHit(appliedPolicy, comboWriter, resolver, res, ret, packetWriter, tcpGuard); if (policyResult == PolicyResult::HaveAnswer) { - if (g_dns64Prefix && dq.qtype == QType::AAAA && dns64Candidate(dc->d_mdp.d_qtype, res, ret)) { - res = getFakeAAAARecords(dq.qname, *g_dns64Prefix, ret); + if (g_dns64Prefix && dnsQuestion.qtype == QType::AAAA && dns64Candidate(comboWriter->d_mdp.d_qtype, res, ret)) { + res = getFakeAAAARecords(dnsQuestion.qname, *g_dns64Prefix, ret); shouldNotValidate = true; } - goto haveAnswer; + goto haveAnswer; // NOLINT(cppcoreguidelines-avoid-goto) } else if (policyResult == PolicyResult::Drop) { return; @@ -1224,47 +1231,47 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity // Query did not get handled for Client IP or QNAME Policy reasons, now actually go out to find an answer try { - sr.d_appliedPolicy = appliedPolicy; - sr.d_policyTags = std::move(dc->d_policyTags); + resolver.d_appliedPolicy = appliedPolicy; + resolver.d_policyTags = std::move(comboWriter->d_policyTags); - if (!dc->d_routingTag.empty()) { - sr.d_routingTag = dc->d_routingTag; + if (!comboWriter->d_routingTag.empty()) { + resolver.d_routingTag = comboWriter->d_routingTag; } ret.clear(); // policy might have filled it with custom records but we decided not to use them - res = sr.beginResolve(dc->d_mdp.d_qname, QType(dc->d_mdp.d_qtype), dc->d_mdp.d_qclass, ret); - shouldNotValidate = sr.wasOutOfBand(); + res = resolver.beginResolve(comboWriter->d_mdp.d_qname, QType(comboWriter->d_mdp.d_qtype), comboWriter->d_mdp.d_qclass, ret); + shouldNotValidate = resolver.wasOutOfBand(); } catch (const ImmediateQueryDropException& e) { // XXX We need to export a protobuf message (and do a NOD lookup) if requested! t_Counters.at(rec::Counter::policyDrops)++; - SLOG(g_log << Logger::Debug << "Dropping query because of a filtering policy " << makeLoginfo(dc) << endl, - sr.d_slog->info(Logr::Debug, "Dropping query because of a filtering policy")); + SLOG(g_log << Logger::Debug << "Dropping query because of a filtering policy " << makeLoginfo(comboWriter) << endl, + resolver.d_slog->info(Logr::Debug, "Dropping query because of a filtering policy")); return; } catch (const ImmediateServFailException& e) { if (g_logCommonErrors) { - SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << dc->getRemote() << " during resolve of '" << dc->d_mdp.d_qname << "' because: " << e.reason << endl, - sr.d_slog->error(Logr::Notice, e.reason, "Sending SERVFAIL during resolve")); + SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << comboWriter->getRemote() << " during resolve of '" << comboWriter->d_mdp.d_qname << "' because: " << e.reason << endl, + resolver.d_slog->error(Logr::Notice, e.reason, "Sending SERVFAIL during resolve")); } res = RCode::ServFail; } catch (const SendTruncatedAnswerException& e) { ret.clear(); - sr.d_appliedPolicy.addSOAtoRPZResult(ret); + resolver.d_appliedPolicy.addSOAtoRPZResult(ret); res = RCode::NoError; - pw.getHeader()->tc = 1; + packetWriter.getHeader()->tc = 1; } catch (const PolicyHitException& e) { res = -2; } - dq.validationState = sr.getValidationState(); - appliedPolicy = sr.d_appliedPolicy; - dc->d_policyTags = std::move(sr.d_policyTags); + dnsQuestion.validationState = resolver.getValidationState(); + appliedPolicy = resolver.d_appliedPolicy; + comboWriter->d_policyTags = std::move(resolver.d_policyTags); if (appliedPolicy.d_type != DNSFilterEngine::PolicyType::None && appliedPolicy.d_zoneData && appliedPolicy.d_zoneData->d_extendedErrorCode) { - dc->d_extendedErrorCode = *appliedPolicy.d_zoneData->d_extendedErrorCode; - dc->d_extendedErrorExtra = appliedPolicy.d_zoneData->d_extendedErrorExtra; + comboWriter->d_extendedErrorCode = *appliedPolicy.d_zoneData->d_extendedErrorCode; + comboWriter->d_extendedErrorExtra = appliedPolicy.d_zoneData->d_extendedErrorExtra; } // During lookup, an NSDNAME or NSIP trigger was hit in RPZ @@ -1272,9 +1279,9 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity if (appliedPolicy.d_kind == DNSFilterEngine::PolicyKind::NoAction) { throw PDNSException("NoAction policy returned while a NSDNAME or NSIP trigger was hit"); } - auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw, tcpGuard); + auto policyResult = handlePolicyHit(appliedPolicy, comboWriter, resolver, res, ret, packetWriter, tcpGuard); if (policyResult == PolicyResult::HaveAnswer) { - goto haveAnswer; + goto haveAnswer; // NOLINT(cppcoreguidelines-avoid-goto) } else if (policyResult == PolicyResult::Drop) { return; @@ -1282,61 +1289,61 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } bool luaHookHandled = false; - if (dc->d_luaContext) { + if (comboWriter->d_luaContext) { PolicyResult policyResult = PolicyResult::NoAction; - if (answerIsNOData(dc->d_mdp.d_qtype, res, ret)) { - if (dc->d_luaContext->nodata(dq, res, sr.d_eventTrace)) { + if (answerIsNOData(comboWriter->d_mdp.d_qtype, res, ret)) { + if (comboWriter->d_luaContext->nodata(dnsQuestion, res, resolver.d_eventTrace)) { luaHookHandled = true; shouldNotValidate = true; - policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw, tcpGuard); + policyResult = handlePolicyHit(appliedPolicy, comboWriter, resolver, res, ret, packetWriter, tcpGuard); } } - else if (res == RCode::NXDomain && dc->d_luaContext->nxdomain(dq, res, sr.d_eventTrace)) { + else if (res == RCode::NXDomain && comboWriter->d_luaContext->nxdomain(dnsQuestion, res, resolver.d_eventTrace)) { luaHookHandled = true; shouldNotValidate = true; - policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw, tcpGuard); + policyResult = handlePolicyHit(appliedPolicy, comboWriter, resolver, res, ret, packetWriter, tcpGuard); } if (policyResult == PolicyResult::HaveAnswer) { - goto haveAnswer; + goto haveAnswer; // NOLINT(cppcoreguidelines-avoid-goto) } else if (policyResult == PolicyResult::Drop) { return; } } // dc->d_luaContext - if (!luaHookHandled && g_dns64Prefix && dc->d_mdp.d_qtype == QType::AAAA && (shouldNotValidate || !sr.isDNSSECValidationRequested() || !vStateIsBogus(dq.validationState)) && dns64Candidate(dc->d_mdp.d_qtype, res, ret)) { - res = getFakeAAAARecords(dq.qname, *g_dns64Prefix, ret); + if (!luaHookHandled && g_dns64Prefix && comboWriter->d_mdp.d_qtype == QType::AAAA && (shouldNotValidate || !resolver.isDNSSECValidationRequested() || !vStateIsBogus(dnsQuestion.validationState)) && dns64Candidate(comboWriter->d_mdp.d_qtype, res, ret)) { + res = getFakeAAAARecords(dnsQuestion.qname, *g_dns64Prefix, ret); shouldNotValidate = true; } - if (dc->d_luaContext) { + if (comboWriter->d_luaContext) { PolicyResult policyResult = PolicyResult::NoAction; - if (dc->d_luaContext->d_postresolve_ffi) { - RecursorLua4::PostResolveFFIHandle handle(dq); - sr.d_eventTrace.add(RecEventTrace::LuaPostResolveFFI); - bool pr = dc->d_luaContext->postresolve_ffi(handle); - sr.d_eventTrace.add(RecEventTrace::LuaPostResolveFFI, pr, false); - if (pr) { + if (comboWriter->d_luaContext->d_postresolve_ffi) { + RecursorLua4::PostResolveFFIHandle handle(dnsQuestion); + resolver.d_eventTrace.add(RecEventTrace::LuaPostResolveFFI); + bool prResult = comboWriter->d_luaContext->postresolve_ffi(handle); + resolver.d_eventTrace.add(RecEventTrace::LuaPostResolveFFI, prResult, false); + if (prResult) { shouldNotValidate = true; - policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw, tcpGuard); + policyResult = handlePolicyHit(appliedPolicy, comboWriter, resolver, res, ret, packetWriter, tcpGuard); } } - else if (dc->d_luaContext->postresolve(dq, res, sr.d_eventTrace)) { + else if (comboWriter->d_luaContext->postresolve(dnsQuestion, res, resolver.d_eventTrace)) { shouldNotValidate = true; - policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw, tcpGuard); + policyResult = handlePolicyHit(appliedPolicy, comboWriter, resolver, res, ret, packetWriter, tcpGuard); } if (policyResult == PolicyResult::HaveAnswer) { - goto haveAnswer; + goto haveAnswer; // NOLINT(cppcoreguidelines-avoid-goto) } else if (policyResult == PolicyResult::Drop) { return; } } // dc->d_luaContext } - else if (dc->d_luaContext) { + else if (comboWriter->d_luaContext) { // preresolve returned true shouldNotValidate = true; - auto policyResult = handlePolicyHit(appliedPolicy, dc, sr, res, ret, pw, tcpGuard); + auto policyResult = handlePolicyHit(appliedPolicy, comboWriter, resolver, res, ret, packetWriter, tcpGuard); // haveAnswer case redundant if (policyResult == PolicyResult::Drop) { return; @@ -1344,103 +1351,107 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } haveAnswer:; - if (tracedQuery || res == -1 || res == RCode::ServFail || pw.getHeader()->rcode == RCode::ServFail) { - dumpTrace(sr.getTrace(), sr.d_fixednow); + if (tracedQuery || res == -1 || res == RCode::ServFail || packetWriter.getHeader()->rcode == static_cast(RCode::ServFail)) { + dumpTrace(resolver.getTrace(), resolver.d_fixednow); } if (res == -1) { - pw.getHeader()->rcode = RCode::ServFail; + packetWriter.getHeader()->rcode = RCode::ServFail; // no commit here, because no record ++t_Counters.at(rec::Counter::servFails); } else { - pw.getHeader()->rcode = res; + packetWriter.getHeader()->rcode = res; // Does the validation mode or query demand validation? - if (!shouldNotValidate && sr.isDNSSECValidationRequested()) { + if (!shouldNotValidate && resolver.isDNSSECValidationRequested()) { try { - auto state = sr.getValidationState(); + auto state = resolver.getValidationState(); string x_marker; std::shared_ptr log; - if (sr.doLog() || vStateIsBogus(state)) { + if (resolver.doLog() || vStateIsBogus(state)) { // Only create logging object if needed below, beware if you change the logging logic! - log = sr.d_slog->withValues("vstate", Logging::Loggable(state)); + log = resolver.d_slog->withValues("vstate", Logging::Loggable(state)); auto xdnssec = g_xdnssec.getLocal(); - if (xdnssec->check(dc->d_mdp.d_qname)) { + if (xdnssec->check(comboWriter->d_mdp.d_qname)) { log = log->withValues("in-x-dnssec-names", Logging::Loggable(1)); x_marker = " [in x-dnssec-names]"; } } if (state == vState::Secure) { - if (sr.doLog()) { - SLOG(g_log << Logger::Warning << "Answer to " << dc->d_mdp.d_qname << "|" << QType(dc->d_mdp.d_qtype) << x_marker << " for " << dc->getRemote() << " validates correctly" << endl, + if (resolver.doLog()) { + SLOG(g_log << Logger::Warning << "Answer to " << comboWriter->d_mdp.d_qname << "|" << QType(comboWriter->d_mdp.d_qtype) << x_marker << " for " << comboWriter->getRemote() << " validates correctly" << endl, log->info(Logr::Info, "Validates Correctly")); } // Is the query source interested in the value of the ad-bit? - if (dc->d_mdp.d_header.ad || DNSSECOK) - pw.getHeader()->ad = 1; + if (comboWriter->d_mdp.d_header.ad || DNSSECOK) { + packetWriter.getHeader()->ad = 1; + } } else if (state == vState::Insecure) { - if (sr.doLog()) { - SLOG(g_log << Logger::Warning << "Answer to " << dc->d_mdp.d_qname << "|" << QType(dc->d_mdp.d_qtype) << x_marker << " for " << dc->getRemote() << " validates as Insecure" << endl, + if (resolver.doLog()) { + SLOG(g_log << Logger::Warning << "Answer to " << comboWriter->d_mdp.d_qname << "|" << QType(comboWriter->d_mdp.d_qtype) << x_marker << " for " << comboWriter->getRemote() << " validates as Insecure" << endl, log->info(Logr::Info, "Validates as Insecure")); } - pw.getHeader()->ad = 0; + packetWriter.getHeader()->ad = 0; } else if (vStateIsBogus(state)) { - if (t_bogusremotes) - t_bogusremotes->push_back(dc->d_source); - if (t_bogusqueryring) - t_bogusqueryring->push_back({dc->d_mdp.d_qname, dc->d_mdp.d_qtype}); - if (g_dnssecLogBogus || sr.doLog() || g_dnssecmode == DNSSECMode::ValidateForLog) { - SLOG(g_log << Logger::Warning << "Answer to " << dc->d_mdp.d_qname << "|" << QType(dc->d_mdp.d_qtype) << x_marker << " for " << dc->getRemote() << " validates as " << vStateToString(state) << endl, + if (t_bogusremotes) { + t_bogusremotes->push_back(comboWriter->d_source); + } + if (t_bogusqueryring) { + t_bogusqueryring->push_back({comboWriter->d_mdp.d_qname, comboWriter->d_mdp.d_qtype}); + } + if (g_dnssecLogBogus || resolver.doLog() || g_dnssecmode == DNSSECMode::ValidateForLog) { + SLOG(g_log << Logger::Warning << "Answer to " << comboWriter->d_mdp.d_qname << "|" << QType(comboWriter->d_mdp.d_qtype) << x_marker << " for " << comboWriter->getRemote() << " validates as " << vStateToString(state) << endl, log->info(Logr::Notice, "Validates as Bogus")); } // Does the query or validation mode sending out a SERVFAIL on validation errors? - if (!pw.getHeader()->cd && (g_dnssecmode == DNSSECMode::ValidateAll || dc->d_mdp.d_header.ad || DNSSECOK)) { - if (sr.doLog()) { - SLOG(g_log << Logger::Warning << "Sending out SERVFAIL for " << dc->d_mdp.d_qname << "|" << QType(dc->d_mdp.d_qtype) << " because recursor or query demands it for Bogus results" << endl, + if (!packetWriter.getHeader()->cd && (g_dnssecmode == DNSSECMode::ValidateAll || comboWriter->d_mdp.d_header.ad || DNSSECOK)) { + if (resolver.doLog()) { + SLOG(g_log << Logger::Warning << "Sending out SERVFAIL for " << comboWriter->d_mdp.d_qname << "|" << QType(comboWriter->d_mdp.d_qtype) << " because recursor or query demands it for Bogus results" << endl, log->info(Logr::Notice, "Sending out SERVFAIL because recursor or query demands it for Bogus results")); } - pw.getHeader()->rcode = RCode::ServFail; - goto sendit; + packetWriter.getHeader()->rcode = RCode::ServFail; + goto sendit; // NOLINT(cppcoreguidelines-avoid-goto) } else { - if (sr.doLog()) { - SLOG(g_log << Logger::Warning << "Not sending out SERVFAIL for " << dc->d_mdp.d_qname << "|" << QType(dc->d_mdp.d_qtype) << x_marker << " Bogus validation since neither config nor query demands this" << endl, + if (resolver.doLog()) { + SLOG(g_log << Logger::Warning << "Not sending out SERVFAIL for " << comboWriter->d_mdp.d_qname << "|" << QType(comboWriter->d_mdp.d_qtype) << x_marker << " Bogus validation since neither config nor query demands this" << endl, log->info(Logr::Notice, "Sending out SERVFAIL because recursor or query demands it for Bogus results")); } } } } catch (const ImmediateServFailException& e) { - if (g_logCommonErrors) - SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << dc->getRemote() << " during validation of '" << dc->d_mdp.d_qname << "|" << QType(dc->d_mdp.d_qtype) << "' because: " << e.reason << endl, - sr.d_slog->error(Logr::Notice, e.reason, "Sending SERVFAIL during validation", "exception", Logging::Loggable("ImmediateServFailException"))); - goto sendit; + if (g_logCommonErrors) { + SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << comboWriter->getRemote() << " during validation of '" << comboWriter->d_mdp.d_qname << "|" << QType(comboWriter->d_mdp.d_qtype) << "' because: " << e.reason << endl, + resolver.d_slog->error(Logr::Notice, e.reason, "Sending SERVFAIL during validation", "exception", Logging::Loggable("ImmediateServFailException"))); + } + goto sendit; // NOLINT(cppcoreguidelines-avoid-goto) } } - if (ret.size()) { + if (!ret.empty()) { pdns::orderAndShuffle(ret, false); - if (auto sl = luaconfsLocal->sortlist.getOrderCmp(dc->d_source)) { - stable_sort(ret.begin(), ret.end(), *sl); + if (auto listToSort = luaconfsLocal->sortlist.getOrderCmp(comboWriter->d_source)) { + stable_sort(ret.begin(), ret.end(), *listToSort); variableAnswer = true; } } bool needCommit = false; - for (auto i = ret.cbegin(); i != ret.cend(); ++i) { - if (!DNSSECOK && (i->d_type == QType::NSEC3 || ((i->d_type == QType::RRSIG || i->d_type == QType::NSEC) && ((dc->d_mdp.d_qtype != i->d_type && dc->d_mdp.d_qtype != QType::ANY) || (i->d_place != DNSResourceRecord::ANSWER && i->d_place != DNSResourceRecord::ADDITIONAL))))) { + for (const auto & record : ret) { + if (!DNSSECOK && (record.d_type == QType::NSEC3 || ((record.d_type == QType::RRSIG || record.d_type == QType::NSEC) && ((comboWriter->d_mdp.d_qtype != record.d_type && comboWriter->d_mdp.d_qtype != QType::ANY) || (record.d_place != DNSResourceRecord::ANSWER && record.d_place != DNSResourceRecord::ADDITIONAL))))) { continue; } - if (!addRecordToPacket(pw, *i, minTTL, dc->d_ttlCap, maxanswersize, seenAuthSOA)) { + if (!addRecordToPacket(packetWriter, record, minTTL, comboWriter->d_ttlCap, maxanswersize, seenAuthSOA)) { needCommit = false; break; } @@ -1449,7 +1460,7 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity bool udr = false; #ifdef NOD_ENABLED if (g_udrEnabled) { - udr = udrCheckUniqueDNSRecord(nodlogger, dc->d_mdp.d_qname, dc->d_mdp.d_qtype, *i); + udr = udrCheckUniqueDNSRecord(nodlogger, comboWriter->d_mdp.d_qname, comboWriter->d_mdp.d_qtype, record); if (!hasUDR && udr) { hasUDR = true; } @@ -1461,26 +1472,26 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity // If a single answer causes a too big protobuf message, it wil be dropped by queueData() // But note addRR has code to prevent that if (pbMessage.size() < std::numeric_limits::max() / 2) { - pbMessage.addRR(*i, luaconfsLocal->protobufExportConfig.exportTypes, udr); + pbMessage.addRR(record, luaconfsLocal->protobufExportConfig.exportTypes, udr); } } } if (needCommit) { - pw.commit(); + packetWriter.commit(); } #ifdef NOD_ENABLED #ifdef HAVE_FSTRM if (hasUDR) { if (isEnabledForUDRs(t_nodFrameStreamServersInfo.servers)) { - struct timespec ts; + struct timespec timeSpec{}; std::string str; - if (g_useKernelTimestamp && dc->d_kernelTimestamp.tv_sec) { - TIMEVAL_TO_TIMESPEC(&(dc->d_kernelTimestamp), &ts); + if (g_useKernelTimestamp && comboWriter->d_kernelTimestamp.tv_sec != 0) { + TIMEVAL_TO_TIMESPEC(&comboWriter->d_kernelTimestamp, &timeSpec); // NOLINT } else { - TIMEVAL_TO_TIMESPEC(&(dc->d_now), &ts); + TIMEVAL_TO_TIMESPEC(&comboWriter->d_now, &timeSpec); // NOLINT } - DnstapMessage message(str, DnstapMessage::MessageType::resolver_response, SyncRes::s_serverID, &dc->d_source, &dc->d_destination, dc->d_tcp ? DnstapMessage::ProtocolType::DoTCP : DnstapMessage::ProtocolType::DoUDP, reinterpret_cast(&*packet.begin()), packet.size(), &ts, nullptr, dc->d_mdp.d_qname); + DnstapMessage message(str, DnstapMessage::MessageType::resolver_response, SyncRes::s_serverID, &comboWriter->d_source, &comboWriter->d_destination, comboWriter->d_tcp ? DnstapMessage::ProtocolType::DoTCP : DnstapMessage::ProtocolType::DoUDP, reinterpret_cast(&*packet.begin()), packet.size(), &timeSpec, nullptr, comboWriter->d_mdp.d_qname); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) for (auto& logger : *(t_nodFrameStreamServersInfo.servers)) { if (logger->logUDRs()) { @@ -1494,18 +1505,18 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } sendit:; - if (g_useIncomingECS && dc->d_ecsFound && !sr.wasVariable() && !variableAnswer) { - EDNSSubnetOpts eo; - eo.source = dc->d_ednssubnet.source; - ComboAddress sa; - sa.reset(); - sa.sin4.sin_family = eo.source.getNetwork().sin4.sin_family; - eo.scope = Netmask(sa, 0); - auto ecsPayload = makeEDNSSubnetOptsString(eo); + if (g_useIncomingECS && comboWriter->d_ecsFound && !resolver.wasVariable() && !variableAnswer) { + EDNSSubnetOpts ednsOptions; + ednsOptions.source = comboWriter->d_ednssubnet.source; + ComboAddress sourceAddr; + sourceAddr.reset(); + sourceAddr.sin4.sin_family = ednsOptions.source.getNetwork().sin4.sin_family; + ednsOptions.scope = Netmask(sourceAddr, 0); + auto ecsPayload = makeEDNSSubnetOptsString(ednsOptions); // if we don't have enough space available let's just not set that scope of zero, // it will prevent some caching, mostly from dnsdist, but that's fine - if (pw.size() < maxanswersize && (maxanswersize - pw.size()) >= (EDNSOptionCodeSize + EDNSOptionLengthSize + ecsPayload.size())) { + if (packetWriter.size() < maxanswersize && (maxanswersize - packetWriter.size()) >= (EDNSOptionCodeSize + EDNSOptionLengthSize + ecsPayload.size())) { maxanswersize -= EDNSOptionCodeSize + EDNSOptionLengthSize + ecsPayload.size(); @@ -1514,7 +1525,7 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } if (haveEDNS && addPaddingToResponse) { - size_t currentSize = pw.getSizeWithOpts(returnedEdnsOptions); + size_t currentSize = packetWriter.getSizeWithOpts(returnedEdnsOptions); /* we don't use maxawnswersize because it accounts for some EDNS options, but not all of them (for example ECS) */ size_t maxSize = min(static_cast(edo.d_packetsize >= 512 ? edo.d_packetsize : 512), g_udpTruncationThreshold); @@ -1538,18 +1549,18 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } if (haveEDNS) { - auto state = sr.getValidationState(); - if (dc->d_extendedErrorCode || sr.d_extendedError || (SyncRes::s_addExtendedResolutionDNSErrors && vStateIsBogus(state))) { - EDNSExtendedError::code code; + auto state = resolver.getValidationState(); + if (comboWriter->d_extendedErrorCode || resolver.d_extendedError || (SyncRes::s_addExtendedResolutionDNSErrors && vStateIsBogus(state))) { + EDNSExtendedError::code code = EDNSExtendedError::code::Other; std::string extra; - if (dc->d_extendedErrorCode) { - code = static_cast(*dc->d_extendedErrorCode); - extra = std::move(dc->d_extendedErrorExtra); + if (comboWriter->d_extendedErrorCode) { + code = static_cast(*comboWriter->d_extendedErrorCode); + extra = std::move(comboWriter->d_extendedErrorExtra); } - else if (sr.d_extendedError) { - code = static_cast(sr.d_extendedError->infoCode); - extra = std::move(sr.d_extendedError->extraText); + else if (resolver.d_extendedError) { + code = static_cast(resolver.d_extendedError->infoCode); + extra = std::move(resolver.d_extendedError->extraText); } else { switch (state) { @@ -1593,8 +1604,6 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity code = EDNSExtendedError::code::NoZoneKeyBitSet; break; case vState::BogusRevokedDNSKEY: - code = EDNSExtendedError::code::DNSSECBogus; - break; case vState::BogusInvalidDNSKEYProtocol: code = EDNSExtendedError::code::DNSSECBogus; break; @@ -1607,7 +1616,7 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity eee.infoCode = static_cast(code); eee.extraText = std::move(extra); - if (pw.size() < maxanswersize && (maxanswersize - pw.size()) >= (EDNSOptionCodeSize + EDNSOptionLengthSize + sizeof(eee.infoCode) + eee.extraText.size())) { + if (packetWriter.size() < maxanswersize && (maxanswersize - packetWriter.size()) >= (EDNSOptionCodeSize + EDNSOptionLengthSize + sizeof(eee.infoCode) + eee.extraText.size())) { returnedEdnsOptions.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(eee)); } } @@ -1618,28 +1627,28 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity OPT record. This MUST also occur when a truncated response (using the DNS header's TC bit) is returned." */ - pw.addOpt(512, ednsExtRCode, DNSSECOK ? EDNSOpts::DNSSECOK : 0, returnedEdnsOptions); - pw.commit(); + packetWriter.addOpt(512, ednsExtRCode, DNSSECOK ? EDNSOpts::DNSSECOK : 0, returnedEdnsOptions); + packetWriter.commit(); } - t_Counters.at(rec::ResponseStats::responseStats).submitResponse(dc->d_mdp.d_qtype, packet.size(), pw.getHeader()->rcode); - updateResponseStats(res, dc->d_source, packet.size(), &dc->d_mdp.d_qname, dc->d_mdp.d_qtype); + t_Counters.at(rec::ResponseStats::responseStats).submitResponse(comboWriter->d_mdp.d_qtype, packet.size(), packetWriter.getHeader()->rcode); + updateResponseStats(res, comboWriter->d_source, packet.size(), &comboWriter->d_mdp.d_qname, comboWriter->d_mdp.d_qtype); #ifdef NOD_ENABLED bool nod = false; if (g_nodEnabled) { - if (nodCheckNewDomain(nodlogger, dc->d_mdp.d_qname)) { + if (nodCheckNewDomain(nodlogger, comboWriter->d_mdp.d_qname)) { nod = true; #ifdef HAVE_FSTRM if (isEnabledForNODs(t_nodFrameStreamServersInfo.servers)) { - struct timespec ts; + struct timespec timeSpec{}; std::string str; - if (g_useKernelTimestamp && dc->d_kernelTimestamp.tv_sec) { - TIMEVAL_TO_TIMESPEC(&(dc->d_kernelTimestamp), &ts); + if (g_useKernelTimestamp && comboWriter->d_kernelTimestamp.tv_sec != 0) { + TIMEVAL_TO_TIMESPEC(&comboWriter->d_kernelTimestamp, &timeSpec); // NOLINT } else { - TIMEVAL_TO_TIMESPEC(&(dc->d_now), &ts); + TIMEVAL_TO_TIMESPEC(&comboWriter->d_now, &timeSpec); // NOLINT } - DnstapMessage message(str, DnstapMessage::MessageType::client_query, SyncRes::s_serverID, &dc->d_source, &dc->d_destination, dc->d_tcp ? DnstapMessage::ProtocolType::DoTCP : DnstapMessage::ProtocolType::DoUDP, nullptr, 0, &ts, nullptr, dc->d_mdp.d_qname); + DnstapMessage message(str, DnstapMessage::MessageType::client_query, SyncRes::s_serverID, &comboWriter->d_source, &comboWriter->d_destination, comboWriter->d_tcp ? DnstapMessage::ProtocolType::DoTCP : DnstapMessage::ProtocolType::DoUDP, nullptr, 0, &timeSpec, nullptr, comboWriter->d_mdp.d_qname); for (auto& logger : *(t_nodFrameStreamServersInfo.servers)) { if (logger->logNODs()) { @@ -1652,13 +1661,13 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } #endif /* NOD_ENABLED */ - if (variableAnswer || sr.wasVariable()) { + if (variableAnswer || resolver.wasVariable()) { t_Counters.at(rec::Counter::variableResponses)++; } - if (t_protobufServers.servers && !(luaconfsLocal->protobufExportConfig.taggedOnly && appliedPolicy.getName().empty() && dc->d_policyTags.empty())) { + if (t_protobufServers.servers && !(luaconfsLocal->protobufExportConfig.taggedOnly && appliedPolicy.getName().empty() && comboWriter->d_policyTags.empty())) { // Start constructing embedded DNSResponse object - pbMessage.setResponseCode(pw.getHeader()->rcode); + pbMessage.setResponseCode(packetWriter.getHeader()->rcode); if (!appliedPolicy.getName().empty()) { pbMessage.setAppliedPolicy(appliedPolicy.getName()); pbMessage.setAppliedPolicyType(appliedPolicy.d_type); @@ -1666,101 +1675,101 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity pbMessage.setAppliedPolicyHit(appliedPolicy.d_hit); pbMessage.setAppliedPolicyKind(appliedPolicy.d_kind); } - pbMessage.addPolicyTags(dc->d_policyTags); + pbMessage.addPolicyTags(comboWriter->d_policyTags); pbMessage.setInBytes(packet.size()); - pbMessage.setValidationState(sr.getValidationState()); + pbMessage.setValidationState(resolver.getValidationState()); // Take s snap of the current protobuf buffer state to store in the PC pbDataForCache = boost::make_optional(RecursorPacketCache::PBData{ pbMessage.getMessageBuf(), pbMessage.getResponseBuf(), - !appliedPolicy.getName().empty() || !dc->d_policyTags.empty()}); + !appliedPolicy.getName().empty() || !comboWriter->d_policyTags.empty()}); #ifdef NOD_ENABLED // if (g_udrEnabled) ?? pbMessage.clearUDR(pbDataForCache->d_response); #endif } - const bool intoPC = g_packetCache && !variableAnswer && !sr.wasVariable(); + const bool intoPC = g_packetCache && !variableAnswer && !resolver.wasVariable(); if (intoPC) { - minTTL = capPacketCacheTTL(*pw.getHeader(), minTTL, seenAuthSOA); - g_packetCache->insertResponsePacket(dc->d_tag, dc->d_qhash, std::move(dc->d_query), dc->d_mdp.d_qname, - dc->d_mdp.d_qtype, dc->d_mdp.d_qclass, - string((const char*)&*packet.begin(), packet.size()), + minTTL = capPacketCacheTTL(*packetWriter.getHeader(), minTTL, seenAuthSOA); + g_packetCache->insertResponsePacket(comboWriter->d_tag, comboWriter->d_qhash, std::move(comboWriter->d_query), comboWriter->d_mdp.d_qname, + comboWriter->d_mdp.d_qtype, comboWriter->d_mdp.d_qclass, + string(reinterpret_cast(&*packet.begin()), packet.size()), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) g_now.tv_sec, minTTL, - dq.validationState, - std::move(pbDataForCache), dc->d_tcp); + dnsQuestion.validationState, + std::move(pbDataForCache), comboWriter->d_tcp); } if (g_regressionTestMode) { t_Counters.updateSnap(g_regressionTestMode); } - if (!dc->d_tcp) { - struct msghdr msgh; - struct iovec iov; - cmsgbuf_aligned cbuf; - fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)&*packet.begin(), packet.size(), &dc->d_remote); - msgh.msg_control = NULL; + if (!comboWriter->d_tcp) { + struct msghdr msgh{}; + struct iovec iov{}; + cmsgbuf_aligned cbuf{}; + fillMSGHdr(&msgh, &iov, &cbuf, 0, reinterpret_cast(&*packet.begin()), packet.size(), &comboWriter->d_remote); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + msgh.msg_control = nullptr; - if (g_fromtosockets.count(dc->d_socket)) { - addCMsgSrcAddr(&msgh, &cbuf, &dc->d_local, 0); + if (g_fromtosockets.count(comboWriter->d_socket) > 0) { + addCMsgSrcAddr(&msgh, &cbuf, &comboWriter->d_local, 0); } - int sendErr = sendOnNBSocket(dc->d_socket, &msgh); - if (sendErr && g_logCommonErrors) { - SLOG(g_log << Logger::Warning << "Sending UDP reply to client " << dc->getRemote() << " failed with: " - << strerror(sendErr) << endl, + int sendErr = sendOnNBSocket(comboWriter->d_socket, &msgh); + if (sendErr != 0 && g_logCommonErrors) { + SLOG(g_log << Logger::Warning << "Sending UDP reply to client " << comboWriter->getRemote() << " failed with: " + << stringerror(sendErr) << endl, g_slogudpin->error(Logr::Warning, sendErr, "Sending UDP reply to client failed")); } } else { - bool hadError = sendResponseOverTCP(dc, packet); - finishTCPReply(dc, hadError, true); + bool hadError = sendResponseOverTCP(comboWriter, packet); + finishTCPReply(comboWriter, hadError, true); tcpGuard.setHandled(); } - sr.d_eventTrace.add(RecEventTrace::AnswerSent); + resolver.d_eventTrace.add(RecEventTrace::AnswerSent); // Now do the per query changing part ot the protobuf message - if (t_protobufServers.servers && !(luaconfsLocal->protobufExportConfig.taggedOnly && appliedPolicy.getName().empty() && dc->d_policyTags.empty())) { + if (t_protobufServers.servers && !(luaconfsLocal->protobufExportConfig.taggedOnly && appliedPolicy.getName().empty() && comboWriter->d_policyTags.empty())) { // Below are the fields that are not stored in the packet cache and will be appended here and on a cache hit - if (g_useKernelTimestamp && dc->d_kernelTimestamp.tv_sec) { - pbMessage.setQueryTime(dc->d_kernelTimestamp.tv_sec, dc->d_kernelTimestamp.tv_usec); + if (g_useKernelTimestamp && comboWriter->d_kernelTimestamp.tv_sec != 0) { + pbMessage.setQueryTime(comboWriter->d_kernelTimestamp.tv_sec, comboWriter->d_kernelTimestamp.tv_usec); } else { - pbMessage.setQueryTime(dc->d_now.tv_sec, dc->d_now.tv_usec); + pbMessage.setQueryTime(comboWriter->d_now.tv_sec, comboWriter->d_now.tv_usec); } - pbMessage.setMessageIdentity(dc->d_uuid); - pbMessage.setSocketProtocol(dc->d_tcp ? pdns::ProtoZero::Message::TransportProtocol::TCP : pdns::ProtoZero::Message::TransportProtocol::UDP); + pbMessage.setMessageIdentity(comboWriter->d_uuid); + pbMessage.setSocketProtocol(comboWriter->d_tcp ? pdns::ProtoZero::Message::TransportProtocol::TCP : pdns::ProtoZero::Message::TransportProtocol::UDP); if (!luaconfsLocal->protobufExportConfig.logMappedFrom) { - pbMessage.setSocketFamily(dc->d_source.sin4.sin_family); - Netmask requestorNM(dc->d_source, dc->d_source.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); + pbMessage.setSocketFamily(comboWriter->d_source.sin4.sin_family); + Netmask requestorNM(comboWriter->d_source, comboWriter->d_source.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); ComboAddress requestor = requestorNM.getMaskedNetwork(); pbMessage.setFrom(requestor); - pbMessage.setFromPort(dc->d_source.getPort()); + pbMessage.setFromPort(comboWriter->d_source.getPort()); } else { - pbMessage.setSocketFamily(dc->d_mappedSource.sin4.sin_family); - Netmask requestorNM(dc->d_mappedSource, dc->d_mappedSource.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); + pbMessage.setSocketFamily(comboWriter->d_mappedSource.sin4.sin_family); + Netmask requestorNM(comboWriter->d_mappedSource, comboWriter->d_mappedSource.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); ComboAddress requestor = requestorNM.getMaskedNetwork(); pbMessage.setFrom(requestor); - pbMessage.setFromPort(dc->d_mappedSource.getPort()); + pbMessage.setFromPort(comboWriter->d_mappedSource.getPort()); } - pbMessage.setTo(dc->d_destination); - pbMessage.setId(dc->d_mdp.d_header.id); + pbMessage.setTo(comboWriter->d_destination); + pbMessage.setId(comboWriter->d_mdp.d_header.id); pbMessage.setTime(); - pbMessage.setEDNSSubnet(dc->d_ednssubnet.source, dc->d_ednssubnet.source.isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); - pbMessage.setRequestorId(dq.requestorId); - pbMessage.setDeviceId(dq.deviceId); - pbMessage.setDeviceName(dq.deviceName); - pbMessage.setToPort(dc->d_destination.getPort()); + pbMessage.setEDNSSubnet(comboWriter->d_ednssubnet.source, comboWriter->d_ednssubnet.source.isIPv4() ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); + pbMessage.setRequestorId(dnsQuestion.requestorId); + pbMessage.setDeviceId(dnsQuestion.deviceId); + pbMessage.setDeviceName(dnsQuestion.deviceName); + pbMessage.setToPort(comboWriter->d_destination.getPort()); - for (const auto& m : dq.meta) { - pbMessage.setMeta(m.first, m.second.stringVal, m.second.intVal); + for (const auto& metaValue : dnsQuestion.meta) { + pbMessage.setMeta(metaValue.first, metaValue.second.stringVal, metaValue.second.intVal); } #ifdef NOD_ENABLED if (g_nodEnabled) { @@ -1773,55 +1782,55 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } } #endif /* NOD_ENABLED */ - if (sr.d_eventTrace.enabled() && SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_pb) { - pbMessage.addEvents(sr.d_eventTrace); + if (resolver.d_eventTrace.enabled() && (SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_pb) != 0) { + pbMessage.addEvents(resolver.d_eventTrace); } - if (dc->d_logResponse) { + if (comboWriter->d_logResponse) { protobufLogResponse(pbMessage); } } - if (sr.d_eventTrace.enabled() && SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_log) { - SLOG(g_log << Logger::Info << sr.d_eventTrace.toString() << endl, - sr.d_slog->info(Logr::Info, sr.d_eventTrace.toString())); // Maybe we want it to be more fancy? + if (resolver.d_eventTrace.enabled() && (SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_log) != 0) { + SLOG(g_log << Logger::Info << resolver.d_eventTrace.toString() << endl, + resolver.d_slog->info(Logr::Info, resolver.d_eventTrace.toString())); // Maybe we want it to be more fancy? } // Originally this code used a mix of floats, doubles, uint64_t with different units. // Now it always uses an integral number of microseconds, except for averages, which use doubles - uint64_t spentUsec = uSec(sr.getNow() - dc->d_now); + uint64_t spentUsec = uSec(resolver.getNow() - comboWriter->d_now); if (!g_quiet) { if (!g_slogStructured) { - g_log << Logger::Error << RecThreadInfo::id() << " [" << MT->getTid() << "/" << MT->numProcesses() << "] answer to " << (dc->d_mdp.d_header.rd ? "" : "non-rd ") << "question '" << dc->d_mdp.d_qname << "|" << DNSRecordContent::NumberToType(dc->d_mdp.d_qtype); - g_log << "': " << ntohs(pw.getHeader()->ancount) << " answers, " << ntohs(pw.getHeader()->arcount) << " additional, took " << sr.d_outqueries << " packets, " << sr.d_totUsec / 1000.0 << " netw ms, " << spentUsec / 1000.0 << " tot ms, " << sr.d_throttledqueries << " throttled, " << sr.d_timeouts << " timeouts, " << sr.d_tcpoutqueries << "/" << sr.d_dotoutqueries << " tcp/dot connections, rcode=" << res; + g_log << Logger::Error << RecThreadInfo::id() << " [" << g_multiTasker->getTid() << "/" << g_multiTasker->numProcesses() << "] answer to " << (comboWriter->d_mdp.d_header.rd ? "" : "non-rd ") << "question '" << comboWriter->d_mdp.d_qname << "|" << DNSRecordContent::NumberToType(comboWriter->d_mdp.d_qtype); + g_log << "': " << ntohs(packetWriter.getHeader()->ancount) << " answers, " << ntohs(packetWriter.getHeader()->arcount) << " additional, took " << resolver.d_outqueries << " packets, " << resolver.d_totUsec / 1000.0 << " netw ms, " << static_cast(spentUsec) / 1000.0 << " tot ms, " << resolver.d_throttledqueries << " throttled, " << resolver.d_timeouts << " timeouts, " << resolver.d_tcpoutqueries << "/" << resolver.d_dotoutqueries << " tcp/dot connections, rcode=" << res; - if (!shouldNotValidate && sr.isDNSSECValidationRequested()) { - g_log << ", dnssec=" << sr.getValidationState(); + if (!shouldNotValidate && resolver.isDNSSECValidationRequested()) { + g_log << ", dnssec=" << resolver.getValidationState(); } - g_log << " answer-is-variable=" << sr.wasVariable() << ", into-packetcache=" << intoPC; - g_log << " maxdepth=" << sr.d_maxdepth; + g_log << " answer-is-variable=" << resolver.wasVariable() << ", into-packetcache=" << intoPC; + g_log << " maxdepth=" << resolver.d_maxdepth; g_log << endl; } else { - sr.d_slog->info(Logr::Info, "Answer", "rd", Logging::Loggable(dc->d_mdp.d_header.rd), - "answers", Logging::Loggable(ntohs(pw.getHeader()->ancount)), - "additional", Logging::Loggable(ntohs(pw.getHeader()->arcount)), - "outqueries", Logging::Loggable(sr.d_outqueries), - "netms", Logging::Loggable(sr.d_totUsec / 1000.0), - "totms", Logging::Loggable(spentUsec / 1000.0), - "throttled", Logging::Loggable(sr.d_throttledqueries), - "timeouts", Logging::Loggable(sr.d_timeouts), - "tcpout", Logging::Loggable(sr.d_tcpoutqueries), - "dotout", Logging::Loggable(sr.d_dotoutqueries), + resolver.d_slog->info(Logr::Info, "Answer", "rd", Logging::Loggable(comboWriter->d_mdp.d_header.rd), + "answers", Logging::Loggable(ntohs(packetWriter.getHeader()->ancount)), + "additional", Logging::Loggable(ntohs(packetWriter.getHeader()->arcount)), + "outqueries", Logging::Loggable(resolver.d_outqueries), + "netms", Logging::Loggable(resolver.d_totUsec / 1000.0), + "totms", Logging::Loggable(static_cast(spentUsec) / 1000.0), + "throttled", Logging::Loggable(resolver.d_throttledqueries), + "timeouts", Logging::Loggable(resolver.d_timeouts), + "tcpout", Logging::Loggable(resolver.d_tcpoutqueries), + "dotout", Logging::Loggable(resolver.d_dotoutqueries), "rcode", Logging::Loggable(res), - "validationState", Logging::Loggable(sr.getValidationState()), - "answer-is-variable", Logging::Loggable(sr.wasVariable()), + "validationState", Logging::Loggable(resolver.getValidationState()), + "answer-is-variable", Logging::Loggable(resolver.wasVariable()), "into-packetcache", Logging::Loggable(intoPC), - "maxdepth", Logging::Loggable(sr.d_maxdepth)); + "maxdepth", Logging::Loggable(resolver.d_maxdepth)); } } - if (dc->d_mdp.d_header.opcode == Opcode::Query) { - if (sr.d_outqueries || sr.d_authzonequeries) { + if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Query)) { + if (resolver.d_outqueries != 0 || resolver.d_authzonequeries != 0) { g_recCache->cacheMisses++; } else { @@ -1832,37 +1841,37 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity t_Counters.at(rec::Histogram::answers)(spentUsec); t_Counters.at(rec::Histogram::cumulativeAnswers)(spentUsec); - double newLat = spentUsec; + auto newLat = static_cast(spentUsec); newLat = min(newLat, g_networkTimeoutMsec * 1000.0); // outliers of several minutes exist.. t_Counters.at(rec::DoubleWAvgCounter::avgLatencyUsec).addToRollingAvg(newLat, g_latencyStatSize); // no worries, we do this for packet cache hits elsewhere - if (spentUsec >= sr.d_totUsec) { - uint64_t ourtime = spentUsec - sr.d_totUsec; + if (spentUsec >= resolver.d_totUsec) { + uint64_t ourtime = spentUsec - resolver.d_totUsec; t_Counters.at(rec::Histogram::ourtime)(ourtime); - newLat = ourtime; // usec + newLat = static_cast(ourtime); // usec t_Counters.at(rec::DoubleWAvgCounter::avgLatencyOursUsec).addToRollingAvg(newLat, g_latencyStatSize); } #ifdef NOD_ENABLED if (nod) { - sendNODLookup(nodlogger, dc->d_mdp.d_qname); + sendNODLookup(nodlogger, comboWriter->d_mdp.d_qname); } #endif /* NOD_ENABLED */ // cout<d_mdp.d_qname<<"\t"<getUsec()<<"\t"<error(Logr::Error, ae.reason, "startDoResolve problem", "exception", Logging::Loggable("PDNSException"))); + SLOG(g_log << Logger::Error << "startDoResolve problem " << makeLoginfo(comboWriter) << ": " << ae.reason << endl, + resolver.d_slog->error(Logr::Error, ae.reason, "startDoResolve problem", "exception", Logging::Loggable("PDNSException"))); } catch (const MOADNSException& mde) { - SLOG(g_log << Logger::Error << "DNS parser error " << makeLoginfo(dc) << ": " << dc->d_mdp.d_qname << ", " << mde.what() << endl, - sr.d_slog->error(Logr::Error, mde.what(), "DNS parser error")); + SLOG(g_log << Logger::Error << "DNS parser error " << makeLoginfo(comboWriter) << ": " << comboWriter->d_mdp.d_qname << ", " << mde.what() << endl, + resolver.d_slog->error(Logr::Error, mde.what(), "DNS parser error")); } catch (const std::exception& e) { - SLOG(g_log << Logger::Error << "STL error " << makeLoginfo(dc) << ": " << e.what(), - sr.d_slog->error(Logr::Error, e.what(), "Exception in resolver context ", "exception", Logging::Loggable("std::exception"))); + SLOG(g_log << Logger::Error << "STL error " << makeLoginfo(comboWriter) << ": " << e.what(), + resolver.d_slog->error(Logr::Error, e.what(), "Exception in resolver context ", "exception", Logging::Loggable("std::exception"))); // Luawrapper nests the exception from Lua, so we unnest it here try { @@ -1870,7 +1879,7 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } catch (const std::exception& ne) { SLOG(g_log << ". Extra info: " << ne.what(), - sr.d_slog->error(Logr::Error, ne.what(), "Nested exception in resolver context", Logging::Loggable("std::exception"))); + resolver.d_slog->error(Logr::Error, ne.what(), "Nested exception in resolver context", Logging::Loggable("std::exception"))); } catch (...) { } @@ -1879,26 +1888,26 @@ void startDoResolve(void* p) // NOLINT(readability-function-cognitive-complexity } } catch (...) { - SLOG(g_log << Logger::Error << "Any other exception in a resolver context " << makeLoginfo(dc) << endl, - sr.d_slog->info(Logr::Error, "Any other exception in a resolver context")); + SLOG(g_log << Logger::Error << "Any other exception in a resolver context " << makeLoginfo(comboWriter) << endl, + resolver.d_slog->info(Logr::Error, "Any other exception in a resolver context")); } runTaskOnce(g_logCommonErrors); static const size_t stackSizeThreshold = 9 * ::arg().asNum("stack-size") / 10; - if (MT->getMaxStackUsage() >= stackSizeThreshold) { - SLOG(g_log << Logger::Error << "Reached mthread stack usage of 90%: " << MT->getMaxStackUsage() << " " << makeLoginfo(dc) << " after " << sr.d_outqueries << " out queries, " << sr.d_tcpoutqueries << " TCP out queries, " << sr.d_dotoutqueries << " DoT out queries" << endl, - sr.d_slog->info(Logr::Error, "Reached mthread stack usage of 90%", - "stackUsage", Logging::Loggable(MT->getMaxStackUsage()), - "outqueries", Logging::Loggable(sr.d_outqueries), - "netms", Logging::Loggable(sr.d_totUsec / 1000.0), - "throttled", Logging::Loggable(sr.d_throttledqueries), - "timeouts", Logging::Loggable(sr.d_timeouts), - "tcpout", Logging::Loggable(sr.d_tcpoutqueries), - "dotout", Logging::Loggable(sr.d_dotoutqueries), - "validationState", Logging::Loggable(sr.getValidationState()))); - } - t_Counters.at(rec::Counter::maxMThreadStackUsage) = max(MT->getMaxStackUsage(), t_Counters.at(rec::Counter::maxMThreadStackUsage)); + if (g_multiTasker->getMaxStackUsage() >= stackSizeThreshold) { + SLOG(g_log << Logger::Error << "Reached mthread stack usage of 90%: " << g_multiTasker->getMaxStackUsage() << " " << makeLoginfo(comboWriter) << " after " << resolver.d_outqueries << " out queries, " << resolver.d_tcpoutqueries << " TCP out queries, " << resolver.d_dotoutqueries << " DoT out queries" << endl, + resolver.d_slog->info(Logr::Error, "Reached mthread stack usage of 90%", + "stackUsage", Logging::Loggable(g_multiTasker->getMaxStackUsage()), + "outqueries", Logging::Loggable(resolver.d_outqueries), + "netms", Logging::Loggable(resolver.d_totUsec / 1000.0), + "throttled", Logging::Loggable(resolver.d_throttledqueries), + "timeouts", Logging::Loggable(resolver.d_timeouts), + "tcpout", Logging::Loggable(resolver.d_tcpoutqueries), + "dotout", Logging::Loggable(resolver.d_dotoutqueries), + "validationState", Logging::Loggable(resolver.getValidationState()))); + } + t_Counters.at(rec::Counter::maxMThreadStackUsage) = max(g_multiTasker->getMaxStackUsage(), t_Counters.at(rec::Counter::maxMThreadStackUsage)); t_Counters.updateSnap(g_regressionTestMode); } @@ -1907,14 +1916,14 @@ void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* { const bool lookForECS = ednssubnet != nullptr; const dnsheader_aligned dnshead(question.data()); - const dnsheader* dh = dnshead.get(); + const dnsheader* dhPointer = dnshead.get(); size_t questionLen = question.length(); unsigned int consumed = 0; - *dnsname = DNSName(question.c_str(), questionLen, sizeof(dnsheader), false, qtype, qclass, &consumed); + *dnsname = DNSName(question.c_str(), static_cast(questionLen), sizeof(dnsheader), false, qtype, qclass, &consumed); size_t pos = sizeof(dnsheader) + consumed + 4; const size_t headerSize = /* root */ 1 + sizeof(dnsrecordheader); - const uint16_t arcount = ntohs(dh->arcount); + const uint16_t arcount = ntohs(dhPointer->arcount); for (uint16_t arpos = 0; arpos < arcount && questionLen > (pos + headerSize) && (lookForECS && !foundECS); arpos++) { if (question.at(pos) != 0) { @@ -1923,7 +1932,7 @@ void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* } pos += 1; - const dnsrecordheader* drh = reinterpret_cast(&question.at(pos)); + const auto* drh = reinterpret_cast(&question.at(pos)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) pos += sizeof(dnsrecordheader); if (pos >= questionLen) { @@ -1932,11 +1941,11 @@ void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* /* OPT root label (1) followed by type (2) */ if (lookForECS && ntohs(drh->d_type) == QType::OPT) { - if (!options) { + if (options == nullptr) { size_t ecsStartPosition = 0; size_t ecsLen = 0; /* we need to pass the record len */ - int res = getEDNSOption(reinterpret_cast(&question.at(pos - sizeof(drh->d_clen))), questionLen - pos + sizeof(drh->d_clen), EDNSOptionCode::ECS, &ecsStartPosition, &ecsLen); + int res = getEDNSOption(reinterpret_cast(&question.at(pos - sizeof(drh->d_clen))), questionLen - pos + sizeof(drh->d_clen), EDNSOptionCode::ECS, &ecsStartPosition, &ecsLen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) if (res == 0 && ecsLen > 4) { EDNSSubnetOpts eso; if (getEDNSSubnetOptsFromString(&question.at(pos - sizeof(drh->d_clen) + ecsStartPosition + 4), ecsLen - 4, &eso)) { @@ -1947,12 +1956,12 @@ void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* } else { /* we need to pass the record len */ - int res = getEDNSOptions(reinterpret_cast(&question.at(pos - sizeof(drh->d_clen))), questionLen - pos + (sizeof(drh->d_clen)), *options); + int res = getEDNSOptions(reinterpret_cast(&question.at(pos - sizeof(drh->d_clen))), questionLen - pos + (sizeof(drh->d_clen)), *options); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) if (res == 0) { - const auto& it = options->find(EDNSOptionCode::ECS); - if (it != options->end() && !it->second.values.empty() && it->second.values.at(0).content != nullptr && it->second.values.at(0).size > 0) { + const auto& iter = options->find(EDNSOptionCode::ECS); + if (iter != options->end() && !iter->second.values.empty() && iter->second.values.at(0).content != nullptr && iter->second.values.at(0).size > 0) { EDNSSubnetOpts eso; - if (getEDNSSubnetOptsFromString(it->second.values.at(0).content, it->second.values.at(0).size, &eso)) { + if (getEDNSSubnetOptsFromString(iter->second.values.at(0).content, iter->second.values.at(0).size, &eso)) { *ednssubnet = eso; foundECS = true; } @@ -1975,8 +1984,8 @@ bool checkForCacheHit(bool qnameParsed, unsigned int tag, const string& data, return false; } bool cacheHit = false; - uint32_t age; - vState valState; + uint32_t age = 0; + vState valState = vState::Indeterminate; if (qnameParsed) { cacheHit = g_packetCache->getResponsePacket(tag, data, qname, qtype, qclass, now.tv_sec, &response, &age, &valState, &qhash, &pbData, tcp); @@ -2041,11 +2050,11 @@ void requestWipeCaches(const DNSName& canon) { // send a message to the handler thread asking it // to wipe all of the caches - ThreadMSG* tmsg = new ThreadMSG(); + ThreadMSG* tmsg = new ThreadMSG(); // NOLINT: pointer owner tmsg->func = [=] { return pleaseWipeCaches(canon, true, 0xffff); }; tmsg->wantAnswer = false; - if (write(RecThreadInfo::info(0).pipes.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { - delete tmsg; + if (write(RecThreadInfo::info(0).pipes.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // NOLINT: correct sizeof + delete tmsg; // NOLINT: pointer owner unixDie("write to thread pipe returned wrong size or error"); } @@ -2062,13 +2071,13 @@ bool expectProxyProtocol(const ComboAddress& from) // source: the address we assume the query is coming from, might be set by proxy protocol // destination: the address we assume the query was sent to, might be set by proxy protocol // mappedSource: the address we assume the query is coming from. Differs from source if table based mapping has been applied -static string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fromaddr, const ComboAddress& destaddr, ComboAddress source, ComboAddress destination, const ComboAddress& mappedSource, struct timeval tv, int fd, std::vector& proxyProtocolValues, RecEventTrace& eventTrace) +static string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fromaddr, const ComboAddress& destaddr, ComboAddress source, ComboAddress destination, const ComboAddress& mappedSource, struct timeval tval, int fileDesc, std::vector& proxyProtocolValues, RecEventTrace& eventTrace) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 { ++(RecThreadInfo::self().numberOfDistributedQueries); gettimeofday(&g_now, nullptr); - if (tv.tv_sec) { - struct timeval diff = g_now - tv; - double delta = (diff.tv_sec * 1000 + diff.tv_usec / 1000.0); + if (tval.tv_sec != 0) { + struct timeval diff = g_now - tval; + double delta = (static_cast(diff.tv_sec) * 1000 + static_cast(diff.tv_usec) / 1000.0); if (delta > 1000.0) { t_Counters.at(rec::Counter::tooOldDrops)++; @@ -2078,12 +2087,13 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr ++t_Counters.at(rec::Counter::qcounter); - if (fromaddr.sin4.sin_family == AF_INET6) + if (fromaddr.sin4.sin_family == AF_INET6) { t_Counters.at(rec::Counter::ipv6qcounter)++; + } string response; const dnsheader_aligned headerdata(question.data()); - const dnsheader* dh = headerdata.get(); + const dnsheader* dnsheader = headerdata.get(); unsigned int ctag = 0; uint32_t qhash = 0; bool needECS = false; @@ -2096,7 +2106,7 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr string routingTag; bool logQuery = false; bool logResponse = false; - boost::uuids::uuid uniqueId; + boost::uuids::uuid uniqueId{}; auto luaconfsLocal = g_luaconfs.getLocal(); const auto pbExport = checkProtobufExport(luaconfsLocal); const auto outgoingbExport = checkOutgoingProtobufExport(luaconfsLocal); @@ -2140,7 +2150,7 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr #endif // We do not have a SyncRes specific Lua context at this point yet, so ok to use t_pdl - if (needECS || (t_pdl && (t_pdl->d_gettag || t_pdl->d_gettag_ffi)) || dh->opcode == Opcode::Notify) { + if (needECS || (t_pdl && (t_pdl->d_gettag || t_pdl->d_gettag_ffi)) || dnsheader->opcode == static_cast(Opcode::Notify)) { try { EDNSOptionViewMap ednsOptions; @@ -2186,7 +2196,7 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr RecursorPacketCache::OptPBData pbData{boost::none}; if (t_protobufServers.servers) { if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && policyTags.empty())) { - protobufLogQuery(luaconfsLocal, uniqueId, source, destination, mappedSource, ednssubnet.source, false, dh->id, question.size(), qname, qtype, qclass, policyTags, requestorId, deviceId, deviceName, meta); + protobufLogQuery(luaconfsLocal, uniqueId, source, destination, mappedSource, ednssubnet.source, false, dnsheader->id, question.size(), qname, qtype, qclass, policyTags, requestorId, deviceId, deviceName, meta); } } @@ -2194,7 +2204,7 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr ctag = g_paddingTag; } - if (dh->opcode == Opcode::Query) { + if (dnsheader->opcode == static_cast(Opcode::Query)) { /* It might seem like a good idea to skip the packet cache lookup if we know that the answer is not cacheable, but it means that the hash would not be computed. If some script decides at a later time to mark back the answer as cacheable we would cache it with a wrong tag, so better safe than sorry. */ @@ -2208,38 +2218,38 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr "qname", Logging::Loggable(qname), "qtype", Logging::Loggable(QType(qtype)), "source", Logging::Loggable(source), "remote", Logging::Loggable(fromaddr))); } - struct msghdr msgh; - struct iovec iov; - cmsgbuf_aligned cbuf; - fillMSGHdr(&msgh, &iov, &cbuf, 0, (char*)response.c_str(), response.length(), const_cast(&fromaddr)); - msgh.msg_control = NULL; + struct msghdr msgh{}; + struct iovec iov{}; + cmsgbuf_aligned cbuf{}; + fillMSGHdr(&msgh, &iov, &cbuf, 0, reinterpret_cast(response.data()), response.length(), const_cast(&fromaddr)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-type-const-cast) + msgh.msg_control = nullptr; - if (g_fromtosockets.count(fd)) { + if (g_fromtosockets.count(fileDesc) != 0) { addCMsgSrcAddr(&msgh, &cbuf, &destaddr, 0); } - int sendErr = sendOnNBSocket(fd, &msgh); + int sendErr = sendOnNBSocket(fileDesc, &msgh); eventTrace.add(RecEventTrace::AnswerSent); - if (t_protobufServers.servers && logResponse && !(luaconfsLocal->protobufExportConfig.taggedOnly && pbData && !pbData->d_tagged)) { - protobufLogResponse(dh, luaconfsLocal, pbData, tv, false, source, destination, mappedSource, ednssubnet, uniqueId, requestorId, deviceId, deviceName, meta, eventTrace); + if (t_protobufServers.servers && logResponse && (!luaconfsLocal->protobufExportConfig.taggedOnly || !pbData || pbData->d_tagged)) { + protobufLogResponse(dnsheader, luaconfsLocal, pbData, tval, false, source, destination, mappedSource, ednssubnet, uniqueId, requestorId, deviceId, deviceName, meta, eventTrace); } - if (eventTrace.enabled() && SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_log) { + if (eventTrace.enabled() && (SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_log) != 0) { SLOG(g_log << Logger::Info << eventTrace.toString() << endl, g_slogudpin->info(Logr::Info, eventTrace.toString())); // Do we want more fancy logging here? } - if (sendErr && g_logCommonErrors) { + if (sendErr != 0 && g_logCommonErrors) { SLOG(g_log << Logger::Warning << "Sending UDP reply to client " << source.toStringWithPort() << (source != fromaddr ? " (via " + fromaddr.toStringWithPort() + ")" : "") << " failed with: " - << strerror(sendErr) << endl, + << stringerror(sendErr) << endl, g_slogudpin->error(Logr::Error, sendErr, "Sending UDP reply to client failed", "source", Logging::Loggable(source), "remote", Logging::Loggable(fromaddr))); } - struct timeval now; + struct timeval now{}; Utility::gettimeofday(&now, nullptr); - uint64_t spentUsec = uSec(now - tv); + uint64_t spentUsec = uSec(now - tval); t_Counters.at(rec::Histogram::cumulativeAnswers)(spentUsec); t_Counters.updateSnap(g_regressionTestMode); - return 0; + return nullptr; } } } @@ -2248,30 +2258,30 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr SLOG(g_log << Logger::Error << "Error processing or aging answer packet: " << e.what() << endl, g_slogudpin->error(Logr::Error, e.what(), "Error processing or aging answer packet", "exception", Logging::Loggable("std::exception"))); } - return 0; + return nullptr; } if (t_pdl) { - bool ipf = t_pdl->ipfilter(source, destination, *dh, eventTrace); + bool ipf = t_pdl->ipfilter(source, destination, *dnsheader, eventTrace); if (ipf) { if (!g_quiet) { - SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " [" << MT->getTid() << "/" << MT->numProcesses() << "] DROPPED question from " << source.toStringWithPort() << (source != fromaddr ? " (via " + fromaddr.toStringWithPort() + ")" : "") << " based on policy" << endl, + SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " [" << g_multiTasker->getTid() << "/" << g_multiTasker->numProcesses() << "] DROPPED question from " << source.toStringWithPort() << (source != fromaddr ? " (via " + fromaddr.toStringWithPort() + ")" : "") << " based on policy" << endl, g_slogudpin->info(Logr::Notice, "Dropped question based on policy", "source", Logging::Loggable(source), "remote", Logging::Loggable(fromaddr))); } t_Counters.at(rec::Counter::policyDrops)++; - return 0; + return nullptr; } } - if (dh->opcode == Opcode::Notify) { + if (dnsheader->opcode == static_cast(Opcode::Notify)) { if (!isAllowNotifyForZone(qname)) { if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping UDP NOTIFY from " << source.toStringWithPort() << (source != fromaddr ? " (via " + fromaddr.toStringWithPort() + ")" : "") << ", for " << qname.toLogString() << ", zone not matched by allow-notify-for" << endl, + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping UDP NOTIFY from " << source.toStringWithPort() << (source != fromaddr ? " (via " + fromaddr.toStringWithPort() + ")" : "") << ", for " << qname.toLogString() << ", zone not matched by allow-notify-for" << endl, g_slogudpin->info(Logr::Notice, "Dropping UDP NOTIFY, zone not matched by allow-notify-for", "source", Logging::Loggable(source), "remote", Logging::Loggable(fromaddr))); } t_Counters.at(rec::Counter::zoneDisallowedNotify)++; - return 0; + return nullptr; } if (!g_quiet) { @@ -2288,64 +2298,64 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr variable = true; } - if (MT->numProcesses() > g_maxMThreads) { - if (!g_quiet) - SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " [" << MT->getTid() << "/" << MT->numProcesses() << "] DROPPED question from " << source.toStringWithPort() << (source != fromaddr ? " (via " + fromaddr.toStringWithPort() + ")" : "") << ", over capacity" << endl, + if (g_multiTasker->numProcesses() > g_maxMThreads) { + if (!g_quiet) { + SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " [" << g_multiTasker->getTid() << "/" << g_multiTasker->numProcesses() << "] DROPPED question from " << source.toStringWithPort() << (source != fromaddr ? " (via " + fromaddr.toStringWithPort() + ")" : "") << ", over capacity" << endl, g_slogudpin->info(Logr::Notice, "Dropped question, over capacity", "source", Logging::Loggable(source), "remote", Logging::Loggable(fromaddr))); - + } t_Counters.at(rec::Counter::overCapacityDrops)++; - return 0; - } - - auto dc = std::make_unique(question, g_now, std::move(policyTags), t_pdl, std::move(data), std::move(records)); - - dc->setSocket(fd); - dc->d_tag = ctag; - dc->d_qhash = qhash; - dc->setRemote(fromaddr); // the address the query is coming from - dc->setSource(source); // the address we assume the query is coming from, might be set by proxy protocol - dc->setLocal(destaddr); // the address the query was received on - dc->setDestination(destination); // the address we assume the query is sent to, might be set by proxy protocol - dc->setMappedSource(mappedSource); // the address we assume the query is coming from. Differs from source if table-based mapping has been applied - dc->d_tcp = false; - dc->d_ecsFound = ecsFound; - dc->d_ecsParsed = ecsParsed; - dc->d_ednssubnet = ednssubnet; - dc->d_ttlCap = ttlCap; - dc->d_variable = variable; - dc->d_followCNAMERecords = followCNAMEs; - dc->d_rcode = rcode; - dc->d_logResponse = logResponse; + return nullptr; + } + + auto comboWriter = std::make_unique(question, g_now, std::move(policyTags), t_pdl, std::move(data), std::move(records)); + + comboWriter->setSocket(fileDesc); + comboWriter->d_tag = ctag; + comboWriter->d_qhash = qhash; + comboWriter->setRemote(fromaddr); // the address the query is coming from + comboWriter->setSource(source); // the address we assume the query is coming from, might be set by proxy protocol + comboWriter->setLocal(destaddr); // the address the query was received on + comboWriter->setDestination(destination); // the address we assume the query is sent to, might be set by proxy protocol + comboWriter->setMappedSource(mappedSource); // the address we assume the query is coming from. Differs from source if table-based mapping has been applied + comboWriter->d_tcp = false; + comboWriter->d_ecsFound = ecsFound; + comboWriter->d_ecsParsed = ecsParsed; + comboWriter->d_ednssubnet = ednssubnet; + comboWriter->d_ttlCap = ttlCap; + comboWriter->d_variable = variable; + comboWriter->d_followCNAMERecords = followCNAMEs; + comboWriter->d_rcode = rcode; + comboWriter->d_logResponse = logResponse; if (t_protobufServers.servers || t_outgoingProtobufServers.servers) { - dc->d_uuid = std::move(uniqueId); - } - dc->d_requestorId = requestorId; - dc->d_deviceId = deviceId; - dc->d_deviceName = deviceName; - dc->d_kernelTimestamp = tv; - dc->d_proxyProtocolValues = std::move(proxyProtocolValues); - dc->d_routingTag = std::move(routingTag); - dc->d_extendedErrorCode = extendedErrorCode; - dc->d_extendedErrorExtra = std::move(extendedErrorExtra); - dc->d_responsePaddingDisabled = responsePaddingDisabled; - dc->d_meta = std::move(meta); - - dc->d_eventTrace = std::move(eventTrace); - MT->makeThread(startDoResolve, (void*)dc.release()); // deletes dc + comboWriter->d_uuid = uniqueId; + } + comboWriter->d_requestorId = requestorId; + comboWriter->d_deviceId = deviceId; + comboWriter->d_deviceName = deviceName; + comboWriter->d_kernelTimestamp = tval; + comboWriter->d_proxyProtocolValues = std::move(proxyProtocolValues); + comboWriter->d_routingTag = std::move(routingTag); + comboWriter->d_extendedErrorCode = extendedErrorCode; + comboWriter->d_extendedErrorExtra = std::move(extendedErrorExtra); + comboWriter->d_responsePaddingDisabled = responsePaddingDisabled; + comboWriter->d_meta = std::move(meta); + + comboWriter->d_eventTrace = std::move(eventTrace); + g_multiTasker->makeThread(startDoResolve, (void*)comboWriter.release()); // deletes dc - return 0; + return nullptr; } -static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) +static void handleNewUDPQuestion(int fileDesc, FDMultiplexer::funcparam_t& /* var */) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 { - ssize_t len; + ssize_t len = 0; static const size_t maxIncomingQuerySize = g_proxyProtocolACL.empty() ? 512 : (512 + g_proxyProtocolMaximumSize); static thread_local std::string data; ComboAddress fromaddr; // the address the query is coming from ComboAddress source; // the address we assume the query is coming from, might be set by proxy protocol ComboAddress destination; // the address we assume the query was sent to, might be set by proxy protocol - struct msghdr msgh; - struct iovec iov; + struct msghdr msgh{}; + struct iovec iov{}; cmsgbuf_aligned cbuf; bool firstQuery = true; std::vector proxyProtocolValues; @@ -2356,16 +2366,16 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) proxyProtocolValues.clear(); data.resize(maxIncomingQuerySize); fromaddr.sin6.sin6_family = AF_INET6; // this makes sure fromaddr is big enough - fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), &data[0], data.size(), &fromaddr); + fillMSGHdr(&msgh, &iov, &cbuf, sizeof(cbuf), data.data(), data.size(), &fromaddr); - if ((len = recvmsg(fd, &msgh, 0)) >= 0) { + if ((len = recvmsg(fileDesc, &msgh, 0)) >= 0) { eventTrace.clear(); - eventTrace.setEnabled(SyncRes::s_event_trace_enabled); + eventTrace.setEnabled(SyncRes::s_event_trace_enabled != 0); eventTrace.add(RecEventTrace::ReqRecv); firstQuery = false; - if (msgh.msg_flags & MSG_TRUNC) { + if ((msgh.msg_flags & MSG_TRUNC) != 0) { t_Counters.at(rec::Counter::truncatedDrops)++; if (!g_quiet) { SLOG(g_log << Logger::Error << "Ignoring truncated query from " << fromaddr.toString() << endl, @@ -2377,7 +2387,7 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) data.resize(static_cast(len)); if (expectProxyProtocol(fromaddr)) { - bool tcp; + bool tcp = false; ssize_t used = parseProxyHeader(data, proxyProto, source, destination, tcp, proxyProtocolValues); if (used <= 0) { ++t_Counters.at(rec::Counter::proxyProtocolInvalidCount); @@ -2388,7 +2398,7 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) } return; } - else if (static_cast(used) > g_proxyProtocolMaximumSize) { + if (static_cast(used) > g_proxyProtocolMaximumSize) { if (g_quiet) { SLOG(g_log << Logger::Error << "Proxy protocol header in UDP packet from " << fromaddr.toStringWithPort() << " is larger than proxy-protocol-maximum-size (" << used << "), dropping" << endl, g_slogudpin->info(Logr::Error, "Proxy protocol header in UDP packet is larger than proxy-protocol-maximum-size", @@ -2425,9 +2435,9 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) } ComboAddress mappedSource = source; if (t_proxyMapping) { - if (auto it = t_proxyMapping->lookup(source)) { - mappedSource = it->second.address; - ++it->second.stats.netmaskMatches; + if (const auto *iter = t_proxyMapping->lookup(source)) { + mappedSource = iter->second.address; + ++iter->second.stats.netmaskMatches; } } if (t_remotes) { @@ -2436,7 +2446,7 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) if (t_allowFrom && !t_allowFrom->match(&mappedSource)) { if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping UDP query from " << mappedSource.toString() << ", address not matched by allow-from" << endl, + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping UDP query from " << mappedSource.toString() << ", address not matched by allow-from" << endl, g_slogudpin->info(Logr::Error, "Dropping UDP query, address not matched by allow-from", "source", Logging::Loggable(mappedSource))); } @@ -2445,9 +2455,9 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) } BOOST_STATIC_ASSERT(offsetof(sockaddr_in, sin_port) == offsetof(sockaddr_in6, sin6_port)); - if (!fromaddr.sin4.sin_port) { // also works for IPv6 + if (fromaddr.sin4.sin_port == 0) { // also works for IPv6 if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping UDP query from " << fromaddr.toStringWithPort() << ", can't deal with port 0" << endl, + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping UDP query from " << fromaddr.toStringWithPort() << ", can't deal with port 0" << endl, g_slogudpin->info(Logr::Error, "Dropping UDP query can't deal with port 0", "remote", Logging::Loggable(fromaddr))); } @@ -2457,23 +2467,23 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) try { const dnsheader_aligned headerdata(data.data()); - const dnsheader* dh = headerdata.get(); + const dnsheader* dnsheader = headerdata.get(); - if (dh->qr) { + if (dnsheader->qr) { t_Counters.at(rec::Counter::ignoredCount)++; if (g_logCommonErrors) { SLOG(g_log << Logger::Error << "Ignoring answer from " << fromaddr.toString() << " on server socket!" << endl, g_slogudpin->info(Logr::Error, "Ignoring answer on server socket", "remote", Logging::Loggable(fromaddr))); } } - else if (dh->opcode != Opcode::Query && dh->opcode != Opcode::Notify) { + else if (dnsheader->opcode != static_cast(Opcode::Query) && dnsheader->opcode != static_cast(Opcode::Notify)) { t_Counters.at(rec::Counter::ignoredCount)++; if (g_logCommonErrors) { - SLOG(g_log << Logger::Error << "Ignoring unsupported opcode " << Opcode::to_s(dh->opcode) << " from " << fromaddr.toString() << " on server socket!" << endl, - g_slogudpin->info(Logr::Error, "Ignoring unsupported opcode server socket", "remote", Logging::Loggable(fromaddr), "opcode", Logging::Loggable(Opcode::to_s(dh->opcode)))); + SLOG(g_log << Logger::Error << "Ignoring unsupported opcode " << Opcode::to_s(dnsheader->opcode) << " from " << fromaddr.toString() << " on server socket!" << endl, + g_slogudpin->info(Logr::Error, "Ignoring unsupported opcode server socket", "remote", Logging::Loggable(fromaddr), "opcode", Logging::Loggable(Opcode::to_s(dnsheader->opcode)))); } } - else if (dh->qdcount == 0) { + else if (dnsheader->qdcount == 0U) { t_Counters.at(rec::Counter::emptyQueriesCount)++; if (g_logCommonErrors) { SLOG(g_log << Logger::Error << "Ignoring empty (qdcount == 0) query from " << fromaddr.toString() << " on server socket!" << endl, @@ -2481,10 +2491,10 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) } } else { - if (dh->opcode == Opcode::Notify) { + if (dnsheader->opcode == static_cast(Opcode::Notify)) { if (!t_allowNotifyFrom || !t_allowNotifyFrom->match(&mappedSource)) { if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping UDP NOTIFY from " << mappedSource.toString() << ", address not matched by allow-notify-from" << endl, + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping UDP NOTIFY from " << mappedSource.toString() << ", address not matched by allow-notify-from" << endl, g_slogudpin->info(Logr::Error, "Dropping UDP NOTIFY from address not matched by allow-notify-from", "source", Logging::Loggable(mappedSource))); } @@ -2494,39 +2504,39 @@ static void handleNewUDPQuestion(int fd, FDMultiplexer::funcparam_t& /* var */) } } - struct timeval tv = {0, 0}; - HarvestTimestamp(&msgh, &tv); - ComboAddress dest; // the address the query was sent to to - dest.reset(); // this makes sure we ignore this address if not returned by recvmsg above - auto loc = rplookup(g_listenSocketsAddresses, fd); - if (HarvestDestinationAddress(&msgh, &dest)) { + struct timeval tval = {0, 0}; + HarvestTimestamp(&msgh, &tval); + ComboAddress destaddr; // the address the query was sent to to + destaddr.reset(); // this makes sure we ignore this address if not returned by recvmsg above + const auto *loc = rplookup(g_listenSocketsAddresses, fileDesc); + if (HarvestDestinationAddress(&msgh, &destaddr)) { // but.. need to get port too - if (loc) { - dest.sin4.sin_port = loc->sin4.sin_port; + if (loc != nullptr) { + destaddr.sin4.sin_port = loc->sin4.sin_port; } } else { - if (loc) { - dest = *loc; + if (loc != nullptr) { + destaddr = *loc; } else { - dest.sin4.sin_family = fromaddr.sin4.sin_family; - socklen_t slen = dest.getSocklen(); - getsockname(fd, (sockaddr*)&dest, &slen); // if this fails, we're ok with it + destaddr.sin4.sin_family = fromaddr.sin4.sin_family; + socklen_t slen = destaddr.getSocklen(); + getsockname(fileDesc, reinterpret_cast(&destaddr), &slen); // if this fails, we're ok with it // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) } } if (!proxyProto) { - destination = dest; + destination = destaddr; } if (RecThreadInfo::weDistributeQueries()) { std::string localdata = data; - distributeAsyncFunction(data, [localdata, fromaddr, dest, source, destination, mappedSource, tv, fd, proxyProtocolValues, eventTrace]() mutable { - return doProcessUDPQuestion(localdata, fromaddr, dest, source, destination, mappedSource, tv, fd, proxyProtocolValues, eventTrace); + distributeAsyncFunction(data, [localdata, fromaddr, destaddr, source, destination, mappedSource, tval, fileDesc, proxyProtocolValues, eventTrace]() mutable { + return doProcessUDPQuestion(localdata, fromaddr, destaddr, source, destination, mappedSource, tval, fileDesc, proxyProtocolValues, eventTrace); }); } else { - doProcessUDPQuestion(data, fromaddr, dest, source, destination, mappedSource, tv, fd, proxyProtocolValues, eventTrace); + doProcessUDPQuestion(data, fromaddr, destaddr, source, destination, mappedSource, tval, fileDesc, proxyProtocolValues, eventTrace); } } } @@ -2580,20 +2590,20 @@ void makeUDPServerSockets(deferredAdd_t& deferredAdds, Logr::log_t log) } if (IsAnyAddress(address)) { if (address.sin4.sin_family == AF_INET) { - if (!setsockopt(socketFd, IPPROTO_IP, GEN_IP_PKTINFO, &one, sizeof(one))) { // linux supports this, so why not - might fail on other systems + if (setsockopt(socketFd, IPPROTO_IP, GEN_IP_PKTINFO, &one, sizeof(one)) == 0) { // linux supports this, so why not - might fail on other systems g_fromtosockets.insert(socketFd); } } #ifdef IPV6_RECVPKTINFO if (address.sin4.sin_family == AF_INET6) { - if (!setsockopt(socketFd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one))) { + if (setsockopt(socketFd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)) == 0) { g_fromtosockets.insert(socketFd); } } #endif if (address.sin6.sin6_family == AF_INET6 && setsockopt(socketFd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)) < 0) { int err = errno; - SLOG(g_log << Logger::Error << "Failed to set IPv6 socket to IPv6 only, continuing anyhow: " << strerror(err) << endl, + SLOG(g_log << Logger::Error << "Failed to set IPv6 socket to IPv6 only, continuing anyhow: " << stringerror(err) << endl, log->error(Logr::Error, "Failed to set IPv6 socket to IPv6 only, continuing anyhow")); } } @@ -2638,7 +2648,7 @@ void makeUDPServerSockets(deferredAdd_t& deferredAdds, Logr::log_t log) } socklen_t socklen = address.getSocklen(); - if (::bind(socketFd, (struct sockaddr*)&address, socklen) < 0) { + if (::bind(socketFd, reinterpret_cast(&address), socklen) < 0) { // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) throw PDNSException("Resolver binding to server socket on " + address.toStringWithPort() + ": " + stringerror()); } @@ -2662,10 +2672,10 @@ static bool trySendingQueryToWorker(unsigned int target, ThreadMSG* tmsg) const auto& tps = targetInfo.pipes; - ssize_t written = write(tps.writeQueriesToThread, &tmsg, sizeof(tmsg)); + ssize_t written = write(tps.writeQueriesToThread, &tmsg, sizeof(tmsg)); // NOLINT: correct sizeof if (written > 0) { - if (static_cast(written) != sizeof(tmsg)) { - delete tmsg; + if (static_cast(written) != sizeof(tmsg)) { // NOLINT: correct sizeof + delete tmsg; // NOLINT: pointer ownership unixDie("write to thread pipe returned wrong size or error"); } } @@ -2674,10 +2684,8 @@ static bool trySendingQueryToWorker(unsigned int target, ThreadMSG* tmsg) if (error == EAGAIN || error == EWOULDBLOCK) { return false; } - else { - delete tmsg; - unixDie("write to thread pipe returned wrong size or error:" + std::to_string(error)); - } + delete tmsg; // NOLINT: pointer ownership + unixDie("write to thread pipe returned wrong size or error:" + std::to_string(error)); } return true; @@ -2685,16 +2693,16 @@ static bool trySendingQueryToWorker(unsigned int target, ThreadMSG* tmsg) static unsigned int getWorkerLoad(size_t workerIdx) { - const auto mt = RecThreadInfo::info(RecThreadInfo::numHandlers() + RecThreadInfo::numDistributors() + workerIdx).mt; - if (mt != nullptr) { - return mt->numProcesses(); + const auto* multiThreader = RecThreadInfo::info(RecThreadInfo::numHandlers() + RecThreadInfo::numDistributors() + workerIdx).mt; + if (multiThreader != nullptr) { + return multiThreader->numProcesses(); } return 0; } static unsigned int selectWorker(unsigned int hash) { - assert(RecThreadInfo::numWorkers() != 0); + assert(RecThreadInfo::numWorkers() != 0); // NOLINT: assert implementation if (g_balancingFactor == 0) { return RecThreadInfo::numHandlers() + RecThreadInfo::numDistributors() + (hash % RecThreadInfo::numWorkers()); } @@ -2730,16 +2738,16 @@ void distributeAsyncFunction(const string& packet, const pipefunc_t& func) _exit(1); } - bool ok; - unsigned int hash = hashQuestion(reinterpret_cast(packet.data()), packet.length(), g_disthashseed, ok); - if (!ok) { + bool hashOK = false; + unsigned int hash = hashQuestion(reinterpret_cast(packet.data()), packet.length(), g_disthashseed, hashOK); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + if (!hashOK) { // hashQuestion does detect invalid names, so we might as well punt here instead of in the worker thread t_Counters.at(rec::Counter::ignoredCount)++; throw MOADNSException("too-short (" + std::to_string(packet.length()) + ") or invalid name"); } unsigned int target = selectWorker(hash); - ThreadMSG* tmsg = new ThreadMSG(); + ThreadMSG* tmsg = new ThreadMSG(); // NOLINT: pointer ownership tmsg->func = func; tmsg->wantAnswer = false; @@ -2753,7 +2761,7 @@ void distributeAsyncFunction(const string& packet, const pipefunc_t& func) if (!trySendingQueryToWorker(newTarget, tmsg)) { t_Counters.at(rec::Counter::queryPipeFullDrops)++; - delete tmsg; + delete tmsg; // NOLINT: pointer ownership } } // coverity[leaked_storage] @@ -2765,39 +2773,40 @@ static void doResends(MT_t::waiters_t::iterator& iter, const std::shared_ptrkey->closed = true; - if (iter->key->chain.empty()) + if (iter->key->chain.empty()) { return; - for (PacketID::chain_t::iterator i = iter->key->chain.begin(); i != iter->key->chain.end(); ++i) { - auto r = std::make_shared(*resend); - r->fd = -1; - r->id = *i; - MT->sendEvent(r, &content); + } + for (auto i = iter->key->chain.begin(); i != iter->key->chain.end(); ++i) { + auto packetID = std::make_shared(*resend); + packetID->fd = -1; + packetID->id = *i; + g_multiTasker->sendEvent(packetID, &content); t_Counters.at(rec::Counter::chainResends)++; } } -static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var) +static void handleUDPServerResponse(int fileDesc, FDMultiplexer::funcparam_t& var) { - std::shared_ptr pid = boost::any_cast>(var); + auto pid = boost::any_cast>(var); PacketBuffer packet; packet.resize(g_outgoingEDNSBufsize); ComboAddress fromaddr; socklen_t addrlen = sizeof(fromaddr); - ssize_t len = recvfrom(fd, &packet.at(0), packet.size(), 0, reinterpret_cast(&fromaddr), &addrlen); + ssize_t len = recvfrom(fileDesc, &packet.at(0), packet.size(), 0, reinterpret_cast(&fromaddr), &addrlen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) const ssize_t signed_sizeof_sdnsheader = sizeof(dnsheader); if (len < 0) { // len < 0: error on socket - t_udpclientsocks->returnSocket(fd); + t_udpclientsocks->returnSocket(fileDesc); PacketBuffer empty; - MT_t::waiters_t::iterator iter = MT->d_waiters.find(pid); - if (iter != MT->d_waiters.end()) { + MT_t::waiters_t::iterator iter = g_multiTasker->d_waiters.find(pid); + if (iter != g_multiTasker->d_waiters.end()) { doResends(iter, pid, empty); } - MT->sendEvent(pid, &empty); // this denotes error (does retry lookup using other NS) + g_multiTasker->sendEvent(pid, &empty); // this denotes error (does retry lookup using other NS) return; } @@ -2814,28 +2823,28 @@ static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var) // We have at least a full header packet.resize(len); - dnsheader dh; - memcpy(&dh, &packet.at(0), sizeof(dh)); + dnsheader dnsheader{}; + memcpy(&dnsheader, &packet.at(0), sizeof(dnsheader)); auto pident = std::make_shared(); pident->remote = fromaddr; - pident->id = dh.id; - pident->fd = fd; + pident->id = dnsheader.id; + pident->fd = fileDesc; - if (!dh.qr && g_logCommonErrors) { + if (!dnsheader.qr && g_logCommonErrors) { SLOG(g_log << Logger::Notice << "Not taking data from question on outgoing socket from " << fromaddr.toStringWithPort() << endl, g_slogout->info(Logr::Error, "Not taking data from question on outgoing socket", "from", Logging::Loggable(fromaddr))); } - if (!dh.qdcount || // UPC, Nominum, very old BIND on FormErr, NSD - !dh.qr) { // one weird server + if (dnsheader.qdcount == 0U || // UPC, Nominum, very old BIND on FormErr, NSD + dnsheader.qr == 0U) { // one weird server pident->domain.clear(); pident->type = 0; } else { try { if (len > signed_sizeof_sdnsheader) { - pident->domain = DNSName(reinterpret_cast(packet.data()), len, static_cast(sizeof(dnsheader)), false, &pident->type); // don't copy this from above - we need to do the actual read + pident->domain = DNSName(reinterpret_cast(packet.data()), static_cast(len), static_cast(sizeof(dnsheader)), false, &pident->type); // don't copy this from above - we need to do the actual read // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) } else { // len == sizeof(dnsheader), only header case @@ -2854,45 +2863,45 @@ static void handleUDPServerResponse(int fd, FDMultiplexer::funcparam_t& var) } if (!pident->domain.empty()) { - MT_t::waiters_t::iterator iter = MT->d_waiters.find(pident); - if (iter != MT->d_waiters.end()) { + MT_t::waiters_t::iterator iter = g_multiTasker->d_waiters.find(pident); + if (iter != g_multiTasker->d_waiters.end()) { doResends(iter, pident, packet); } } retryWithName: - if (pident->domain.empty() || MT->sendEvent(pident, &packet) == 0) { + if (pident->domain.empty() || g_multiTasker->sendEvent(pident, &packet) == 0) { /* we did not find a match for this response, something is wrong */ // we do a full scan for outstanding queries on unexpected answers. not too bad since we only accept them on the right port number, which is hard enough to guess - for (MT_t::waiters_t::iterator mthread = MT->d_waiters.begin(); mthread != MT->d_waiters.end(); ++mthread) { - if (pident->fd == mthread->key->fd && mthread->key->remote == pident->remote && mthread->key->type == pident->type && pident->domain == mthread->key->domain) { + for (const auto & d_waiter : g_multiTasker->d_waiters) { + if (pident->fd == d_waiter.key->fd && d_waiter.key->remote == pident->remote && d_waiter.key->type == pident->type && pident->domain == d_waiter.key->domain) { /* we are expecting an answer from that exact source, on that exact port (since we are using connected sockets), for that qname/qtype, but with a different message ID. That smells like a spoofing attempt. For now we will just increase the counter and will deal with that later. */ - mthread->key->nearMisses++; + d_waiter.key->nearMisses++; } // be a bit paranoid here since we're weakening our matching - if (pident->domain.empty() && !mthread->key->domain.empty() && !pident->type && mthread->key->type && pident->id == mthread->key->id && mthread->key->remote == pident->remote) { + if (pident->domain.empty() && !d_waiter.key->domain.empty() && pident->type == 0 && d_waiter.key->type != 0 && pident->id == d_waiter.key->id && d_waiter.key->remote == pident->remote) { // cerr<<"Empty response, rest matches though, sending to a waiter"<domain = mthread->key->domain; - pident->type = mthread->key->type; - goto retryWithName; // note that this only passes on an error, lwres will still reject the packet + pident->domain = d_waiter.key->domain; + pident->type = d_waiter.key->type; + goto retryWithName; // note that this only passes on an error, lwres will still reject the packet NOLINT(cppcoreguidelines-avoid-goto) } } t_Counters.at(rec::Counter::unexpectedCount)++; // if we made it here, it really is an unexpected answer if (g_logCommonErrors) { - SLOG(g_log << Logger::Warning << "Discarding unexpected packet from " << fromaddr.toStringWithPort() << ": " << (pident->domain.empty() ? "" : pident->domain.toString()) << ", " << pident->type << ", " << MT->d_waiters.size() << " waiters" << endl, + SLOG(g_log << Logger::Warning << "Discarding unexpected packet from " << fromaddr.toStringWithPort() << ": " << (pident->domain.empty() ? "" : pident->domain.toString()) << ", " << pident->type << ", " << g_multiTasker->d_waiters.size() << " waiters" << endl, g_slogudpin->info(Logr::Warning, "Discarding unexpected packet", "from", Logging::Loggable(fromaddr), "qname", Logging::Loggable(pident->domain), "qtype", Logging::Loggable(QType(pident->type)), - "waiters", Logging::Loggable(MT->d_waiters.size()))); + "waiters", Logging::Loggable(g_multiTasker->d_waiters.size()))); } } - else if (fd >= 0) { + else if (fileDesc >= 0) { /* we either found a waiter (1) or encountered an issue (-1), it's up to us to clean the socket anyway */ - t_udpclientsocks->returnSocket(fd); + t_udpclientsocks->returnSocket(fileDesc); } } diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 225c72d80a0d..f46d32eab1c6 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2573,7 +2573,7 @@ static void recLoop() auto& threadInfo = RecThreadInfo::self(); while (!RecursorControlChannel::stop) { - while (MT->schedule(&g_now)) { + while (g_multiTasker->schedule(&g_now)) { ; // MTasker letting the mthreads do their thing } @@ -2584,7 +2584,7 @@ static void recLoop() { }; Utility::gettimeofday(&start); - MT->makeThread(houseKeeping, nullptr); + g_multiTasker->makeThread(houseKeeping, nullptr); if (!threadInfo.isTaskThread()) { struct timeval stop { @@ -2619,7 +2619,7 @@ static void recLoop() Utility::gettimeofday(&g_now, nullptr); if ((g_now.tv_sec - last_carbon) >= carbonInterval) { - MT->makeThread(doCarbonDump, nullptr); + g_multiTasker->makeThread(doCarbonDump, nullptr); last_carbon = g_now.tv_sec; } } @@ -2713,8 +2713,8 @@ static void recursorThread() t_bogusqueryring = std::make_unique>>(); t_bogusqueryring->set_capacity(ringsize); } - MT = std::make_unique(::arg().asNum("stack-size"), ::arg().asNum("stack-cache-size")); - threadInfo.mt = MT.get(); + g_multiTasker = std::make_unique(::arg().asNum("stack-size"), ::arg().asNum("stack-cache-size")); + threadInfo.mt = g_multiTasker.get(); /* start protobuf export threads if needed */ auto luaconfsLocal = g_luaconfs.getLocal(); diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index 303306837f51..4d0ac45a41c3 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -169,10 +169,10 @@ public: { } - LWResult::Result getSocket(const ComboAddress& toaddr, int* fd); + LWResult::Result getSocket(const ComboAddress& toaddr, int* fileDesc); // return a socket to the pool, or simply erase it - void returnSocket(int fd); + void returnSocket(int fileDesc); private: // returns -1 for errors which might go away, throws for ones that won't @@ -186,7 +186,7 @@ enum class PaddingMode }; typedef MTasker, PacketBuffer, PacketIDCompare> MT_t; -extern thread_local std::unique_ptr MT; // the big MTasker +extern thread_local std::unique_ptr g_multiTasker; // the big MTasker extern std::unique_ptr g_packetCache; using RemoteLoggerStats_t = std::unordered_map; @@ -284,7 +284,7 @@ extern thread_local std::unique_ptr t_tcpClientCounts; inline MT_t* getMT() { - return MT ? MT.get() : nullptr; + return g_multiTasker ? g_multiTasker.get() : nullptr; } /* this function is called with both a string and a vector representing a packet */ @@ -540,7 +540,7 @@ void protobufLogResponse(const struct dnsheader* header, LocalStateHolder& meta, const RecEventTrace& eventTrace); void requestWipeCaches(const DNSName& canon); -void startDoResolve(void* p); +void startDoResolve(void*); bool expectProxyProtocol(const ComboAddress& from); void finishTCPReply(std::unique_ptr&, bool hadError, bool updateInFlight); void checkFastOpenSysctl(bool active, Logr::log_t); diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index d814d5721696..948a709b98eb 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -44,7 +44,8 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v cerr << []() { timeval t; gettimeofday(&t, nullptr); return t.tv_sec % 10 + t.tv_usec/1000000.0; }() << " FD " << (tcpsock) << ' ' << x; \ } while (0) #else -#define TCPLOG(pid, x) +// We do not define this as empty since that produces a duplicate case label warning from clang-tidy +#define TCPLOG(pid, x) while (false) { cerr << x; } // NOLINT(cppcoreguidelines-macro-usage,bugprone-macro-parentheses) #endif std::atomic TCPConnection::s_currentConnections; @@ -278,7 +279,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v } if (t_allowFrom && !t_allowFrom->match(&conn->d_mappedSource)) { if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping TCP query from " << conn->d_mappedSource.toString() << ", address not matched by allow-from" << endl, + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP query from " << conn->d_mappedSource.toString() << ", address not matched by allow-from" << endl, g_slogtcpin->info(Logr::Error, "Dropping TCP query, address not matched by allow-from", "remote", Logging::Loggable(conn->d_remote))); } @@ -475,7 +476,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v bool ipf = t_pdl->ipfilter(comboWriter->d_source, comboWriter->d_destination, *dnsheader, comboWriter->d_eventTrace); if (ipf) { if (!g_quiet) { - SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " [" << MT->getTid() << "/" << MT->numProcesses() << "] DROPPED TCP question from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << " based on policy" << endl, + SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " [" << g_multiTasker->getTid() << "/" << g_multiTasker->numProcesses() << "] DROPPED TCP question from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << " based on policy" << endl, g_slogtcpin->info(Logr::Info, "Dropped TCP question based on policy", "remote", Logging::Loggable(conn->d_remote), "source", Logging::Loggable(comboWriter->d_source))); } t_Counters.at(rec::Counter::policyDrops)++; @@ -520,7 +521,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { if (!t_allowNotifyFrom || !t_allowNotifyFrom->match(comboWriter->d_mappedSource)) { if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", address not matched by allow-notify-from" << endl, + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", address not matched by allow-notify-from" << endl, g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, address not matched by allow-notify-from", "source", Logging::Loggable(comboWriter->d_mappedSource))); } @@ -530,7 +531,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v if (!isAllowNotifyForZone(qname)) { if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", for " << qname.toLogString() << ", zone not matched by allow-notify-for" << endl, + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", for " << qname.toLogString() << ", zone not matched by allow-notify-for" << endl, g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, zone not matched by allow-notify-for", "source", Logging::Loggable(comboWriter->d_mappedSource), "zone", Logging::Loggable(qname))); } @@ -612,7 +613,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v t_fdm->setReadTTD(fileDesc, ttd, g_tcpTimeout); } tcpGuard.keep(); - MT->makeThread(startDoResolve, comboWriter.release()); // deletes dc + g_multiTasker->makeThread(startDoResolve, comboWriter.release()); // deletes dc } // good query } // read full query } // reading query @@ -628,7 +629,7 @@ void handleNewTCPQuestion(int fileDesc, [[maybe_unused]] FDMultiplexer::funcpara socklen_t addrlen = sizeof(addr); int newsock = accept(fileDesc, reinterpret_cast(&addr), &addrlen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) if (newsock >= 0) { - if (MT->numProcesses() > g_maxMThreads) { + if (g_multiTasker->numProcesses() > g_maxMThreads) { t_Counters.at(rec::Counter::overCapacityDrops)++; try { closesocket(newsock); @@ -654,7 +655,7 @@ void handleNewTCPQuestion(int fileDesc, [[maybe_unused]] FDMultiplexer::funcpara } if (!fromProxyProtocolSource && t_allowFrom && !t_allowFrom->match(&mappedSource)) { if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << MT->getTid() << "] dropping TCP query from " << mappedSource.toString() << ", address neither matched by allow-from nor proxy-protocol-from" << endl, + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP query from " << mappedSource.toString() << ", address neither matched by allow-from nor proxy-protocol-from" << endl, g_slogtcpin->info(Logr::Error, "dropping TCP query address neither matched by allow-from nor proxy-protocol-from", "source", Logging::Loggable(mappedSource))); } t_Counters.at(rec::Counter::unauthorizedTCP)++; @@ -809,7 +810,7 @@ static void TCPIOHandlerIO(int fileDesc, FDMultiplexer::funcparam_t& var) pid->inMSG.resize(pid->inPos); // old content (if there) + new bytes read, only relevant for the inIncompleteOkay case newstate = IOState::Done; TCPIOHandlerStateChange(pid->lowState, newstate, pid); - MT->sendEvent(pid, &pid->inMSG); + g_multiTasker->sendEvent(pid, &pid->inMSG); return; } break; @@ -825,7 +826,7 @@ static void TCPIOHandlerIO(int fileDesc, FDMultiplexer::funcparam_t& var) TCPLOG(pid->tcpsock, "read exception..." << e.what() << endl); PacketBuffer empty; TCPIOHandlerStateChange(pid->lowState, newstate, pid); - MT->sendEvent(pid, &empty); // this conveys error status + g_multiTasker->sendEvent(pid, &empty); // this conveys error status return; } break; @@ -840,7 +841,7 @@ static void TCPIOHandlerIO(int fileDesc, FDMultiplexer::funcparam_t& var) case IOState::Done: { TCPLOG(pid->tcpsock, "tryWrite: Done" << endl); TCPIOHandlerStateChange(pid->lowState, newstate, pid); - MT->sendEvent(pid, &pid->outMSG); // send back what we sent to convey everything is ok + g_multiTasker->sendEvent(pid, &pid->outMSG); // send back what we sent to convey everything is ok return; } case IOState::NeedRead: @@ -859,7 +860,7 @@ static void TCPIOHandlerIO(int fileDesc, FDMultiplexer::funcparam_t& var) TCPLOG(pid->tcpsock, "write exception..." << e.what() << endl); PacketBuffer sent; TCPIOHandlerStateChange(pid->lowState, newstate, pid); - MT->sendEvent(pid, &sent); // we convey error status by sending empty string + g_multiTasker->sendEvent(pid, &sent); // we convey error status by sending empty string return; } break; @@ -937,7 +938,7 @@ LWResult::Result asendtcp(const PacketBuffer& data, shared_ptr& ha TCPIOHandlerStateChange(IOState::Done, state, pident); PacketBuffer packet; - int ret = MT->waitEvent(pident, &packet, g_networkTimeoutMsec); + int ret = g_multiTasker->waitEvent(pident, &packet, g_networkTimeoutMsec); TCPLOG(pident->tcpsock, "asendtcp waitEvent returned " << ret << ' ' << packet.size() << '/' << data.size() << ' '); if (ret == 0) { TCPLOG(pident->tcpsock, "timeout" << endl); @@ -1007,7 +1008,7 @@ LWResult::Result arecvtcp(PacketBuffer& data, const size_t len, shared_ptrlowState TCPIOHandlerStateChange(IOState::Done, state, pident); - int ret = MT->waitEvent(pident, &data, g_networkTimeoutMsec); + int ret = g_multiTasker->waitEvent(pident, &data, g_networkTimeoutMsec); TCPLOG(pident->tcpsock, "arecvtcp " << ret << ' ' << data.size() << ' '); if (ret == 0) { TCPLOG(pident->tcpsock, "timeout" << endl); diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 38d823d686b8..c4a8bace6a93 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -905,11 +905,11 @@ extern bool g_lowercaseOutgoing; std::string reloadZoneConfiguration(); typedef std::function pipefunc_t; void broadcastFunction(const pipefunc_t& func); -void distributeAsyncFunction(const std::string& question, const pipefunc_t& func); +void distributeAsyncFunction(const std::string& packet, const pipefunc_t& func); int directResolve(const DNSName& qname, QType qtype, QClass qclass, vector& ret, const shared_ptr& pdl, Logr::log_t); int directResolve(const DNSName& qname, QType qtype, QClass qclass, vector& ret, const shared_ptr& pdl, bool qnamemin, Logr::log_t); -int followCNAMERecords(std::vector& ret, const QType qtype, int oldret); +int followCNAMERecords(std::vector& ret, QType qtype, int rcode); int getFakeAAAARecords(const DNSName& qname, ComboAddress prefix, vector& ret); int getFakePTRRecords(const DNSName& qname, vector& ret); From 2257761941fdbe1a9e6c45b08310f88db2207a9c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 14 Jun 2023 09:56:56 +0200 Subject: [PATCH 357/909] Reformat --- pdns/recursordist/pdns_recursor.cc | 126 ++++++++++++++++------------- pdns/recursordist/rec-tcp.cc | 5 +- 2 files changed, 76 insertions(+), 55 deletions(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index f56375739717..2ae64233b7a8 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -211,7 +211,7 @@ static void handleGenUDPQueryResponse(int fileDesc, FDMultiplexer::funcparam_t& ComboAddress fromaddr; socklen_t addrlen = sizeof(fromaddr); - ssize_t ret = recvfrom(fileDesc, resp.data(), resp.size(), 0, reinterpret_cast(&fromaddr), &addrlen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + ssize_t ret = recvfrom(fileDesc, resp.data(), resp.size(), 0, reinterpret_cast(&fromaddr), &addrlen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) if (fromaddr != pident->remote) { SLOG(g_log << Logger::Notice << "Response received from the wrong remote host (" << fromaddr.toStringWithPort() << " instead of " << pident->remote.toStringWithPort() << "), discarding" << endl, g_slog->withName("lua")->info(Logr::Notice, "Response received from the wrong remote host. discarding", "method", Logging::Loggable("GenUDPQueryResponse"), "fromaddr", Logging::Loggable(fromaddr), "expected", Logging::Loggable(pident->remote))); @@ -562,7 +562,7 @@ static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy if (g_logCommonErrors) { SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << comboWriter->getRemote() << " during resolve of the custom filter policy '" << appliedPolicy.getName() << "' while resolving '" << comboWriter->d_mdp.d_qname << "' because: " << e.reason << endl, resolver.d_slog->error(Logr::Notice, e.reason, "Sending SERVFAIL during resolve of the custom filter policy", - "policyName", Logging::Loggable(appliedPolicy.getName()), "exception", Logging::Loggable("ImmediateServFailException"))); + "policyName", Logging::Loggable(appliedPolicy.getName()), "exception", Logging::Loggable("ImmediateServFailException"))); } res = RCode::ServFail; break; @@ -571,7 +571,7 @@ static PolicyResult handlePolicyHit(const DNSFilterEngine::Policy& appliedPolicy if (g_logCommonErrors) { SLOG(g_log << Logger::Notice << "Sending SERVFAIL to " << comboWriter->getRemote() << " during resolve of the custom filter policy '" << appliedPolicy.getName() << "' while resolving '" << comboWriter->d_mdp.d_qname << "' because another RPZ policy was hit" << endl, resolver.d_slog->info(Logr::Notice, "Sending SERVFAIL during resolve of the custom filter policy because another RPZ policy was hit", - "policyName", Logging::Loggable(appliedPolicy.getName()), "exception", Logging::Loggable("PolicyHitException"))); + "policyName", Logging::Loggable(appliedPolicy.getName()), "exception", Logging::Loggable("PolicyHitException"))); } res = RCode::ServFail; break; @@ -908,7 +908,7 @@ static uint32_t capPacketCacheTTL(const struct dnsheader& hdr, uint32_t ttl, boo void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 { - auto comboWriter = std::unique_ptr(reinterpret_cast(arg)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + auto comboWriter = std::unique_ptr(reinterpret_cast(arg)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) SyncRes resolver(comboWriter->d_now); try { if (t_queryring) { @@ -1110,11 +1110,11 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi dnsQuestion.fromAuthIP = &resolver.d_fromAuthIP; resolver.d_slog = resolver.d_slog->withValues("qname", Logging::Loggable(comboWriter->d_mdp.d_qname), - "qtype", Logging::Loggable(QType(comboWriter->d_mdp.d_qtype)), - "remote", Logging::Loggable(comboWriter->getRemote()), - "proto", Logging::Loggable(comboWriter->d_tcp ? "tcp" : "udp"), - "ecs", Logging::Loggable(comboWriter->d_ednssubnet.source.empty() ? "" : comboWriter->d_ednssubnet.source.toString()), - "mtid", Logging::Loggable(g_multiTasker->getTid())); + "qtype", Logging::Loggable(QType(comboWriter->d_mdp.d_qtype)), + "remote", Logging::Loggable(comboWriter->getRemote()), + "proto", Logging::Loggable(comboWriter->d_tcp ? "tcp" : "udp"), + "ecs", Logging::Loggable(comboWriter->d_ednssubnet.source.empty() ? "" : comboWriter->d_ednssubnet.source.toString()), + "mtid", Logging::Loggable(g_multiTasker->getTid())); RunningResolveGuard tcpGuard(comboWriter); if (ednsExtRCode != 0 || comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { @@ -1446,7 +1446,7 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi } bool needCommit = false; - for (const auto & record : ret) { + for (const auto& record : ret) { if (!DNSSECOK && (record.d_type == QType::NSEC3 || ((record.d_type == QType::RRSIG || record.d_type == QType::NSEC) && ((comboWriter->d_mdp.d_qtype != record.d_type && comboWriter->d_mdp.d_qtype != QType::ANY) || (record.d_place != DNSResourceRecord::ANSWER && record.d_place != DNSResourceRecord::ADDITIONAL))))) { continue; } @@ -1483,7 +1483,9 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi #ifdef HAVE_FSTRM if (hasUDR) { if (isEnabledForUDRs(t_nodFrameStreamServersInfo.servers)) { - struct timespec timeSpec{}; + struct timespec timeSpec + { + }; std::string str; if (g_useKernelTimestamp && comboWriter->d_kernelTimestamp.tv_sec != 0) { TIMEVAL_TO_TIMESPEC(&comboWriter->d_kernelTimestamp, &timeSpec); // NOLINT @@ -1491,7 +1493,7 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi else { TIMEVAL_TO_TIMESPEC(&comboWriter->d_now, &timeSpec); // NOLINT } - DnstapMessage message(str, DnstapMessage::MessageType::resolver_response, SyncRes::s_serverID, &comboWriter->d_source, &comboWriter->d_destination, comboWriter->d_tcp ? DnstapMessage::ProtocolType::DoTCP : DnstapMessage::ProtocolType::DoUDP, reinterpret_cast(&*packet.begin()), packet.size(), &timeSpec, nullptr, comboWriter->d_mdp.d_qname); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + DnstapMessage message(str, DnstapMessage::MessageType::resolver_response, SyncRes::s_serverID, &comboWriter->d_source, &comboWriter->d_destination, comboWriter->d_tcp ? DnstapMessage::ProtocolType::DoTCP : DnstapMessage::ProtocolType::DoUDP, reinterpret_cast(&*packet.begin()), packet.size(), &timeSpec, nullptr, comboWriter->d_mdp.d_qname); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) for (auto& logger : *(t_nodFrameStreamServersInfo.servers)) { if (logger->logUDRs()) { @@ -1640,7 +1642,9 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi nod = true; #ifdef HAVE_FSTRM if (isEnabledForNODs(t_nodFrameStreamServersInfo.servers)) { - struct timespec timeSpec{}; + struct timespec timeSpec + { + }; std::string str; if (g_useKernelTimestamp && comboWriter->d_kernelTimestamp.tv_sec != 0) { TIMEVAL_TO_TIMESPEC(&comboWriter->d_kernelTimestamp, &timeSpec); // NOLINT @@ -1695,7 +1699,7 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi minTTL = capPacketCacheTTL(*packetWriter.getHeader(), minTTL, seenAuthSOA); g_packetCache->insertResponsePacket(comboWriter->d_tag, comboWriter->d_qhash, std::move(comboWriter->d_query), comboWriter->d_mdp.d_qname, comboWriter->d_mdp.d_qtype, comboWriter->d_mdp.d_qclass, - string(reinterpret_cast(&*packet.begin()), packet.size()), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + string(reinterpret_cast(&*packet.begin()), packet.size()), // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) g_now.tv_sec, minTTL, dnsQuestion.validationState, @@ -1707,10 +1711,14 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi } if (!comboWriter->d_tcp) { - struct msghdr msgh{}; - struct iovec iov{}; + struct msghdr msgh + { + }; + struct iovec iov + { + }; cmsgbuf_aligned cbuf{}; - fillMSGHdr(&msgh, &iov, &cbuf, 0, reinterpret_cast(&*packet.begin()), packet.size(), &comboWriter->d_remote); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + fillMSGHdr(&msgh, &iov, &cbuf, 0, reinterpret_cast(&*packet.begin()), packet.size(), &comboWriter->d_remote); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) msgh.msg_control = nullptr; if (g_fromtosockets.count(comboWriter->d_socket) > 0) { @@ -1812,20 +1820,20 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi } else { resolver.d_slog->info(Logr::Info, "Answer", "rd", Logging::Loggable(comboWriter->d_mdp.d_header.rd), - "answers", Logging::Loggable(ntohs(packetWriter.getHeader()->ancount)), - "additional", Logging::Loggable(ntohs(packetWriter.getHeader()->arcount)), - "outqueries", Logging::Loggable(resolver.d_outqueries), - "netms", Logging::Loggable(resolver.d_totUsec / 1000.0), - "totms", Logging::Loggable(static_cast(spentUsec) / 1000.0), - "throttled", Logging::Loggable(resolver.d_throttledqueries), - "timeouts", Logging::Loggable(resolver.d_timeouts), - "tcpout", Logging::Loggable(resolver.d_tcpoutqueries), - "dotout", Logging::Loggable(resolver.d_dotoutqueries), - "rcode", Logging::Loggable(res), - "validationState", Logging::Loggable(resolver.getValidationState()), - "answer-is-variable", Logging::Loggable(resolver.wasVariable()), - "into-packetcache", Logging::Loggable(intoPC), - "maxdepth", Logging::Loggable(resolver.d_maxdepth)); + "answers", Logging::Loggable(ntohs(packetWriter.getHeader()->ancount)), + "additional", Logging::Loggable(ntohs(packetWriter.getHeader()->arcount)), + "outqueries", Logging::Loggable(resolver.d_outqueries), + "netms", Logging::Loggable(resolver.d_totUsec / 1000.0), + "totms", Logging::Loggable(static_cast(spentUsec) / 1000.0), + "throttled", Logging::Loggable(resolver.d_throttledqueries), + "timeouts", Logging::Loggable(resolver.d_timeouts), + "tcpout", Logging::Loggable(resolver.d_tcpoutqueries), + "dotout", Logging::Loggable(resolver.d_dotoutqueries), + "rcode", Logging::Loggable(res), + "validationState", Logging::Loggable(resolver.getValidationState()), + "answer-is-variable", Logging::Loggable(resolver.wasVariable()), + "into-packetcache", Logging::Loggable(intoPC), + "maxdepth", Logging::Loggable(resolver.d_maxdepth)); } } @@ -1898,14 +1906,14 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi if (g_multiTasker->getMaxStackUsage() >= stackSizeThreshold) { SLOG(g_log << Logger::Error << "Reached mthread stack usage of 90%: " << g_multiTasker->getMaxStackUsage() << " " << makeLoginfo(comboWriter) << " after " << resolver.d_outqueries << " out queries, " << resolver.d_tcpoutqueries << " TCP out queries, " << resolver.d_dotoutqueries << " DoT out queries" << endl, resolver.d_slog->info(Logr::Error, "Reached mthread stack usage of 90%", - "stackUsage", Logging::Loggable(g_multiTasker->getMaxStackUsage()), - "outqueries", Logging::Loggable(resolver.d_outqueries), - "netms", Logging::Loggable(resolver.d_totUsec / 1000.0), - "throttled", Logging::Loggable(resolver.d_throttledqueries), - "timeouts", Logging::Loggable(resolver.d_timeouts), - "tcpout", Logging::Loggable(resolver.d_tcpoutqueries), - "dotout", Logging::Loggable(resolver.d_dotoutqueries), - "validationState", Logging::Loggable(resolver.getValidationState()))); + "stackUsage", Logging::Loggable(g_multiTasker->getMaxStackUsage()), + "outqueries", Logging::Loggable(resolver.d_outqueries), + "netms", Logging::Loggable(resolver.d_totUsec / 1000.0), + "throttled", Logging::Loggable(resolver.d_throttledqueries), + "timeouts", Logging::Loggable(resolver.d_timeouts), + "tcpout", Logging::Loggable(resolver.d_tcpoutqueries), + "dotout", Logging::Loggable(resolver.d_dotoutqueries), + "validationState", Logging::Loggable(resolver.getValidationState()))); } t_Counters.at(rec::Counter::maxMThreadStackUsage) = max(g_multiTasker->getMaxStackUsage(), t_Counters.at(rec::Counter::maxMThreadStackUsage)); t_Counters.updateSnap(g_regressionTestMode); @@ -1932,7 +1940,7 @@ void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* } pos += 1; - const auto* drh = reinterpret_cast(&question.at(pos)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + const auto* drh = reinterpret_cast(&question.at(pos)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) pos += sizeof(dnsrecordheader); if (pos >= questionLen) { @@ -1945,7 +1953,7 @@ void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* size_t ecsStartPosition = 0; size_t ecsLen = 0; /* we need to pass the record len */ - int res = getEDNSOption(reinterpret_cast(&question.at(pos - sizeof(drh->d_clen))), questionLen - pos + sizeof(drh->d_clen), EDNSOptionCode::ECS, &ecsStartPosition, &ecsLen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + int res = getEDNSOption(reinterpret_cast(&question.at(pos - sizeof(drh->d_clen))), questionLen - pos + sizeof(drh->d_clen), EDNSOptionCode::ECS, &ecsStartPosition, &ecsLen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) if (res == 0 && ecsLen > 4) { EDNSSubnetOpts eso; if (getEDNSSubnetOptsFromString(&question.at(pos - sizeof(drh->d_clen) + ecsStartPosition + 4), ecsLen - 4, &eso)) { @@ -1956,7 +1964,7 @@ void getQNameAndSubnet(const std::string& question, DNSName* dnsname, uint16_t* } else { /* we need to pass the record len */ - int res = getEDNSOptions(reinterpret_cast(&question.at(pos - sizeof(drh->d_clen))), questionLen - pos + (sizeof(drh->d_clen)), *options); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + int res = getEDNSOptions(reinterpret_cast(&question.at(pos - sizeof(drh->d_clen))), questionLen - pos + (sizeof(drh->d_clen)), *options); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) if (res == 0) { const auto& iter = options->find(EDNSOptionCode::ECS); if (iter != options->end() && !iter->second.values.empty() && iter->second.values.at(0).content != nullptr && iter->second.values.at(0).size > 0) { @@ -2218,10 +2226,14 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr "qname", Logging::Loggable(qname), "qtype", Logging::Loggable(QType(qtype)), "source", Logging::Loggable(source), "remote", Logging::Loggable(fromaddr))); } - struct msghdr msgh{}; - struct iovec iov{}; + struct msghdr msgh + { + }; + struct iovec iov + { + }; cmsgbuf_aligned cbuf{}; - fillMSGHdr(&msgh, &iov, &cbuf, 0, reinterpret_cast(response.data()), response.length(), const_cast(&fromaddr)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-type-const-cast) + fillMSGHdr(&msgh, &iov, &cbuf, 0, reinterpret_cast(response.data()), response.length(), const_cast(&fromaddr)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-type-const-cast) msgh.msg_control = nullptr; if (g_fromtosockets.count(fileDesc) != 0) { @@ -2244,7 +2256,9 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr << stringerror(sendErr) << endl, g_slogudpin->error(Logr::Error, sendErr, "Sending UDP reply to client failed", "source", Logging::Loggable(source), "remote", Logging::Loggable(fromaddr))); } - struct timeval now{}; + struct timeval now + { + }; Utility::gettimeofday(&now, nullptr); uint64_t spentUsec = uSec(now - tval); t_Counters.at(rec::Histogram::cumulativeAnswers)(spentUsec); @@ -2354,8 +2368,12 @@ static void handleNewUDPQuestion(int fileDesc, FDMultiplexer::funcparam_t& /* va ComboAddress fromaddr; // the address the query is coming from ComboAddress source; // the address we assume the query is coming from, might be set by proxy protocol ComboAddress destination; // the address we assume the query was sent to, might be set by proxy protocol - struct msghdr msgh{}; - struct iovec iov{}; + struct msghdr msgh + { + }; + struct iovec iov + { + }; cmsgbuf_aligned cbuf; bool firstQuery = true; std::vector proxyProtocolValues; @@ -2435,7 +2453,7 @@ static void handleNewUDPQuestion(int fileDesc, FDMultiplexer::funcparam_t& /* va } ComboAddress mappedSource = source; if (t_proxyMapping) { - if (const auto *iter = t_proxyMapping->lookup(source)) { + if (const auto* iter = t_proxyMapping->lookup(source)) { mappedSource = iter->second.address; ++iter->second.stats.netmaskMatches; } @@ -2508,7 +2526,7 @@ static void handleNewUDPQuestion(int fileDesc, FDMultiplexer::funcparam_t& /* va HarvestTimestamp(&msgh, &tval); ComboAddress destaddr; // the address the query was sent to to destaddr.reset(); // this makes sure we ignore this address if not returned by recvmsg above - const auto *loc = rplookup(g_listenSocketsAddresses, fileDesc); + const auto* loc = rplookup(g_listenSocketsAddresses, fileDesc); if (HarvestDestinationAddress(&msgh, &destaddr)) { // but.. need to get port too if (loc != nullptr) { @@ -2648,7 +2666,7 @@ void makeUDPServerSockets(deferredAdd_t& deferredAdds, Logr::log_t log) } socklen_t socklen = address.getSocklen(); - if (::bind(socketFd, reinterpret_cast(&address), socklen) < 0) { // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + if (::bind(socketFd, reinterpret_cast(&address), socklen) < 0) { // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) throw PDNSException("Resolver binding to server socket on " + address.toStringWithPort() + ": " + stringerror()); } @@ -2739,7 +2757,7 @@ void distributeAsyncFunction(const string& packet, const pipefunc_t& func) } bool hashOK = false; - unsigned int hash = hashQuestion(reinterpret_cast(packet.data()), packet.length(), g_disthashseed, hashOK); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + unsigned int hash = hashQuestion(reinterpret_cast(packet.data()), packet.length(), g_disthashseed, hashOK); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) if (!hashOK) { // hashQuestion does detect invalid names, so we might as well punt here instead of in the worker thread t_Counters.at(rec::Counter::ignoredCount)++; @@ -2793,7 +2811,7 @@ static void handleUDPServerResponse(int fileDesc, FDMultiplexer::funcparam_t& va ComboAddress fromaddr; socklen_t addrlen = sizeof(fromaddr); - ssize_t len = recvfrom(fileDesc, &packet.at(0), packet.size(), 0, reinterpret_cast(&fromaddr), &addrlen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + ssize_t len = recvfrom(fileDesc, &packet.at(0), packet.size(), 0, reinterpret_cast(&fromaddr), &addrlen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) const ssize_t signed_sizeof_sdnsheader = sizeof(dnsheader); @@ -2875,7 +2893,7 @@ static void handleUDPServerResponse(int fileDesc, FDMultiplexer::funcparam_t& va /* we did not find a match for this response, something is wrong */ // we do a full scan for outstanding queries on unexpected answers. not too bad since we only accept them on the right port number, which is hard enough to guess - for (const auto & d_waiter : g_multiTasker->d_waiters) { + for (const auto& d_waiter : g_multiTasker->d_waiters) { if (pident->fd == d_waiter.key->fd && d_waiter.key->remote == pident->remote && d_waiter.key->type == pident->type && pident->domain == d_waiter.key->domain) { /* we are expecting an answer from that exact source, on that exact port (since we are using connected sockets), for that qname/qtype, but with a different message ID. That smells like a spoofing attempt. For now we will just increase the counter and will deal with diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 948a709b98eb..70c3f9595a0f 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -45,7 +45,10 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v } while (0) #else // We do not define this as empty since that produces a duplicate case label warning from clang-tidy -#define TCPLOG(pid, x) while (false) { cerr << x; } // NOLINT(cppcoreguidelines-macro-usage,bugprone-macro-parentheses) +#define TCPLOG(pid, x) /* NOLINT(cppcoreguidelines-macro-usage) */ \ + while (false) { \ + cerr << x; /* NOLINT(bugprone-macro-parentheses) */ \ + } #endif std::atomic TCPConnection::s_currentConnections; From b26ff5312a4f260bc7de765ac3c05cb34d220661 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 29 Jun 2023 12:52:32 +0200 Subject: [PATCH 358/909] Take one suggestion form review. The others keep on producing clang-tidy issues. --- pdns/recursordist/pdns_recursor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 2ae64233b7a8..927cf06dd8e5 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -908,7 +908,7 @@ static uint32_t capPacketCacheTTL(const struct dnsheader& hdr, uint32_t ttl, boo void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 { - auto comboWriter = std::unique_ptr(reinterpret_cast(arg)); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + auto comboWriter = std::unique_ptr(static_cast(arg)); SyncRes resolver(comboWriter->d_now); try { if (t_queryring) { From 26c36ae61d3aa8d3eede694be95013d90c75a9b6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 29 Jun 2023 14:41:52 +0200 Subject: [PATCH 359/909] Prep for rec-4.9.0 --- docs/secpoll.zone | 11 +++++----- pdns/recursordist/docs/appendices/EOL.rst | 18 +++++++++------- pdns/recursordist/docs/changelog/4.9.rst | 25 +++++++++++++++++++++++ pdns/recursordist/docs/performance.rst | 2 ++ pdns/recursordist/docs/upgrade.rst | 5 ++--- 5 files changed, 46 insertions(+), 15 deletions(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index eaaaa7b20bcd..90cace64d848 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023061501 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023063001 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -330,7 +330,7 @@ recursor-4.6.2.security-status 60 IN TXT "3 Upgrade now recursor-4.6.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.6.4.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.6.5.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" -recursor-4.6.6.security-status 60 IN TXT "1 OK" +recursor-4.6.6.security-status 60 IN TXT "2 Unsupported release (EOL)" recursor-4.7.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.7.0-beta1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.7.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" @@ -349,9 +349,10 @@ recursor-4.8.1.security-status 60 IN TXT "3 Upgrade now recursor-4.8.2.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.8.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.8.4.security-status 60 IN TXT "1 OK" -recursor-4.9.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release" -recursor-4.9.0-beta1.security-status 60 IN TXT "1 Unsupported pre-release" -recursor-4.9.0-rc1.security-status 60 IN TXT "1 Unsupported pre-release" +recursor-4.9.0-alpha1.security-status 60 IN TXT "2 Unsupported pre-release" +recursor-4.9.0-beta1.security-status 60 IN TXT "2 Unsupported pre-release" +recursor-4.9.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release" +recursor-4.9.0.security-status 60 IN TXT "1 OK" ; Recursor Debian recursor-3.6.2-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/" diff --git a/pdns/recursordist/docs/appendices/EOL.rst b/pdns/recursordist/docs/appendices/EOL.rst index d4dab6877313..e826a14f2534 100644 --- a/pdns/recursordist/docs/appendices/EOL.rst +++ b/pdns/recursordist/docs/appendices/EOL.rst @@ -10,15 +10,15 @@ The two releases before that get critical updates only. Older releases are marked end of life and receive no updates at all. Pre-releases do not receive immediate security updates. -The currently supported release train of the PowerDNS Recursor is 4.8. +The currently supported release train of the PowerDNS Recursor is 4.9. + +PowerDNS Recursor 4.8 will only receive critical updates and will be +end of life after PowerDNS Recursor 4.11 or 5.1 is released. PowerDNS Recursor 4.7 will only receive critical updates and will be end of life after PowerDNS Recursor 4.10 or 5.0 is released. -PowerDNS Recursor 4.6 will only receive critical updates and will be -end of life after PowerDNS Recursor 4.9 is released. - -PowerDNS Recursor 4.0 through 4.5, 3.x, and 2.x are End of Life. +PowerDNS Recursor 4.0 through 4.6, 3.x, and 2.x are End of Life. Note: Users with a commercial agreement with PowerDNS.COM BV or Open-Xchange can receive extended support for releases which are End Of Life. If you are @@ -34,9 +34,13 @@ for details. - Release date - Critical-Only updates - End of Life + * - 4.9 + - June 30 2023 + - ~ December 2023 + - ~ December 2024 * - 4.8 - December 12 2022 - - ~ June 2023 + - June 30 2023 - ~ June 2024 * - 4.7 - May 30 2022 @@ -45,7 +49,7 @@ for details. * - 4.6 - December 17 2021 - May 30 2022 - - ~ June 2023 + - EOL June 30 2023 * - 4.5 - May 11 2021 - December 17 2021 diff --git a/pdns/recursordist/docs/changelog/4.9.rst b/pdns/recursordist/docs/changelog/4.9.rst index e6128ed64d68..263fb23579af 100644 --- a/pdns/recursordist/docs/changelog/4.9.rst +++ b/pdns/recursordist/docs/changelog/4.9.rst @@ -1,5 +1,30 @@ Changelogs for 4.9.X ==================== +.. changelog:: + :version: 4.9.0 + :released: 30th of June 2023 + + .. change:: + :tags: Bug Fixes + :pullreq: 12968 + :tickets: 12963 + + Fix qname length getting out-of-sync with qname-minimization iteration count. + + .. change:: + :tags: Bug Fixes + :pullreq: 12936 + :tickets: 12933 + + Rewrite and fix loop that checks if algorithms are available. + + .. change:: + :tags: Bug Fixes + :pullreq: 12932 + :tickets: 12928 + + Fix daemonize() to properly background the process. + .. changelog:: :version: 4.9.0-rc1 :released: 15nd of June 2023 diff --git a/pdns/recursordist/docs/performance.rst b/pdns/recursordist/docs/performance.rst index 5ab0ea07f366..4f5f6e76d15e 100644 --- a/pdns/recursordist/docs/performance.rst +++ b/pdns/recursordist/docs/performance.rst @@ -34,6 +34,8 @@ If ``SO_REUSEPORT`` support is available and :ref:`setting-reuseport` is set to default since version 4.9.0, separate listening sockets are opened for each worker thread and the query distributions is handled by the kernel, avoiding any thundering herd issue as well as preventing the distributor thread from becoming the bottleneck. The next section discusses how to determine if the mechanism is working properly. +.. _worker_imbalance: + Imbalance ^^^^^^^^^ Due to the nature of the distribution method used by the kernel imbalance with the new default settings of :ref:`setting-reuseport` and :ref:`setting-pdns-distributes-queries` may occur if you have very few clients. diff --git a/pdns/recursordist/docs/upgrade.rst b/pdns/recursordist/docs/upgrade.rst index 233a6ea95906..5f433dd30871 100644 --- a/pdns/recursordist/docs/upgrade.rst +++ b/pdns/recursordist/docs/upgrade.rst @@ -30,9 +30,8 @@ New settings Changed settings ~~~~~~~~~~~~~~~~ The first two settings below have effect on the way the recursor distributes queries over threads. -In some rare cases, this can have negative performance impact. -In those cases it might be needed to change these settings. -See :doc:`performance`. +In some cases, this can lead to imbalance of the number of queries process per thread. +See :doc:`performance`, in particular the :ref:`worker_imbalance` section. - The :ref:`setting-pdns-distributes-queries` default has been changed to ``no``. - The :ref:`setting-reuseport` default has been changed to ``yes``. From ea90d2dd10c4088565c242bb6b566cbc46bb3304 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 30 Jun 2023 09:55:08 +0200 Subject: [PATCH 360/909] build-packages: Normalize 'recursor' to 'pdns-recursor' --- .github/workflows/build-packages.yml | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index b6dc27a97bfd..3df8f9dbe9d7 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -94,12 +94,21 @@ jobs: name: ${{ inputs.product }}-${{ matrix.os }}-${{ steps.getversion.outputs.version }} path: built_pkgs/ retention-days: 7 + - name: Normalize package name + id: normalize-name + run: | + if [ "x${{ inputs.product }}" = "xrecursor" ]; then + echo "normalized-package-name=pdns-recursor" >> $GITHUB_OUTPUT + else + echo "normalized-package-name=${{ inputs.product }}" >> $GITHUB_OUTPUT + fi + - name: Extract packages from the tarball # so we get provenance for individual packages (and the JSON package manifests from the builder) id: extract run: | mkdir -m 700 -p ./packages/ - tar xvf ./built_pkgs/*/*/${{ inputs.product }}-${{ steps.getversion.outputs.version }}-${{ matrix.os }}.tar.bz2 -C ./packages/ --transform='s/.*\///' + tar xvf ./built_pkgs/*/*/${{ steps.normalize-name.outputs.normalized-package-name }}-${{ steps.getversion.outputs.version }}-${{ matrix.os }}.tar.bz2 -C ./packages/ --transform='s/.*\///' - name: Generate package hashes for provenance shell: bash id: pkghashes From 1738caadfd12dd9b0a0abc24163bfe8ca54a5f1d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 30 Jun 2023 09:55:35 +0200 Subject: [PATCH 361/909] build-tags: Fix product names --- .github/workflows/build-packages.yml | 4 +++- .github/workflows/build-tags.yml | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index 3df8f9dbe9d7..958fed260632 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -97,7 +97,9 @@ jobs: - name: Normalize package name id: normalize-name run: | - if [ "x${{ inputs.product }}" = "xrecursor" ]; then + if [ "x${{ inputs.product }}" = "xauthoritative" ]; then + echo "normalized-package-name=pdns" >> $GITHUB_OUTPUT + elif [ "x${{ inputs.product }}" = "xrecursor" ]; then echo "normalized-package-name=pdns-recursor" >> $GITHUB_OUTPUT else echo "normalized-package-name=${{ inputs.product }}" >> $GITHUB_OUTPUT diff --git a/.github/workflows/build-tags.yml b/.github/workflows/build-tags.yml index 89e69a100adc..6431ec9d5ff9 100644 --- a/.github/workflows/build-tags.yml +++ b/.github/workflows/build-tags.yml @@ -14,7 +14,7 @@ jobs: if: startsWith(github.ref_name, 'auth') with: is_release: 'YES' - product: 'auth' + product: 'authoritative' ref: ${{ github.ref_name }} secrets: DOWNLOADS_AUTOBUILT_SECRET: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} @@ -38,7 +38,7 @@ jobs: if: startsWith(github.ref_name, 'rec') with: is_release: 'YES' - product: 'auth' + product: 'recursor' ref: ${{ github.ref_name }} secrets: DOWNLOADS_AUTOBUILT_SECRET: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} From ee10f6fce9b9d888f2eac2fb51608c57b48676c7 Mon Sep 17 00:00:00 2001 From: Jacob Bunk Nielsen Date: Fri, 30 Jun 2023 13:28:34 +0200 Subject: [PATCH 362/909] Document the StatNodeStats.hits attribute. --- pdns/dnsdistdist/docs/reference/config.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 03fb56b3820e..e8d2e027e9ff 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -1661,6 +1661,10 @@ StatNode The number of No Error answers returned for that node. + .. attribute:: StatNodeStats.hits + + The number of cache hits for that node. + .. attribute:: StatNodeStats.nxdomains The number of NXDomain answers returned for that node. From c5e72582c33fac7a133b189677249353468771d7 Mon Sep 17 00:00:00 2001 From: Jacob Bunk Nielsen Date: Fri, 30 Jun 2023 15:22:16 +0200 Subject: [PATCH 363/909] Update pdns/dnsdistdist/docs/reference/config.rst Co-authored-by: Remi Gacogne --- pdns/dnsdistdist/docs/reference/config.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index e8d2e027e9ff..32e81c02a4b0 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -1662,6 +1662,8 @@ StatNode The number of No Error answers returned for that node. .. attribute:: StatNodeStats.hits + + .. versionadded:: 1.8.0 The number of cache hits for that node. From 9a42ce944ef429b90a58463e17884a97c4ceaf3c Mon Sep 17 00:00:00 2001 From: Jacob Bunk Nielsen Date: Fri, 30 Jun 2023 15:41:40 +0200 Subject: [PATCH 364/909] Document the trailing '.' in StatNode.fullname --- pdns/dnsdistdist/docs/reference/config.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 32e81c02a4b0..36e147dcc428 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -1635,11 +1635,11 @@ StatNode .. attribute:: StatNode.fullname - The complete name of that node, ie 'www.powerdns.com'. + The complete name of that node, ie 'www.powerdns.com.'. .. attribute:: StatNode.labelsCount - The number of labels in that node, for example 3 for 'www.powerdns.com'. + The number of labels in that node, for example 3 for 'www.powerdns.com.'. .. method:: StatNode:numChildren @@ -1662,7 +1662,7 @@ StatNode The number of No Error answers returned for that node. .. attribute:: StatNodeStats.hits - + .. versionadded:: 1.8.0 The number of cache hits for that node. From 4bcb6039bcfa0e5b2761dce1dfcbd2d94688e419 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 30 Jun 2023 18:16:03 +0200 Subject: [PATCH 365/909] dnsdist: Fix "Pointer to local outside storage" reported by Coverity We use a temporary `std::string` for a very short tile after it is no longer required to exist when adding a new custom metric. Reported by Coverity as CID 394511. --- pdns/dnsdistdist/dnsdist-metrics.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-metrics.cc b/pdns/dnsdistdist/dnsdist-metrics.cc index e86439c89e98..268778aef23a 100644 --- a/pdns/dnsdistdist/dnsdist-metrics.cc +++ b/pdns/dnsdistdist/dnsdist-metrics.cc @@ -160,12 +160,13 @@ std::optional declareCustomMetric(const std::string& name, const st return std::string("Unable to declare metric '") + std::string(name) + std::string("': invalid name\n"); } + const std::string finalCustomName(customName ? *customName : ""); if (type == "counter") { auto customCounters = s_customCounters.write_lock(); auto itp = customCounters->insert({name, MutableCounter()}); if (itp.second) { g_stats.entries.write_lock()->emplace_back(Stats::EntryPair{name, &(*customCounters)[name].d_value}); - dnsdist::prometheus::PrometheusMetricDefinition def{name, "counter", description, customName ? *customName : ""}; + dnsdist::prometheus::PrometheusMetricDefinition def{name, type, description, finalCustomName}; addMetricDefinition(def); } } @@ -174,7 +175,7 @@ std::optional declareCustomMetric(const std::string& name, const st auto itp = customGauges->insert({name, MutableGauge()}); if (itp.second) { g_stats.entries.write_lock()->emplace_back(Stats::EntryPair{name, &(*customGauges)[name].d_value}); - dnsdist::prometheus::PrometheusMetricDefinition def{name, "gauge", description, customName ? *customName : ""}; + dnsdist::prometheus::PrometheusMetricDefinition def{name, type, description, finalCustomName}; addMetricDefinition(def); } } From 2e63e431478aa4ffbc59b1e821ad755f2b12db9c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 12 May 2023 12:53:00 +0200 Subject: [PATCH 366/909] Clarify which types are supported, implemented, meta, etc --- pdns/backends/gsql/gsqlbackend.cc | 2 +- pdns/dnsparser.cc | 5 +++++ pdns/dnsparser.hh | 7 ++++++- pdns/qtype.cc | 9 +++------ pdns/qtype.hh | 11 +++++++++++ pdns/rfc2136handler.cc | 20 +++++++++++++------- 6 files changed, 39 insertions(+), 15 deletions(-) diff --git a/pdns/backends/gsql/gsqlbackend.cc b/pdns/backends/gsql/gsqlbackend.cc index ead6243d68fa..4143f99dfe30 100644 --- a/pdns/backends/gsql/gsqlbackend.cc +++ b/pdns/backends/gsql/gsqlbackend.cc @@ -2156,7 +2156,7 @@ void GSQLBackend::extractRecord(SSqlStatement::row_t& row, DNSResourceRecord& r) r.qtype=row[3]; - if (d_upgradeContent && DNSRecordContent::isUnknownType(row[3]) && r.qtype.isSupportedType()) { + if (d_upgradeContent && DNSRecordContent::isUnknownType(row[3]) && r.qtype.isSupportedType() && !r.qtype.isMetadataType() && DNSRecordContent::isRegisteredType(r.qtype, r.qclass) && r.qtype != QType::NSEC && r.qtype != QType::NSEC3 && r.qtype != QType::ANY) { r.content = DNSRecordContent::upgradeContent(r.qname, r.qtype, row[0]); } else if (r.qtype==QType::MX || r.qtype==QType::SRV) { diff --git a/pdns/dnsparser.cc b/pdns/dnsparser.cc index 7f755793cedd..b7c6a9bbe768 100644 --- a/pdns/dnsparser.cc +++ b/pdns/dnsparser.cc @@ -195,6 +195,11 @@ DNSRecordContent::zmakermap_t& DNSRecordContent::getZmakermap() return zmakermap; } +bool DNSRecordContent::isRegisteredType(uint16_t rtype, uint16_t rclass) +{ + return getTypemap().count(pair(rclass, rtype)) != 0; +} + DNSRecord::DNSRecord(const DNSResourceRecord& rr): d_name(rr.qname) { d_type = rr.qtype.getCode(); diff --git a/pdns/dnsparser.hh b/pdns/dnsparser.hh index 4b22a7ac7c51..014087ef35ab 100644 --- a/pdns/dnsparser.hh +++ b/pdns/dnsparser.hh @@ -268,7 +268,7 @@ public: throw runtime_error("Unknown DNS type '"+name+"'"); } - static const string NumberToType(uint16_t num, uint16_t classnum=1) + static const string NumberToType(uint16_t num, uint16_t classnum = QClass::IN) { auto iter = getT2Namemap().find(pair(classnum, num)); if(iter == getT2Namemap().end()) @@ -277,6 +277,11 @@ public: return iter->second; } + /** + * \brief Return whether we have implemented a content representation for this type + */ + static bool isRegisteredType(uint16_t rtype, uint16_t rclass = QClass::IN); + virtual uint16_t getType() const = 0; protected: diff --git a/pdns/qtype.cc b/pdns/qtype.cc index f8069f8696d5..a0d5732cd10e 100644 --- a/pdns/qtype.cc +++ b/pdns/qtype.cc @@ -119,13 +119,10 @@ bool QType::isSupportedType() const bool QType::isMetadataType() const { - if (code == QType::AXFR || - code == QType::MAILA || - code == QType::MAILB || - code == QType::TSIG || - code == QType::IXFR) + // rfc6895 section 3.1, note ANY is 255 and falls outside the range + if (code == QType::OPT || (code >= rfc6895MetaLowerBound && code <= rfc6895MetaUpperBound)) { return true; - + } return false; } diff --git a/pdns/qtype.hh b/pdns/qtype.hh index e66dbefff5ee..f5a879bef8f5 100644 --- a/pdns/qtype.hh +++ b/pdns/qtype.hh @@ -57,7 +57,18 @@ public: return code; } + /** + * \brief Return whether we know the name of this type. + * + * This does not presume that we have an implemented a content representation for this type, + * for that please see DNSRecordContent::isRegisteredType(). + */ bool isSupportedType() const; + /** + * \brief Whether the type is either a QTYPE or Meta-Type as defined by rfc6895 section 3.1. + * + * Note that ANY is 255 and falls outside the range. + */ bool isMetadataType() const; static uint16_t chartocode(const char* p); diff --git a/pdns/rfc2136handler.cc b/pdns/rfc2136handler.cc index ceeb2d3c6fd5..2f993bfa4a44 100644 --- a/pdns/rfc2136handler.cc +++ b/pdns/rfc2136handler.cc @@ -68,25 +68,31 @@ int PacketHandler::checkUpdatePrerequisites(const DNSRecord *rr, DomainInfo *di) // Method implements section 3.4.1 of RFC2136 int PacketHandler::checkUpdatePrescan(const DNSRecord *rr) { // The RFC stats that d_class != ZCLASS, but we only support the IN class. - if (rr->d_class != QClass::IN && rr->d_class != QClass::NONE && rr->d_class != QClass::ANY) + if (rr->d_class != QClass::IN && rr->d_class != QClass::NONE && rr->d_class != QClass::ANY) { return RCode::FormErr; + } QType qtype = QType(rr->d_type); - if (! qtype.isSupportedType()) + if (!qtype.isSupportedType()) { return RCode::FormErr; + } - if ((rr->d_class == QClass::NONE || rr->d_class == QClass::ANY) && rr->d_ttl != 0) + if ((rr->d_class == QClass::NONE || rr->d_class == QClass::ANY) && rr->d_ttl != 0) { return RCode::FormErr; + } - if (rr->d_class == QClass::ANY && rr->d_clen != 0) + if (rr->d_class == QClass::ANY && rr->d_clen != 0) { return RCode::FormErr; + } - if (qtype.isMetadataType()) - return RCode::FormErr; + if (qtype.isMetadataType()) { + return RCode::FormErr; + } - if (rr->d_class != QClass::ANY && qtype.getCode() == QType::ANY) + if (rr->d_class != QClass::ANY && qtype.getCode() == QType::ANY) { return RCode::FormErr; + } return RCode::NoError; } From 9b703b51ca25838eeec19449a1c49cb926aef52a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 3 Jul 2023 14:06:05 +0200 Subject: [PATCH 367/909] dnsdist: Fix a crash when X-Forwarded-For overrides the initial source IP When both the processing of X-Forwarded-For DNS-over-https headers (`trustForwardedForHeader=true`) and a maximum number of concurrent TCP connections per client (`setMaxTCPConnectionsPerClient()`) are enabled, dnsdist could crash because of an uncaught exception: ``` dnsdist[X]: terminate called after throwing an instance of 'std::runtime_error' dnsdist[X]: what(): DOH thread failed to launch: map::at ``` This was caused by the TCP connection being first accounted for with the initial source IP (from the upstream HTTP proxy) but later released using the IP extracted from the X-Forwarded-For header, leading to an unexpected failure to locate the corresponding entry in the map. We might not actually want to enforce the maximum number of concurrent TCP connections per client when X-Forwarded-For processing is enabled, though, because we usually want to rate limit the actual client and not the HTTP proxy, but X-Forwarded-For being set per HTTP query, instead of per-connection, makes that pretty much impossible at our level since the same connection from the HTTP proxy can be reused for several clients. The proxy protocol would be a better option to enforce that limit. --- pdns/dnsdistdist/doh.cc | 21 +++++++++++++-------- regression-tests.dnsdist/test_DOH.py | 3 +++ 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 4959039ffed6..c88cb11130b3 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -909,7 +909,7 @@ static bool getHTTPHeaderValue(const h2o_req_t* req, const std::string& headerNa } /* can only be called from the main DoH thread */ -static void processForwardedForHeader(const h2o_req_t* req, ComboAddress& remote) +static std::optional processForwardedForHeader(const h2o_req_t* req, const ComboAddress& remote) { static const std::string headerName = "x-forwarded-for"; std::string_view value; @@ -927,8 +927,7 @@ static void processForwardedForHeader(const h2o_req_t* req, ComboAddress& remote value = value.substr(pos); } } - auto newRemote = ComboAddress(std::string(value)); - remote = newRemote; + return ComboAddress(std::string(value)); } catch (const std::exception& e) { vinfolog("Invalid X-Forwarded-For header ('%s') received from %s : %s", std::string(value), remote.toStringWithPort(), e.what()); @@ -937,6 +936,8 @@ static void processForwardedForHeader(const h2o_req_t* req, ComboAddress& remote vinfolog("Invalid X-Forwarded-For header ('%s') received from %s : %s", std::string(value), remote.toStringWithPort(), e.reason); } } + + return std::nullopt; } /* @@ -971,14 +972,18 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) h2o_socket_getsockname(sock, reinterpret_cast(&conn.d_local)); } + auto remote = conn.d_remote; if (dsc->df->d_trustForwardedForHeader) { - processForwardedForHeader(req, conn.d_remote); + auto newRemote = processForwardedForHeader(req, remote); + if (newRemote) { + remote = std::move(*newRemote); + } } auto& holders = dsc->holders; - if (!holders.acl->match(conn.d_remote)) { + if (!holders.acl->match(remote)) { ++dnsdist::metrics::g_stats.aclDrops; - vinfolog("Query from %s (DoH) dropped because of ACL", conn.d_remote.toStringWithPort()); + vinfolog("Query from %s (DoH) dropped because of ACL", remote.toStringWithPort()); h2o_send_error_403(req, "Forbidden", "dns query not allowed because of ACL", 0); return 0; } @@ -1034,7 +1039,7 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) query.reserve(req->entity.len + maxAdditionalSizeForEDNS); query.resize(req->entity.len); memcpy(query.data(), req->entity.base, req->entity.len); - doh_dispatch_query(dsc, self, req, std::move(query), conn.d_local, conn.d_remote, std::move(path)); + doh_dispatch_query(dsc, self, req, std::move(query), conn.d_local, remote, std::move(path)); } else if(req->query_at != SIZE_MAX && (req->path.len - req->query_at > 5)) { auto pos = path.find("?dns="); @@ -1073,7 +1078,7 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) else ++dsc->df->d_http1Stats.d_nbQueries; - doh_dispatch_query(dsc, self, req, std::move(decoded), conn.d_local, conn.d_remote, std::move(path)); + doh_dispatch_query(dsc, self, req, std::move(decoded), conn.d_local, remote, std::move(path)); } } else diff --git a/regression-tests.dnsdist/test_DOH.py b/regression-tests.dnsdist/test_DOH.py index 61936de4411d..2dd016fd1b66 100644 --- a/regression-tests.dnsdist/test_DOH.py +++ b/regression-tests.dnsdist/test_DOH.py @@ -1064,6 +1064,9 @@ class TestDOHForwardedFor(DNSDistDOHTest): setACL('192.0.2.1/32') addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {trustForwardedForHeader=true}) + -- Set a maximum number of TCP connections per client, to exercise + -- that code along with X-Forwarded-For support + setMaxTCPConnectionsPerClient(2) """ _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey'] From 7406cfbe5991b3edd1324b0f446c68c7acdc95e1 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 3 Jul 2023 15:28:21 +0200 Subject: [PATCH 368/909] builder-dispatch: Explicitly grant id-token: write to the build package workflow --- .github/workflows/builder-dispatch.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/workflows/builder-dispatch.yml b/.github/workflows/builder-dispatch.yml index 456af0af244f..30cab32c47f7 100644 --- a/.github/workflows/builder-dispatch.yml +++ b/.github/workflows/builder-dispatch.yml @@ -35,6 +35,11 @@ on: - 'NO' - 'YES' +permissions: # least privileges, see https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions + actions: read + contents: write # To be able to upload assets as release artifacts + id-token: write # To sign the provenance in the build packages reusable workflow. + jobs: call-build-packages: uses: PowerDNS/pdns/.github/workflows/build-packages.yml@master From bfacb42321c6b287823ef9b685658488c6462e04 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 3 Jul 2023 20:03:54 +0200 Subject: [PATCH 369/909] dnsdist: Make clang-tidy happy We will have to come back if ComboAddress ever becomes heavier, but hey. --- pdns/dnsdistdist/doh.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index c88cb11130b3..c8931c5cdb13 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -976,7 +976,7 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) if (dsc->df->d_trustForwardedForHeader) { auto newRemote = processForwardedForHeader(req, remote); if (newRemote) { - remote = std::move(*newRemote); + remote = *newRemote; } } From bc90e72e012c633f04a2fa52e3f852359aee8a79 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 3 Jul 2023 20:08:36 +0200 Subject: [PATCH 370/909] auth: Simplify the SQL upgrade condition --- pdns/backends/gsql/gsqlbackend.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/backends/gsql/gsqlbackend.cc b/pdns/backends/gsql/gsqlbackend.cc index 4143f99dfe30..61d7ea08a85c 100644 --- a/pdns/backends/gsql/gsqlbackend.cc +++ b/pdns/backends/gsql/gsqlbackend.cc @@ -2156,7 +2156,7 @@ void GSQLBackend::extractRecord(SSqlStatement::row_t& row, DNSResourceRecord& r) r.qtype=row[3]; - if (d_upgradeContent && DNSRecordContent::isUnknownType(row[3]) && r.qtype.isSupportedType() && !r.qtype.isMetadataType() && DNSRecordContent::isRegisteredType(r.qtype, r.qclass) && r.qtype != QType::NSEC && r.qtype != QType::NSEC3 && r.qtype != QType::ANY) { + if (d_upgradeContent && DNSRecordContent::isUnknownType(row[3]) && DNSRecordContent::isRegisteredType(r.qtype, r.qclass)) { r.content = DNSRecordContent::upgradeContent(r.qname, r.qtype, row[0]); } else if (r.qtype==QType::MX || r.qtype==QType::SRV) { From ef1f2639147d4d28b79f562fd995a925938b9869 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 3 Jul 2023 18:00:40 +0200 Subject: [PATCH 371/909] debian auth packaging: use sdig for smoke tests --- .../debian-buster/tests-source/smoke-bind | 2 +- .../debian-buster/tests-source/smoke-lmdb | 2 +- .../authoritative/debian-buster/tests/control | 22 +++++++++---------- .../debian-buster/tests/smoke-bind | 2 +- .../debian-buster/tests/smoke-mysql | 2 +- .../debian-buster/tests/smoke-mysql-sp | 2 +- .../debian-buster/tests/smoke-pgsql | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/builder-support/debian/authoritative/debian-buster/tests-source/smoke-bind b/builder-support/debian/authoritative/debian-buster/tests-source/smoke-bind index 8d18eaf4547d..f10656d1aec9 100755 --- a/builder-support/debian/authoritative/debian-buster/tests-source/smoke-bind +++ b/builder-support/debian/authoritative/debian-buster/tests-source/smoke-bind @@ -31,7 +31,7 @@ EOF ./launch-pdns -dig -p 5301 @127.0.0.1 smoke.bind.example.org 2>&1 | tee "$TMPFILE" +../../pdns/sdig 127.0.0.1 5301 smoke.bind.example.org A 2>&1 | tee "$TMPFILE" if grep -c '127\.0\.0\.123' "$TMPFILE"; then echo success diff --git a/builder-support/debian/authoritative/debian-buster/tests-source/smoke-lmdb b/builder-support/debian/authoritative/debian-buster/tests-source/smoke-lmdb index 8278ec152839..0078b4662409 100755 --- a/builder-support/debian/authoritative/debian-buster/tests-source/smoke-lmdb +++ b/builder-support/debian/authoritative/debian-buster/tests-source/smoke-lmdb @@ -23,7 +23,7 @@ EOF ./launch-pdns -dig -p 5301 @127.0.0.1 smoke.lmdb.example.org SOA 2>&1 | tee "$TMPFILE" +../../pdns/sdig 127.0.0.1 5301 smoke.lmdb.example.org SOA 2>&1 | tee "$TMPFILE" if grep -c 'a.misconfigured' "$TMPFILE"; then echo success diff --git a/builder-support/debian/authoritative/debian-buster/tests/control b/builder-support/debian/authoritative/debian-buster/tests/control index ffda575ee3f3..a38cae59cbdc 100644 --- a/builder-support/debian/authoritative/debian-buster/tests/control +++ b/builder-support/debian/authoritative/debian-buster/tests/control @@ -1,27 +1,27 @@ Tests: smoke-bind -Depends: dnsutils, - pdns-backend-bind, - pdns-server +Depends: pdns-backend-bind, + pdns-server, + pdns-tools Restrictions: needs-root Tests: smoke-mysql -Depends: dnsutils, - mariadb-server, +Depends: mariadb-server, pdns-backend-mysql, - pdns-server + pdns-server, + pdns-tools Restrictions: needs-root, isolation-container Tests: smoke-mysql-sp -Depends: dnsutils, - mariadb-server, +Depends: mariadb-server, pdns-backend-mysql, - pdns-server + pdns-server, + pdns-tools Restrictions: needs-root, isolation-container Tests: smoke-pgsql -Depends: dnsutils, - pdns-backend-pgsql, +Depends: pdns-backend-pgsql, pdns-server, + pdns-tools, postgresql Restrictions: needs-root, isolation-container diff --git a/builder-support/debian/authoritative/debian-buster/tests/smoke-bind b/builder-support/debian/authoritative/debian-buster/tests/smoke-bind index f9dbdb8fb46c..71a54e85c196 100755 --- a/builder-support/debian/authoritative/debian-buster/tests/smoke-bind +++ b/builder-support/debian/authoritative/debian-buster/tests/smoke-bind @@ -25,7 +25,7 @@ cleanup() { } trap cleanup EXIT -dig @127.0.0.1 smoke.$ZONE 2>&1 | tee "$TMPFILE" +sdig 127.0.0.1 53 smoke.$ZONE A 2>&1 | tee "$TMPFILE" if grep -c '127\.0\.0\.222' "$TMPFILE"; then echo success diff --git a/builder-support/debian/authoritative/debian-buster/tests/smoke-mysql b/builder-support/debian/authoritative/debian-buster/tests/smoke-mysql index e9bf89145f95..fd09deed9804 100755 --- a/builder-support/debian/authoritative/debian-buster/tests/smoke-mysql +++ b/builder-support/debian/authoritative/debian-buster/tests/smoke-mysql @@ -61,7 +61,7 @@ cleanup() { } trap cleanup EXIT -dig @127.0.0.1 smoke.$ZONE 2>&1 | tee "$TMPFILE" +sdig 127.0.0.1 53 smoke.$ZONE A 2>&1 | tee "$TMPFILE" if grep -c '127\.0\.0\.222' "$TMPFILE"; then echo success diff --git a/builder-support/debian/authoritative/debian-buster/tests/smoke-mysql-sp b/builder-support/debian/authoritative/debian-buster/tests/smoke-mysql-sp index ec112d2c059b..da1087d73e0d 100755 --- a/builder-support/debian/authoritative/debian-buster/tests/smoke-mysql-sp +++ b/builder-support/debian/authoritative/debian-buster/tests/smoke-mysql-sp @@ -72,7 +72,7 @@ cleanup() { } trap cleanup EXIT -dig @127.0.0.1 smoke.$ZONE 2>&1 | tee "$TMPFILE" +sdig 127.0.0.1 53 smoke.$ZONE A 2>&1 | tee "$TMPFILE" if grep -c '127\.0\.0\.222' "$TMPFILE"; then echo success diff --git a/builder-support/debian/authoritative/debian-buster/tests/smoke-pgsql b/builder-support/debian/authoritative/debian-buster/tests/smoke-pgsql index c10b027e153f..ce44af55db83 100755 --- a/builder-support/debian/authoritative/debian-buster/tests/smoke-pgsql +++ b/builder-support/debian/authoritative/debian-buster/tests/smoke-pgsql @@ -59,7 +59,7 @@ cleanup() { } trap cleanup EXIT -dig @127.0.0.1 smoke.$ZONE 2>&1 | tee "$TMPFILE" +sdig 127.0.0.1 53 smoke.$ZONE A 2>&1 | tee "$TMPFILE" if grep -c '127\.0\.0\.222' "$TMPFILE"; then echo success From 77dbb2a6393db591334d2125f035a7f2ff762164 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 3 Jul 2023 18:01:01 +0200 Subject: [PATCH 372/909] builder: add debian-trixie target --- .../Dockerfile.target.debian-trixie | 36 +++++++++++++++++++ .../Dockerfile.target.debian-trixie-amd64 | 1 + .../Dockerfile.target.debian-trixie-arm64 | 1 + 3 files changed, 38 insertions(+) create mode 100644 builder-support/dockerfiles/Dockerfile.target.debian-trixie create mode 120000 builder-support/dockerfiles/Dockerfile.target.debian-trixie-amd64 create mode 120000 builder-support/dockerfiles/Dockerfile.target.debian-trixie-arm64 diff --git a/builder-support/dockerfiles/Dockerfile.target.debian-trixie b/builder-support/dockerfiles/Dockerfile.target.debian-trixie new file mode 100644 index 000000000000..0c23eb98b00f --- /dev/null +++ b/builder-support/dockerfiles/Dockerfile.target.debian-trixie @@ -0,0 +1,36 @@ +# First do the source builds +@INCLUDE Dockerfile.target.sdist + +@IF [ ${BUILDER_TARGET} = debian-trixie ] +FROM debian:trixie as dist-base +@ENDIF +@IF [ ${BUILDER_TARGET} = debian-trixie-amd64 ] +FROM amd64/debian:trixie as dist-base +@ENDIF +@IF [ ${BUILDER_TARGET} = debian-trixie-arm64 ] +FROM arm64v8/debian:trixie as dist-base +@ENDIF + +ARG BUILDER_CACHE_BUSTER= +ARG APT_URL +RUN apt-get update && apt-get -y dist-upgrade + +@INCLUDE Dockerfile.debbuild-prepare + +@IF [ -n "$M_authoritative$M_all" ] +ADD builder-support/debian/authoritative/debian-buster/ pdns-${BUILDER_VERSION}/debian/ +@ENDIF + +@IF [ -n "$M_recursor$M_all" ] +ADD builder-support/debian/recursor/debian-buster/ pdns-recursor-${BUILDER_VERSION}/debian/ +@ENDIF + +@IF [ -n "$M_dnsdist$M_all" ] +ADD builder-support/debian/dnsdist/debian-buster/ dnsdist-${BUILDER_VERSION}/debian/ +@ENDIF + +@INCLUDE Dockerfile.debbuild + +# Do a test install and verify +# Can be skipped with skiptests=1 in the environment +# @EXEC [ "$skiptests" = "" ] && include Dockerfile.debtest diff --git a/builder-support/dockerfiles/Dockerfile.target.debian-trixie-amd64 b/builder-support/dockerfiles/Dockerfile.target.debian-trixie-amd64 new file mode 120000 index 000000000000..fed04d5f74bc --- /dev/null +++ b/builder-support/dockerfiles/Dockerfile.target.debian-trixie-amd64 @@ -0,0 +1 @@ +Dockerfile.target.debian-trixie \ No newline at end of file diff --git a/builder-support/dockerfiles/Dockerfile.target.debian-trixie-arm64 b/builder-support/dockerfiles/Dockerfile.target.debian-trixie-arm64 new file mode 120000 index 000000000000..fed04d5f74bc --- /dev/null +++ b/builder-support/dockerfiles/Dockerfile.target.debian-trixie-arm64 @@ -0,0 +1 @@ +Dockerfile.target.debian-trixie \ No newline at end of file From d70b236d32d5925c45adddb60434b50701e1bff3 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 3 Jul 2023 20:51:12 +0200 Subject: [PATCH 373/909] add debian-trixie to daily build test --- .github/workflows/builder.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index f0edb1afc0d5..2ec3c5641d0f 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -25,6 +25,7 @@ jobs: - ubuntu-kinetic - ubuntu-lunar - debian-bookworm + - debian-trixie - amazon-2023 fail-fast: false steps: From 3071bc616d2a7593a6067dbc4d734fc50cbc11a6 Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Thu, 6 Jul 2023 10:02:34 +0200 Subject: [PATCH 374/909] auth: docs, catalog zone is now RFC 9432 --- docs/catalog.rst | 6 +++--- docs/dnsupdate.rst | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/catalog.rst b/docs/catalog.rst index e0ffbdabb776..e98aa1fa5528 100644 --- a/docs/catalog.rst +++ b/docs/catalog.rst @@ -1,4 +1,4 @@ -Catalog Zones (RFC TBD) +Catalog Zones (RFC 9432) ======================== Starting with the PowerDNS Authoritative Server 4.7.0, catalog zone support is available. @@ -11,7 +11,7 @@ Supported catalog versions +=================+==========+==========+ | 1 (ISC) | No | Yes | +-----------------+----------+----------+ -| 2 (RFC TBD) | Yes | Yes | +| 2 (:rfc:`9432`) | Yes | Yes | +-----------------+----------+----------+ All the important features of catalog zones version "2" are supported. @@ -54,7 +54,7 @@ Setting up catalog zones ------------------------ .. note:: - Catalog zone specification and operation is described in `DNS Catalog Zones `__. + Catalog zone specification and operation is described in :rfc:`9432`. Setting up a producer zone ~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/dnsupdate.rst b/docs/dnsupdate.rst index e8efc0c87d67..6d0ddf2b3c5c 100644 --- a/docs/dnsupdate.rst +++ b/docs/dnsupdate.rst @@ -1,5 +1,5 @@ -Dynamic DNS Update (RFC2136) -============================ +Dynamic DNS Update (RFC 2136) +============================= Starting with the PowerDNS Authoritative Server 3.4.0, DNS update support is available. There are a number of items NOT supported: From d250e94f22407e2c8a08853229c8030382c75581 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 4 Jul 2023 20:25:09 +0200 Subject: [PATCH 375/909] auth lmdb: add 'index check domains' and 'index refresh domains ' backend-cmds --- modules/lmdbbackend/lmdbbackend.cc | 98 ++++++++++++++++++++++++++++-- 1 file changed, 94 insertions(+), 4 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index ada437db984b..506cd4783dd5 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -2620,17 +2620,107 @@ bool LMDBBackend::getTSIGKeys(std::vector& keys) string LMDBBackend::directBackendCmd(const string& query) { - if (query == "info") { - ostringstream ret; + ostringstream ret, usage; + usage << "info show some information about the database" << endl; + usage << "index check domains check zone<>ID indexes" << endl; + usage << "index refresh domains refresh index for zone with this ID" << endl; + + vector argv; + stringtok(argv, query); + + if (argv.empty()) { + return usage.str(); + } + + string& cmd = argv[0]; + + if (cmd == "help") { + return usage.str(); + } + + if (cmd == "info") { ret << "shards: " << s_shards << endl; ret << "schemaversion: " << SCHEMAVERSION << endl; return ret.str(); } - else { - return "unknown lmdbbackend command\n"; + + if (cmd == "index") { + if (argv.size() < 2) { + return "need an index subcommand\n"; + } + + string& subcmd = argv[1]; + + if (subcmd == "check") { + if (argv.size() < 3) { + return "need an index name\n"; + } + + if (argv[2] != "domains") { + return "can only check the domains index\n"; + } + + auto txn = d_tdomains->getROTransaction(); + + for (auto iter = txn.begin(); iter != txn.end(); ++iter) { + DomainInfo di = *iter; + + auto id = iter.getID(); + + LMDBIDvec ids; + txn.get_multi<0>(di.zone, ids); + + if (ids.size() != 1) { + ret << "ID->zone index has " << id << "->" << di.zone << ", "; + + if (ids.empty()) { + ret << "zone->ID index has no entry for " << di.zone << endl; + ret << " suggested remedy: index refresh domains " << id << endl; + } + else { + // ids.size() > 1 + ret << "zone->ID index has multiple entries for " << di.zone << ": "; + for (auto id_ : ids) { + ret << id_ << " "; + } + ret << endl; + } + } + } + return ret.str(); + } + if (subcmd == "refresh") { + // index refresh domains 12345 + if (argv.size() < 4) { + return "usage: index refresh domains \n"; + } + + if (argv[2] != "domains") { + return "can only refresh in the domains index\n"; + } + + uint32_t id = 0; + + try { + id = pdns::checked_stoi(argv[3]); + } + catch (const std::out_of_range& e) { + return "ID out of range\n"; + } + + if (genChangeDomain(id, [](DomainInfo& /* di */) {})) { + ret << "refreshed" << endl; + } + else { + ret << "failed" << endl; + } + return ret.str(); + } } + + return "unknown lmdbbackend command\n"; } class LMDBFactory : public BackendFactory From a451e81e890c91833d8f0c66488f488647ed51b6 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 6 Jul 2023 12:28:22 +0200 Subject: [PATCH 376/909] auth lmdb: add index refresh-all backend command --- modules/lmdbbackend/lmdbbackend.cc | 64 +++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 19 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 506cd4783dd5..d9b94763ed4b 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -2625,7 +2625,7 @@ string LMDBBackend::directBackendCmd(const string& query) usage << "info show some information about the database" << endl; usage << "index check domains check zone<>ID indexes" << endl; usage << "index refresh domains refresh index for zone with this ID" << endl; - + usage << "index refresh-all domains refresh index for all zones with disconnected indexes" << endl; vector argv; stringtok(argv, query); @@ -2653,7 +2653,13 @@ string LMDBBackend::directBackendCmd(const string& query) string& subcmd = argv[1]; - if (subcmd == "check") { + if (subcmd == "check" || subcmd == "refresh-all") { + bool refresh = false; + + if (subcmd == "refresh-all") { + refresh = true; + } + if (argv.size() < 3) { return "need an index name\n"; } @@ -2662,30 +2668,50 @@ string LMDBBackend::directBackendCmd(const string& query) return "can only check the domains index\n"; } - auto txn = d_tdomains->getROTransaction(); + vector refreshQueue; + + { + auto txn = d_tdomains->getROTransaction(); + + for (auto iter = txn.begin(); iter != txn.end(); ++iter) { + DomainInfo di = *iter; - for (auto iter = txn.begin(); iter != txn.end(); ++iter) { - DomainInfo di = *iter; + auto id = iter.getID(); - auto id = iter.getID(); + LMDBIDvec ids; + txn.get_multi<0>(di.zone, ids); - LMDBIDvec ids; - txn.get_multi<0>(di.zone, ids); + if (ids.size() != 1) { + ret << "ID->zone index has " << id << "->" << di.zone << ", "; - if (ids.size() != 1) { - ret << "ID->zone index has " << id << "->" << di.zone << ", "; + if (ids.empty()) { + ret << "zone->ID index has no entry for " << di.zone << endl; + if (refresh) { + refreshQueue.push_back(id); + } + else { + ret << " suggested remedy: index refresh domains " << id << endl; + } + } + else { + // ids.size() > 1 + ret << "zone->ID index has multiple entries for " << di.zone << ": "; + for (auto id_ : ids) { + ret << id_ << " "; + } + ret << endl; + } + } + } + } - if (ids.empty()) { - ret << "zone->ID index has no entry for " << di.zone << endl; - ret << " suggested remedy: index refresh domains " << id << endl; + if (refresh) { + for (const auto& id : refreshQueue) { + if (genChangeDomain(id, [](DomainInfo& /* di */) {})) { + ret << "refreshed " << id << endl; } else { - // ids.size() > 1 - ret << "zone->ID index has multiple entries for " << di.zone << ": "; - for (auto id_ : ids) { - ret << id_ << " "; - } - ret << endl; + ret << "failed to refresh " << id << endl; } } } From 3a99c00de710001bf28b940578ddc8d92272b28a Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 6 Jul 2023 15:09:07 +0200 Subject: [PATCH 377/909] auth lmdb: in Lightning Stream mode, during deleteDomain, use RW transaction to get ID list --- modules/lmdbbackend/lmdbbackend.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index ada437db984b..7a062b24d59b 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1321,7 +1321,11 @@ bool LMDBBackend::deleteDomain(const DNSName& domain) idvec.push_back(txn.get<0>(domain, di)); } else { - auto txn = d_tdomains->getROTransaction(); + // this transaction used to be RO. + // it is now RW to narrow a race window between PowerDNS and Lightning Stream + // FIXME: turn the entire delete, including this ID scan, into one RW transaction + // when doing that, first do a short RO check to see if we actually have anything to delete + auto txn = d_tdomains->getRWTransaction(); txn.get_multi<0>(domain, idvec); } From db24855eb88dde9d2b96889d32afedb8364939db Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 10:02:52 +0200 Subject: [PATCH 378/909] Initial needed files from openssh-portable --- ext/arc4random/arc4random.c | 254 ++++++++++++++++++++++++++++ ext/arc4random/arc4random.h | 89 ++++++++++ ext/arc4random/arc4random_uniform.c | 64 +++++++ ext/arc4random/bsd-getentropy.c | 83 +++++++++ ext/arc4random/chacha_private.h | 224 ++++++++++++++++++++++++ 5 files changed, 714 insertions(+) create mode 100644 ext/arc4random/arc4random.c create mode 100644 ext/arc4random/arc4random.h create mode 100644 ext/arc4random/arc4random_uniform.c create mode 100644 ext/arc4random/bsd-getentropy.c create mode 100644 ext/arc4random/chacha_private.h diff --git a/ext/arc4random/arc4random.c b/ext/arc4random/arc4random.c new file mode 100644 index 000000000000..ffd33734db56 --- /dev/null +++ b/ext/arc4random/arc4random.c @@ -0,0 +1,254 @@ +/* $OpenBSD: arc4random.c,v 1.58 2022/07/31 13:41:45 tb Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * ChaCha based random number generator for OpenBSD. + */ + +/* OPENBSD ORIGINAL: lib/libc/crypt/arc4random.c */ + +#include "includes.h" + +#include + +#include +#include +#include +#ifdef HAVE_STDINT_H +#include +#endif +#include +#include +#include +#include +#include + +#ifndef HAVE_ARC4RANDOM + +/* + * Always use the getentropy implementation from bsd-getentropy.c, which + * will call a native getentropy if available then fall back as required. + * We use a different name so that OpenSSL cannot call the wrong getentropy. + */ +int _ssh_compat_getentropy(void *, size_t); +#ifdef getentropy +# undef getentropy +#endif +#define getentropy(x, y) (_ssh_compat_getentropy((x), (y))) + +#include "log.h" + +#define KEYSTREAM_ONLY +#include "chacha_private.h" + +#define minimum(a, b) ((a) < (b) ? (a) : (b)) + +#if defined(__GNUC__) || defined(_MSC_VER) +#define inline __inline +#else /* __GNUC__ || _MSC_VER */ +#define inline +#endif /* !__GNUC__ && !_MSC_VER */ + +#define KEYSZ 32 +#define IVSZ 8 +#define BLOCKSZ 64 +#define RSBUFSZ (16*BLOCKSZ) + +#define REKEY_BASE (1024*1024) /* NB. should be a power of 2 */ + +/* Marked MAP_INHERIT_ZERO, so zero'd out in fork children. */ +static struct _rs { + size_t rs_have; /* valid bytes at end of rs_buf */ + size_t rs_count; /* bytes till reseed */ +} *rs; + +/* Maybe be preserved in fork children, if _rs_allocate() decides. */ +static struct _rsx { + chacha_ctx rs_chacha; /* chacha context for random keystream */ + u_char rs_buf[RSBUFSZ]; /* keystream blocks */ +} *rsx; + +static inline int _rs_allocate(struct _rs **, struct _rsx **); +static inline void _rs_forkdetect(void); +#include "arc4random.h" + +static inline void _rs_rekey(u_char *dat, size_t datlen); + +static inline void +_rs_init(u_char *buf, size_t n) +{ + if (n < KEYSZ + IVSZ) + return; + + if (rs == NULL) { + if (_rs_allocate(&rs, &rsx) == -1) + _exit(1); + } + + chacha_keysetup(&rsx->rs_chacha, buf, KEYSZ * 8); + chacha_ivsetup(&rsx->rs_chacha, buf + KEYSZ); +} + +static void +_rs_stir(void) +{ + u_char rnd[KEYSZ + IVSZ]; + uint32_t rekey_fuzz = 0; + + if (getentropy(rnd, sizeof rnd) == -1) + _getentropy_fail(); + + if (!rs) + _rs_init(rnd, sizeof(rnd)); + else + _rs_rekey(rnd, sizeof(rnd)); + explicit_bzero(rnd, sizeof(rnd)); /* discard source seed */ + + /* invalidate rs_buf */ + rs->rs_have = 0; + memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); + + /* rekey interval should not be predictable */ + chacha_encrypt_bytes(&rsx->rs_chacha, (uint8_t *)&rekey_fuzz, + (uint8_t *)&rekey_fuzz, sizeof(rekey_fuzz)); + rs->rs_count = REKEY_BASE + (rekey_fuzz % REKEY_BASE); +} + +static inline void +_rs_stir_if_needed(size_t len) +{ + _rs_forkdetect(); + if (!rs || rs->rs_count <= len) + _rs_stir(); + if (rs->rs_count <= len) + rs->rs_count = 0; + else + rs->rs_count -= len; +} + +static inline void +_rs_rekey(u_char *dat, size_t datlen) +{ +#ifndef KEYSTREAM_ONLY + memset(rsx->rs_buf, 0, sizeof(rsx->rs_buf)); +#endif + /* fill rs_buf with the keystream */ + chacha_encrypt_bytes(&rsx->rs_chacha, rsx->rs_buf, + rsx->rs_buf, sizeof(rsx->rs_buf)); + /* mix in optional user provided data */ + if (dat) { + size_t i, m; + + m = minimum(datlen, KEYSZ + IVSZ); + for (i = 0; i < m; i++) + rsx->rs_buf[i] ^= dat[i]; + } + /* immediately reinit for backtracking resistance */ + _rs_init(rsx->rs_buf, KEYSZ + IVSZ); + memset(rsx->rs_buf, 0, KEYSZ + IVSZ); + rs->rs_have = sizeof(rsx->rs_buf) - KEYSZ - IVSZ; +} + +static inline void +_rs_random_buf(void *_buf, size_t n) +{ + u_char *buf = (u_char *)_buf; + u_char *keystream; + size_t m; + + _rs_stir_if_needed(n); + while (n > 0) { + if (rs->rs_have > 0) { + m = minimum(n, rs->rs_have); + keystream = rsx->rs_buf + sizeof(rsx->rs_buf) + - rs->rs_have; + memcpy(buf, keystream, m); + memset(keystream, 0, m); + buf += m; + n -= m; + rs->rs_have -= m; + } + if (rs->rs_have == 0) + _rs_rekey(NULL, 0); + } +} + +static inline void +_rs_random_u32(uint32_t *val) +{ + u_char *keystream; + + _rs_stir_if_needed(sizeof(*val)); + if (rs->rs_have < sizeof(*val)) + _rs_rekey(NULL, 0); + keystream = rsx->rs_buf + sizeof(rsx->rs_buf) - rs->rs_have; + memcpy(val, keystream, sizeof(*val)); + memset(keystream, 0, sizeof(*val)); + rs->rs_have -= sizeof(*val); +} + +uint32_t +arc4random(void) +{ + uint32_t val; + + _ARC4_LOCK(); + _rs_random_u32(&val); + _ARC4_UNLOCK(); + return val; +} +DEF_WEAK(arc4random); + +/* + * If we are providing arc4random, then we can provide a more efficient + * arc4random_buf(). + */ +# ifndef HAVE_ARC4RANDOM_BUF +void +arc4random_buf(void *buf, size_t n) +{ + _ARC4_LOCK(); + _rs_random_buf(buf, n); + _ARC4_UNLOCK(); +} +DEF_WEAK(arc4random_buf); +# endif /* !HAVE_ARC4RANDOM_BUF */ +#endif /* !HAVE_ARC4RANDOM */ + +/* arc4random_buf() that uses platform arc4random() */ +#if !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) +void +arc4random_buf(void *_buf, size_t n) +{ + size_t i; + u_int32_t r = 0; + char *buf = (char *)_buf; + + for (i = 0; i < n; i++) { + if (i % 4 == 0) + r = arc4random(); + buf[i] = r & 0xff; + r >>= 8; + } + explicit_bzero(&r, sizeof(r)); +} +#endif /* !defined(HAVE_ARC4RANDOM_BUF) && defined(HAVE_ARC4RANDOM) */ + diff --git a/ext/arc4random/arc4random.h b/ext/arc4random/arc4random.h new file mode 100644 index 000000000000..5af3a4492a82 --- /dev/null +++ b/ext/arc4random/arc4random.h @@ -0,0 +1,89 @@ +/* $OpenBSD: arc4random_linux.h,v 1.12 2019/07/11 10:37:28 inoguchi Exp $ */ + +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * Copyright (c) 2014, Theo de Raadt + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Stub functions for portability. From LibreSSL with some adaptations. + */ + +#include + +#include + +/* OpenSSH isn't multithreaded */ +#define _ARC4_LOCK() +#define _ARC4_UNLOCK() +#define _ARC4_ATFORK(f) + +static inline void +_getentropy_fail(void) +{ + fatal("getentropy failed"); +} + +static volatile sig_atomic_t _rs_forked; + +static inline void +_rs_forkhandler(void) +{ + _rs_forked = 1; +} + +static inline void +_rs_forkdetect(void) +{ + static pid_t _rs_pid = 0; + pid_t pid = getpid(); + + if (_rs_pid == 0 || _rs_pid == 1 || _rs_pid != pid || _rs_forked) { + _rs_pid = pid; + _rs_forked = 0; + if (rs) + memset(rs, 0, sizeof(*rs)); + } +} + +static inline int +_rs_allocate(struct _rs **rsp, struct _rsx **rsxp) +{ +#if defined(MAP_ANON) && defined(MAP_PRIVATE) + if ((*rsp = mmap(NULL, sizeof(**rsp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) + return (-1); + + if ((*rsxp = mmap(NULL, sizeof(**rsxp), PROT_READ|PROT_WRITE, + MAP_ANON|MAP_PRIVATE, -1, 0)) == MAP_FAILED) { + munmap(*rsp, sizeof(**rsp)); + *rsp = NULL; + return (-1); + } +#else + if ((*rsp = calloc(1, sizeof(**rsp))) == NULL) + return (-1); + if ((*rsxp = calloc(1, sizeof(**rsxp))) == NULL) { + free(*rsp); + *rsp = NULL; + return (-1); + } +#endif + + _ARC4_ATFORK(_rs_forkhandler); + return (0); +} diff --git a/ext/arc4random/arc4random_uniform.c b/ext/arc4random/arc4random_uniform.c new file mode 100644 index 000000000000..591f92d150fa --- /dev/null +++ b/ext/arc4random/arc4random_uniform.c @@ -0,0 +1,64 @@ +/* $OpenBSD: arc4random_uniform.c,v 1.3 2019/01/20 02:59:07 bcook Exp $ */ + +/* + * Copyright (c) 2008, Damien Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* OPENBSD ORIGINAL: lib/libc/crypto/arc4random_uniform.c */ + +#include "includes.h" + +#ifdef HAVE_STDINT_H +# include +#endif +#include + +#ifndef HAVE_ARC4RANDOM_UNIFORM +/* + * Calculate a uniformly distributed random number less than upper_bound + * avoiding "modulo bias". + * + * Uniformity is achieved by generating new random numbers until the one + * returned is outside the range [0, 2**32 % upper_bound). This + * guarantees the selected random number will be inside + * [2**32 % upper_bound, 2**32) which maps back to [0, upper_bound) + * after reduction modulo upper_bound. + */ +uint32_t +arc4random_uniform(uint32_t upper_bound) +{ + uint32_t r, min; + + if (upper_bound < 2) + return 0; + + /* 2**32 % x == (2**32 - x) % x */ + min = -upper_bound % upper_bound; + + /* + * This could theoretically loop forever but each retry has + * p > 0.5 (worst case, usually far better) of selecting a + * number inside the range we need, so it should rarely need + * to re-roll. + */ + for (;;) { + r = arc4random(); + if (r >= min) + break; + } + + return r % upper_bound; +} +#endif /* !HAVE_ARC4RANDOM_UNIFORM */ diff --git a/ext/arc4random/bsd-getentropy.c b/ext/arc4random/bsd-getentropy.c new file mode 100644 index 000000000000..0231e066c5fa --- /dev/null +++ b/ext/arc4random/bsd-getentropy.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1996, David Mazieres + * Copyright (c) 2008, Damien Miller + * Copyright (c) 2013, Markus Friedl + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "includes.h" + +#ifndef SSH_RANDOM_DEV +# define SSH_RANDOM_DEV "/dev/urandom" +#endif /* SSH_RANDOM_DEV */ + +#include +#ifdef HAVE_SYS_RANDOM_H +# include +#endif + +#include +#include +#include +#include +#ifdef WITH_OPENSSL +#include +#include +#endif + +#include "log.h" + +int +_ssh_compat_getentropy(void *s, size_t len) +{ +#ifdef WITH_OPENSSL + if (RAND_bytes(s, len) <= 0) + fatal("Couldn't obtain random bytes (error 0x%lx)", + (unsigned long)ERR_get_error()); +#else + int fd, save_errno; + ssize_t r; + size_t o = 0; + +#ifdef HAVE_GETENTROPY + if ((r = getentropy(s, len)) == 0) + return 0; +#endif /* HAVE_GETENTROPY */ +#ifdef HAVE_GETRANDOM + if ((r = getrandom(s, len, 0)) > 0 && (size_t)r == len) + return 0; +#endif /* HAVE_GETRANDOM */ + + if ((fd = open(SSH_RANDOM_DEV, O_RDONLY)) == -1) { + save_errno = errno; + /* Try egd/prngd before giving up. */ + if (seed_from_prngd(s, len) == 0) + return 0; + fatal("Couldn't open %s: %s", SSH_RANDOM_DEV, + strerror(save_errno)); + } + while (o < len) { + r = read(fd, (u_char *)s + o, len - o); + if (r < 0) { + if (errno == EAGAIN || errno == EINTR || + errno == EWOULDBLOCK) + continue; + fatal("read %s: %s", SSH_RANDOM_DEV, strerror(errno)); + } + o += r; + } + close(fd); +#endif /* WITH_OPENSSL */ + return 0; +} diff --git a/ext/arc4random/chacha_private.h b/ext/arc4random/chacha_private.h new file mode 100644 index 000000000000..cdcb78560825 --- /dev/null +++ b/ext/arc4random/chacha_private.h @@ -0,0 +1,224 @@ +/* OPENBSD ORIGINAL: lib/libc/crypt/chacha_private.h */ + +/* +chacha-merged.c version 20080118 +D. J. Bernstein +Public domain. +*/ + +/* $OpenBSD: chacha_private.h,v 1.3 2022/02/28 21:56:29 dtucker Exp $ */ + +typedef unsigned char u8; +typedef unsigned int u32; + +typedef struct +{ + u32 input[16]; /* could be compressed */ +} chacha_ctx; + +#define U8C(v) (v##U) +#define U32C(v) (v##U) + +#define U8V(v) ((u8)(v) & U8C(0xFF)) +#define U32V(v) ((u32)(v) & U32C(0xFFFFFFFF)) + +#define ROTL32(v, n) \ + (U32V((v) << (n)) | ((v) >> (32 - (n)))) + +#define U8TO32_LITTLE(p) \ + (((u32)((p)[0]) ) | \ + ((u32)((p)[1]) << 8) | \ + ((u32)((p)[2]) << 16) | \ + ((u32)((p)[3]) << 24)) + +#define U32TO8_LITTLE(p, v) \ + do { \ + (p)[0] = U8V((v) ); \ + (p)[1] = U8V((v) >> 8); \ + (p)[2] = U8V((v) >> 16); \ + (p)[3] = U8V((v) >> 24); \ + } while (0) + +#define ROTATE(v,c) (ROTL32(v,c)) +#define XOR(v,w) ((v) ^ (w)) +#define PLUS(v,w) (U32V((v) + (w))) +#define PLUSONE(v) (PLUS((v),1)) + +#define QUARTERROUND(a,b,c,d) \ + a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \ + a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \ + c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); + +static const char sigma[16] = "expand 32-byte k"; +static const char tau[16] = "expand 16-byte k"; + +static void +chacha_keysetup(chacha_ctx *x,const u8 *k,u32 kbits) +{ + const char *constants; + + x->input[4] = U8TO32_LITTLE(k + 0); + x->input[5] = U8TO32_LITTLE(k + 4); + x->input[6] = U8TO32_LITTLE(k + 8); + x->input[7] = U8TO32_LITTLE(k + 12); + if (kbits == 256) { /* recommended */ + k += 16; + constants = sigma; + } else { /* kbits == 128 */ + constants = tau; + } + x->input[8] = U8TO32_LITTLE(k + 0); + x->input[9] = U8TO32_LITTLE(k + 4); + x->input[10] = U8TO32_LITTLE(k + 8); + x->input[11] = U8TO32_LITTLE(k + 12); + x->input[0] = U8TO32_LITTLE(constants + 0); + x->input[1] = U8TO32_LITTLE(constants + 4); + x->input[2] = U8TO32_LITTLE(constants + 8); + x->input[3] = U8TO32_LITTLE(constants + 12); +} + +static void +chacha_ivsetup(chacha_ctx *x,const u8 *iv) +{ + x->input[12] = 0; + x->input[13] = 0; + x->input[14] = U8TO32_LITTLE(iv + 0); + x->input[15] = U8TO32_LITTLE(iv + 4); +} + +static void +chacha_encrypt_bytes(chacha_ctx *x,const u8 *m,u8 *c,u32 bytes) +{ + u32 x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; + u32 j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; + u8 *ctarget = NULL; + u8 tmp[64]; + u_int i; + + if (!bytes) return; + + j0 = x->input[0]; + j1 = x->input[1]; + j2 = x->input[2]; + j3 = x->input[3]; + j4 = x->input[4]; + j5 = x->input[5]; + j6 = x->input[6]; + j7 = x->input[7]; + j8 = x->input[8]; + j9 = x->input[9]; + j10 = x->input[10]; + j11 = x->input[11]; + j12 = x->input[12]; + j13 = x->input[13]; + j14 = x->input[14]; + j15 = x->input[15]; + + for (;;) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) tmp[i] = m[i]; + m = tmp; + ctarget = c; + c = tmp; + } + x0 = j0; + x1 = j1; + x2 = j2; + x3 = j3; + x4 = j4; + x5 = j5; + x6 = j6; + x7 = j7; + x8 = j8; + x9 = j9; + x10 = j10; + x11 = j11; + x12 = j12; + x13 = j13; + x14 = j14; + x15 = j15; + for (i = 20;i > 0;i -= 2) { + QUARTERROUND( x0, x4, x8,x12) + QUARTERROUND( x1, x5, x9,x13) + QUARTERROUND( x2, x6,x10,x14) + QUARTERROUND( x3, x7,x11,x15) + QUARTERROUND( x0, x5,x10,x15) + QUARTERROUND( x1, x6,x11,x12) + QUARTERROUND( x2, x7, x8,x13) + QUARTERROUND( x3, x4, x9,x14) + } + x0 = PLUS(x0,j0); + x1 = PLUS(x1,j1); + x2 = PLUS(x2,j2); + x3 = PLUS(x3,j3); + x4 = PLUS(x4,j4); + x5 = PLUS(x5,j5); + x6 = PLUS(x6,j6); + x7 = PLUS(x7,j7); + x8 = PLUS(x8,j8); + x9 = PLUS(x9,j9); + x10 = PLUS(x10,j10); + x11 = PLUS(x11,j11); + x12 = PLUS(x12,j12); + x13 = PLUS(x13,j13); + x14 = PLUS(x14,j14); + x15 = PLUS(x15,j15); + +#ifndef KEYSTREAM_ONLY + x0 = XOR(x0,U8TO32_LITTLE(m + 0)); + x1 = XOR(x1,U8TO32_LITTLE(m + 4)); + x2 = XOR(x2,U8TO32_LITTLE(m + 8)); + x3 = XOR(x3,U8TO32_LITTLE(m + 12)); + x4 = XOR(x4,U8TO32_LITTLE(m + 16)); + x5 = XOR(x5,U8TO32_LITTLE(m + 20)); + x6 = XOR(x6,U8TO32_LITTLE(m + 24)); + x7 = XOR(x7,U8TO32_LITTLE(m + 28)); + x8 = XOR(x8,U8TO32_LITTLE(m + 32)); + x9 = XOR(x9,U8TO32_LITTLE(m + 36)); + x10 = XOR(x10,U8TO32_LITTLE(m + 40)); + x11 = XOR(x11,U8TO32_LITTLE(m + 44)); + x12 = XOR(x12,U8TO32_LITTLE(m + 48)); + x13 = XOR(x13,U8TO32_LITTLE(m + 52)); + x14 = XOR(x14,U8TO32_LITTLE(m + 56)); + x15 = XOR(x15,U8TO32_LITTLE(m + 60)); +#endif + + j12 = PLUSONE(j12); + if (!j12) { + j13 = PLUSONE(j13); + /* stopping at 2^70 bytes per nonce is user's responsibility */ + } + + U32TO8_LITTLE(c + 0,x0); + U32TO8_LITTLE(c + 4,x1); + U32TO8_LITTLE(c + 8,x2); + U32TO8_LITTLE(c + 12,x3); + U32TO8_LITTLE(c + 16,x4); + U32TO8_LITTLE(c + 20,x5); + U32TO8_LITTLE(c + 24,x6); + U32TO8_LITTLE(c + 28,x7); + U32TO8_LITTLE(c + 32,x8); + U32TO8_LITTLE(c + 36,x9); + U32TO8_LITTLE(c + 40,x10); + U32TO8_LITTLE(c + 44,x11); + U32TO8_LITTLE(c + 48,x12); + U32TO8_LITTLE(c + 52,x13); + U32TO8_LITTLE(c + 56,x14); + U32TO8_LITTLE(c + 60,x15); + + if (bytes <= 64) { + if (bytes < 64) { + for (i = 0;i < bytes;++i) ctarget[i] = c[i]; + } + x->input[12] = j12; + x->input[13] = j13; + return; + } + bytes -= 64; + c += 64; +#ifndef KEYSTREAM_ONLY + m += 64; +#endif + } +} From 8be2b8385cd1cf1ccd53d941087101f4547670ff Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 11:17:00 +0200 Subject: [PATCH 379/909] Port of the openss-poratble arc4random code to our build environment --- ext/arc4random/.gitignore | 5 +++++ ext/arc4random/Makefile.am | 6 ++++++ ext/arc4random/arc4random.c | 3 +++ ext/arc4random/arc4random.h | 4 ++-- ext/arc4random/arc4random.hh | 9 +++++++++ ext/arc4random/includes.h | 20 ++++++++++++++++++++ ext/arc4random/log.h | 1 + 7 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 ext/arc4random/.gitignore create mode 100644 ext/arc4random/Makefile.am create mode 100644 ext/arc4random/arc4random.hh create mode 100644 ext/arc4random/includes.h create mode 100644 ext/arc4random/log.h diff --git a/ext/arc4random/.gitignore b/ext/arc4random/.gitignore new file mode 100644 index 000000000000..24ad051c6ec8 --- /dev/null +++ b/ext/arc4random/.gitignore @@ -0,0 +1,5 @@ +*.la +*.lo +*.o +Makefile +Makefile.in diff --git a/ext/arc4random/Makefile.am b/ext/arc4random/Makefile.am new file mode 100644 index 000000000000..ee46ad2a57d7 --- /dev/null +++ b/ext/arc4random/Makefile.am @@ -0,0 +1,6 @@ +noinst_LTLIBRARIES = libarc4random.la +libarc4random_la_SOURCES = arc4random.c arc4random.h \ + arc4random_uniform.c \ + bsd-getentropy.c \ + includes.h \ + log.h diff --git a/ext/arc4random/arc4random.c b/ext/arc4random/arc4random.c index ffd33734db56..afcaa64720e2 100644 --- a/ext/arc4random/arc4random.c +++ b/ext/arc4random/arc4random.c @@ -205,6 +205,9 @@ _rs_random_u32(uint32_t *val) rs->rs_have -= sizeof(*val); } +#include +static pthread_mutex_t arc4mutex = PTHREAD_MUTEX_INITIALIZER; + uint32_t arc4random(void) { diff --git a/ext/arc4random/arc4random.h b/ext/arc4random/arc4random.h index 5af3a4492a82..402b26312a46 100644 --- a/ext/arc4random/arc4random.h +++ b/ext/arc4random/arc4random.h @@ -28,8 +28,8 @@ #include /* OpenSSH isn't multithreaded */ -#define _ARC4_LOCK() -#define _ARC4_UNLOCK() +#define _ARC4_LOCK() pthread_mutex_lock(&arc4mutex); +#define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4mutex); #define _ARC4_ATFORK(f) static inline void diff --git a/ext/arc4random/arc4random.hh b/ext/arc4random/arc4random.hh new file mode 100644 index 000000000000..72449fb24883 --- /dev/null +++ b/ext/arc4random/arc4random.hh @@ -0,0 +1,9 @@ +#pragma once + +#include + +extern "C" { +uint32_t arc4random(void); +void arc4random_buf(void *buf, size_t nbytes); +uint32_t arc4random_uniform(uint32_t upper_bound); +} diff --git a/ext/arc4random/includes.h b/ext/arc4random/includes.h new file mode 100644 index 000000000000..8914c12aa9b0 --- /dev/null +++ b/ext/arc4random/includes.h @@ -0,0 +1,20 @@ +#include "config.h" + +#ifdef HAVE_GETRANDOM +#include +#endif + +#include +#include +#include + +#include +#include + +#define seed_from_prngd(a, b) -1 + +uint32_t arc4random(void); +void arc4random_buf(void *buf, size_t nbytes); +uint32_t arc4random_uniform(uint32_t upper_bound); + +#define DEF_WEAK(x) diff --git a/ext/arc4random/log.h b/ext/arc4random/log.h new file mode 100644 index 000000000000..51d7af279919 --- /dev/null +++ b/ext/arc4random/log.h @@ -0,0 +1 @@ +#define fatal(...) do { fprintf(stderr, __VA_ARGS__); abort(); } while (0) From a0d8a0f08ec470d7da2abf91c6fb2a090a42e203 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 11:19:42 +0200 Subject: [PATCH 380/909] Start buildina and using arc4random --- configure.ac | 4 +- ext/Makefile.am | 2 + pdns/Makefile.am | 24 +- pdns/auth-main.cc | 2 - pdns/calidns.cc | 1 - pdns/dns_random.cc | 407 ------------------ pdns/dns_random.hh | 20 +- pdns/dns_random_urandom.cc | 2 - pdns/dnsdistdist/Makefile.am | 9 +- pdns/dnsdistdist/configure.ac | 5 +- pdns/dnsdistdist/ext/arc4random/.gitignore | 5 + pdns/dnsdistdist/ext/arc4random/Makefile.am | 1 + pdns/dnsdistdist/ext/arc4random/arc4random.c | 1 + pdns/dnsdistdist/ext/arc4random/arc4random.h | 1 + pdns/dnsdistdist/ext/arc4random/arc4random.hh | 1 + .../ext/arc4random/arc4random_uniform.c | 1 + .../ext/arc4random/bsd-getentropy.c | 1 + .../ext/arc4random/chacha_private.h | 1 + pdns/dnsdistdist/ext/arc4random/includes.h | 1 + pdns/dnsdistdist/ext/arc4random/log.h | 1 + pdns/ixfrdist.cc | 2 - pdns/pdnsutil.cc | 2 - pdns/recursordist/Makefile.am | 13 +- pdns/recursordist/configure.ac | 4 +- pdns/recursordist/dns_random.cc | 1 - pdns/recursordist/dns_random_urandom.cc | 1 - pdns/recursordist/ext/Makefile.am | 2 + pdns/recursordist/ext/arc4random/.gitignore | 5 + pdns/recursordist/ext/arc4random/Makefile.am | 1 + pdns/recursordist/ext/arc4random/arc4random.c | 1 + pdns/recursordist/ext/arc4random/arc4random.h | 1 + .../recursordist/ext/arc4random/arc4random.hh | 1 + .../ext/arc4random/arc4random_uniform.c | 1 + .../ext/arc4random/bsd-getentropy.c | 1 + .../ext/arc4random/chacha_private.h | 1 + pdns/recursordist/ext/arc4random/includes.h | 1 + pdns/recursordist/ext/arc4random/log.h | 1 + pdns/recursordist/rec-main.cc | 2 - pdns/speedtest.cc | 1 - pdns/test-dns_random_hh.cc | 9 - 40 files changed, 82 insertions(+), 459 deletions(-) delete mode 100644 pdns/dns_random.cc delete mode 100644 pdns/dns_random_urandom.cc create mode 100644 pdns/dnsdistdist/ext/arc4random/.gitignore create mode 120000 pdns/dnsdistdist/ext/arc4random/Makefile.am create mode 120000 pdns/dnsdistdist/ext/arc4random/arc4random.c create mode 120000 pdns/dnsdistdist/ext/arc4random/arc4random.h create mode 120000 pdns/dnsdistdist/ext/arc4random/arc4random.hh create mode 120000 pdns/dnsdistdist/ext/arc4random/arc4random_uniform.c create mode 120000 pdns/dnsdistdist/ext/arc4random/bsd-getentropy.c create mode 120000 pdns/dnsdistdist/ext/arc4random/chacha_private.h create mode 120000 pdns/dnsdistdist/ext/arc4random/includes.h create mode 120000 pdns/dnsdistdist/ext/arc4random/log.h delete mode 120000 pdns/recursordist/dns_random.cc delete mode 120000 pdns/recursordist/dns_random_urandom.cc create mode 100644 pdns/recursordist/ext/arc4random/.gitignore create mode 120000 pdns/recursordist/ext/arc4random/Makefile.am create mode 120000 pdns/recursordist/ext/arc4random/arc4random.c create mode 120000 pdns/recursordist/ext/arc4random/arc4random.h create mode 120000 pdns/recursordist/ext/arc4random/arc4random.hh create mode 120000 pdns/recursordist/ext/arc4random/arc4random_uniform.c create mode 120000 pdns/recursordist/ext/arc4random/bsd-getentropy.c create mode 120000 pdns/recursordist/ext/arc4random/chacha_private.h create mode 120000 pdns/recursordist/ext/arc4random/includes.h create mode 120000 pdns/recursordist/ext/arc4random/log.h diff --git a/configure.ac b/configure.ac index 93430f7a1df3..ca8ac283c886 100644 --- a/configure.ac +++ b/configure.ac @@ -152,7 +152,8 @@ PDNS_FROM_GIT dnl Checks for library functions. dnl the *_r functions are in posix so we can use them unconditionally, but the ext/yahttp code is dnl using the defines. -AC_CHECK_FUNCS_ONCE([strcasestr localtime_r gmtime_r recvmmsg sched_setscheduler getrandom arc4random]) +AC_CHECK_FUNCS_ONCE([strcasestr localtime_r gmtime_r recvmmsg sched_setscheduler]) +AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) AM_CONDITIONAL([HAVE_RECVMMSG], [test "x$ac_cv_func_recvmmsg" = "xyes"]) @@ -345,6 +346,7 @@ AC_CONFIG_FILES([ docs/Makefile pdns/pdns.init ext/Makefile + ext/arc4random/Makefile ext/ipcrypt/Makefile ext/yahttp/Makefile ext/yahttp/yahttp/Makefile diff --git a/ext/Makefile.am b/ext/Makefile.am index 4cf7265338f0..0ae01c430f3e 100644 --- a/ext/Makefile.am +++ b/ext/Makefile.am @@ -1,9 +1,11 @@ SUBDIRS = \ + arc4random \ ipcrypt \ json11 \ yahttp DIST_SUBDIRS = \ + arc4random \ ipcrypt \ json11 \ yahttp diff --git a/pdns/Makefile.am b/pdns/Makefile.am index a982f05168be..50f93222c2fe 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1,4 +1,5 @@ JSON11_LIBS = $(top_builddir)/ext/json11/libjson11.la +ARC4RANDOM_LIBS = $(top_builddir)/ext/arc4random/libarc4random.la AM_CPPFLAGS += \ -I$(top_srcdir)/ext/json11 \ @@ -18,6 +19,7 @@ AM_CXXFLAGS = \ AM_LDFLAGS = \ $(PROGRAM_LDFLAGS) \ $(LIBCRYPTO_LIBS) \ + $(ARC4RANDOM_LIBS) \ $(THREADFLAGS) AM_LFLAGS = -i @@ -214,7 +216,7 @@ pdns_server_SOURCES = \ digests.hh \ distributor.hh \ dns.cc dns.hh \ - dns_random.cc dns_random.hh \ + dns_random.hh \ dnsbackend.cc dnsbackend.hh \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ @@ -355,7 +357,6 @@ pdnsutil_SOURCES = \ credentials.cc credentials.hh \ dbdnsseckeeper.cc \ dns.cc \ - dns_random.cc \ dnsbackend.cc \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ @@ -454,7 +455,6 @@ zone2sql_SOURCES = \ bindparser.yy \ bindparserclasses.hh \ dns.cc \ - dns_random_urandom.cc \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ dnsparser.cc \ @@ -520,7 +520,6 @@ zone2ldap_SOURCES = \ bindlexer.l \ bindparser.yy \ bindparserclasses.hh \ - dns_random_urandom.cc \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ dnsparser.cc \ @@ -603,7 +602,7 @@ calidns_SOURCES = \ base32.cc \ base64.cc base64.hh \ calidns.cc \ - dns_random_urandom.cc dns_random.hh \ + dns_random.hh \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ dnsparser.cc dnsparser.hh \ @@ -654,7 +653,6 @@ stubquery_SOURCES = \ arguments.cc arguments.hh \ base32.cc \ base64.cc \ - dns_random_urandom.cc \ dnslabeltext.cc \ dnsname.cc \ dnsparser.cc \ @@ -679,7 +677,7 @@ stubquery_LDFLAGS = $(AM_LDFLAGS) $(LIBCRYPTO_LDFLAGS) saxfr_SOURCES = \ base32.cc \ base64.cc base64.hh \ - dns_random_urandom.cc dns_random.hh \ + dns_random.hh \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ dnsparser.cc dnsparser.hh \ @@ -719,7 +717,7 @@ ixfrdist_SOURCES = \ base64.cc base64.hh \ credentials.cc credentials.hh \ dns.cc \ - dns_random_urandom.cc dns_random.hh \ + dns_random.hh \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ dnsparser.cc dnsparser.hh \ @@ -785,7 +783,7 @@ ixplore_SOURCES = \ base32.cc \ base64.cc base64.hh \ dns.cc \ - dns_random_urandom.cc dns_random.hh \ + dns_random.hh \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ dnsparser.cc dnsparser.hh \ @@ -896,7 +894,7 @@ tsig_tests_SOURCES = \ base64.cc base64.hh \ digests.hh \ dns.cc \ - dns_random_urandom.cc dns_random.hh \ + dns_random.hh \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ dnsparser.cc dnsparser.hh \ @@ -933,7 +931,7 @@ speedtest_SOURCES = \ base32.cc \ base64.cc base64.hh \ credentials.cc credentials.hh \ - dns_random.cc dns_random.hh \ + dns_random.hh \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ dnsparser.cc dnsparser.hh \ @@ -980,7 +978,7 @@ dnsbulktest_SOURCES = \ arguments.cc arguments.hh \ base32.cc \ base64.cc \ - dns_random.cc dns_random.hh \ + dns_random.hh \ dnsbulktest.cc \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ @@ -1134,7 +1132,6 @@ pdns_notify_SOURCES = \ base32.cc \ base64.cc base64.hh \ dns.cc \ - dns_random.cc \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ dnsparser.cc dnsparser.hh \ @@ -1341,7 +1338,6 @@ testrunner_SOURCES = \ credentials.cc credentials.hh \ dbdnsseckeeper.cc \ dns.cc \ - dns_random.cc \ dnsbackend.cc \ dnslabeltext.cc \ dnsname.cc \ diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index 12722088bb2a..390f7188f4c0 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -1303,8 +1303,6 @@ int main(int argc, char** argv) openssl_thread_setup(); openssl_seed(); - /* setup rng */ - dns_random_init(); #ifdef HAVE_LUA_RECORDS MiniCurl::init(); diff --git a/pdns/calidns.cc b/pdns/calidns.cc index 89886e3a7049..87bfbe57edba 100644 --- a/pdns/calidns.cc +++ b/pdns/calidns.cc @@ -299,7 +299,6 @@ try Netmask ecsRange; if (g_vm.count("ecs")) { - dns_random_init("0123456789abcdef"); try { ecsRange = Netmask(g_vm["ecs"].as()); diff --git a/pdns/dns_random.cc b/pdns/dns_random.cc deleted file mode 100644 index a1991f438bd0..000000000000 --- a/pdns/dns_random.cc +++ /dev/null @@ -1,407 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include -#include -#include -#include -#include -#include -#include "dns_random.hh" -#include "arguments.hh" -#include "logger.hh" - -#if defined(HAVE_RANDOMBYTES_STIR) -#include -#endif -#if defined(HAVE_RAND_BYTES) -#include -#endif -#if defined(HAVE_GETRANDOM) -#include -#endif - -static enum DNS_RNG { - RNG_UNINITIALIZED = 0, - RNG_SODIUM, - RNG_OPENSSL, - RNG_GETRANDOM, - RNG_ARC4RANDOM, - RNG_URANDOM, - RNG_KISS, -} chosen_rng - = RNG_UNINITIALIZED; - -static int urandom_fd = -1; - -#if defined(HAVE_KISS_RNG) -/* KISS is intended for development use only */ -static unsigned int kiss_seed; -static uint32_t kiss_z, kiss_w, kiss_jsr, kiss_jcong; - -static void -kiss_init(unsigned int seed) -{ - kiss_seed = seed; - kiss_jsr = 0x5eed5eed; /* simply mustn't be 0 */ - kiss_z = 1 ^ (kiss_w = kiss_jcong = seed); /* w=z=0 is bad, see Rose */ -} - -static unsigned int -kiss_rand(void) -{ - kiss_z = 36969 * (kiss_z & 65535) + (kiss_z >> 16); - kiss_w = 18000 * (kiss_w & 65535) + (kiss_w >> 16); - kiss_jcong = 69069 * kiss_jcong + 1234567; - kiss_jsr ^= (kiss_jsr << 13); /* <<17, >>13 gives cycle length 2^28.2 max */ - kiss_jsr ^= (kiss_jsr >> 17); /* <<13, >>17 gives maximal cycle length */ - kiss_jsr ^= (kiss_jsr << 5); - return (((kiss_z << 16) + kiss_w) ^ kiss_jcong) + kiss_jsr; -} -#endif - -static void dns_random_setup(bool force = false) -{ - string rdev; - string rng; - /* check if selection has been done */ - if (chosen_rng > RNG_UNINITIALIZED && !force) { - return; - } - -/* XXX: A horrible hack to allow using dns_random in places where arguments are not available. - Forces /dev/urandom usage -*/ -#if defined(USE_URANDOM_ONLY) - chosen_rng = RNG_URANDOM; - rdev = "/dev/urandom"; -#else - rng = ::arg()["rng"]; - rdev = ::arg()["entropy-source"]; - if (rng == "auto") { // NOLINT: I see no way to avoid repeating blocks reported by clang-tidy -#if defined(HAVE_GETRANDOM) - chosen_rng = RNG_GETRANDOM; -#elif defined(HAVE_ARC4RANDOM) - chosen_rng = RNG_ARC4RANDOM; -#elif defined(HAVE_RANDOMBYTES_STIR) - chosen_rng = RNG_SODIUM; -#elif defined(HAVE_RAND_BYTES) - chosen_rng = RNG_OPENSSL; -#else - chosen_rng = RNG_URANDOM; -#endif -#if defined(HAVE_RANDOMBYTES_STIR) - } - else if (rng == "sodium") { - chosen_rng = RNG_SODIUM; -#endif -#if defined(HAVE_RAND_BYTES) - } - else if (rng == "openssl") { - chosen_rng = RNG_OPENSSL; -#endif -#if defined(HAVE_GETRANDOM) - } - else if (rng == "getrandom") { - chosen_rng = RNG_GETRANDOM; -#endif -#if defined(HAVE_ARC4RANDOM) - } - else if (rng == "arc4random") { - chosen_rng = RNG_ARC4RANDOM; -#endif - } - else if (rng == "urandom") { - chosen_rng = RNG_URANDOM; -#if defined(HAVE_KISS_RNG) - } - else if (rng == "kiss") { - chosen_rng = RNG_KISS; - g_log << Logger::Warning << "kiss rng should not be used in production environment" << std::endl; -#endif - } - else { - throw std::runtime_error("Unsupported rng '" + rng + "'"); - } - -#if defined(HAVE_RANDOMBYTES_STIR) - if (chosen_rng == RNG_SODIUM) { - if (sodium_init() == -1) { - throw std::runtime_error("Unable to initialize sodium crypto library"); - } - /* make sure it's set up */ - randombytes_stir(); - } -#endif - -#if defined(HAVE_GETRANDOM) - if (chosen_rng == RNG_GETRANDOM) { - char buf = 0; - // some systems define getrandom but it does not really work, e.g. because it's - // not present in kernel. - if (getrandom(&buf, sizeof(buf), 0) == -1 && errno != EINTR) { - g_log << Logger::Warning << "getrandom() failed: " << stringerror() << ", falling back to " + rdev << std::endl; - chosen_rng = RNG_URANDOM; - } - } -#endif - -#if defined(HAVE_RAND_BYTES) - if (chosen_rng == RNG_OPENSSL) { - int ret = 0; - unsigned char buf = 0; - if ((ret = RAND_bytes(&buf, sizeof(buf))) == -1) { - throw std::runtime_error("RAND_bytes not supported by current SSL engine"); - } - if (ret == 0) { - throw std::runtime_error("Openssl RNG was not seeded"); - } - } -#endif -#endif /* USE_URANDOM_ONLY */ - if (chosen_rng == RNG_URANDOM) { - urandom_fd = open(rdev.c_str(), O_RDONLY); - if (urandom_fd == -1) { - throw std::runtime_error("Cannot open " + rdev + ": " + stringerror()); - } - } -#if defined(HAVE_KISS_RNG) - if (chosen_rng == RNG_KISS) { - int fileDesc = open(rdev.c_str(), O_RDONLY); - if (fileDesc == -1) { - throw std::runtime_error("Cannot open " + rdev + ": " + stringerror()); - } - unsigned int seed = 0; - if (read(urandom_fd, &seed, sizeof(seed)) < 0) { - (void)close(fileDesc); - throw std::runtime_error("Cannot read random device"); - } - kiss_init(seed); - (void)close(fileDesc); - } -#endif -} - -void dns_random_init(const string& data __attribute__((unused)), bool force) -{ - dns_random_setup(force); - (void)dns_random(1); - // init should occur already in dns_random_setup - // this interface is only for KISS -#if defined(HAVE_KISS_RNG) - unsigned int seed; - if (chosen_rng != RNG_KISS) - return; - if (data.size() != 16) - throw std::runtime_error("invalid seed"); - seed = (data[0] + (data[1] << 8) + (data[2] << 16) + (data[3] << 24)) ^ (data[4] + (data[5] << 8) + (data[6] << 16) + (data[7] << 24)) ^ (data[8] + (data[9] << 8) + (data[10] << 16) + (data[11] << 24)) ^ (data[12] + (data[13] << 8) + (data[14] << 16) + (data[15] << 24)); - kiss_init(seed); -#endif -} - -uint32_t dns_random_uint32() -{ - if (chosen_rng == RNG_UNINITIALIZED) { - dns_random_setup(); - } - - switch (chosen_rng) { - case RNG_UNINITIALIZED: - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached - case RNG_SODIUM: -#if defined(HAVE_RANDOMBYTES_STIR) && !defined(USE_URANDOM_ONLY) - return randombytes_random(); -#else - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached -#endif /* RND_SODIUM */ - case RNG_OPENSSL: { -#if defined(HAVE_RAND_BYTES) && !defined(USE_URANDOM_ONLY) - uint32_t num = 0; - if (RAND_bytes(reinterpret_cast(&num), sizeof(num)) < 1) { // NOLINT: API - throw std::runtime_error("Openssl RNG was not seeded"); - } - return num; -#else - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached -#endif /* RNG_OPENSSL */ - } - case RNG_GETRANDOM: { -#if defined(HAVE_GETRANDOM) && !defined(USE_URANDOM_ONLY) - uint32_t num = 0; - do { - auto got = getrandom(&num, sizeof(num), 0); - if (got == -1 && errno == EINTR) { - continue; - } - if (got != sizeof(num)) { - throw std::runtime_error("getrandom() failed: " + stringerror()); - } - break; - } while (true); - return num; -#else - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached -#endif - } - case RNG_ARC4RANDOM: -#if defined(HAVE_ARC4RANDOM) && !defined(USE_URANDOM_ONLY) - return arc4random(); -#else - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached -#endif - case RNG_URANDOM: { - uint32_t num = 0; - size_t attempts = 5; - ssize_t got = read(urandom_fd, &num, sizeof(num)); - do { - if (got < 0) { - if (errno == EINTR) { - continue; - } - throw std::runtime_error("Cannot read random device"); - } - if (static_cast(got) != sizeof(num)) { - /* short read, let's retry */ - if (attempts == 0) { - throw std::runtime_error("Too many short reads on random device"); - } - attempts--; - continue; - } - break; - } while (true); - return num; - } -#if defined(HAVE_KISS_RNG) - case RNG_KISS: { - uint32_t num = kiss_rand(); - return num; - } -#endif - default: - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached - }; -} - -uint32_t dns_random(uint32_t upper_bound) -{ - if (chosen_rng == RNG_UNINITIALIZED) { - dns_random_setup(); - } - - if (upper_bound < 2) { - return 0; - } - - unsigned int min = pdns::random_minimum_acceptable_value(upper_bound); - - switch (chosen_rng) { - case RNG_UNINITIALIZED: - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached - case RNG_SODIUM: -#if defined(HAVE_RANDOMBYTES_STIR) && !defined(USE_URANDOM_ONLY) - return randombytes_uniform(upper_bound); -#else - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached -#endif /* RND_SODIUM */ - case RNG_OPENSSL: { -#if defined(HAVE_RAND_BYTES) && !defined(USE_URANDOM_ONLY) - uint32_t num = 0; - do { - if (RAND_bytes(reinterpret_cast(&num), sizeof(num)) < 1) { // NOLINT: API - throw std::runtime_error("Openssl RNG was not seeded"); - } - } while (num < min); - - return num % upper_bound; -#else - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached -#endif /* RNG_OPENSSL */ - } - case RNG_GETRANDOM: { -#if defined(HAVE_GETRANDOM) && !defined(USE_URANDOM_ONLY) - uint32_t num = 0; - do { - auto got = getrandom(&num, sizeof(num), 0); - if (got == -1 && errno == EINTR) { - continue; - } - if (got != sizeof(num)) { - throw std::runtime_error("getrandom() failed: " + stringerror()); - } - } while (num < min); - - return num % upper_bound; -#else - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached -#endif - } - case RNG_ARC4RANDOM: -#if defined(HAVE_ARC4RANDOM) && !defined(USE_URANDOM_ONLY) - return arc4random_uniform(upper_bound); -#else - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached -#endif - case RNG_URANDOM: { - uint32_t num = 0; - size_t attempts = 5; - do { - ssize_t got = read(urandom_fd, &num, sizeof(num)); - if (got < 0) { - if (errno == EINTR) { - continue; - } - throw std::runtime_error("Cannot read random device"); - } - if (static_cast(got) != sizeof(num)) { - /* short read, let's retry */ - if (attempts == 0) { - throw std::runtime_error("Too many short reads on random device"); - } - attempts--; - continue; - } - } while (num < min); - - return num % upper_bound; - } -#if defined(HAVE_KISS_RNG) - case RNG_KISS: { - uint32_t num = 0; - do { - num = kiss_rand(); - } while (num < min); - - return num % upper_bound; - } -#endif - default: - throw std::runtime_error("Unreachable at " __FILE__ ":" + std::to_string(__LINE__)); // cannot be reached - }; -} - -uint16_t dns_random_uint16() -{ - return dns_random_uint32() & 0xffff; -} diff --git a/pdns/dns_random.hh b/pdns/dns_random.hh index 634d233c1c39..c3bd314d16f7 100644 --- a/pdns/dns_random.hh +++ b/pdns/dns_random.hh @@ -24,10 +24,22 @@ #include #include -void dns_random_init(const std::string& data = "", bool force_reinit = false); -uint32_t dns_random(uint32_t upper_bound); -uint32_t dns_random_uint32(); -uint16_t dns_random_uint16(); +#include + +inline uint32_t dns_random(uint32_t upper_bound) +{ + return arc4random_uniform(upper_bound); +} + +inline uint32_t dns_random_uint32() +{ + return arc4random(); +} + +inline uint16_t dns_random_uint16() +{ + return arc4random() & 0xffff; +} namespace pdns { diff --git a/pdns/dns_random_urandom.cc b/pdns/dns_random_urandom.cc deleted file mode 100644 index 708d3dfdf610..000000000000 --- a/pdns/dns_random_urandom.cc +++ /dev/null @@ -1,2 +0,0 @@ -#define USE_URANDOM_ONLY -#include "dns_random.cc" diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index aaac2e206666..9b951a586694 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -13,7 +13,8 @@ AM_CPPFLAGS += $(SYSTEMD_CFLAGS) \ ACLOCAL_AMFLAGS = -I m4 -SUBDIRS=ext/ipcrypt \ +SUBDIRS=ext/arc4random \ + ext/ipcrypt \ ext/yahttp CLEANFILES = \ @@ -354,7 +355,8 @@ dnsdist_LDADD = \ $(SYSTEMD_LIBS) \ $(NET_SNMP_LIBS) \ $(LIBCAP_LIBS) \ - $(IPCRYPT_LIBS) + $(IPCRYPT_LIBS) \ + $(ARC4RANDOM_LIBS) testrunner_LDFLAGS = \ $(AM_LDFLAGS) \ @@ -368,7 +370,8 @@ testrunner_LDADD = \ $(LIBSODIUM_LIBS) \ $(LUA_LIBS) \ $(RT_LIBS) \ - $(LIBCAP_LIBS) + $(LIBCAP_LIBS) \ + $(ARC4RANDOM_LIBS) if HAVE_CDB dnsdist_LDADD += $(CDB_LDFLAGS) $(CDB_LIBS) diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index 96caf08194ae..6e758c63d7f9 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -48,11 +48,13 @@ PDNS_WITH_SERVICE_USER([dnsdist]) dnl the *_r functions are in posix so we can use them unconditionally, but the ext/yahttp code is dnl using the defines. -AC_CHECK_FUNCS_ONCE([localtime_r gmtime_r getrandom]) +AC_CHECK_FUNCS_ONCE([localtime_r gmtime_r]) +AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) AC_SUBST([YAHTTP_CFLAGS], ['-I$(top_srcdir)/ext/yahttp']) AC_SUBST([YAHTTP_LIBS], ['$(top_builddir)/ext/yahttp/yahttp/libyahttp.la']) AC_SUBST([IPCRYPT_CFLAGS], ['-I$(top_srcdir)/ext/ipcrypt']) AC_SUBST([IPCRYPT_LIBS], ['$(top_builddir)/ext/ipcrypt/libipcrypt.la']) +AC_SUBST([ARC4RANDOM_LIBS], ['$(top_builddir)/ext/arc4random/libarc4random.la']) PDNS_WITH_LUA([mandatory]) AS_IF([test "x$LUAPC" = "xluajit"], [ @@ -156,6 +158,7 @@ AS_IF([test "x$PACKAGEVERSION" != "x"], ) AC_CONFIG_FILES([Makefile + ext/arc4random/Makefile ext/yahttp/Makefile ext/yahttp/yahttp/Makefile ext/ipcrypt/Makefile]) diff --git a/pdns/dnsdistdist/ext/arc4random/.gitignore b/pdns/dnsdistdist/ext/arc4random/.gitignore new file mode 100644 index 000000000000..24ad051c6ec8 --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/.gitignore @@ -0,0 +1,5 @@ +*.la +*.lo +*.o +Makefile +Makefile.in diff --git a/pdns/dnsdistdist/ext/arc4random/Makefile.am b/pdns/dnsdistdist/ext/arc4random/Makefile.am new file mode 120000 index 000000000000..c55d4b1bcb97 --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/Makefile.am @@ -0,0 +1 @@ +../../../../ext/arc4random/Makefile.am \ No newline at end of file diff --git a/pdns/dnsdistdist/ext/arc4random/arc4random.c b/pdns/dnsdistdist/ext/arc4random/arc4random.c new file mode 120000 index 000000000000..9ffca369f3cd --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/arc4random.c @@ -0,0 +1 @@ +../../../../ext/arc4random/arc4random.c \ No newline at end of file diff --git a/pdns/dnsdistdist/ext/arc4random/arc4random.h b/pdns/dnsdistdist/ext/arc4random/arc4random.h new file mode 120000 index 000000000000..55bd2ca6934c --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/arc4random.h @@ -0,0 +1 @@ +../../../../ext/arc4random/arc4random.h \ No newline at end of file diff --git a/pdns/dnsdistdist/ext/arc4random/arc4random.hh b/pdns/dnsdistdist/ext/arc4random/arc4random.hh new file mode 120000 index 000000000000..9fde95a82a84 --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/arc4random.hh @@ -0,0 +1 @@ +../../../../ext/arc4random/arc4random.hh \ No newline at end of file diff --git a/pdns/dnsdistdist/ext/arc4random/arc4random_uniform.c b/pdns/dnsdistdist/ext/arc4random/arc4random_uniform.c new file mode 120000 index 000000000000..fdc2e987fa4a --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/arc4random_uniform.c @@ -0,0 +1 @@ +../../../../ext/arc4random/arc4random_uniform.c \ No newline at end of file diff --git a/pdns/dnsdistdist/ext/arc4random/bsd-getentropy.c b/pdns/dnsdistdist/ext/arc4random/bsd-getentropy.c new file mode 120000 index 000000000000..afa68dd83b79 --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/bsd-getentropy.c @@ -0,0 +1 @@ +../../../../ext/arc4random/bsd-getentropy.c \ No newline at end of file diff --git a/pdns/dnsdistdist/ext/arc4random/chacha_private.h b/pdns/dnsdistdist/ext/arc4random/chacha_private.h new file mode 120000 index 000000000000..b7217838125d --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/chacha_private.h @@ -0,0 +1 @@ +../../../../ext/arc4random/chacha_private.h \ No newline at end of file diff --git a/pdns/dnsdistdist/ext/arc4random/includes.h b/pdns/dnsdistdist/ext/arc4random/includes.h new file mode 120000 index 000000000000..7536dff6176a --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/includes.h @@ -0,0 +1 @@ +../../../../ext/arc4random/includes.h \ No newline at end of file diff --git a/pdns/dnsdistdist/ext/arc4random/log.h b/pdns/dnsdistdist/ext/arc4random/log.h new file mode 120000 index 000000000000..60bb7526361d --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/log.h @@ -0,0 +1 @@ +../../../../ext/arc4random/log.h \ No newline at end of file diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index 6c1193f5fca7..81d7b03cef55 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -1382,8 +1382,6 @@ int main(int argc, char** argv) { // Init the things we need reportAllTypes(); - dns_random_init(); - std::thread ut(updateThread, config["work-dir"].as(), config["keep"].as(), diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 525b4636f43a..2f6a173ca0e2 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -156,8 +156,6 @@ static void loadMainConfig(const std::string& configdir) } #endif openssl_seed(); - /* init rng before chroot */ - dns_random_init(); if (!::arg()["chroot"].empty()) { if (chroot(::arg()["chroot"].c_str())<0 || chdir("/") < 0) { diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index ac6a44ea4730..f65fa102c5e3 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -1,5 +1,6 @@ JSON11_LIBS = $(top_srcdir)/ext/json11/libjson11.la PROBDS_LIBS = $(top_srcdir)/ext/probds/libprobds.la +ARC4RANDOM_LIBS = $(top_srcdir)/ext/arc4random/libarc4random.la AM_CPPFLAGS = $(LUA_CFLAGS) $(YAHTTP_CFLAGS) $(BOOST_CPPFLAGS) $(LIBSODIUM_CFLAGS) $(NET_SNMP_CFLAGS) $(LIBCAP_CFLAGS) $(SANITIZER_FLAGS) -O3 -Wall -pthread -DSYSCONFDIR=\"${sysconfdir}\" $(SYSTEMD_CFLAGS) @@ -113,7 +114,7 @@ pdns_recursor_SOURCES = \ comment.hh \ credentials.cc credentials.hh \ dns.hh dns.cc \ - dns_random.hh dns_random.cc \ + dns_random.hh \ dnsbackend.hh \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ @@ -236,7 +237,8 @@ pdns_recursor_LDADD = \ $(RT_LIBS) \ $(BOOST_SYSTEM_LIBS) \ $(PROBDS_LIBS) \ - $(LIBCAP_LIBS) + $(LIBCAP_LIBS) \ + $(ARC4RANDOM_LIBS) pdns_recursor_LDFLAGS = $(AM_LDFLAGS) \ $(LIBCRYPTO_LDFLAGS) $(BOOST_CONTEXT_LDFLAGS) \ @@ -264,7 +266,7 @@ testrunner_SOURCES = \ circular_buffer.hh \ credentials.cc credentials.hh \ dns.cc dns.hh \ - dns_random.cc dns_random.hh \ + dns_random.hh \ dnslabeltext.cc \ dnsname.cc dnsname.hh \ dnsparser.hh dnsparser.cc \ @@ -382,7 +384,8 @@ testrunner_LDADD = \ $(RT_LIBS) \ $(BOOST_SYSTEM_LIBS) \ $(PROBDS_LIBS) \ - $(LIBCAP_LIBS) + $(LIBCAP_LIBS) \ + $(ARC4RANDOM_LIBS) if NOD_ENABLED testrunner_SOURCES += nod.hh nod.cc \ @@ -399,7 +402,7 @@ pdns_recursor_SOURCES += \ sodiumsigners.cc pdns_recursor_LDADD += $(LIBSODIUM_LIBS) -rec_control_LDADD += $(LIBSODIUM_LIBS) +rec_control_LDADD += $(LIBSODIUM_LIBS) $(ARC4RANDOM_LIBS) testrunner_SOURCES += \ sodiumsigners.cc diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index 8f7e900b7e1d..52bc6d89348e 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -112,7 +112,8 @@ PDNS_CHECK_CURL dnl the *_r functions are in posix so we can use them unconditionally, but the ext/yahttp code is dnl using the defines. -AC_CHECK_FUNCS_ONCE([localtime_r gmtime_r strcasestr getrandom arc4random]) +AC_CHECK_FUNCS_ONCE([localtime_r gmtime_r strcasestr]) +AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) PDNS_CHECK_PTHREAD_NP @@ -190,6 +191,7 @@ CXXVERSION=`$CXX --version | head -1` AC_CONFIG_FILES([Makefile ext/Makefile + ext/arc4random/Makefile ext/json11/Makefile ext/probds/Makefile ext/yahttp/Makefile diff --git a/pdns/recursordist/dns_random.cc b/pdns/recursordist/dns_random.cc deleted file mode 120000 index 9fa10216ba05..000000000000 --- a/pdns/recursordist/dns_random.cc +++ /dev/null @@ -1 +0,0 @@ -../dns_random.cc \ No newline at end of file diff --git a/pdns/recursordist/dns_random_urandom.cc b/pdns/recursordist/dns_random_urandom.cc deleted file mode 120000 index a412aeab0590..000000000000 --- a/pdns/recursordist/dns_random_urandom.cc +++ /dev/null @@ -1 +0,0 @@ -../dns_random_urandom.cc \ No newline at end of file diff --git a/pdns/recursordist/ext/Makefile.am b/pdns/recursordist/ext/Makefile.am index a908d92a41a2..65131d0b277e 100644 --- a/pdns/recursordist/ext/Makefile.am +++ b/pdns/recursordist/ext/Makefile.am @@ -1,9 +1,11 @@ SUBDIRS = \ + arc4random \ yahttp \ json11 \ probds DIST_SUBDIRS = \ + arc4random \ yahttp \ json11 \ probds diff --git a/pdns/recursordist/ext/arc4random/.gitignore b/pdns/recursordist/ext/arc4random/.gitignore new file mode 100644 index 000000000000..24ad051c6ec8 --- /dev/null +++ b/pdns/recursordist/ext/arc4random/.gitignore @@ -0,0 +1,5 @@ +*.la +*.lo +*.o +Makefile +Makefile.in diff --git a/pdns/recursordist/ext/arc4random/Makefile.am b/pdns/recursordist/ext/arc4random/Makefile.am new file mode 120000 index 000000000000..c55d4b1bcb97 --- /dev/null +++ b/pdns/recursordist/ext/arc4random/Makefile.am @@ -0,0 +1 @@ +../../../../ext/arc4random/Makefile.am \ No newline at end of file diff --git a/pdns/recursordist/ext/arc4random/arc4random.c b/pdns/recursordist/ext/arc4random/arc4random.c new file mode 120000 index 000000000000..9ffca369f3cd --- /dev/null +++ b/pdns/recursordist/ext/arc4random/arc4random.c @@ -0,0 +1 @@ +../../../../ext/arc4random/arc4random.c \ No newline at end of file diff --git a/pdns/recursordist/ext/arc4random/arc4random.h b/pdns/recursordist/ext/arc4random/arc4random.h new file mode 120000 index 000000000000..55bd2ca6934c --- /dev/null +++ b/pdns/recursordist/ext/arc4random/arc4random.h @@ -0,0 +1 @@ +../../../../ext/arc4random/arc4random.h \ No newline at end of file diff --git a/pdns/recursordist/ext/arc4random/arc4random.hh b/pdns/recursordist/ext/arc4random/arc4random.hh new file mode 120000 index 000000000000..9fde95a82a84 --- /dev/null +++ b/pdns/recursordist/ext/arc4random/arc4random.hh @@ -0,0 +1 @@ +../../../../ext/arc4random/arc4random.hh \ No newline at end of file diff --git a/pdns/recursordist/ext/arc4random/arc4random_uniform.c b/pdns/recursordist/ext/arc4random/arc4random_uniform.c new file mode 120000 index 000000000000..fdc2e987fa4a --- /dev/null +++ b/pdns/recursordist/ext/arc4random/arc4random_uniform.c @@ -0,0 +1 @@ +../../../../ext/arc4random/arc4random_uniform.c \ No newline at end of file diff --git a/pdns/recursordist/ext/arc4random/bsd-getentropy.c b/pdns/recursordist/ext/arc4random/bsd-getentropy.c new file mode 120000 index 000000000000..afa68dd83b79 --- /dev/null +++ b/pdns/recursordist/ext/arc4random/bsd-getentropy.c @@ -0,0 +1 @@ +../../../../ext/arc4random/bsd-getentropy.c \ No newline at end of file diff --git a/pdns/recursordist/ext/arc4random/chacha_private.h b/pdns/recursordist/ext/arc4random/chacha_private.h new file mode 120000 index 000000000000..b7217838125d --- /dev/null +++ b/pdns/recursordist/ext/arc4random/chacha_private.h @@ -0,0 +1 @@ +../../../../ext/arc4random/chacha_private.h \ No newline at end of file diff --git a/pdns/recursordist/ext/arc4random/includes.h b/pdns/recursordist/ext/arc4random/includes.h new file mode 120000 index 000000000000..7536dff6176a --- /dev/null +++ b/pdns/recursordist/ext/arc4random/includes.h @@ -0,0 +1 @@ +../../../../ext/arc4random/includes.h \ No newline at end of file diff --git a/pdns/recursordist/ext/arc4random/log.h b/pdns/recursordist/ext/arc4random/log.h new file mode 120000 index 000000000000..60bb7526361d --- /dev/null +++ b/pdns/recursordist/ext/arc4random/log.h @@ -0,0 +1 @@ +../../../../ext/arc4random/log.h \ No newline at end of file diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index f46d32eab1c6..e94401e74f18 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2131,8 +2131,6 @@ static int serviceMain(Logr::log_t log) openssl_thread_setup(); openssl_seed(); - /* setup rng before chroot */ - dns_random_init(); if (::arg()["server-id"].empty()) { ::arg().set("server-id") = myHostname.has_value() ? *myHostname : ""; diff --git a/pdns/speedtest.cc b/pdns/speedtest.cc index b8268d01d240..055cb44bed9d 100644 --- a/pdns/speedtest.cc +++ b/pdns/speedtest.cc @@ -1084,7 +1084,6 @@ struct RndSpeedTest explicit RndSpeedTest(std::string which) : name(which){ ::arg().set("entropy-source", "If set, read entropy from this file")="/dev/urandom"; ::arg().set("rng", "") = which; - dns_random_init("", true); } string getName() const { diff --git a/pdns/test-dns_random_hh.cc b/pdns/test-dns_random_hh.cc index db8a0eb0ab78..7c19d72ec82a 100644 --- a/pdns/test-dns_random_hh.cc +++ b/pdns/test-dns_random_hh.cc @@ -44,11 +44,8 @@ const std::vector rndSources = { BOOST_AUTO_TEST_CASE(test_dns_random_garbage) { - ::arg().set("rng") = "garbage"; ::arg().set("entropy-source") = "/dev/urandom"; - - BOOST_CHECK_THROW(dns_random_init("", true), std::runtime_error); } BOOST_AUTO_TEST_CASE(test_dns_random_upper_bound) @@ -56,8 +53,6 @@ BOOST_AUTO_TEST_CASE(test_dns_random_upper_bound) ::arg().set("rng") = "auto"; ::arg().set("entropy-source") = "/dev/urandom"; - dns_random_init("", true); - map seen; for (unsigned int iteration = 0; iteration < 100000; ++iteration) { seen[dns_random(10)] = true; @@ -81,8 +76,6 @@ static void test_dns_random_avg(const string& source) ::arg().set("rng") = source; ::arg().set("entropy-source") = "/dev/urandom"; - dns_random_init("", true); - acc_t acc; for (unsigned int iteration = 0; iteration < 100000; ++iteration) { @@ -99,8 +92,6 @@ static void test_dns_random_uint32_avg(const string& source) ::arg().set("rng") = source; ::arg().set("entropy-source") = "/dev/urandom"; - dns_random_init("", true); - acc_t acc; for (unsigned int iteration = 0; iteration < 100000; ++iteration) { From f87175b0e2714ec42b94f90b7d4070dd7c5e74dc Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 12:01:54 +0200 Subject: [PATCH 381/909] Tweaks for macOS --- configure.ac | 3 +++ ext/arc4random/includes.h | 6 +++--- pdns/dnsdistdist/configure.ac | 4 ++++ pdns/recursordist/configure.ac | 4 ++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/configure.ac b/configure.ac index ca8ac283c886..3d1969078cec 100644 --- a/configure.ac +++ b/configure.ac @@ -84,6 +84,9 @@ AC_CHECK_HEADERS( )], [have_mmap=no] ) +AC_CHECK_HEADERS([ + sys/random.h +]) PDNS_WITH_LIBSODIUM PDNS_WITH_LIBDECAF diff --git a/ext/arc4random/includes.h b/ext/arc4random/includes.h index 8914c12aa9b0..8d17335b6799 100644 --- a/ext/arc4random/includes.h +++ b/ext/arc4random/includes.h @@ -1,8 +1,8 @@ #include "config.h" -#ifdef HAVE_GETRANDOM -#include -#endif +//#ifdef HAVE_SYS_RANDOM_H +//#include +//#endif #include #include diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index 6e758c63d7f9..501f87a6a33f 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -56,6 +56,10 @@ AC_SUBST([IPCRYPT_CFLAGS], ['-I$(top_srcdir)/ext/ipcrypt']) AC_SUBST([IPCRYPT_LIBS], ['$(top_builddir)/ext/ipcrypt/libipcrypt.la']) AC_SUBST([ARC4RANDOM_LIBS], ['$(top_builddir)/ext/arc4random/libarc4random.la']) +AC_CHECK_HEADERS([ + sys/random.h +]) + PDNS_WITH_LUA([mandatory]) AS_IF([test "x$LUAPC" = "xluajit"], [ # export all symbols with default visibility, to be able to use the Lua FFI interface diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index 52bc6d89348e..3f455a7f5d9c 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -115,6 +115,10 @@ dnl using the defines. AC_CHECK_FUNCS_ONCE([localtime_r gmtime_r strcasestr]) AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) +AC_CHECK_HEADERS([ + sys/random.h +]) + PDNS_CHECK_PTHREAD_NP AC_SUBST([socketdir]) From 3dc4644f6a04a4c3e5b9ef89a178f5e7dd87ed26 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 12:50:36 +0200 Subject: [PATCH 382/909] Stop using random(), only place left is in dnsdist-random.cc as a fallback --- pdns/auth-main.cc | 2 -- pdns/credentials.cc | 3 ++- pdns/dnsdist-lua-rules.cc | 5 +++-- pdns/dnsdistdist/dnsdist-lbpolicies.cc | 3 ++- pdns/dnsdistdist/dnsdist-rules.hh | 3 ++- pdns/misc.cc | 5 +++-- pdns/pdnsutil.cc | 2 +- pdns/recursordist/rec-main.cc | 1 - pdns/unix_utility.cc | 8 -------- pdns/utility.hh | 3 --- 10 files changed, 13 insertions(+), 22 deletions(-) diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index 390f7188f4c0..38d81c56aaed 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -685,8 +685,6 @@ static void triggerLoadOfLibraries() static void mainthread() { - Utility::srandom(); - gid_t newgid = 0; if (!::arg()["setgid"].empty()) newgid = strToGID(::arg()["setgid"]); diff --git a/pdns/credentials.cc b/pdns/credentials.cc index 343c1205ecac..5038804b6386 100644 --- a/pdns/credentials.cc +++ b/pdns/credentials.cc @@ -40,6 +40,7 @@ #include #include "base64.hh" +#include "dns_random.hh" #include "credentials.hh" #include "misc.hh" @@ -373,7 +374,7 @@ CredentialsHolder::CredentialsHolder(std::string&& password, bool hashPlaintext) } if (!d_isHashed) { - d_fallbackHashPerturb = random(); + d_fallbackHashPerturb = dns_random_uint32(); d_fallbackHash = burtle(reinterpret_cast(d_credentials.getString().data()), d_credentials.getString().size(), d_fallbackHashPerturb); } } diff --git a/pdns/dnsdist-lua-rules.cc b/pdns/dnsdist-lua-rules.cc index 762e4e670db1..8549014e72ef 100644 --- a/pdns/dnsdist-lua-rules.cc +++ b/pdns/dnsdist-lua-rules.cc @@ -22,6 +22,7 @@ #include "dnsdist.hh" #include "dnsdist-lua.hh" #include "dnsdist-rules.hh" +#include "dns_random.hh" std::shared_ptr makeRule(const luadnsrule_t& var) { @@ -443,9 +444,9 @@ void setupLuaRules(LuaContext& luaCtx) items.reserve(1000); for (int n = 0; n < 1000; ++n) { struct item i; - i.ids.qname = DNSName(std::to_string(random())); + i.ids.qname = DNSName(std::to_string(dns_random_uint32())); i.ids.qname += suffix; - i.ids.qtype = random() % 0xff; + i.ids.qtype = dns_random(0xff); i.ids.qclass = QClass::IN; i.ids.protocol = dnsdist::Protocol::DoUDP; i.ids.origRemote = ComboAddress("127.0.0.1"); diff --git a/pdns/dnsdistdist/dnsdist-lbpolicies.cc b/pdns/dnsdistdist/dnsdist-lbpolicies.cc index 70fec893c88a..3aed13d54ab1 100644 --- a/pdns/dnsdistdist/dnsdist-lbpolicies.cc +++ b/pdns/dnsdistdist/dnsdist-lbpolicies.cc @@ -25,6 +25,7 @@ #include "dnsdist-lua.hh" #include "dnsdist-lua-ffi.hh" #include "dolog.hh" +#include "dns_random.hh" GlobalStateHolder g_policy; bool g_roundrobinFailOnNoServer{false}; @@ -153,7 +154,7 @@ static shared_ptr valrandom(const unsigned int val, const Serve shared_ptr wrandom(const ServerPolicy::NumberedServerVector& servers, const DNSQuestion* dq) { - return valrandom(random(), servers); + return valrandom(dns_random_uint32(), servers); } uint32_t g_hashperturb; diff --git a/pdns/dnsdistdist/dnsdist-rules.hh b/pdns/dnsdistdist/dnsdist-rules.hh index 651911e4f800..5b4e80a3947f 100644 --- a/pdns/dnsdistdist/dnsdist-rules.hh +++ b/pdns/dnsdistdist/dnsdist-rules.hh @@ -33,6 +33,7 @@ #include "dnsdist-lua-ffi.hh" #include "dolog.hh" #include "dnsparser.hh" +#include "dns_random.hh" class MaxQPSIPRule : public DNSRule { @@ -1055,7 +1056,7 @@ public: { if(d_proba == 1.0) return true; - double rnd = 1.0*random() / RAND_MAX; + double rnd = 1.0*dns_random_uint32() / UINT32_MAX; return rnd > (1.0 - d_proba); } string toString() const override diff --git a/pdns/misc.cc b/pdns/misc.cc index 4cfe6d4196cc..5c9c81785fa4 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -56,6 +56,7 @@ #include #include "iputils.hh" #include "dnsparser.hh" +#include "dns_random.hh" #include #include #include @@ -432,7 +433,7 @@ int waitForMultiData(const set& fds, const int seconds, const int useconds, } } set::const_iterator it(pollinFDs.begin()); - advance(it, random() % pollinFDs.size()); + advance(it, dns_random(pollinFDs.size())); *fdOut = *it; return 1; } @@ -463,7 +464,7 @@ int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int*fd) else if((pfds[1].revents & POLLIN) && !(pfds[0].revents & POLLIN)) *fd = pfds[1].fd; else if(ret == 2) { - *fd = pfds[random()%2].fd; + *fd = pfds[dns_random_uint32()%2].fd; } else *fd = -1; // should never happen diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 2f6a173ca0e2..bbb840cbdf88 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -216,7 +216,7 @@ static void dbBench(const std::string& fname) while(B.get(rr)) { hits++; } - B.lookup(QType(QType::A), DNSName(std::to_string(random()))+domain, -1); + B.lookup(QType(QType::A), DNSName(std::to_string(dns_random_uint32()))+domain, -1); while(B.get(rr)) { } misses++; diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index e94401e74f18..2d5dc826f5e3 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -3116,7 +3116,6 @@ int main(int argc, char** argv) { g_argc = argc; g_argv = argv; - Utility::srandom(); versionSetProduct(ProductRecursor); reportBasicTypes(); reportOtherTypes(); diff --git a/pdns/unix_utility.cc b/pdns/unix_utility.cc index 26c0782e1c53..2fb2d00e07ca 100644 --- a/pdns/unix_utility.cc +++ b/pdns/unix_utility.cc @@ -204,14 +204,6 @@ int Utility::gettimeofday( struct timeval *tv, void * /* tz */) return ::gettimeofday(tv, nullptr); } -// Sets the random seed. -void Utility::srandom() -{ - struct timeval tv; - gettimeofday(&tv, nullptr); - ::srandom(tv.tv_sec ^ tv.tv_usec ^ getpid()); -} - // Writes a vector. int Utility::writev(int socket, const iovec *vector, size_t count ) { diff --git a/pdns/utility.hh b/pdns/utility.hh index 296449e4ef5e..5ddf2cc0f2b0 100644 --- a/pdns/utility.hh +++ b/pdns/utility.hh @@ -121,9 +121,6 @@ public: //! Writes a vector. static int writev( Utility::sock_t socket, const iovec *vector, size_t count ); - //! Sets the random seed. - static void srandom(void); - //! Drops the program's group privileges. static void dropGroupPrivs( uid_t uid, gid_t gid ); From 760a7c99771e71d359ffddd8e119528f7bb72145 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 12:52:41 +0200 Subject: [PATCH 383/909] Format --- ext/arc4random/arc4random.hh | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/ext/arc4random/arc4random.hh b/ext/arc4random/arc4random.hh index 72449fb24883..a130d7f8a6c4 100644 --- a/ext/arc4random/arc4random.hh +++ b/ext/arc4random/arc4random.hh @@ -2,8 +2,9 @@ #include -extern "C" { -uint32_t arc4random(void); -void arc4random_buf(void *buf, size_t nbytes); -uint32_t arc4random_uniform(uint32_t upper_bound); +extern "C" +{ + uint32_t arc4random(void); + void arc4random_buf(void *buf, size_t nbytes); + uint32_t arc4random_uniform(uint32_t upper_bound); } From cd1bed45ee2c246548053031c206940835f430d6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 12:56:23 +0200 Subject: [PATCH 384/909] Zap reference to dns_random_urandom.cc --- modules/remotebackend/Makefile.am | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/remotebackend/Makefile.am b/modules/remotebackend/Makefile.am index 38f531f2c3e1..aedc767dfbb4 100644 --- a/modules/remotebackend/Makefile.am +++ b/modules/remotebackend/Makefile.am @@ -110,7 +110,6 @@ libtestremotebackend_la_SOURCES = \ ../../pdns/base32.cc \ ../../pdns/base64.cc \ ../../pdns/dns.hh ../../pdns/dns.cc \ - ../../pdns/dns_random_urandom.cc \ ../../pdns/dnsbackend.hh ../../pdns/dnsbackend.cc \ ../../pdns/dnslabeltext.cc \ ../../pdns/dnsname.cc ../../pdns/dnsname.hh \ From e42c94a88b5bf0edf3b80c8f40540f60b0a5e6e5 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 13:11:07 +0200 Subject: [PATCH 385/909] Fix configure syntax --- configure.ac | 4 +--- pdns/dnsdistdist/configure.ac | 4 +--- pdns/recursordist/configure.ac | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/configure.ac b/configure.ac index 3d1969078cec..13dc98fa2f38 100644 --- a/configure.ac +++ b/configure.ac @@ -84,9 +84,7 @@ AC_CHECK_HEADERS( )], [have_mmap=no] ) -AC_CHECK_HEADERS([ - sys/random.h -]) +AC_CHECK_HEADERS([sys/random.h]) PDNS_WITH_LIBSODIUM PDNS_WITH_LIBDECAF diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index 501f87a6a33f..aa7ffbf7a44e 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -56,9 +56,7 @@ AC_SUBST([IPCRYPT_CFLAGS], ['-I$(top_srcdir)/ext/ipcrypt']) AC_SUBST([IPCRYPT_LIBS], ['$(top_builddir)/ext/ipcrypt/libipcrypt.la']) AC_SUBST([ARC4RANDOM_LIBS], ['$(top_builddir)/ext/arc4random/libarc4random.la']) -AC_CHECK_HEADERS([ - sys/random.h -]) +AC_CHECK_HEADERS([sys/random.h]) PDNS_WITH_LUA([mandatory]) AS_IF([test "x$LUAPC" = "xluajit"], [ diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index 3f455a7f5d9c..e466237cbe7f 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -115,9 +115,7 @@ dnl using the defines. AC_CHECK_FUNCS_ONCE([localtime_r gmtime_r strcasestr]) AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) -AC_CHECK_HEADERS([ - sys/random.h -]) +AC_CHECK_HEADERS([sys/random.h]) PDNS_CHECK_PTHREAD_NP From 4644f23733337f9ca481acd5c7243ed1ac464227 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 13:46:50 +0200 Subject: [PATCH 386/909] Fuzzing target needs arc4random as well --- ext/arc4random/arc4random.hh | 2 +- pdns/Makefile.am | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/arc4random/arc4random.hh b/ext/arc4random/arc4random.hh index a130d7f8a6c4..b2f10608650a 100644 --- a/ext/arc4random/arc4random.hh +++ b/ext/arc4random/arc4random.hh @@ -5,6 +5,6 @@ extern "C" { uint32_t arc4random(void); - void arc4random_buf(void *buf, size_t nbytes); + void arc4random_buf(void* buf, size_t nbytes); uint32_t arc4random_uniform(uint32_t upper_bound); } diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 50f93222c2fe..5d188b1ce061 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1536,7 +1536,7 @@ fuzz_targets_programs = \ fuzz_target_yahttp \ fuzz_target_zoneparsertng -fuzz_targets: $(fuzz_targets_programs) +fuzz_targets: $(ARC4RANDOM_LIBS) $(fuzz_targets_programs) bin_PROGRAMS += \ $(fuzz_targets_programs) From 9e261ed3ff761ee4af3271667206ecba16cbd8d5 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 15:29:03 +0200 Subject: [PATCH 387/909] Fix dependency for remote backend test code --- modules/remotebackend/Makefile.am | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/remotebackend/Makefile.am b/modules/remotebackend/Makefile.am index aedc767dfbb4..1e2032a59d36 100644 --- a/modules/remotebackend/Makefile.am +++ b/modules/remotebackend/Makefile.am @@ -16,6 +16,7 @@ endif AM_LDFLAGS = $(THREADFLAGS) JSON11_LIBS = $(top_builddir)/ext/json11/libjson11.la +ARC4RANDOM_LIBS = $(top_builddir)/ext/arc4random/libarc4random.la EXTRA_DIST = \ OBJECTFILES \ @@ -188,39 +189,39 @@ remotebackend_http_test_SOURCES = \ test-remotebackend-keys.hh \ test-remotebackend.cc -remotebackend_http_test_LDADD = libtestremotebackend.la +remotebackend_http_test_LDADD = libtestremotebackend.la $(ARC4RANDOM_LIBS) remotebackend_json_test_SOURCES = \ test-remotebackend-json.cc \ test-remotebackend-keys.hh \ test-remotebackend.cc -remotebackend_json_test_LDADD = libtestremotebackend.la +remotebackend_json_test_LDADD = libtestremotebackend.la $(ARC4RANDOM_LIBS) remotebackend_pipe_test_SOURCES = \ test-remotebackend-keys.hh \ test-remotebackend-pipe.cc \ test-remotebackend.cc -remotebackend_pipe_test_LDADD = libtestremotebackend.la +remotebackend_pipe_test_LDADD = libtestremotebackend.la $(ARC4RANDOM_LIBS) remotebackend_post_test_SOURCES = \ test-remotebackend-keys.hh \ test-remotebackend-post.cc \ test-remotebackend.cc -remotebackend_post_test_LDADD = libtestremotebackend.la +remotebackend_post_test_LDADD = libtestremotebackend.la $(ARC4RANDOM_LIBS) remotebackend_unix_test_SOURCES = \ test-remotebackend-keys.hh \ test-remotebackend-unix.cc \ test-remotebackend.cc -remotebackend_unix_test_LDADD = libtestremotebackend.la +remotebackend_unix_test_LDADD = libtestremotebackend.la $(ARC4RANDOM_LIBS) remotebackend_zeromq_test_SOURCES = \ test-remotebackend-keys.hh \ test-remotebackend-zeromq.cc \ test-remotebackend.cc -remotebackend_zeromq_test_LDADD = libtestremotebackend.la +remotebackend_zeromq_test_LDADD = libtestremotebackend.la $(ARC4RANDOM_LIBS) From ead76a5b6d01d9e4561e6e4cf3280679c207342f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 16:31:27 +0200 Subject: [PATCH 388/909] Build libarc4random in CodeQL target for dnsdist --- .github/workflows/codeql-analysis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index c37001a7e5df..874ec85e773a 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -121,6 +121,7 @@ jobs: cd pdns/dnsdistdist autoreconf -vfi ./configure --enable-unit-tests --enable-dnstap --enable-dnscrypt --enable-dns-over-tls --enable-dns-over-https LIBS=-lwslay CFLAGS='-O0' CXXFLAGS='-O0' + make -j8 -C ext/arc4random make -j8 -C ext/ipcrypt make -j8 -C ext/yahttp make -j4 dnsdist From 9e4c7ebb9ab35d01fd6b8450467036eb306c1109 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 16:47:35 +0200 Subject: [PATCH 389/909] Remove commented out code, add #pragma once --- ext/arc4random/includes.h | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ext/arc4random/includes.h b/ext/arc4random/includes.h index 8d17335b6799..81f04a3befa1 100644 --- a/ext/arc4random/includes.h +++ b/ext/arc4random/includes.h @@ -1,8 +1,6 @@ -#include "config.h" +#pragma once -//#ifdef HAVE_SYS_RANDOM_H -//#include -//#endif +#include "config.h" #include #include From f668f57639c3eb71657777a8cc26f131a22b80a6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 20 Jun 2023 16:57:21 +0200 Subject: [PATCH 390/909] delint waitFor2Data --- pdns/misc.cc | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/pdns/misc.cc b/pdns/misc.cc index 5c9c81785fa4..4bbc865f6bed 100644 --- a/pdns/misc.cc +++ b/pdns/misc.cc @@ -439,35 +439,40 @@ int waitForMultiData(const set& fds, const int seconds, const int useconds, } // returns -1 in case of error, 0 if no data is available, 1 if there is. In the first two cases, errno is set -int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int*fd) +int waitFor2Data(int fd1, int fd2, int seconds, int useconds, int* fdPtr) { - int ret; - - struct pollfd pfds[2]; - memset(&pfds[0], 0, 2*sizeof(struct pollfd)); + std::array pfds{}; + memset(pfds.data(), 0, pfds.size() * sizeof(struct pollfd)); pfds[0].fd = fd1; pfds[1].fd = fd2; pfds[0].events= pfds[1].events = POLLIN; - int nsocks = 1 + (fd2 >= 0); // fd2 can optionally be -1 + int nsocks = 1 + static_cast(fd2 >= 0); // fd2 can optionally be -1 - if(seconds >= 0) - ret = poll(pfds, nsocks, seconds * 1000 + useconds/1000); - else - ret = poll(pfds, nsocks, -1); - if(!ret || ret < 0) + int ret{}; + if (seconds >= 0) { + ret = poll(pfds.data(), nsocks, seconds * 1000 + useconds / 1000); + } + else { + ret = poll(pfds.data(), nsocks, -1); + } + if (ret <= 0) { return ret; + } - if((pfds[0].revents & POLLIN) && !(pfds[1].revents & POLLIN)) - *fd = pfds[0].fd; - else if((pfds[1].revents & POLLIN) && !(pfds[0].revents & POLLIN)) - *fd = pfds[1].fd; + if ((pfds[0].revents & POLLIN) != 0 && (pfds[1].revents & POLLIN) == 0) { + *fdPtr = pfds[0].fd; + } + else if ((pfds[1].revents & POLLIN) != 0 && (pfds[0].revents & POLLIN) == 0) { + *fdPtr = pfds[1].fd; + } else if(ret == 2) { - *fd = pfds[dns_random_uint32()%2].fd; + *fdPtr = pfds.at(dns_random_uint32() % 2).fd; + } + else { + *fdPtr = -1; // should never happen } - else - *fd = -1; // should never happen return 1; } From ac9c9bd22e5de81ddcb242c83e6c99e4c801dc28 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 7 Jul 2023 11:04:23 +0200 Subject: [PATCH 391/909] Fix build: put arc4random.hh into _SOURCES Also a tiny bit of cleanup --- ext/arc4random/Makefile.am | 5 ++++- ext/arc4random/arc4random.hh | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/ext/arc4random/Makefile.am b/ext/arc4random/Makefile.am index ee46ad2a57d7..3a33bbe3c9cf 100644 --- a/ext/arc4random/Makefile.am +++ b/ext/arc4random/Makefile.am @@ -1,5 +1,8 @@ noinst_LTLIBRARIES = libarc4random.la -libarc4random_la_SOURCES = arc4random.c arc4random.h \ +libarc4random_la_SOURCES = \ + arc4random.c \ + arc4random.h \ + arc4random.hh \ arc4random_uniform.c \ bsd-getentropy.c \ includes.h \ diff --git a/ext/arc4random/arc4random.hh b/ext/arc4random/arc4random.hh index b2f10608650a..1af8fee3805a 100644 --- a/ext/arc4random/arc4random.hh +++ b/ext/arc4random/arc4random.hh @@ -1,6 +1,7 @@ #pragma once -#include +#include +#include extern "C" { From e03b2c5c9de78a026da6d7040b03e688ea8dc80b Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 7 Jul 2023 12:02:14 +0200 Subject: [PATCH 392/909] Fix build: put chacha_private.h into _SOURCES Also fix redundant declaration warnings Followup to #12999 --- ext/arc4random/Makefile.am | 1 + ext/arc4random/arc4random.hh | 6 ++++++ ext/arc4random/includes.h | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/ext/arc4random/Makefile.am b/ext/arc4random/Makefile.am index 3a33bbe3c9cf..e776e0e0addc 100644 --- a/ext/arc4random/Makefile.am +++ b/ext/arc4random/Makefile.am @@ -5,5 +5,6 @@ libarc4random_la_SOURCES = \ arc4random.hh \ arc4random_uniform.c \ bsd-getentropy.c \ + chacha_private.h \ includes.h \ log.h diff --git a/ext/arc4random/arc4random.hh b/ext/arc4random/arc4random.hh index 1af8fee3805a..f9f779f12e38 100644 --- a/ext/arc4random/arc4random.hh +++ b/ext/arc4random/arc4random.hh @@ -5,7 +5,13 @@ extern "C" { +#ifndef HAVE_ARC4RANDOM uint32_t arc4random(void); +#endif +#ifndef HAVE_ARC4RANDOM_BUF void arc4random_buf(void* buf, size_t nbytes); +#endif +#ifndef HAVE_ARC4RANDOM_UNIFORM uint32_t arc4random_uniform(uint32_t upper_bound); +#endif } diff --git a/ext/arc4random/includes.h b/ext/arc4random/includes.h index 81f04a3befa1..0a3882e4836a 100644 --- a/ext/arc4random/includes.h +++ b/ext/arc4random/includes.h @@ -11,8 +11,14 @@ #define seed_from_prngd(a, b) -1 +#ifndef HAVE_ARC4RANDOM uint32_t arc4random(void); +#endif +#ifndef HAVE_ARC4RANDOM_BUF void arc4random_buf(void *buf, size_t nbytes); +#endif +#ifndef HAVE_ARC4RANDOM_UNIFORM uint32_t arc4random_uniform(uint32_t upper_bound); +#endif #define DEF_WEAK(x) From 0e006d27997a2159cf6d6cbcfa4b149ad8d9fa02 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 7 Jul 2023 12:49:24 +0200 Subject: [PATCH 393/909] Also include explcit_bzero(), which is needed when using older glibc --- configure.ac | 2 +- ext/arc4random/Makefile.am | 1 + ext/arc4random/arc4random.hh | 3 + ext/arc4random/explicit_bzero.c | 65 +++++++++++++++++++ ext/arc4random/includes.h | 3 + pdns/dnsdistdist/configure.ac | 2 +- .../ext/arc4random/explicit_bzero.c | 1 + pdns/recursordist/configure.ac | 2 +- .../ext/arc4random/explicit_bzero.c | 1 + 9 files changed, 77 insertions(+), 3 deletions(-) create mode 100644 ext/arc4random/explicit_bzero.c create mode 120000 pdns/dnsdistdist/ext/arc4random/explicit_bzero.c create mode 120000 pdns/recursordist/ext/arc4random/explicit_bzero.c diff --git a/configure.ac b/configure.ac index 13dc98fa2f38..ce048aef2392 100644 --- a/configure.ac +++ b/configure.ac @@ -154,7 +154,7 @@ dnl Checks for library functions. dnl the *_r functions are in posix so we can use them unconditionally, but the ext/yahttp code is dnl using the defines. AC_CHECK_FUNCS_ONCE([strcasestr localtime_r gmtime_r recvmmsg sched_setscheduler]) -AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) +AC_CHECK_FUNCS_ONCE([explicit_bzero memset_s getrandom getentropy arc4random arc4random_uniform arc4random_buf]) AM_CONDITIONAL([HAVE_RECVMMSG], [test "x$ac_cv_func_recvmmsg" = "xyes"]) diff --git a/ext/arc4random/Makefile.am b/ext/arc4random/Makefile.am index e776e0e0addc..73479d160afc 100644 --- a/ext/arc4random/Makefile.am +++ b/ext/arc4random/Makefile.am @@ -6,5 +6,6 @@ libarc4random_la_SOURCES = \ arc4random_uniform.c \ bsd-getentropy.c \ chacha_private.h \ + explicit_bzero.c \ includes.h \ log.h diff --git a/ext/arc4random/arc4random.hh b/ext/arc4random/arc4random.hh index f9f779f12e38..c9bedac4733f 100644 --- a/ext/arc4random/arc4random.hh +++ b/ext/arc4random/arc4random.hh @@ -14,4 +14,7 @@ extern "C" #ifndef HAVE_ARC4RANDOM_UNIFORM uint32_t arc4random_uniform(uint32_t upper_bound); #endif +#ifndef HAVE_EXPLICIT_BZERO + void explicit_bzero(void *, size_t len); +#endif } diff --git a/ext/arc4random/explicit_bzero.c b/ext/arc4random/explicit_bzero.c new file mode 100644 index 000000000000..68cd2c10b3c8 --- /dev/null +++ b/ext/arc4random/explicit_bzero.c @@ -0,0 +1,65 @@ +/* OPENBSD ORIGINAL: lib/libc/string/explicit_bzero.c */ +/* $OpenBSD: explicit_bzero.c,v 1.1 2014/01/22 21:06:45 tedu Exp $ */ +/* + * Public domain. + * Written by Ted Unangst + */ + +#include "includes.h" + +#include + +/* + * explicit_bzero - don't let the compiler optimize away bzero + */ + +#ifndef HAVE_EXPLICIT_BZERO + +#ifdef HAVE_EXPLICIT_MEMSET + +void +explicit_bzero(void *p, size_t n) +{ + (void)explicit_memset(p, 0, n); +} + +#elif defined(HAVE_MEMSET_S) + +void +explicit_bzero(void *p, size_t n) +{ + if (n == 0) + return; + (void)memset_s(p, n, 0, n); +} + +#else /* HAVE_MEMSET_S */ + +/* + * Indirect bzero through a volatile pointer to hopefully avoid + * dead-store optimisation eliminating the call. + */ +static void (* volatile ssh_bzero)(void *, size_t) = bzero; + +void +explicit_bzero(void *p, size_t n) +{ + if (n == 0) + return; + /* + * clang -fsanitize=memory needs to intercept memset-like functions + * to correctly detect memory initialisation. Make sure one is called + * directly since our indirection trick above successfully confuses it. + */ +#if defined(__has_feature) +# if __has_feature(memory_sanitizer) + memset(p, 0, n); +# endif +#endif + + ssh_bzero(p, n); +} + +#endif /* HAVE_MEMSET_S */ + +#endif /* HAVE_EXPLICIT_BZERO */ diff --git a/ext/arc4random/includes.h b/ext/arc4random/includes.h index 0a3882e4836a..5ef06b816bf2 100644 --- a/ext/arc4random/includes.h +++ b/ext/arc4random/includes.h @@ -20,5 +20,8 @@ void arc4random_buf(void *buf, size_t nbytes); #ifndef HAVE_ARC4RANDOM_UNIFORM uint32_t arc4random_uniform(uint32_t upper_bound); #endif +#ifndef HAVE_EXPLICIT_BZERO +void explicit_bzero(void *, size_t len); +#endif #define DEF_WEAK(x) diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index aa7ffbf7a44e..6ab2749d3ad4 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -49,7 +49,7 @@ PDNS_WITH_SERVICE_USER([dnsdist]) dnl the *_r functions are in posix so we can use them unconditionally, but the ext/yahttp code is dnl using the defines. AC_CHECK_FUNCS_ONCE([localtime_r gmtime_r]) -AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) +AC_CHECK_FUNCS_ONCE([explicit_bzero memset_s getrandom getentropy arc4random arc4random_uniform arc4random_buf]) AC_SUBST([YAHTTP_CFLAGS], ['-I$(top_srcdir)/ext/yahttp']) AC_SUBST([YAHTTP_LIBS], ['$(top_builddir)/ext/yahttp/yahttp/libyahttp.la']) AC_SUBST([IPCRYPT_CFLAGS], ['-I$(top_srcdir)/ext/ipcrypt']) diff --git a/pdns/dnsdistdist/ext/arc4random/explicit_bzero.c b/pdns/dnsdistdist/ext/arc4random/explicit_bzero.c new file mode 120000 index 000000000000..4b950e0401b8 --- /dev/null +++ b/pdns/dnsdistdist/ext/arc4random/explicit_bzero.c @@ -0,0 +1 @@ +../../../../ext/arc4random/explicit_bzero.c \ No newline at end of file diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index e466237cbe7f..8945ae661842 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -113,7 +113,7 @@ PDNS_CHECK_CURL dnl the *_r functions are in posix so we can use them unconditionally, but the ext/yahttp code is dnl using the defines. AC_CHECK_FUNCS_ONCE([localtime_r gmtime_r strcasestr]) -AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) +AC_CHECK_FUNCS_ONCE([explicit_bzero memset_s getrandom getentropy arc4random arc4random_uniform arc4random_buf]) AC_CHECK_HEADERS([sys/random.h]) diff --git a/pdns/recursordist/ext/arc4random/explicit_bzero.c b/pdns/recursordist/ext/arc4random/explicit_bzero.c new file mode 120000 index 000000000000..4b950e0401b8 --- /dev/null +++ b/pdns/recursordist/ext/arc4random/explicit_bzero.c @@ -0,0 +1 @@ +../../../../ext/arc4random/explicit_bzero.c \ No newline at end of file From 5818e9553044d6a982d9ca4b48028948aa9ea7bd Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 7 Jul 2023 14:03:33 +0200 Subject: [PATCH 394/909] Use PDNS_CHECK_SECURE_MEMSET, as suggested by @rcagogne --- configure.ac | 3 ++- ext/arc4random/arc4random.hh | 2 +- m4/pdns_check_secure_memset.m4 | 2 +- pdns/dnsdistdist/configure.ac | 2 +- pdns/recursordist/configure.ac | 3 ++- pdns/recursordist/m4/pdns_check_secure_memset.m4 | 1 + 6 files changed, 8 insertions(+), 5 deletions(-) create mode 120000 pdns/recursordist/m4/pdns_check_secure_memset.m4 diff --git a/configure.ac b/configure.ac index ce048aef2392..d6ad04a3c527 100644 --- a/configure.ac +++ b/configure.ac @@ -154,7 +154,8 @@ dnl Checks for library functions. dnl the *_r functions are in posix so we can use them unconditionally, but the ext/yahttp code is dnl using the defines. AC_CHECK_FUNCS_ONCE([strcasestr localtime_r gmtime_r recvmmsg sched_setscheduler]) -AC_CHECK_FUNCS_ONCE([explicit_bzero memset_s getrandom getentropy arc4random arc4random_uniform arc4random_buf]) +AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) +PDNS_CHECK_SECURE_MEMSET AM_CONDITIONAL([HAVE_RECVMMSG], [test "x$ac_cv_func_recvmmsg" = "xyes"]) diff --git a/ext/arc4random/arc4random.hh b/ext/arc4random/arc4random.hh index c9bedac4733f..cff8dd031ecd 100644 --- a/ext/arc4random/arc4random.hh +++ b/ext/arc4random/arc4random.hh @@ -15,6 +15,6 @@ extern "C" uint32_t arc4random_uniform(uint32_t upper_bound); #endif #ifndef HAVE_EXPLICIT_BZERO - void explicit_bzero(void *, size_t len); + void explicit_bzero(void*, size_t len); #endif } diff --git a/m4/pdns_check_secure_memset.m4 b/m4/pdns_check_secure_memset.m4 index 4f582199a905..220eaebe6690 100644 --- a/m4/pdns_check_secure_memset.m4 +++ b/m4/pdns_check_secure_memset.m4 @@ -1,3 +1,3 @@ AC_DEFUN([PDNS_CHECK_SECURE_MEMSET], [ - AC_CHECK_FUNCS([explicit_bzero explicit_memset]) + AC_CHECK_FUNCS([explicit_bzero explicit_memset memset_s]) ]) diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index 6ab2749d3ad4..aa7ffbf7a44e 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -49,7 +49,7 @@ PDNS_WITH_SERVICE_USER([dnsdist]) dnl the *_r functions are in posix so we can use them unconditionally, but the ext/yahttp code is dnl using the defines. AC_CHECK_FUNCS_ONCE([localtime_r gmtime_r]) -AC_CHECK_FUNCS_ONCE([explicit_bzero memset_s getrandom getentropy arc4random arc4random_uniform arc4random_buf]) +AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) AC_SUBST([YAHTTP_CFLAGS], ['-I$(top_srcdir)/ext/yahttp']) AC_SUBST([YAHTTP_LIBS], ['$(top_builddir)/ext/yahttp/yahttp/libyahttp.la']) AC_SUBST([IPCRYPT_CFLAGS], ['-I$(top_srcdir)/ext/ipcrypt']) diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index 8945ae661842..2e8f9351b35e 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -113,7 +113,8 @@ PDNS_CHECK_CURL dnl the *_r functions are in posix so we can use them unconditionally, but the ext/yahttp code is dnl using the defines. AC_CHECK_FUNCS_ONCE([localtime_r gmtime_r strcasestr]) -AC_CHECK_FUNCS_ONCE([explicit_bzero memset_s getrandom getentropy arc4random arc4random_uniform arc4random_buf]) +AC_CHECK_FUNCS_ONCE([getrandom getentropy arc4random arc4random_uniform arc4random_buf]) +PDNS_CHECK_SECURE_MEMSET AC_CHECK_HEADERS([sys/random.h]) diff --git a/pdns/recursordist/m4/pdns_check_secure_memset.m4 b/pdns/recursordist/m4/pdns_check_secure_memset.m4 new file mode 120000 index 000000000000..58f6bd3bee2c --- /dev/null +++ b/pdns/recursordist/m4/pdns_check_secure_memset.m4 @@ -0,0 +1 @@ +../../../m4/pdns_check_secure_memset.m4 \ No newline at end of file From b5f0d73678bd775dc03729589bbe8e101c5bdb19 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 7 Jul 2023 14:32:33 +0200 Subject: [PATCH 395/909] auth 4.8.1: docs & secpoll --- docs/changelog/4.8.rst | 38 ++++++++++++++++++++++++++++++++++++++ docs/secpoll.zone | 3 ++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/docs/changelog/4.8.rst b/docs/changelog/4.8.rst index cd4af69a0bee..0de0c699f3d4 100644 --- a/docs/changelog/4.8.rst +++ b/docs/changelog/4.8.rst @@ -1,6 +1,44 @@ Changelogs for 4.8.x ==================== +.. changelog:: + :version: 4.8.1 + :released: 7th of July 2023 + + This is release 4.8.1 of the Authoritative Server. + + This release contains a small collection of fixes: + + .. change:: + :tags: Improvements + :pullreq: 12996 + + lmdb: in Lightning Stream mode, during deleteDomain, use RW transaction to get ID list + + .. change:: + :tags: New Features + :pullreq: 12997 + + lmdb: add backend commands for checking & refreshing indexes + + .. change:: + :tags: Improvements + :pullreq: 12993 + + Stop using the now deprecated ERR_load_CRYPTO_strings() to detect OpenSSL + + .. change:: + :tags: Bug Fixes + :pullreq: 12992 + + YaHTTP: Prevent integer overflow on very large chunks + + .. change:: + :tags: Improvements + :pullreq: 12991 + + Work around Red Hat 8 pooping the bed in OpenSSL's headers + .. changelog:: :version: 4.8.0 :released: 1st of June 2023 diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 90cace64d848..368d759870e9 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023063001 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023070701 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -121,6 +121,7 @@ auth-4.7.4.security-status 60 IN TXT "1 OK" auth-4.8.0-alpha1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" auth-4.8.0-beta1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" auth-4.8.0.security-status 60 IN TXT "1 OK" +auth-4.8.1.security-status 60 IN TXT "1 OK" ; Auth Debian auth-3.4.1-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2015-02/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-03/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-04/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-05/" From ca250bdad16b9ac6a2789541be88bf17a653262b Mon Sep 17 00:00:00 2001 From: Jelle Kaufmann Date: Sun, 9 Jul 2023 07:04:12 +0200 Subject: [PATCH 396/909] Fix incorrect optsize --- pdns/dnspacket.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnspacket.cc b/pdns/dnspacket.cc index b9fcdfabe307..a9ec83529bb6 100644 --- a/pdns/dnspacket.cc +++ b/pdns/dnspacket.cc @@ -333,7 +333,7 @@ void DNSPacket::wrapup(bool throwsOnTruncation) if (d_haveednscookie) { if (d_eco.isWellFormed()) { - optsize += EDNSCookiesOpt::EDNSCookieOptSize; + optsize += EDNS_OPTION_CODE_SIZE + EDNS_OPTION_LENGTH_SIZE + EDNSCookiesOpt::EDNSCookieOptSize; } } From da73e6b3253d0eede1725fbc6910ab8ae366b38b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 10 Jul 2023 13:50:57 +0200 Subject: [PATCH 397/909] dnsdist: Add metrics for health-check failures --- pdns/dnsdist-carbon.cc | 6 +++ pdns/dnsdist-web.cc | 25 ++++++++++- pdns/dnsdist.hh | 18 ++++++-- pdns/dnsdistdist/dnsdist-backend.cc | 4 ++ pdns/dnsdistdist/dnsdist-healthchecks.cc | 15 ++++++- pdns/dnsdistdist/docs/guides/webserver.rst | 6 +++ regression-tests.dnsdist/test_API.py | 2 +- regression-tests.dnsdist/test_HealthChecks.py | 43 +++++++++++++++++-- 8 files changed, 109 insertions(+), 10 deletions(-) diff --git a/pdns/dnsdist-carbon.cc b/pdns/dnsdist-carbon.cc index 65f739721e87..693f498c435f 100644 --- a/pdns/dnsdist-carbon.cc +++ b/pdns/dnsdist-carbon.cc @@ -98,6 +98,12 @@ static bool doOneCarbonExport(const Carbon::Endpoint& endpoint) str << base << "tcpavgqueriesperconnection" << ' ' << state->tcpAvgQueriesPerConnection.load() << " " << now << "\r\n"; str << base << "tcpavgconnectionduration" << ' ' << state->tcpAvgConnectionDuration.load() << " " << now << "\r\n"; str << base << "tcptoomanyconcurrentconnections" << ' ' << state->tcpTooManyConcurrentConnections.load() << " " << now << "\r\n"; + str << base << "healthcheckfailures" << ' ' << state->d_healthCheckMetrics.d_failures << " " << now << "\r\n"; + str << base << "healthcheckfailuresparsing" << ' ' << state->d_healthCheckMetrics.d_parseErrors << " " << now << "\r\n"; + str << base << "healthcheckfailurestimeout" << ' ' << state->d_healthCheckMetrics.d_timeOuts << " " << now << "\r\n"; + str << base << "healthcheckfailuresnetwork" << ' ' << state->d_healthCheckMetrics.d_networkErrors << " " << now << "\r\n"; + str << base << "healthcheckfailuresmismatch" << ' ' << state->d_healthCheckMetrics.d_mismatchErrors << " " << now << "\r\n"; + str << base << "healthcheckfailuresinvalid" << ' ' << state->d_healthCheckMetrics.d_invalidResponseErrors << " " << now << "\r\n"; } std::map frontendDuplicates; diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index d47f33cd6331..d1132d37839f 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -593,6 +593,18 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) output << "# TYPE " << statesbase << "tlsresumptions " << "counter" << "\n"; output << "# HELP " << statesbase << "tcplatency " << "Server's latency when answering TCP questions in milliseconds" << "\n"; output << "# TYPE " << statesbase << "tcplatency " << "gauge" << "\n"; + output << "# HELP " << statesbase << "healthcheckfailures " << "Number of health check attempts that failed (total)" << "\n"; + output << "# TYPE " << statesbase << "healthcheckfailures " << "counter" << "\n"; + output << "# HELP " << statesbase << "healthcheckfailuresparsing " << "Number of health check attempts where the response could not be parsed" << "\n"; + output << "# TYPE " << statesbase << "healthcheckfailuresparsing " << "counter" << "\n"; + output << "# HELP " << statesbase << "healthcheckfailurestimeout " << "Number of health check attempts where the response did not arrive in time" << "\n"; + output << "# TYPE " << statesbase << "healthcheckfailurestimeout " << "counter" << "\n"; + output << "# HELP " << statesbase << "healthcheckfailuresnetwork " << "Number of health check attempts that experienced a network issue" << "\n"; + output << "# TYPE " << statesbase << "healthcheckfailuresnetwork " << "counter" << "\n"; + output << "# HELP " << statesbase << "healthcheckfailuresmismatch " << "Number of health check attempts where the response did not match the query" << "\n"; + output << "# TYPE " << statesbase << "healthcheckfailuresmismatch " << "counter" << "\n"; + output << "# HELP " << statesbase << "healthcheckfailuresinvalid " << "Number of health check attempts where the DNS response was invalid" << "\n"; + output << "# TYPE " << statesbase << "healthcheckfailuresinvalid " << "counter" << "\n"; for (const auto& state : *states) { string serverName; @@ -636,6 +648,12 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) output << statesbase << "tcpavgqueriesperconn" << label << " " << state->tcpAvgQueriesPerConnection << "\n"; output << statesbase << "tcpavgconnduration" << label << " " << state->tcpAvgConnectionDuration << "\n"; output << statesbase << "tlsresumptions" << label << " " << state->tlsResumptions << "\n"; + output << statesbase << "healthcheckfailures" << label << " " << state->d_healthCheckMetrics.d_failures << "\n"; + output << statesbase << "healthcheckfailuresparsing" << label << " " << state->d_healthCheckMetrics.d_parseErrors << "\n"; + output << statesbase << "healthcheckfailurestimeout" << label << " " << state->d_healthCheckMetrics.d_timeOuts << "\n"; + output << statesbase << "healthcheckfailuresnetwork" << label << " " << state->d_healthCheckMetrics.d_networkErrors << "\n"; + output << statesbase << "healthcheckfailuresmismatch" << label << " " << state->d_healthCheckMetrics.d_mismatchErrors << "\n"; + output << statesbase << "healthcheckfailuresinvalid" << label << " " << state->d_healthCheckMetrics.d_invalidResponseErrors << "\n"; } const string frontsbase = "dnsdist_frontend_"; @@ -673,7 +691,6 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) output << "# TYPE " << frontsbase << "tlsunknownticketkeys " << "counter" << "\n"; output << "# HELP " << frontsbase << "tlsinactiveticketkeys " << "Amount of TLS sessions resumed from an inactive key" << "\n"; output << "# TYPE " << frontsbase << "tlsinactiveticketkeys " << "counter" << "\n"; - output << "# HELP " << frontsbase << "tlshandshakefailures " << "Amount of TLS handshake failures" << "\n"; output << "# TYPE " << frontsbase << "tlshandshakefailures " << "counter" << "\n"; @@ -1059,6 +1076,12 @@ static void addServerToJSON(Json::array& servers, int id, const std::shared_ptr< {"tcpAvgConnectionDuration", (double)a->tcpAvgConnectionDuration}, {"tlsResumptions", (double)a->tlsResumptions}, {"tcpLatency", (double)(a->latencyUsecTCP/1000.0)}, + {"healthCheckFailures", (double)(a->d_healthCheckMetrics.d_failures)}, + {"healthCheckFailuresParsing", (double)(a->d_healthCheckMetrics.d_parseErrors)}, + {"healthCheckFailuresTimeout", (double)(a->d_healthCheckMetrics.d_timeOuts)}, + {"healthCheckFailuresNetwork", (double)(a->d_healthCheckMetrics.d_networkErrors)}, + {"healthCheckFailuresMismatch", (double)(a->d_healthCheckMetrics.d_mismatchErrors)}, + {"healthCheckFailuresInvalid", (double)(a->d_healthCheckMetrics.d_invalidResponseErrors)}, {"dropRate", (double)a->dropRate} }; diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index fca2e3c4dbdd..be2e6ebb7c5e 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -701,6 +701,16 @@ struct DownstreamState: public std::enable_shared_from_this bool d_upgradeToLazyHealthChecks{false}; }; + struct HealthCheckMetrics + { + stat_t d_failures{0}; + stat_t d_timeOuts{0}; + stat_t d_parseErrors{0}; + stat_t d_networkErrors{0}; + stat_t d_mismatchErrors{0}; + stat_t d_invalidResponseErrors{0}; + }; + DownstreamState(DownstreamState::Config&& config, std::shared_ptr tlsCtx, bool connect); DownstreamState(const ComboAddress& remote): DownstreamState(DownstreamState::Config(remote), nullptr, false) { @@ -709,6 +719,7 @@ struct DownstreamState: public std::enable_shared_from_this ~DownstreamState(); Config d_config; + HealthCheckMetrics d_healthCheckMetrics; stat_t sendErrors{0}; stat_t outstanding{0}; stat_t reuseds{0}; @@ -767,18 +778,20 @@ public: double latencyUsecTCP{0.0}; unsigned int d_nextCheck{0}; uint16_t currentCheckFailures{0}; - uint8_t consecutiveSuccessfulChecks{0}; std::atomic hashesComputed{false}; std::atomic connected{false}; bool upStatus{false}; private: + void handleUDPTimeout(IDState& ids); + void updateNextLazyHealthCheck(LazyHealthCheckStats& stats, bool checkScheduled, std::optional currentTime = std::nullopt); void connectUDPSockets(); std::thread tid; std::mutex connectLock; std::condition_variable d_connectedWait; std::atomic_flag threadStarted; + uint8_t consecutiveSuccessfulChecks{0}; bool d_stopped{false}; public: @@ -935,9 +948,6 @@ public: static int s_udpTimeout; static bool s_randomizeSockets; static bool s_randomizeIDs; -private: - void handleUDPTimeout(IDState& ids); - void updateNextLazyHealthCheck(LazyHealthCheckStats& stats, bool checkScheduled, std::optional currentTime = std::nullopt); }; using servers_t = vector>; diff --git a/pdns/dnsdistdist/dnsdist-backend.cc b/pdns/dnsdistdist/dnsdist-backend.cc index 87326c93a59f..45a50446da71 100644 --- a/pdns/dnsdistdist/dnsdist-backend.cc +++ b/pdns/dnsdistdist/dnsdist-backend.cc @@ -700,6 +700,10 @@ void DownstreamState::updateNextLazyHealthCheck(LazyHealthCheckStats& stats, boo void DownstreamState::submitHealthCheckResult(bool initial, bool newResult) { + if (!newResult) { + ++d_healthCheckMetrics.d_failures; + } + if (initial) { /* if this is the initial health-check, at startup, we do not care about the minimum number of failed/successful health-checks */ diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index dc77022fa39b..cc73a9d75478 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -60,6 +60,7 @@ static bool handleResponse(std::shared_ptr& data) auto& ds = data->d_ds; try { if (data->d_buffer.size() < sizeof(dnsheader)) { + ++data->d_ds->d_healthCheckMetrics.d_parseErrors; if (g_verboseHealthChecks) { infolog("Invalid health check response of size %d from backend %s, expecting at least %d", data->d_buffer.size(), ds->getNameWithAddr(), sizeof(dnsheader)); } @@ -68,6 +69,7 @@ static bool handleResponse(std::shared_ptr& data) const dnsheader * responseHeader = reinterpret_cast(data->d_buffer.data()); if (responseHeader->id != data->d_queryID) { + ++data->d_ds->d_healthCheckMetrics.d_mismatchErrors; if (g_verboseHealthChecks) { infolog("Invalid health check response id %d from backend %s, expecting %d", responseHeader->id, ds->getNameWithAddr(), data->d_queryID); } @@ -75,6 +77,7 @@ static bool handleResponse(std::shared_ptr& data) } if (!responseHeader->qr) { + ++data->d_ds->d_healthCheckMetrics.d_invalidResponseErrors; if (g_verboseHealthChecks) { infolog("Invalid health check response from backend %s, expecting QR to be set", ds->getNameWithAddr()); } @@ -82,6 +85,7 @@ static bool handleResponse(std::shared_ptr& data) } if (responseHeader->rcode == RCode::ServFail) { + ++data->d_ds->d_healthCheckMetrics.d_invalidResponseErrors; if (g_verboseHealthChecks) { infolog("Backend %s responded to health check with ServFail", ds->getNameWithAddr()); } @@ -89,6 +93,7 @@ static bool handleResponse(std::shared_ptr& data) } if (ds->d_config.mustResolve && (responseHeader->rcode == RCode::NXDomain || responseHeader->rcode == RCode::Refused)) { + ++data->d_ds->d_healthCheckMetrics.d_invalidResponseErrors; if (g_verboseHealthChecks) { infolog("Backend %s responded to health check with %s while mustResolve is set", ds->getNameWithAddr(), responseHeader->rcode == RCode::NXDomain ? "NXDomain" : "Refused"); } @@ -100,13 +105,15 @@ static bool handleResponse(std::shared_ptr& data) DNSName receivedName(reinterpret_cast(data->d_buffer.data()), data->d_buffer.size(), sizeof(dnsheader), false, &receivedType, &receivedClass); if (receivedName != data->d_checkName || receivedType != data->d_checkType || receivedClass != data->d_checkClass) { + ++data->d_ds->d_healthCheckMetrics.d_mismatchErrors; if (g_verboseHealthChecks) { infolog("Backend %s responded to health check with an invalid qname (%s vs %s), qtype (%s vs %s) or qclass (%d vs %d)", ds->getNameWithAddr(), receivedName.toLogString(), data->d_checkName.toLogString(), QType(receivedType).toString(), QType(data->d_checkType).toString(), receivedClass, data->d_checkClass); } return false; } } - catch(const std::exception& e) { + catch (const std::exception& e) { + ++data->d_ds->d_healthCheckMetrics.d_parseErrors; if (g_verboseHealthChecks) { infolog("Error checking the health of backend %s: %s", ds->getNameWithAddr(), e.what()); } @@ -151,6 +158,7 @@ class HealthCheckQuerySender : public TCPQuerySender void notifyIOError(InternalQueryState&& query, const struct timeval& now) override { + ++d_data->d_ds->d_healthCheckMetrics.d_networkErrors; d_data->d_ds->submitHealthCheckResult(d_data->d_initial, false); } @@ -173,6 +181,7 @@ static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) if (g_verboseHealthChecks) { infolog("Error receiving health check response from %s: %s", data->d_ds->d_config.remote.toStringWithPort(), stringerror(savederrno)); } + ++data->d_ds->d_healthCheckMetrics.d_networkErrors; data->d_ds->submitHealthCheckResult(data->d_initial, false); return; } @@ -183,6 +192,7 @@ static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) if (g_verboseHealthChecks) { infolog("Invalid health check response received from %s, expecting one from %s", from.toStringWithPort(), data->d_ds->d_config.remote.toStringWithPort()); } + ++data->d_ds->d_healthCheckMetrics.d_networkErrors; data->d_ds->submitHealthCheckResult(data->d_initial, false); return; } @@ -248,6 +258,7 @@ static void healthCheckTCPCallback(int fd, FDMultiplexer::funcparam_t& param) ioGuard.release(); } catch (const std::exception& e) { + ++data->d_ds->d_healthCheckMetrics.d_networkErrors; data->d_ds->submitHealthCheckResult(data->d_initial, false); if (g_verboseHealthChecks) { infolog("Error checking the health of backend %s: %s", data->d_ds->getNameWithAddr(), e.what()); @@ -444,6 +455,7 @@ void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial) infolog("Timeout while waiting for the health check response (ID %d) from backend %s", data->d_queryID, data->d_ds->getNameWithAddr()); } + ++data->d_ds->d_healthCheckMetrics.d_timeOuts; data->d_ds->submitHealthCheckResult(initial, false); } catch (const std::exception& e) { @@ -471,6 +483,7 @@ void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial) infolog("Timeout while waiting for the health check response (ID %d) from backend %s", data->d_queryID, data->d_ds->getNameWithAddr()); } + ++data->d_ds->d_healthCheckMetrics.d_timeOuts; data->d_ds->submitHealthCheckResult(initial, false); } catch (const std::exception& e) { diff --git a/pdns/dnsdistdist/docs/guides/webserver.rst b/pdns/dnsdistdist/docs/guides/webserver.rst index 540b2274720d..453f6d1bcab8 100755 --- a/pdns/dnsdistdist/docs/guides/webserver.rst +++ b/pdns/dnsdistdist/docs/guides/webserver.rst @@ -955,6 +955,12 @@ JSON Objects :property integer tlsResumptions: The number of times a TLS session has been resumed :property integer weight: The weight assigned to this server :property float dropRate: The amount of packets dropped (timing out) per second by this server + :property integer healthCheckFailures: Number of health check attempts that failed (total) + :property integer healthCheckFailureParsing: Number of health check attempts that failed because the payload could not be parsed + :property integer healthCheckFailureTimeout: Number of health check attempts that failed because the response was not received in time + :property integer healthCheckFailureNetwork: Number of health check attempts that failed because of a network error + :property integer healthCheckFailureMismatch: Number of health check attempts that failed because the ID, qname, qtype or qclass did not match + :property integer healthCheckFailureInvalid: Number of health check attempts that failed because the DNS response was not valid .. json:object:: StatisticItem diff --git a/regression-tests.dnsdist/test_API.py b/regression-tests.dnsdist/test_API.py index 2a9f9bf3a248..54e0f94177f3 100644 --- a/regression-tests.dnsdist/test_API.py +++ b/regression-tests.dnsdist/test_API.py @@ -144,7 +144,7 @@ def testServersLocalhost(self): 'dropRate', 'responses', 'nonCompliantResponses', 'tcpDiedSendingQuery', 'tcpDiedReadingResponse', 'tcpGaveUp', 'tcpReadTimeouts', 'tcpWriteTimeouts', 'tcpCurrentConnections', 'tcpNewConnections', 'tcpReusedConnections', 'tlsResumptions', 'tcpAvgQueriesPerConnection', - 'tcpAvgConnectionDuration', 'tcpLatency', 'protocol']: + 'tcpAvgConnectionDuration', 'tcpLatency', 'protocol', 'healthCheckFailures', 'healthCheckFailuresParsing', 'healthCheckFailuresTimeout', 'healthCheckFailuresNetwork', 'healthCheckFailuresMismatch', 'healthCheckFailuresInvalid']: self.assertIn(key, server) for key in ['id', 'latency', 'weight', 'outstanding', 'qpsLimit', 'reuseds', diff --git a/regression-tests.dnsdist/test_HealthChecks.py b/regression-tests.dnsdist/test_HealthChecks.py index f5554abfdd4b..c1ec51b85d64 100644 --- a/regression-tests.dnsdist/test_HealthChecks.py +++ b/regression-tests.dnsdist/test_HealthChecks.py @@ -1,24 +1,44 @@ #!/usr/bin/env python import base64 +import requests +import ssl import threading import time -import ssl import dns from dnsdisttests import DNSDistTest class HealthCheckTest(DNSDistTest): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort'] + _webTimeout = 2.0 + _webServerPort = 8083 + _webServerAPIKey = 'apisecret' + _webServerAPIKeyHashed = '$scrypt$ln=10,p=1,r=8$9v8JxDfzQVyTpBkTbkUqYg==$bDQzAOHeK1G9UvTPypNhrX48w974ZXbFPtRKS34+aso=' + _config_params = ['_consoleKeyB64', '_consolePort', '_webServerPort', '_webServerAPIKeyHashed', '_testServerPort'] _config_template = """ setKey("%s") controlSocket("127.0.0.1:%d") + webserver("127.0.0.1:%s") + setWebserverConfig({apiKey="%s"}) newServer{address="127.0.0.1:%d"} """ def getBackendStatus(self): return self.sendConsoleCommand("if getServer(0):isUp() then return 'up' else return 'down' end").strip("\n") + def getBackendMetric(self, backendID, metricName): + headers = {'x-api-key': self._webServerAPIKey} + url = 'http://127.0.0.1:' + str(self._webServerPort) + '/api/v1/servers/localhost' + r = requests.get(url, headers=headers, timeout=self._webTimeout) + self.assertTrue(r) + self.assertEqual(r.status_code, 200) + self.assertTrue(r.json()) + content = r.json() + self.assertIn('servers', content) + servers = content['servers'] + server = servers[backendID] + return int(server[metricName]) + class TestDefaultHealthCheck(HealthCheckTest): # this test suite uses a different responder port # because we need fresh counters @@ -31,6 +51,7 @@ def testDefault(self): before = TestDefaultHealthCheck._healthCheckCounter time.sleep(1.5) self.assertGreater(TestDefaultHealthCheck._healthCheckCounter, before) + self.assertEqual(self.getBackendMetric(0, 'healthCheckFailures'), 0) self.assertEqual(self.getBackendStatus(), 'up') self.sendConsoleCommand("getServer(0):setUp()") @@ -64,6 +85,7 @@ def testDefault(self): time.sleep(1.5) self.assertGreater(TestDefaultHealthCheck._healthCheckCounter, before) self.assertEqual(self.getBackendStatus(), 'up') + self.assertEqual(self.getBackendMetric(0, 'healthCheckFailures'), 0) class TestHealthCheckForcedUP(HealthCheckTest): # this test suite uses a different responder port @@ -73,6 +95,8 @@ class TestHealthCheckForcedUP(HealthCheckTest): _config_template = """ setKey("%s") controlSocket("127.0.0.1:%d") + webserver("127.0.0.1:%s") + setWebserverConfig({apiKey="%s"}) srv = newServer{address="127.0.0.1:%d"} srv:setUp() """ @@ -85,6 +109,7 @@ def testForcedUp(self): time.sleep(1.5) self.assertEqual(TestHealthCheckForcedUP._healthCheckCounter, before) self.assertEqual(self.getBackendStatus(), 'up') + self.assertEqual(self.getBackendMetric(0, 'healthCheckFailures'), 0) class TestHealthCheckForcedDown(HealthCheckTest): # this test suite uses a different responder port @@ -94,6 +119,8 @@ class TestHealthCheckForcedDown(HealthCheckTest): _config_template = """ setKey("%s") controlSocket("127.0.0.1:%d") + webserver("127.0.0.1:%s") + setWebserverConfig({apiKey="%s"}) srv = newServer{address="127.0.0.1:%d"} srv:setDown() """ @@ -105,6 +132,7 @@ def testForcedDown(self): before = TestHealthCheckForcedDown._healthCheckCounter time.sleep(1.5) self.assertEqual(TestHealthCheckForcedDown._healthCheckCounter, before) + self.assertEqual(self.getBackendMetric(0, 'healthCheckFailures'), 0) class TestHealthCheckCustomName(HealthCheckTest): # this test suite uses a different responder port @@ -112,10 +140,12 @@ class TestHealthCheckCustomName(HealthCheckTest): _testServerPort = 5383 _healthCheckName = 'powerdns.com.' - _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_healthCheckName'] + _config_params = ['_consoleKeyB64', '_consolePort', '_webServerPort', '_webServerAPIKeyHashed', '_testServerPort', '_healthCheckName'] _config_template = """ setKey("%s") controlSocket("127.0.0.1:%d") + webserver("127.0.0.1:%s") + setWebserverConfig({apiKey="%s"}) srv = newServer{address="127.0.0.1:%d", checkName='%s'} """ @@ -127,6 +157,7 @@ def testAuto(self): time.sleep(1.5) self.assertGreater(TestHealthCheckCustomName._healthCheckCounter, before) self.assertEqual(self.getBackendStatus(), 'up') + self.assertEqual(self.getBackendMetric(0, 'healthCheckFailures'), 0) class TestHealthCheckCustomNameNoAnswer(HealthCheckTest): # this test suite uses a different responder port @@ -137,6 +168,8 @@ class TestHealthCheckCustomNameNoAnswer(HealthCheckTest): _config_template = """ setKey("%s") controlSocket("127.0.0.1:%d") + webserver("127.0.0.1:%s") + setWebserverConfig({apiKey="%s"}) srv = newServer{address="127.0.0.1:%d", checkName='powerdns.com.'} """ @@ -148,6 +181,8 @@ def testAuto(self): time.sleep(1.5) self.assertEqual(TestHealthCheckCustomNameNoAnswer._healthCheckCounter, before) self.assertEqual(self.getBackendStatus(), 'down') + self.assertGreater(self.getBackendMetric(0, 'healthCheckFailures'), 0) + self.assertGreater(self.getBackendMetric(0, 'healthCheckFailuresTimeout'), 0) class TestHealthCheckCustomFunction(HealthCheckTest): # this test suite uses a different responder port @@ -159,6 +194,8 @@ class TestHealthCheckCustomFunction(HealthCheckTest): _config_template = """ setKey("%s") controlSocket("127.0.0.1:%d") + webserver("127.0.0.1:%s") + setWebserverConfig({apiKey="%s"}) function myHealthCheckFunction(qname, qtype, qclass, dh) dh:setCD(true) From e6389e47070e9fa9c749226b7c6ef6db3766b53b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 11 Jul 2023 10:15:51 +0200 Subject: [PATCH 398/909] dnsdist: Add a couple comments in the health-check timeout handling code --- pdns/dnsdistdist/dnsdist-healthchecks.cc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index cc73a9d75478..4df42302f3bc 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -459,11 +459,15 @@ void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial) data->d_ds->submitHealthCheckResult(initial, false); } catch (const std::exception& e) { + /* this is not supposed to happen as the file descriptor has to be + there for us to reach that code, and the submission code should not throw, + but let's provide a nice error message if it ever does. */ if (g_verboseHealthChecks) { infolog("Error while dealing with a timeout for the health check response (ID %d) from backend %s: %s", data->d_queryID, data->d_ds->getNameWithAddr(), e.what()); } } catch (...) { + /* this is even less likely to happen */ if (g_verboseHealthChecks) { infolog("Error while dealing with a timeout for the health check response (ID %d) from backend %s", data->d_queryID, data->d_ds->getNameWithAddr()); } @@ -487,11 +491,14 @@ void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial) data->d_ds->submitHealthCheckResult(initial, false); } catch (const std::exception& e) { + /* this is not supposed to happen as the submission code should not throw, + but let's provide a nice error message if it ever does. */ if (g_verboseHealthChecks) { infolog("Error while dealing with a timeout for the health check response (ID %d) from backend %s: %s", data->d_queryID, data->d_ds->getNameWithAddr(), e.what()); } } catch (...) { + /* this is even less likely to happen */ if (g_verboseHealthChecks) { infolog("Error while dealing with a timeout for the health check response (ID %d) from backend %s", data->d_queryID, data->d_ds->getNameWithAddr()); } From d05c43ba621a37458ca496654b983b731bcde4f8 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 11 Jul 2023 14:18:52 +0200 Subject: [PATCH 399/909] dnsdist: Add Lua bindings to access selector and actions --- pdns/dnsdist-console.cc | 5 ++ pdns/dnsdist-lua-rules.cc | 88 +++++++++++++++++++++-- pdns/dnsdist.hh | 2 +- pdns/dnsdistdist/docs/rules-actions.rst | 96 ++++++++++++++++++++++++- 4 files changed, 183 insertions(+), 8 deletions(-) diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index e3e5bcf3258c..f2e381f222bd 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -519,6 +519,8 @@ const std::vector g_consoleKeywords{ { "getAction", true, "n", "Returns the Action associated with rule n" }, { "getBind", true, "n", "returns the listener at index n" }, { "getBindCount", true, "", "returns the number of listeners all kinds" }, + { "getCacheHitResponseRule", true, "selector", "Return the cache-hit response rule corresponding to the selector, if any" }, + { "getCacheInsertedResponseRule", true, "selector", "Return the cache-inserted response rule corresponding to the selector, if any" }, { "getCurrentTime", true, "", "returns the current time" }, { "getDNSCryptBind", true, "n", "return the `DNSCryptContext` object corresponding to the bind `n`" }, { "getDNSCryptBindCount", true, "", "returns the number of DNSCrypt listeners" }, @@ -535,7 +537,10 @@ const std::vector g_consoleKeywords{ { "getPoolNames", true, "", "returns a table with all the pool names" }, { "getQueryCounters", true, "[max=10]", "show current buffer of query counters, limited by 'max' if provided" }, { "getResponseRing", true, "", "return the current content of the response ring" }, + { "getResponseRule", true, "selector", "Return the response rule corresponding to the selector, if any" }, { "getRespRing", true, "", "return the qname/rcode content of the response ring" }, + { "getRule", true, "selector", "Return the rule corresponding to the selector, if any" }, + { "getSelfAnsweredResponseRule", true, "selector", "Return the self-answered response rule corresponding to the selector, if any" }, { "getServer", true, "id", "returns server with index 'n' or whose uuid matches if 'id' is an UUID string" }, { "getServers", true, "", "returns a table with all defined servers" }, { "getStatisticsCounters", true, "", "returns a map of statistic counters" }, diff --git a/pdns/dnsdist-lua-rules.cc b/pdns/dnsdist-lua-rules.cc index 8549014e72ef..5ab1c476ef1b 100644 --- a/pdns/dnsdist-lua-rules.cc +++ b/pdns/dnsdist-lua-rules.cc @@ -224,12 +224,65 @@ static std::vector getTopRules(const std::vector& rules, unsigned int top) return results; } +template +static LuaArray toLuaArray(std::vector&& rules) +{ + LuaArray results; + results.reserve(rules.size()); + + size_t pos = 1; + for (auto& rule : rules) { + results.emplace_back(pos, std::move(rule)); + pos++; + } + + return results; +} + +template +static boost::optional getRuleFromSelector(const std::vector& rules, const boost::variant& selector) +{ + if (auto str = boost::get(&selector)) { + /* let's see if this a UUID */ + try { + const auto uuid = getUniqueID(*str); + for (const auto& rule : rules) { + if (rule.d_id == uuid) { + return rule; + } + } + } + catch (const std::exception& e) { + /* a name, then */ + for (const auto& rule : rules) { + if (rule.d_name == *str) { + return rule; + } + } + } + } + else if (auto pos = boost::get(&selector)) { + return rules.at(*pos); + } + return boost::none; +} + void setupLuaRules(LuaContext& luaCtx) { luaCtx.writeFunction("makeRule", makeRule); luaCtx.registerFunction::*)()const>("toString", [](const std::shared_ptr& rule) { return rule->toString(); }); + luaCtx.registerFunction::*)()const>("getMatches", [](const std::shared_ptr& rule) { return rule->d_matches.load(); }); + + luaCtx.registerFunction(DNSDistRuleAction::*)()const>("getSelector", [](const DNSDistRuleAction& rule) { return rule.d_rule; }); + + luaCtx.registerFunction(DNSDistRuleAction::*)()const>("getAction", [](const DNSDistRuleAction& rule) { return rule.d_action; }); + + luaCtx.registerFunction(DNSDistResponseRuleAction::*)()const>("getSelector", [](const DNSDistResponseRuleAction& rule) { return rule.d_rule; }); + + luaCtx.registerFunction(DNSDistResponseRuleAction::*)()const>("getAction", [](const DNSDistResponseRuleAction& rule) { return rule.d_action; }); + luaCtx.writeFunction("showResponseRules", [](boost::optional vars) { showRules(&g_respruleactions, vars); }); @@ -327,10 +380,15 @@ void setupLuaRules(LuaContext& luaCtx) }); }); + luaCtx.writeFunction("getRule", [](boost::variant selector) -> boost::optional { + auto rules = g_ruleactions.getLocal(); + return getRuleFromSelector(*rules, selector); + }); + luaCtx.writeFunction("getTopRules", [](boost::optional top) { setLuaNoSideEffect(); auto rules = g_ruleactions.getLocal(); - return getTopRules(*rules, (top ? *top : 10)); + return toLuaArray(getTopRules(*rules, (top ? *top : 10))); }); luaCtx.writeFunction("topRules", [](boost::optional top, boost::optional vars) { @@ -339,10 +397,15 @@ void setupLuaRules(LuaContext& luaCtx) return rulesToString(getTopRules(*rules, (top ? *top : 10)), vars); }); + luaCtx.writeFunction("getCacheHitResponseRule", [](boost::variant selector) -> boost::optional { + auto rules = g_cachehitrespruleactions.getLocal(); + return getRuleFromSelector(*rules, selector); + }); + luaCtx.writeFunction("getTopCacheHitResponseRules", [](boost::optional top) { setLuaNoSideEffect(); auto rules = g_cachehitrespruleactions.getLocal(); - return getTopRules(*rules, (top ? *top : 10)); + return toLuaArray(getTopRules(*rules, (top ? *top : 10))); }); luaCtx.writeFunction("topCacheHitResponseRules", [](boost::optional top, boost::optional vars) { @@ -351,10 +414,15 @@ void setupLuaRules(LuaContext& luaCtx) return rulesToString(getTopRules(*rules, (top ? *top : 10)), vars); }); + luaCtx.writeFunction("getCacheInsertedResponseRule", [](boost::variant selector) -> boost::optional { + auto rules = g_cacheInsertedRespRuleActions.getLocal(); + return getRuleFromSelector(*rules, selector); + }); + luaCtx.writeFunction("getTopCacheInsertedResponseRules", [](boost::optional top) { setLuaNoSideEffect(); auto rules = g_cacheInsertedRespRuleActions.getLocal(); - return getTopRules(*rules, (top ? *top : 10)); + return toLuaArray(getTopRules(*rules, (top ? *top : 10))); }); luaCtx.writeFunction("topCacheInsertedResponseRules", [](boost::optional top, boost::optional vars) { @@ -363,10 +431,15 @@ void setupLuaRules(LuaContext& luaCtx) return rulesToString(getTopRules(*rules, (top ? *top : 10)), vars); }); + luaCtx.writeFunction("getResponseRule", [](boost::variant selector) -> boost::optional { + auto rules = g_respruleactions.getLocal(); + return getRuleFromSelector(*rules, selector); + }); + luaCtx.writeFunction("getTopResponseRules", [](boost::optional top) { setLuaNoSideEffect(); auto rules = g_respruleactions.getLocal(); - return getTopRules(*rules, (top ? *top : 10)); + return toLuaArray(getTopRules(*rules, (top ? *top : 10))); }); luaCtx.writeFunction("topResponseRules", [](boost::optional top, boost::optional vars) { @@ -375,10 +448,15 @@ void setupLuaRules(LuaContext& luaCtx) return rulesToString(getTopRules(*rules, (top ? *top : 10)), vars); }); + luaCtx.writeFunction("getSelfAnsweredResponseRule", [](boost::variant selector) -> boost::optional { + auto rules = g_selfansweredrespruleactions.getLocal(); + return getRuleFromSelector(*rules, selector); + }); + luaCtx.writeFunction("getTopSelfAnsweredResponseRules", [](boost::optional top) { setLuaNoSideEffect(); auto rules = g_selfansweredrespruleactions.getLocal(); - return getTopRules(*rules, (top ? *top : 10)); + return toLuaArray(getTopRules(*rules, (top ? *top : 10))); }); luaCtx.writeFunction("topSelfAnsweredResponseRules", [](boost::optional top, boost::optional vars) { diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index fca2e3c4dbdd..7e9341771391 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -951,7 +951,7 @@ public: virtual ~DNSRule () { } - virtual bool matches(const DNSQuestion* dq) const =0; + virtual bool matches(const DNSQuestion* dq) const = 0; virtual string toString() const = 0; mutable stat_t d_matches{0}; }; diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index be3dffaa3f38..116c57b5982e 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -169,12 +169,62 @@ For Rules related to the incoming query: Remove all current rules. -.. function:: getAction(n) -> Action +.. function:: getAction(n) -> DNSDistRuleAction - Returns the Action associated with rule ``n``. + Returns the :class:`DNSDistRuleAction` associated with rule ``n``. :param int n: The rule number +.. function:: getCacheHitResponseRule(selector) -> DNSDistResponseRuleAction + + .. versionadded:: 1.9.0 + + Return the cache-hit response rule corresponding to the selector, if any. + The selector can be the position of the rule in the list, as an integer, + its name as a string or its UUID as a string as well. + + :param int or str selector: The position in the list, name or UUID of the rule to return. + +.. function:: getCacheInsertedResponseRule(selector) -> DNSDistResponseRuleAction + + .. versionadded:: 1.9.0 + + Return the cache-hit response rule corresponding to the selector, if any. + The selector can be the position of the rule in the list, as an integer, + its name as a string or its UUID as a string as well. + + :param int or str selector: The position in the list, name or UUID of the rule to return. + +.. function:: getResponseRule(selector) -> DNSDistResponseRuleAction + + .. versionadded:: 1.9.0 + + Return the response rule corresponding to the selector, if any. + The selector can be the position of the rule in the list, as an integer, + its name as a string or its UUID as a string as well. + + :param int or str selector: The position in the list, name or UUID of the rule to return. + +.. function:: getRule(selector) -> DNSDistRuleAction + + .. versionadded:: 1.9.0 + + Return the rule corresponding to the selector, if any. + The selector can be the position of the rule in the list, as an integer, + its name as a string or its UUID as a string as well. + + :param int or str selector: The position in the list, name or UUID of the rule to return. + +.. function:: getSelfAnsweredResponseRule(selector) -> DNSDistResponseRuleAction + + .. versionadded:: 1.9.0 + + Return the cache-hit response rule corresponding to the selector, if any. + The selector can be the position of the rule in the list, as an integer, + its name as a string or its UUID as a string as well. + + :param int or str selector: The position in the list, name or UUID of the rule to return. + .. function:: mvRule(from, to) Move rule ``from`` to a position where it is in front of ``to``. @@ -1802,3 +1852,45 @@ The following actions exist. Subsequent rules are processed after this action. :param int ttl: Cache TTL for temporary failure replies + +Objects +------- + +.. class:: DNSDistRuleAction + + .. versionadded:: 1.9.0 + + Represents a rule composed of a :class:`DNSRule` selector, to select the queries this applies to, + and a :class:`DNSAction` action to apply when the selector matches. + + .. method:: DNSDistRuleAction:getAction() + + Return the :class:`DNSAction` action of this rule. + + .. method:: DNSDistRuleAction:getSelector() + + Return the :class:`DNSRule` selector of this rule. + +.. class:: DNSDistResponseRuleAction + + .. versionadded:: 1.9.0 + + Represents a rule composed of a :class:`DNSRule` selector, to select the responses this applies to, + and a :class:`DNSResponseAction` action to apply when the selector matches. + + .. method:: DNSDistResponseRuleAction:getAction() + + Return the :class:`DNSResponseAction` action of this rule. + + .. method:: DNSDistResponseRuleAction:getSelector() + + Return the :class:`DNSRule` selector of this rule. + +.. class:: DNSRule + + .. versionadded:: 1.9.0 + + .. method:: DNSRule:getMatches() -> int + + Return the number of times this selector matched a query or a response. Note that if the same selector is reused for different ``DNSDistRuleAction`` + objects, the counter will be common to all these objects. From ab007121a3e168478e7b0095d74620eefa67399b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 7 Jul 2023 10:30:21 +0200 Subject: [PATCH 400/909] build-packages: Fix provenance generation for the source tarball --- .github/workflows/build-packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index 958fed260632..edb88df7c9ad 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -120,7 +120,7 @@ jobs: shell: bash id: srchashes run: | - echo "srchashes=$(sha256sum ./built_pkgs/*/*/${{ inputs.product }}-${{ steps.getversion.outputs.version }}.tar.bz2 ./packages/*.json | base64 -w0)" >> $GITHUB_OUTPUT + echo "srchashes=$(sha256sum ./built_pkgs/*/*/${{ steps.normalize-name.outputs.normalized-package-name }}-${{ steps.getversion.outputs.version }}.tar.bz2 ./packages/*.json | base64 -w0)" >> $GITHUB_OUTPUT - name: Upload packages to downloads.powerdns.com env: SSHKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} From d0fbd333ed7f13d3396569cad2b5691a76c70728 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Tue, 11 Jul 2023 11:01:07 -0400 Subject: [PATCH 401/909] Report auth settings deprecated in 4.5 --- docs/upgrading.rst | 2 +- pdns/arguments.cc | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/docs/upgrading.rst b/docs/upgrading.rst index 5021c714dda6..fc65427a0148 100644 --- a/docs/upgrading.rst +++ b/docs/upgrading.rst @@ -97,7 +97,7 @@ Renamed options ~~~~~~~~~~~~~~~ Various settings have been renamed. -Their old names still work in 4.5.x, but will be removed in the release after it. +Their old names still work in 4.5.x, but will be removed in a release after it. * :ref:`setting-allow-unsigned-supermaster` is now :ref:`setting-allow-unsigned-autoprimary` * :ref:`setting-master` is now :ref:`setting-primary` diff --git a/pdns/arguments.cc b/pdns/arguments.cc index a1081ddd704e..35c1eb001a7b 100644 --- a/pdns/arguments.cc +++ b/pdns/arguments.cc @@ -364,6 +364,13 @@ static const map deprecateList = { {"snmp-master-socket", "snmp-daemon-socket"}, {"xpf-allow-from", "Proxy Protocol"}, {"xpf-rr-code", "Proxy Protocol"}, + {"allow-unsigned-supermaster", "allow-unsigned-autoprimary"}, + {"master", "primary"}, + {"slave-cycle-interval", "xfr-cycle-interval"}, + {"slave-renotify", "secondary-do-renotify"}, + {"slave", "secondary"}, + {"superslave", "autosecondary"}, + {"domain-metadata-cache-ttl", "zone-metadata-cache-ttl"}, }; void ArgvMap::warnIfDeprecated(const string& var) From 2c72227a2c0e226e925af568d985f2240fed497c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 12 Jul 2023 10:37:29 +0200 Subject: [PATCH 402/909] calidns: Prevent a crash on an empty domains file calidns could have crashed with a null pointer derefence if the main thread exits before the receiver thread has finished, because the vector of sockets no longer existed. --- pdns/calidns.cc | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/pdns/calidns.cc b/pdns/calidns.cc index 87bfbe57edba..6bcbcb3a7a49 100644 --- a/pdns/calidns.cc +++ b/pdns/calidns.cc @@ -55,10 +55,13 @@ static po::variables_map g_vm; static bool g_quiet; -static void* recvThread(const vector>* sockets) +static void recvThread(const std::shared_ptr>> sockets) { vector rfds, fds; - for(const auto& s : *sockets) { + for (const auto& s : *sockets) { + if (s == nullptr) { + continue; + } struct pollfd pfd; pfd.fd = s->getHandle(); pfd.events = POLLIN; @@ -114,7 +117,6 @@ static void* recvThread(const vector>* sockets) } } } - return 0; } static ComboAddress getRandomAddressFromRange(const Netmask& ecsRange) @@ -383,7 +385,7 @@ try cout<<"Generated "<> sockets; + auto sockets = std::make_shared>>(); ComboAddress dest; try { dest = ComboAddress(g_vm["destination"].as(), 53); @@ -412,9 +414,14 @@ try } } - sockets.push_back(std::move(sock)); + sockets->push_back(std::move(sock)); } - new thread(recvThread, &sockets); + + { + std::thread receiver(recvThread, sockets); + receiver.detach(); + } + uint32_t qps; ofstream plot; @@ -465,7 +472,7 @@ try DTime dt; dt.set(); - sendPackets(sockets, toSend, qps, dest, ecsRange); + sendPackets(*sockets, toSend, qps, dest, ecsRange); const auto udiff = dt.udiffNoReset(); const auto realqps=toSend.size()/(udiff/1000000.0); From f78d203b80ffe4210420a4fa5b2df136731c8212 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 12 Jul 2023 11:29:32 +0200 Subject: [PATCH 403/909] calidns: Fix two clang-tidy warnings --- pdns/calidns.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/calidns.cc b/pdns/calidns.cc index 6bcbcb3a7a49..4e6b3cf61326 100644 --- a/pdns/calidns.cc +++ b/pdns/calidns.cc @@ -55,6 +55,7 @@ static po::variables_map g_vm; static bool g_quiet; +//NOLINTNEXTLINE(performance-unnecessary-value-param): we do want a copy to increase the reference count, thank you very much static void recvThread(const std::shared_ptr>> sockets) { vector rfds, fds; @@ -142,7 +143,7 @@ static void replaceEDNSClientSubnet(vector* packet, const Netmask& ecsR memcpy(&packet->at(packetSize - sizeof(addr)), &addr, sizeof(addr)); } -static void sendPackets(const vector>& sockets, const vector* >& packets, int qps, ComboAddress dest, const Netmask& ecsRange) +static void sendPackets(const vector>& sockets, const vector* >& packets, uint32_t qps, ComboAddress dest, const Netmask& ecsRange) { unsigned int burst=100; const auto nsecPerBurst=1*(unsigned long)(burst*1000000000.0/qps); From 5985874043bd243f2f72cfe4dc4437ae15a82dfa Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 12 Jul 2023 15:43:55 +0200 Subject: [PATCH 404/909] rec: libarc4random should be linked even if libsodium is not used --- pdns/recursordist/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index f65fa102c5e3..fc330b3c6d2a 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -252,7 +252,7 @@ pdns_recursor_LDFLAGS += \ $(BOOST_FILESYSTEM_LDFLAGS) endif -rec_control_LDADD = $(LIBCRYPTO_LIBS) +rec_control_LDADD = $(LIBCRYPTO_LIBS) $(ARC4RANDOM_LIBS) rec_control_LDFLAGS = $(AM_LDFLAGS) \ $(LIBCRYPTO_LDFLAGS) @@ -402,7 +402,7 @@ pdns_recursor_SOURCES += \ sodiumsigners.cc pdns_recursor_LDADD += $(LIBSODIUM_LIBS) -rec_control_LDADD += $(LIBSODIUM_LIBS) $(ARC4RANDOM_LIBS) +rec_control_LDADD += $(LIBSODIUM_LIBS) testrunner_SOURCES += \ sodiumsigners.cc From 990102dbf1fc92585086a0d13b8041a00badf494 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Thu, 13 Jul 2023 09:51:45 +0300 Subject: [PATCH 405/909] pkcs11signers: Use emplace_back for attributes --- pdns/pkcs11signers.cc | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/pdns/pkcs11signers.cc b/pdns/pkcs11signers.cc index 9269c9e5f8af..872bd518a560 100644 --- a/pdns/pkcs11signers.cc +++ b/pdns/pkcs11signers.cc @@ -371,9 +371,8 @@ class Pkcs11Token { auto slot = d_slot->lock(); std::vector attr; std::vector key; - attr.push_back(P11KitAttribute(CKA_CLASS, (unsigned long)CKO_PRIVATE_KEY)); -// attr.push_back(P11KitAttribute(CKA_SIGN, (char)CK_TRUE)); - attr.push_back(P11KitAttribute(CKA_LABEL, d_label)); + attr.emplace_back(CKA_CLASS, (unsigned long)CKO_PRIVATE_KEY); + attr.emplace_back(CKA_LABEL, d_label); FindObjects2(*slot, attr, key, 1); if (key.size() == 0) { g_log< Date: Sun, 16 Apr 2023 21:09:29 +0300 Subject: [PATCH 406/909] pkcs11signers: Support CKA_ALWAYS_AUTHENTICATE If private key has this flag, relogin with CKU_CONTEXT_SPECIFIC before sign/verify operation. --- pdns/pkcs11signers.cc | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/pdns/pkcs11signers.cc b/pdns/pkcs11signers.cc index 872bd518a560..181e3da9ee11 100644 --- a/pdns/pkcs11signers.cc +++ b/pdns/pkcs11signers.cc @@ -218,6 +218,7 @@ class Pkcs11Slot { CK_SESSION_HANDLE d_session; CK_SLOT_ID d_slot; CK_RV d_err{}; + std::string d_pin; void logError(const std::string& operation) const { if (d_err) { @@ -248,22 +249,26 @@ class Pkcs11Slot { } } - bool Login(const std::string& pin) { - if (d_logged_in) return true; + bool Login(const std::string& pin, CK_USER_TYPE userType=CKU_USER) { + if (userType == CKU_USER && d_logged_in) return true; auto uPin = std::make_unique(pin.size()); memcpy(uPin.get(), pin.c_str(), pin.size()); - d_err = d_functions->C_Login(this->d_session, CKU_USER, uPin.get(), pin.size()); - memset(uPin.get(), 0, pin.size()); + d_err = d_functions->C_Login(this->d_session, userType, uPin.get(), pin.size()); logError("C_Login"); - if (d_err == 0) { + if (d_err == 0 && userType == CKU_USER) { d_logged_in = true; + d_pin = pin; } return d_logged_in; } + bool Relogin() { + return Login(d_pin, CKU_CONTEXT_SPECIFIC); + } + bool LoggedIn() const { return d_logged_in; } CK_SESSION_HANDLE& Session() { return d_session; } @@ -281,6 +286,7 @@ class Pkcs11Token { CK_OBJECT_HANDLE d_public_key; CK_OBJECT_HANDLE d_private_key; CK_KEY_TYPE d_key_type; + bool d_always_auth; CK_ULONG d_bits; std::string d_exponent; @@ -380,6 +386,11 @@ class Pkcs11Token { } d_private_key = key[0]; attr.clear(); + attr.emplace_back(CKA_ALWAYS_AUTHENTICATE, '\0'); + if (GetAttributeValue2(*slot, d_private_key, attr)==0) { + d_always_auth = attr[0].byte() != 0; + } + attr.clear(); attr.emplace_back(CKA_CLASS, (unsigned long)CKO_PUBLIC_KEY); attr.emplace_back(CKA_LABEL, d_pub_label); FindObjects2(*slot, attr, key, 1); @@ -463,8 +474,12 @@ class Pkcs11Token { CK_ULONG buflen = sizeof buffer; // should be enough for most signatures. auto slot = d_slot->lock(); - // perform signature if ((d_err = slot->f()->C_SignInit(slot->Session(), mechanism, d_private_key))) { logError("C_SignInit"); return d_err; } + // check if we need to relogin + if (d_always_auth) { + slot->Relogin(); + } + // perform signature d_err = slot->f()->C_Sign(slot->Session(), (unsigned char*)data.c_str(), data.size(), buffer, &buflen); if (!d_err) { @@ -480,6 +495,11 @@ class Pkcs11Token { auto slot = d_slot->lock(); if ((d_err = slot->f()->C_VerifyInit(slot->Session(), mechanism, d_public_key))) { logError("C_VerifyInit"); return d_err; } + // check if we need to relogin + if (d_always_auth) { + slot->Relogin(); + } + d_err = slot->f()->C_Verify(slot->Session(), (unsigned char*)data.c_str(), data.size(), (unsigned char*)signature.c_str(), signature.size()); logError("C_Verify"); return d_err; From 98f8cc81d66eba1645c44f10d4806e69b1a23e7d Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Thu, 4 May 2023 22:36:18 +0300 Subject: [PATCH 407/909] pkcs11signers: Add braces Satisfies clang-tidy --- pdns/pkcs11signers.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pdns/pkcs11signers.cc b/pdns/pkcs11signers.cc index 181e3da9ee11..b89f77953582 100644 --- a/pdns/pkcs11signers.cc +++ b/pdns/pkcs11signers.cc @@ -250,7 +250,9 @@ class Pkcs11Slot { } bool Login(const std::string& pin, CK_USER_TYPE userType=CKU_USER) { - if (userType == CKU_USER && d_logged_in) return true; + if (userType == CKU_USER && d_logged_in) { + return true; + } auto uPin = std::make_unique(pin.size()); memcpy(uPin.get(), pin.c_str(), pin.size()); From da3af217dbc9303e1d609930f7eec34270a68f72 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 13 Jul 2023 10:42:55 +0200 Subject: [PATCH 408/909] dnsheader: Switch from bitfield to uint16_t whenever possible --- pdns/dns.hh | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pdns/dns.hh b/pdns/dns.hh index bb7c842cfa0b..24a02e8a4866 100644 --- a/pdns/dns.hh +++ b/pdns/dns.hh @@ -151,7 +151,7 @@ static_assert(sizeof(EDNS0Record) == 4, "EDNS0Record size must be 4"); #endif struct dnsheader { - unsigned id :16; /* query identification number */ + uint16_t id; /* query identification number */ #if BYTE_ORDER == BIG_ENDIAN /* fields in third byte */ unsigned qr: 1; /* response flag */ @@ -180,10 +180,10 @@ struct dnsheader { unsigned ra :1; /* recursion available */ #endif /* remaining bytes */ - unsigned qdcount :16; /* number of question entries */ - unsigned ancount :16; /* number of answer entries */ - unsigned nscount :16; /* number of authority entries */ - unsigned arcount :16; /* number of resource entries */ + uint16_t qdcount; /* number of question entries */ + uint16_t ancount; /* number of answer entries */ + uint16_t nscount; /* number of authority entries */ + uint16_t arcount; /* number of resource entries */ }; static_assert(sizeof(dnsheader) == 12, "dnsheader size must be 12"); From aa1cfa04d3ce770feab1db7faa32a8c3d9de928a Mon Sep 17 00:00:00 2001 From: Andras Kovacs Date: Thu, 13 Jul 2023 22:44:02 +0200 Subject: [PATCH 409/909] wait for mysql.service --- pdns/pdns.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/pdns.service.in b/pdns/pdns.service.in index 1d23347b4d28..d5516eb297ff 100644 --- a/pdns/pdns.service.in +++ b/pdns/pdns.service.in @@ -3,7 +3,7 @@ Description=PowerDNS Authoritative Server Documentation=man:pdns_server(1) man:pdns_control(1) Documentation=https://doc.powerdns.com Wants=network-online.target -After=network-online.target mysqld.service postgresql.service slapd.service mariadb.service time-sync.target +After=network-online.target mysql.service mysqld.service postgresql.service slapd.service mariadb.service time-sync.target [Service] ExecStart=@sbindir@/pdns_server --guardian=no --daemon=no --disable-syslog --log-timestamp=no --write-pid=no From 72f440f1ebdbee09ef73013576d69cfac0f9288a Mon Sep 17 00:00:00 2001 From: Jacob Bunk Nielsen Date: Fri, 14 Jul 2023 14:13:49 +0200 Subject: [PATCH 410/909] Document queue-limit in performance.rst as promised. settings.rst tells the reader to also see performance.rst regarding queue-limit but there's nothing there, until now. --- docs/performance.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/performance.rst b/docs/performance.rst index 610b8965f678..8c44ef24663f 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -63,6 +63,10 @@ the value of the :ref:`stat-qsize-q` variable. This represents the number of packets waiting for database attention. During normal operations the queue should be small. +The value of :ref:`setting-queue-limit` should be set to only keep queries in +queue for as long as someone would be interested in knowing the answer. Many +resolvers will query other name servers for the zone quite aggressively. + Logging truly kills performance as answering a question from the cache is an order of magnitude less work than logging a line about it. Busy sites will prefer to turn :ref:`setting-log-dns-details` off. From 0828c8beba6d4d314f701cefaca2b6d4ac1c647b Mon Sep 17 00:00:00 2001 From: Jacob Bunk Nielsen Date: Fri, 14 Jul 2023 14:14:20 +0200 Subject: [PATCH 411/909] Document that qsize-q will never give meaningful metrics with a single receiver thread. --- docs/performance.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/performance.rst b/docs/performance.rst index 8c44ef24663f..759c59951647 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -260,7 +260,7 @@ Amount of packets in the packetcache qsize-q ^^^^^^^ -Number of packets waiting for database attention +Number of packets waiting for database attention, only available if :ref:`setting-receiver-threads` > 1 .. _stat-query-cache-hit: From 50be1bc562e5be81eccb775bdf20225b2d88c64c Mon Sep 17 00:00:00 2001 From: Seth Arnold Date: Sat, 15 Jul 2023 01:21:01 +0000 Subject: [PATCH 412/909] Update settings.rst -- clarify edns-subnet-allow-list Try to reduce confusion about what the edns-subnet-allow-list setting does and doesn't affect. --- pdns/recursordist/docs/settings.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 2d4790d7da5f..740c2e3a93c0 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -791,6 +791,8 @@ List of netmasks and domains that :rfc:`EDNS Client Subnet <7871>` should be ena For example, an EDNS Client Subnet option containing the address of the initial requestor (but see `ecs-add-for`_) will be added to an outgoing query sent to server 192.0.2.1 for domain X if 192.0.2.1 matches one of the supplied netmasks, or if X matches one of the supplied domains. The initial requestor address will be truncated to 24 bits for IPv4 (see `ecs-ipv4-bits`_) and to 56 bits for IPv6 (see `ecs-ipv6-bits`_), as recommended in the privacy section of RFC 7871. +Note that this setting describes the destination of outgoing queries, not the sources of incoming queries, nor the subnets described in the EDNS Client Subnet option. + By default, this option is empty, meaning no EDNS Client Subnet information is sent. .. _setting-entropy-source: From ef9d8a96c7dbc6c6cb10d93718c47af17a8ab68a Mon Sep 17 00:00:00 2001 From: Call-Me-G-Now <125204742+Call-Me-G-Now@users.noreply.github.com> Date: Sun, 16 Jul 2023 21:12:33 +0200 Subject: [PATCH 413/909] update changelog --- docs/changelog/4.8.rst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docs/changelog/4.8.rst b/docs/changelog/4.8.rst index 0de0c699f3d4..9b8731df6b24 100644 --- a/docs/changelog/4.8.rst +++ b/docs/changelog/4.8.rst @@ -45,6 +45,8 @@ Changelogs for 4.8.x This is release 4.8.0 of the Authoritative Server. + Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x + In 4.8, the LMDB backend gains a new Lightning Stream-compatible schema, which requires a data migration (this is automatic, and there is no migration back to the old schema). LMDB backend users should pay extra attention to the :doc:`Upgrade Notes <../upgrading>`. @@ -85,6 +87,8 @@ Changelogs for 4.8.x This is release 4.8.0-beta1 of the Authoritative Server. + Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x + In 4.8, the LMDB backend gains a new Lightning Stream-compatible schema, which requires a data migration (this is automatic, and there is no migration back to the old schema). LMDB backend users should pay extra attention to the :doc:`Upgrade Notes <../upgrading>`. @@ -148,6 +152,8 @@ Changelogs for 4.8.x This is release 4.8.0-alpha1 of the Authoritative Server. + Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x + In this release, the LMDB backend gains a new Lightning Stream-compatible schema, which requires a data migration (this is automatic, and there is no migration back to the old schema). LMDB backend users should pay extra attention to the :doc:`Upgrade Notes <../upgrading>`. From c6f4542a7c65f22778c8882dd7f9a79301bd35fe Mon Sep 17 00:00:00 2001 From: Call-Me-G-Now <125204742+Call-Me-G-Now@users.noreply.github.com> Date: Sun, 16 Jul 2023 21:17:50 +0200 Subject: [PATCH 414/909] cleanup --- docs/changelog/4.8.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/changelog/4.8.rst b/docs/changelog/4.8.rst index 9b8731df6b24..f1039c37eb5d 100644 --- a/docs/changelog/4.8.rst +++ b/docs/changelog/4.8.rst @@ -7,6 +7,8 @@ Changelogs for 4.8.x This is release 4.8.1 of the Authoritative Server. + Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x. + This release contains a small collection of fixes: .. change:: @@ -45,7 +47,7 @@ Changelogs for 4.8.x This is release 4.8.0 of the Authoritative Server. - Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x + Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x. In 4.8, the LMDB backend gains a new Lightning Stream-compatible schema, which requires a data migration (this is automatic, and there is no migration back to the old schema). LMDB backend users should pay extra attention to the :doc:`Upgrade Notes <../upgrading>`. @@ -87,7 +89,7 @@ Changelogs for 4.8.x This is release 4.8.0-beta1 of the Authoritative Server. - Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x + Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x. In 4.8, the LMDB backend gains a new Lightning Stream-compatible schema, which requires a data migration (this is automatic, and there is no migration back to the old schema). LMDB backend users should pay extra attention to the :doc:`Upgrade Notes <../upgrading>`. @@ -152,7 +154,7 @@ Changelogs for 4.8.x This is release 4.8.0-alpha1 of the Authoritative Server. - Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x + Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x. In this release, the LMDB backend gains a new Lightning Stream-compatible schema, which requires a data migration (this is automatic, and there is no migration back to the old schema). LMDB backend users should pay extra attention to the :doc:`Upgrade Notes <../upgrading>`. From 7157d4a95b56099ed26e129e82aa8763c0ea05e4 Mon Sep 17 00:00:00 2001 From: Call-Me-G-Now <125204742+Call-Me-G-Now@users.noreply.github.com> Date: Sun, 16 Jul 2023 21:54:07 +0200 Subject: [PATCH 415/909] Update changelog --- pdns/recursordist/docs/changelog/4.9.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pdns/recursordist/docs/changelog/4.9.rst b/pdns/recursordist/docs/changelog/4.9.rst index 263fb23579af..8382089f0442 100644 --- a/pdns/recursordist/docs/changelog/4.9.rst +++ b/pdns/recursordist/docs/changelog/4.9.rst @@ -4,6 +4,8 @@ Changelogs for 4.9.X :version: 4.9.0 :released: 30th of June 2023 + Please review the :doc:`Upgrade Notes <../upgrade>` before upgrading from versions < 4.9.x. + .. change:: :tags: Bug Fixes :pullreq: 12968 @@ -29,6 +31,8 @@ Changelogs for 4.9.X :version: 4.9.0-rc1 :released: 15nd of June 2023 + Please review the :doc:`Upgrade Notes <../upgrade>` before upgrading from versions < 4.9.x. + .. change:: :tags: Improvements :pullreq: 12906 @@ -78,6 +82,8 @@ Changelogs for 4.9.X :version: 4.9.0-beta1 :released: 2nd of June 2023 + Please review the :doc:`Upgrade Notes <../upgrade>` before upgrading from versions < 4.9.x. + .. change:: :tags: Improvements :pullreq: 12861 @@ -120,6 +126,8 @@ Changelogs for 4.9.X :version: 4.9.0-alpha1 :released: 14th of April 2023 + Please review the :doc:`Upgrade Notes <../upgrade>` before upgrading from versions < 4.9.x. + .. change:: :tags: Improvements :pullreq: 12710 From 3705813bc3f123e162bd50ac521f9876687ddc9e Mon Sep 17 00:00:00 2001 From: Call-Me-G-Now <125204742+Call-Me-G-Now@users.noreply.github.com> Date: Sun, 16 Jul 2023 21:58:55 +0200 Subject: [PATCH 416/909] Update changelog Naming inconsistencies pdns-auth <> pdns-rec docs - Release Notes <> Release Guide - upgrading.html <> upgrade.html --- pdns/recursordist/docs/changelog/4.9.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pdns/recursordist/docs/changelog/4.9.rst b/pdns/recursordist/docs/changelog/4.9.rst index 8382089f0442..657b809a7b7e 100644 --- a/pdns/recursordist/docs/changelog/4.9.rst +++ b/pdns/recursordist/docs/changelog/4.9.rst @@ -4,7 +4,7 @@ Changelogs for 4.9.X :version: 4.9.0 :released: 30th of June 2023 - Please review the :doc:`Upgrade Notes <../upgrade>` before upgrading from versions < 4.9.x. + Please review the :doc:`Upgrade Guide <../upgrade>` before upgrading from versions < 4.9.x. .. change:: :tags: Bug Fixes @@ -31,7 +31,7 @@ Changelogs for 4.9.X :version: 4.9.0-rc1 :released: 15nd of June 2023 - Please review the :doc:`Upgrade Notes <../upgrade>` before upgrading from versions < 4.9.x. + Please review the :doc:`Upgrade Guide <../upgrade>` before upgrading from versions < 4.9.x. .. change:: :tags: Improvements @@ -82,7 +82,7 @@ Changelogs for 4.9.X :version: 4.9.0-beta1 :released: 2nd of June 2023 - Please review the :doc:`Upgrade Notes <../upgrade>` before upgrading from versions < 4.9.x. + Please review the :doc:`Upgrade Guide <../upgrade>` before upgrading from versions < 4.9.x. .. change:: :tags: Improvements @@ -126,7 +126,7 @@ Changelogs for 4.9.X :version: 4.9.0-alpha1 :released: 14th of April 2023 - Please review the :doc:`Upgrade Notes <../upgrade>` before upgrading from versions < 4.9.x. + Please review the :doc:`Upgrade Guide <../upgrade>` before upgrading from versions < 4.9.x. .. change:: :tags: Improvements From 0deef891dc96ac94c7d3f9fe5e6e573631c9ac9e Mon Sep 17 00:00:00 2001 From: Call-Me-G-Now <125204742+Call-Me-G-Now@users.noreply.github.com> Date: Sun, 16 Jul 2023 22:13:44 +0200 Subject: [PATCH 417/909] Update changelog --- pdns/dnsdistdist/docs/changelog.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index a54a942a503d..6b9b50979c00 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -5,6 +5,8 @@ Changelog :version: 1.7.4 :released: 14th of April 2023 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.8.x. + .. change:: :tags: Bug Fixes :pullreq: 12183 @@ -117,6 +119,8 @@ Changelog :version: 1.8.0 :released: 30th of March 2023 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.8.x. + .. change:: :tags: Bug Fixes :pullreq: 12687 @@ -139,6 +143,8 @@ Changelog :version: 1.8.0-rc3 :released: 16th of March 2023 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.8.x. + .. change:: :tags: Bug Fixes :pullreq: 12641 @@ -173,6 +179,8 @@ Changelog :version: 1.8.0-rc2 :released: 9th of March 2023 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.8.x. + .. change:: :tags: Improvements, Protobuf :pullreq: 12615 @@ -219,6 +227,8 @@ Changelog :version: 1.8.0-rc1 :released: 23rd of February 2023 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.8.x. + .. change:: :tags: Bug Fixes :pullreq: 12569 From 5d11e7c757b5091ee775b9f4326c198e62e920bf Mon Sep 17 00:00:00 2001 From: Call-Me-G-Now <125204742+Call-Me-G-Now@users.noreply.github.com> Date: Sun, 16 Jul 2023 22:28:21 +0200 Subject: [PATCH 418/909] Update changelog --- pdns/dnsdistdist/docs/changelog.rst | 82 ++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index 6b9b50979c00..ca221f0e017f 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -5,7 +5,7 @@ Changelog :version: 1.7.4 :released: 14th of April 2023 - Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.8.x. + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.7.x. .. change:: :tags: Bug Fixes @@ -1081,6 +1081,8 @@ Changelog :version: 1.7.3 :released: 2nd of November 2022 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.7.x. + dnsdist 1.7.3 contains no functional changes or bugfixes. This release strictly serves to bring dnsdist packages to our EL9 and Ubuntu Jammy repositories, and upgrades the dnsdist Docker image from Debian buster to Debian bullseye, as buster is officially EOL. @@ -1106,6 +1108,8 @@ Changelog :version: 1.7.2 :released: 14th of June 2022 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.7.x. + .. change:: :tags: Improvements :pullreq: 11579 @@ -1152,6 +1156,8 @@ Changelog :version: 1.7.1 :released: 25th of April 2022 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.7.x. + .. change:: :tags: Improvements :pullreq: 11195 @@ -1272,6 +1278,8 @@ Changelog :version: 1.7.0 :released: 17th of January 2022 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.7.x. + .. change:: :tags: Bug Fixes :pullreq: 11156 @@ -1283,6 +1291,8 @@ Changelog :version: 1.7.0-rc1 :released: 22nd of December 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.7.x. + .. change:: :tags: Improvements, DNS over TLS, Performance :pullreq: 11037 @@ -1360,6 +1370,8 @@ Changelog :version: 1.7.0-beta1 :released: 16th of November 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.7.x. + .. change:: :tags: Improvements :pullreq: 10646 @@ -1483,6 +1495,8 @@ Changelog :version: 1.7.0-alpha2 :released: 19th of October 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.7.x. + .. change:: :tags: Improvements :pullreq: 10760 @@ -1586,6 +1600,8 @@ Changelog :version: 1.7.0-alpha1 :released: 23rd of September 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.7.x. + .. change:: :tags: Improvements :pullreq: 10157 @@ -1749,6 +1765,8 @@ Changelog :version: 1.6.1 :released: 15th of September 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.6.x. + .. change:: :tags: Bug Fixes :pullreq: 10438 @@ -1800,10 +1818,14 @@ Changelog :version: 1.6.0 :released: 11th of May 2021 -.. changelog:: + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.6.x. + + .. changelog:: :version: 1.5.2 :released: 10th of May 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.5.x. + .. change:: :tags: Bug Fixes :pullreq: 9583 @@ -1881,6 +1903,8 @@ Changelog :version: 1.6.0-rc2 :released: 4th of May 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.6.x. + .. change:: :tags: Improvements, Metrics :pullreq: 10323 @@ -1904,6 +1928,8 @@ Changelog :version: 1.6.0-rc1 :released: 20th of April 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.6.x. + .. change:: :tags: Bug Fixes :pullreq: 10171 @@ -1940,6 +1966,8 @@ Changelog :version: 1.6.0-alpha3 :released: 29th of March 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.6.x. + .. change:: :tags: Improvements :pullreq: 10156 @@ -2005,6 +2033,8 @@ Changelog :version: 1.6.0-alpha2 :released: 4th of March 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.6.x. + .. change:: :tags: Improvements :pullreq: 9361 @@ -2078,6 +2108,8 @@ Changelog :version: 1.6.0-alpha1 :released: 2nd of February 2021 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.6.x. + .. change:: :tags: Improvements :pullreq: 9273 @@ -2472,6 +2504,8 @@ Changelog :version: 1.5.1 :released: 1st of October 2020 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.5.x. + .. change:: :tags: Improvements :pullreq: 9540 @@ -2508,6 +2542,8 @@ Changelog :version: 1.5.0 :released: 30th of July 2020 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.5.x. + .. change:: :tags: Improvements :pullreq: 9231 @@ -2561,6 +2597,8 @@ Changelog :version: 1.5.0-rc4 :released: 7th of July 2020 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.5.x. + .. change:: :tags: Bug Fixes :pullreq: 9278 @@ -2571,6 +2609,8 @@ Changelog :version: 1.5.0-rc3 :released: 18th of June 2020 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.5.x. + .. change:: :tags: Improvements :pullreq: 9100 @@ -2626,6 +2666,8 @@ Changelog :version: 1.5.0-rc2 :released: 13th of May 2020 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.5.x. + .. change:: :tags: Bug Fixes :pullreq: 9031 @@ -2698,6 +2740,8 @@ Changelog :version: 1.5.0-rc1 :released: 16th of April 2020 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.5.x. + .. change:: :tags: Bug Fixes :pullreq: 8955 @@ -2746,6 +2790,8 @@ Changelog :version: 1.5.0-alpha1 :released: 20th of March 2020 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.5.x. + .. change:: :tags: Improvements :pullreq: 7820 @@ -3047,6 +3093,8 @@ Changelog :version: 1.4.0 :released: 20th of November 2019 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.4.x. + .. change:: :tags: Bug Fixes :pullreq: 8524 @@ -3087,6 +3135,8 @@ Changelog :version: 1.4.0-rc5 :released: 30th of October 2019 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.4.x. + .. change:: :tags: Improvements, DNS over HTTPS, Metrics :pullreq: 8465 @@ -3103,6 +3153,8 @@ Changelog :version: 1.4.0-rc4 :released: 25th of October 2019 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.4.x. + .. change:: :tags: New Features, DNS over HTTPS, DNS over TLS :pullreq: 8442 @@ -3243,6 +3295,9 @@ Changelog :version: 1.4.0-rc3 :released: 30th of September 2019 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.4.x. + + .. change:: :tags: Improvements :pullreq: 8083 @@ -3322,6 +3377,9 @@ Changelog :version: 1.4.0-rc2 :released: 2nd of September 2019 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.4.x. + + .. change:: :tags: New Features :pullreq: 8139 @@ -3363,6 +3421,8 @@ Changelog :version: 1.4.0-rc1 :released: 12th of August 2019 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.4.x. + .. change:: :tags: Improvements :pullreq: 7860 @@ -3648,6 +3708,8 @@ Changelog :version: 1.4.0-beta1 :released: 6th of June 2019 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.4.x. + .. change:: :tags: Bug Fixes, DoH :pullreq: 7814 @@ -3685,6 +3747,8 @@ Changelog :version: 1.4.0-alpha2 :released: 26th of April 2019 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.4.x. + .. change:: :tags: Improvements :pullreq: 7410 @@ -3714,6 +3778,8 @@ Changelog :version: 1.4.0-alpha1 :released: 12th of April 2019 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.4.x. + .. change:: :tags: New Features :pullreq: 7209 @@ -3984,6 +4050,8 @@ Changelog :version: 1.3.3 :released: 8th of November 2018 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.3.x. + .. change:: :tags: New Features :pullreq: 6737, 6939 @@ -4170,6 +4238,8 @@ Changelog :version: 1.3.2 :released: 10th of July 2018 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.3.x. + .. change:: :tags: Bug Fixes :pullreq: 6785 @@ -4180,6 +4250,8 @@ Changelog :version: 1.3.1 :released: 10th of July 2018 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.3.x. + .. change:: :tags: Improvements :pullreq: 6358 @@ -4493,6 +4565,8 @@ Changelog :version: 1.3.0 :released: 30th of March 2018 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.3.x. + .. change:: :tags: Improvements, New Features :pullreq: 5576, 5860 @@ -4738,6 +4812,8 @@ Changelog :version: 1.2.1 :released: 16th of February 2018 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.2.x. + .. change:: :tags: New Features :pullreq: 5880 @@ -4816,6 +4892,8 @@ Changelog :version: 1.2.0 :released: 21st of August 2017 + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.2.x. + .. change:: :tags: Improvements :pullreq: 4852 From 9bdc8d155b421501d8dcca50d578bfd2c2e96fb7 Mon Sep 17 00:00:00 2001 From: Call-Me-G-Now <125204742+Call-Me-G-Now@users.noreply.github.com> Date: Sun, 16 Jul 2023 22:34:28 +0200 Subject: [PATCH 419/909] Update changelog --- pdns/dnsdistdist/docs/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index ca221f0e017f..4a841da0390c 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -1820,7 +1820,7 @@ Changelog Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.6.x. - .. changelog:: +.. changelog:: :version: 1.5.2 :released: 10th of May 2021 From ac9d31392ad9ecdcfe78744da4f54490b182c566 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 17 Jul 2023 09:03:23 +0200 Subject: [PATCH 420/909] dnsdist changelog: fix indentation of this line --- pdns/dnsdistdist/docs/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index a54a942a503d..cbda3be730a4 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -1041,7 +1041,7 @@ Changelog :tags: New Features :pullreq: 11051 - Add support to spoof a full self-generated response from lua + Add support to spoof a full self-generated response from lua .. change:: :tags: New Features From b92f183afd503cb683427845c2b91bb52a3d12a4 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 10 Jul 2023 17:49:51 +0200 Subject: [PATCH 421/909] dnsdist: Better handling of spurious wake-ups, interrupted calls If we were woken up by the multiplexer but have actually nothing to read, or the call to `recv()` is interrupted, we do not want to stop listening for the health-check response event. It is also not useful to log about it, even at "verbose health-check" level. Note that we would have logged previously, so this kind of event would not have gone unnoticed anyway. --- pdns/dnsdistdist/dnsdist-healthchecks.cc | 40 +++++++++++++++++------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index 4df42302f3bc..e04ef5a56e34 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -169,22 +169,37 @@ class HealthCheckQuerySender : public TCPQuerySender static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) { auto data = boost::any_cast>(param); - data->d_mplexer.removeReadFD(fd); + ssize_t got = 0; ComboAddress from; - from.sin4.sin_family = data->d_ds->d_config.remote.sin4.sin_family; - auto fromlen = from.getSocklen(); - data->d_buffer.resize(512); - auto got = recvfrom(data->d_udpSocket.getHandle(), &data->d_buffer.at(0), data->d_buffer.size(), 0, reinterpret_cast(&from), &fromlen); - if (got < 0) { - int savederrno = errno; - if (g_verboseHealthChecks) { - infolog("Error receiving health check response from %s: %s", data->d_ds->d_config.remote.toStringWithPort(), stringerror(savederrno)); + do { + from.sin4.sin_family = data->d_ds->d_config.remote.sin4.sin_family; + auto fromlen = from.getSocklen(); + data->d_buffer.resize(512); + + got = recvfrom(data->d_udpSocket.getHandle(), &data->d_buffer.at(0), data->d_buffer.size(), 0, reinterpret_cast(&from), &fromlen); + if (got < 0) { + int savederrno = errno; + if (savederrno == EINTR) { + /* interrupted, let's try again */ + continue; + } + if (savederrno == EWOULDBLOCK || savederrno == EAGAIN) { + /* spurious wake-up, let's return to sleep */ + return; + } + + if (g_verboseHealthChecks) { + infolog("Error receiving health check response from %s: %s", data->d_ds->d_config.remote.toStringWithPort(), stringerror(savederrno)); + } + ++data->d_ds->d_healthCheckMetrics.d_networkErrors; + data->d_ds->submitHealthCheckResult(data->d_initial, false); + data->d_mplexer.removeReadFD(fd); + return; } - ++data->d_ds->d_healthCheckMetrics.d_networkErrors; - data->d_ds->submitHealthCheckResult(data->d_initial, false); - return; } + while (got < 0); + data->d_buffer.resize(static_cast(got)); /* we are using a connected socket but hey.. */ @@ -197,6 +212,7 @@ static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) return; } + data->d_mplexer.removeReadFD(fd); data->d_ds->submitHealthCheckResult(data->d_initial, handleResponse(data)); } From 65f47b8e68c303a59c5aec6bbfc4421d8616fdbb Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 11 Jul 2023 10:37:08 +0200 Subject: [PATCH 422/909] dnsdist: Delint dnsdist-healthchecks.cc --- pdns/dnsdistdist/dnsdist-healthchecks.cc | 133 ++++++++++++----------- pdns/dnsdistdist/dnsdist-healthchecks.hh | 2 +- 2 files changed, 69 insertions(+), 66 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index e04ef5a56e34..1ec3cb06d929 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -35,7 +35,7 @@ struct HealthCheckData { enum class TCPState : uint8_t { WritingQuery, ReadingResponseSize, ReadingResponse }; - HealthCheckData(FDMultiplexer& mplexer, const std::shared_ptr& ds, DNSName&& checkName, uint16_t checkType, uint16_t checkClass, uint16_t queryID): d_ds(ds), d_mplexer(mplexer), d_udpSocket(-1), d_checkName(std::move(checkName)), d_checkType(checkType), d_checkClass(checkClass), d_queryID(queryID) + HealthCheckData(FDMultiplexer& mplexer, std::shared_ptr downstream, DNSName&& checkName, uint16_t checkType, uint16_t checkClass, uint16_t queryID): d_ds(std::move(downstream)), d_mplexer(mplexer), d_udpSocket(-1), d_checkName(std::move(checkName)), d_checkType(checkType), d_checkClass(checkClass), d_queryID(queryID) { } @@ -57,57 +57,58 @@ struct HealthCheckData static bool handleResponse(std::shared_ptr& data) { - auto& ds = data->d_ds; + const auto& downstream = data->d_ds; try { if (data->d_buffer.size() < sizeof(dnsheader)) { ++data->d_ds->d_healthCheckMetrics.d_parseErrors; if (g_verboseHealthChecks) { - infolog("Invalid health check response of size %d from backend %s, expecting at least %d", data->d_buffer.size(), ds->getNameWithAddr(), sizeof(dnsheader)); + infolog("Invalid health check response of size %d from backend %s, expecting at least %d", data->d_buffer.size(), downstream->getNameWithAddr(), sizeof(dnsheader)); } return false; } - const dnsheader * responseHeader = reinterpret_cast(data->d_buffer.data()); - if (responseHeader->id != data->d_queryID) { + dnsheader_aligned responseHeader(data->d_buffer.data()); + if (responseHeader.get()->id != data->d_queryID) { ++data->d_ds->d_healthCheckMetrics.d_mismatchErrors; if (g_verboseHealthChecks) { - infolog("Invalid health check response id %d from backend %s, expecting %d", responseHeader->id, ds->getNameWithAddr(), data->d_queryID); + infolog("Invalid health check response id %d from backend %s, expecting %d", responseHeader.get()->id, downstream->getNameWithAddr(), data->d_queryID); } return false; } - if (!responseHeader->qr) { + if (!responseHeader.get()->qr) { ++data->d_ds->d_healthCheckMetrics.d_invalidResponseErrors; if (g_verboseHealthChecks) { - infolog("Invalid health check response from backend %s, expecting QR to be set", ds->getNameWithAddr()); + infolog("Invalid health check response from backend %s, expecting QR to be set", downstream->getNameWithAddr()); } return false; } - if (responseHeader->rcode == RCode::ServFail) { + if (responseHeader.get()->rcode == RCode::ServFail) { ++data->d_ds->d_healthCheckMetrics.d_invalidResponseErrors; if (g_verboseHealthChecks) { - infolog("Backend %s responded to health check with ServFail", ds->getNameWithAddr()); + infolog("Backend %s responded to health check with ServFail", downstream->getNameWithAddr()); } return false; } - if (ds->d_config.mustResolve && (responseHeader->rcode == RCode::NXDomain || responseHeader->rcode == RCode::Refused)) { + if (downstream->d_config.mustResolve && (responseHeader.get()->rcode == RCode::NXDomain || responseHeader.get()->rcode == RCode::Refused)) { ++data->d_ds->d_healthCheckMetrics.d_invalidResponseErrors; if (g_verboseHealthChecks) { - infolog("Backend %s responded to health check with %s while mustResolve is set", ds->getNameWithAddr(), responseHeader->rcode == RCode::NXDomain ? "NXDomain" : "Refused"); + infolog("Backend %s responded to health check with %s while mustResolve is set", downstream->getNameWithAddr(), responseHeader.get()->rcode == RCode::NXDomain ? "NXDomain" : "Refused"); } return false; } - uint16_t receivedType; - uint16_t receivedClass; - DNSName receivedName(reinterpret_cast(data->d_buffer.data()), data->d_buffer.size(), sizeof(dnsheader), false, &receivedType, &receivedClass); + uint16_t receivedType{0}; + uint16_t receivedClass{0}; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + DNSName receivedName(reinterpret_cast(data->d_buffer.data()), static_cast(data->d_buffer.size()), sizeof(dnsheader), false, &receivedType, &receivedClass); if (receivedName != data->d_checkName || receivedType != data->d_checkType || receivedClass != data->d_checkClass) { ++data->d_ds->d_healthCheckMetrics.d_mismatchErrors; if (g_verboseHealthChecks) { - infolog("Backend %s responded to health check with an invalid qname (%s vs %s), qtype (%s vs %s) or qclass (%d vs %d)", ds->getNameWithAddr(), receivedName.toLogString(), data->d_checkName.toLogString(), QType(receivedType).toString(), QType(data->d_checkType).toString(), receivedClass, data->d_checkClass); + infolog("Backend %s responded to health check with an invalid qname (%s vs %s), qtype (%s vs %s) or qclass (%d vs %d)", downstream->getNameWithAddr(), receivedName.toLogString(), data->d_checkName.toLogString(), QType(receivedType).toString(), QType(data->d_checkType).toString(), receivedClass, data->d_checkClass); } return false; } @@ -115,13 +116,13 @@ static bool handleResponse(std::shared_ptr& data) catch (const std::exception& e) { ++data->d_ds->d_healthCheckMetrics.d_parseErrors; if (g_verboseHealthChecks) { - infolog("Error checking the health of backend %s: %s", ds->getNameWithAddr(), e.what()); + infolog("Error checking the health of backend %s: %s", downstream->getNameWithAddr(), e.what()); } return false; } catch (...) { if (g_verboseHealthChecks) { - infolog("Unknown exception while checking the health of backend %s", ds->getNameWithAddr()); + infolog("Unknown exception while checking the health of backend %s", downstream->getNameWithAddr()); } return false; } @@ -135,12 +136,13 @@ class HealthCheckQuerySender : public TCPQuerySender HealthCheckQuerySender(std::shared_ptr& data): d_data(data) { } + HealthCheckQuerySender(const HealthCheckQuerySender&) = default; + HealthCheckQuerySender(HealthCheckQuerySender&&) = default; + HealthCheckQuerySender& operator=(const HealthCheckQuerySender&) = default; + HealthCheckQuerySender& operator=(HealthCheckQuerySender&&) = default; + ~HealthCheckQuerySender() override = default; - ~HealthCheckQuerySender() - { - } - - bool active() const override + [[nodiscard]] bool active() const override { return true; } @@ -166,7 +168,7 @@ class HealthCheckQuerySender : public TCPQuerySender std::shared_ptr d_data; }; -static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) +static void healthCheckUDPCallback(int descriptor, FDMultiplexer::funcparam_t& param) { auto data = boost::any_cast>(param); @@ -177,6 +179,7 @@ static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) auto fromlen = from.getSocklen(); data->d_buffer.resize(512); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) got = recvfrom(data->d_udpSocket.getHandle(), &data->d_buffer.at(0), data->d_buffer.size(), 0, reinterpret_cast(&from), &fromlen); if (got < 0) { int savederrno = errno; @@ -194,7 +197,7 @@ static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) } ++data->d_ds->d_healthCheckMetrics.d_networkErrors; data->d_ds->submitHealthCheckResult(data->d_initial, false); - data->d_mplexer.removeReadFD(fd); + data->d_mplexer.removeReadFD(descriptor); return; } } @@ -212,11 +215,11 @@ static void healthCheckUDPCallback(int fd, FDMultiplexer::funcparam_t& param) return; } - data->d_mplexer.removeReadFD(fd); + data->d_mplexer.removeReadFD(descriptor); data->d_ds->submitHealthCheckResult(data->d_initial, handleResponse(data)); } -static void healthCheckTCPCallback(int fd, FDMultiplexer::funcparam_t& param) +static void healthCheckTCPCallback(int descriptor, FDMultiplexer::funcparam_t& param) { auto data = boost::any_cast>(param); @@ -237,7 +240,7 @@ static void healthCheckTCPCallback(int fd, FDMultiplexer::funcparam_t& param) ioState = data->d_tcpHandler->tryRead(data->d_buffer, data->d_bufferPos, data->d_buffer.size()); if (ioState == IOState::Done) { data->d_bufferPos = 0; - uint16_t responseSize; + uint16_t responseSize{0}; memcpy(&responseSize, &data->d_buffer.at(0), sizeof(responseSize)); data->d_buffer.resize(ntohs(responseSize)); data->d_tcpState = HealthCheckData::TCPState::ReadingResponse; @@ -288,27 +291,27 @@ static void healthCheckTCPCallback(int fd, FDMultiplexer::funcparam_t& param) } } -bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared_ptr& ds, bool initialCheck) +bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared_ptr& downstream, bool initialCheck) { try { uint16_t queryID = dnsdist::getRandomDNSID(); - DNSName checkName = ds->d_config.checkName; - uint16_t checkType = ds->d_config.checkType.getCode(); - uint16_t checkClass = ds->d_config.checkClass; - dnsheader checkHeader; + DNSName checkName = downstream->d_config.checkName; + uint16_t checkType = downstream->d_config.checkType.getCode(); + uint16_t checkClass = downstream->d_config.checkClass; + dnsheader checkHeader{}; memset(&checkHeader, 0, sizeof(checkHeader)); checkHeader.qdcount = htons(1); checkHeader.id = queryID; checkHeader.rd = true; - if (ds->d_config.setCD) { + if (downstream->d_config.setCD) { checkHeader.cd = true; } - if (ds->d_config.checkFunction) { + if (downstream->d_config.checkFunction) { auto lock = g_lua.lock(); - auto ret = ds->d_config.checkFunction(checkName, checkType, checkClass, &checkHeader); + auto ret = downstream->d_config.checkFunction(checkName, checkType, checkClass, &checkHeader); checkName = std::get<0>(ret); checkType = std::get<1>(ret); checkClass = std::get<2>(ret); @@ -323,88 +326,88 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared uint16_t packetSize = packet.size(); std::string proxyProtocolPayload; size_t proxyProtocolPayloadSize = 0; - if (ds->d_config.useProxyProtocol) { + if (downstream->d_config.useProxyProtocol) { proxyProtocolPayload = makeLocalProxyHeader(); proxyProtocolPayloadSize = proxyProtocolPayload.size(); - if (!ds->isDoH()) { + if (!downstream->isDoH()) { packet.insert(packet.begin(), proxyProtocolPayload.begin(), proxyProtocolPayload.end()); } } - Socket sock(ds->d_config.remote.sin4.sin_family, ds->doHealthcheckOverTCP() ? SOCK_STREAM : SOCK_DGRAM); + Socket sock(downstream->d_config.remote.sin4.sin_family, downstream->doHealthcheckOverTCP() ? SOCK_STREAM : SOCK_DGRAM); sock.setNonBlocking(); #ifdef SO_BINDTODEVICE - if (!ds->d_config.sourceItfName.empty()) { - int res = setsockopt(sock.getHandle(), SOL_SOCKET, SO_BINDTODEVICE, ds->d_config.sourceItfName.c_str(), ds->d_config.sourceItfName.length()); + if (!downstream->d_config.sourceItfName.empty()) { + int res = setsockopt(sock.getHandle(), SOL_SOCKET, SO_BINDTODEVICE, downstream->d_config.sourceItfName.c_str(), downstream->d_config.sourceItfName.length()); if (res != 0 && g_verboseHealthChecks) { - infolog("Error setting SO_BINDTODEVICE on the health check socket for backend '%s': %s", ds->getNameWithAddr(), stringerror()); + infolog("Error setting SO_BINDTODEVICE on the health check socket for backend '%s': %s", downstream->getNameWithAddr(), stringerror()); } } #endif - if (!IsAnyAddress(ds->d_config.sourceAddr)) { - if (ds->doHealthcheckOverTCP()) { + if (!IsAnyAddress(downstream->d_config.sourceAddr)) { + if (downstream->doHealthcheckOverTCP()) { sock.setReuseAddr(); } #ifdef IP_BIND_ADDRESS_NO_PORT - if (ds->d_config.ipBindAddrNoPort) { + if (downstream->d_config.ipBindAddrNoPort) { SSetsockopt(sock.getHandle(), SOL_IP, IP_BIND_ADDRESS_NO_PORT, 1); } #endif - sock.bind(ds->d_config.sourceAddr, false); + sock.bind(downstream->d_config.sourceAddr, false); } - auto data = std::make_shared(*mplexer, ds, std::move(checkName), checkType, checkClass, queryID); + auto data = std::make_shared(*mplexer, downstream, std::move(checkName), checkType, checkClass, queryID); data->d_initial = initialCheck; gettimeofday(&data->d_ttd, nullptr); - data->d_ttd.tv_sec += ds->d_config.checkTimeout / 1000; /* ms to seconds */ - data->d_ttd.tv_usec += (ds->d_config.checkTimeout % 1000) * 1000; /* remaining ms to us */ + data->d_ttd.tv_sec += static_castd_ttd.tv_sec)>(downstream->d_config.checkTimeout / 1000); /* ms to seconds */ + data->d_ttd.tv_usec += static_castd_ttd.tv_usec)>((downstream->d_config.checkTimeout % 1000) * 1000); /* remaining ms to us */ normalizeTV(data->d_ttd); - if (!ds->doHealthcheckOverTCP()) { - sock.connect(ds->d_config.remote); + if (!downstream->doHealthcheckOverTCP()) { + sock.connect(downstream->d_config.remote); data->d_udpSocket = std::move(sock); - ssize_t sent = udpClientSendRequestToBackend(ds, data->d_udpSocket.getHandle(), packet, true); + ssize_t sent = udpClientSendRequestToBackend(downstream, data->d_udpSocket.getHandle(), packet, true); if (sent < 0) { int ret = errno; if (g_verboseHealthChecks) { - infolog("Error while sending a health check query (ID %d) to backend %s: %d", queryID, ds->getNameWithAddr(), ret); + infolog("Error while sending a health check query (ID %d) to backend %s: %d", queryID, downstream->getNameWithAddr(), ret); } return false; } mplexer->addReadFD(data->d_udpSocket.getHandle(), &healthCheckUDPCallback, data, &data->d_ttd); } - else if (ds->isDoH()) { + else if (downstream->isDoH()) { InternalQuery query(std::move(packet), InternalQueryState()); query.d_proxyProtocolPayload = std::move(proxyProtocolPayload); auto sender = std::shared_ptr(new HealthCheckQuerySender(data)); - if (!sendH2Query(ds, mplexer, sender, std::move(query), true)) { + if (!sendH2Query(downstream, mplexer, sender, std::move(query), true)) { data->d_ds->submitHealthCheckResult(data->d_initial, false); } } else { - data->d_tcpHandler = std::make_unique(ds->d_config.d_tlsSubjectName, ds->d_config.d_tlsSubjectIsAddr, sock.releaseHandle(), timeval{ds->d_config.checkTimeout,0}, ds->d_tlsCtx); + data->d_tcpHandler = std::make_unique(downstream->d_config.d_tlsSubjectName, downstream->d_config.d_tlsSubjectIsAddr, sock.releaseHandle(), timeval{downstream->d_config.checkTimeout,0}, downstream->d_tlsCtx); data->d_ioState = std::make_unique(*mplexer, data->d_tcpHandler->getDescriptor()); - if (ds->d_tlsCtx) { + if (downstream->d_tlsCtx) { try { time_t now = time(nullptr); - auto tlsSession = g_sessionCache.getSession(ds->getID(), now); + auto tlsSession = g_sessionCache.getSession(downstream->getID(), now); if (tlsSession) { data->d_tcpHandler->setTLSSession(tlsSession); } } catch (const std::exception& e) { - vinfolog("Unable to restore a TLS session for the DoT healthcheck for backend %s: %s", ds->getNameWithAddr(), e.what()); + vinfolog("Unable to restore a TLS session for the DoT healthcheck for backend %s: %s", downstream->getNameWithAddr(), e.what()); } } - data->d_tcpHandler->tryConnect(ds->d_config.tcpFastOpen, ds->d_config.remote); + data->d_tcpHandler->tryConnect(downstream->d_config.tcpFastOpen, downstream->d_config.remote); - const uint8_t sizeBytes[] = { static_cast(packetSize / 256), static_cast(packetSize % 256) }; - packet.insert(packet.begin() + proxyProtocolPayloadSize, sizeBytes, sizeBytes + 2); + const std::array sizeBytes = { static_cast(packetSize / 256), static_cast(packetSize % 256) }; + packet.insert(packet.begin() + static_cast(proxyProtocolPayloadSize), sizeBytes.begin(), sizeBytes.end()); data->d_buffer = std::move(packet); auto ioState = data->d_tcpHandler->tryWrite(data->d_buffer, data->d_bufferPos, data->d_buffer.size()); @@ -422,13 +425,13 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared } catch (const std::exception& e) { if (g_verboseHealthChecks) { - infolog("Error checking the health of backend %s: %s", ds->getNameWithAddr(), e.what()); + infolog("Error checking the health of backend %s: %s", downstream->getNameWithAddr(), e.what()); } return false; } catch (...) { if (g_verboseHealthChecks) { - infolog("Unknown exception while checking the health of backend %s", ds->getNameWithAddr()); + infolog("Unknown exception while checking the health of backend %s", downstream->getNameWithAddr()); } return false; } @@ -437,7 +440,7 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial) { while (mplexer.getWatchedFDCount(false) > 0 || mplexer.getWatchedFDCount(true) > 0) { - struct timeval now; + struct timeval now{}; int ret = mplexer.run(&now, 100); if (ret == -1) { if (g_verboseHealthChecks) { diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.hh b/pdns/dnsdistdist/dnsdist-healthchecks.hh index 825961e130ab..91c4c1a2a526 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.hh +++ b/pdns/dnsdistdist/dnsdist-healthchecks.hh @@ -27,6 +27,6 @@ extern bool g_verboseHealthChecks; -bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared_ptr& ds, bool initial=false); +bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared_ptr& downstream, bool initial=false); void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial=false); From 601e7126c468860bd70e01196797239b2175d5f0 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 11 Jul 2023 10:38:57 +0200 Subject: [PATCH 423/909] dnsdist: Reformat dnsdist-healthchecks.cc and dnsdist-healthchecks.hh --- pdns/dnsdistdist/dnsdist-healthchecks.cc | 31 ++++++++++++++++-------- pdns/dnsdistdist/dnsdist-healthchecks.hh | 5 ++-- 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index 1ec3cb06d929..d8d73b4e2ad8 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -33,9 +33,15 @@ bool g_verboseHealthChecks{false}; struct HealthCheckData { - enum class TCPState : uint8_t { WritingQuery, ReadingResponseSize, ReadingResponse }; + enum class TCPState : uint8_t + { + WritingQuery, + ReadingResponseSize, + ReadingResponse + }; - HealthCheckData(FDMultiplexer& mplexer, std::shared_ptr downstream, DNSName&& checkName, uint16_t checkType, uint16_t checkClass, uint16_t queryID): d_ds(std::move(downstream)), d_mplexer(mplexer), d_udpSocket(-1), d_checkName(std::move(checkName)), d_checkType(checkType), d_checkClass(checkClass), d_queryID(queryID) + HealthCheckData(FDMultiplexer& mplexer, std::shared_ptr downstream, DNSName&& checkName, uint16_t checkType, uint16_t checkClass, uint16_t queryID) : + d_ds(std::move(downstream)), d_mplexer(mplexer), d_udpSocket(-1), d_checkName(std::move(checkName)), d_checkType(checkType), d_checkClass(checkClass), d_queryID(queryID) { } @@ -46,7 +52,10 @@ struct HealthCheckData PacketBuffer d_buffer; Socket d_udpSocket; DNSName d_checkName; - struct timeval d_ttd{0, 0}; + struct timeval d_ttd + { + 0, 0 + }; size_t d_bufferPos{0}; uint16_t d_checkType; uint16_t d_checkClass; @@ -133,7 +142,8 @@ static bool handleResponse(std::shared_ptr& data) class HealthCheckQuerySender : public TCPQuerySender { public: - HealthCheckQuerySender(std::shared_ptr& data): d_data(data) + HealthCheckQuerySender(std::shared_ptr& data) : + d_data(data) { } HealthCheckQuerySender(const HealthCheckQuerySender&) = default; @@ -180,7 +190,7 @@ static void healthCheckUDPCallback(int descriptor, FDMultiplexer::funcparam_t& p data->d_buffer.resize(512); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - got = recvfrom(data->d_udpSocket.getHandle(), &data->d_buffer.at(0), data->d_buffer.size(), 0, reinterpret_cast(&from), &fromlen); + got = recvfrom(data->d_udpSocket.getHandle(), &data->d_buffer.at(0), data->d_buffer.size(), 0, reinterpret_cast(&from), &fromlen); if (got < 0) { int savederrno = errno; if (savederrno == EINTR) { @@ -200,8 +210,7 @@ static void healthCheckUDPCallback(int descriptor, FDMultiplexer::funcparam_t& p data->d_mplexer.removeReadFD(descriptor); return; } - } - while (got < 0); + } while (got < 0); data->d_buffer.resize(static_cast(got)); @@ -390,7 +399,7 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared } } else { - data->d_tcpHandler = std::make_unique(downstream->d_config.d_tlsSubjectName, downstream->d_config.d_tlsSubjectIsAddr, sock.releaseHandle(), timeval{downstream->d_config.checkTimeout,0}, downstream->d_tlsCtx); + data->d_tcpHandler = std::make_unique(downstream->d_config.d_tlsSubjectName, downstream->d_config.d_tlsSubjectIsAddr, sock.releaseHandle(), timeval{downstream->d_config.checkTimeout, 0}, downstream->d_tlsCtx); data->d_ioState = std::make_unique(*mplexer, data->d_tcpHandler->getDescriptor()); if (downstream->d_tlsCtx) { try { @@ -406,7 +415,7 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared } data->d_tcpHandler->tryConnect(downstream->d_config.tcpFastOpen, downstream->d_config.remote); - const std::array sizeBytes = { static_cast(packetSize / 256), static_cast(packetSize % 256) }; + const std::array sizeBytes = {static_cast(packetSize / 256), static_cast(packetSize % 256)}; packet.insert(packet.begin() + static_cast(proxyProtocolPayloadSize), sizeBytes.begin(), sizeBytes.end()); data->d_buffer = std::move(packet); @@ -440,7 +449,9 @@ bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial) { while (mplexer.getWatchedFDCount(false) > 0 || mplexer.getWatchedFDCount(true) > 0) { - struct timeval now{}; + struct timeval now + { + }; int ret = mplexer.run(&now, 100); if (ret == -1) { if (g_verboseHealthChecks) { diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.hh b/pdns/dnsdistdist/dnsdist-healthchecks.hh index 91c4c1a2a526..e9da6c66de8b 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.hh +++ b/pdns/dnsdistdist/dnsdist-healthchecks.hh @@ -27,6 +27,5 @@ extern bool g_verboseHealthChecks; -bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared_ptr& downstream, bool initial=false); -void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial=false); - +bool queueHealthCheck(std::unique_ptr& mplexer, const std::shared_ptr& downstream, bool initial = false); +void handleQueuedHealthChecks(FDMultiplexer& mplexer, bool initial = false); From b8359cb0abd6e4346ed3b30590532b0c5577dc17 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 11 Jul 2023 10:40:53 +0200 Subject: [PATCH 424/909] Remove dnsdist-healthchecks.* from the 'not formatted' list --- .not-formatted | 2 -- 1 file changed, 2 deletions(-) diff --git a/.not-formatted b/.not-formatted index f09ac66bca40..e48e5f4affe6 100644 --- a/.not-formatted +++ b/.not-formatted @@ -74,8 +74,6 @@ ./pdns/dnsdistdist/connection-management.hh ./pdns/dnsdistdist/dnsdist-backend.cc ./pdns/dnsdistdist/dnsdist-dynblocks.cc -./pdns/dnsdistdist/dnsdist-healthchecks.cc -./pdns/dnsdistdist/dnsdist-healthchecks.hh ./pdns/dnsdistdist/dnsdist-kvs.cc ./pdns/dnsdistdist/dnsdist-kvs.hh ./pdns/dnsdistdist/dnsdist-lbpolicies.cc From 39ad39d58cd8638385286a39996a29e8037dbdd3 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 17 Jul 2023 10:41:13 +0200 Subject: [PATCH 425/909] dnsdist: Set the group of our configuration file to dnsdist on RH and co The file was already readable by the group, but our RPM specs did not set the group to 'dnsdist'. --- builder-support/specs/dnsdist.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/builder-support/specs/dnsdist.spec b/builder-support/specs/dnsdist.spec index a60c6118153a..8089a0d6d0ea 100644 --- a/builder-support/specs/dnsdist.spec +++ b/builder-support/specs/dnsdist.spec @@ -113,6 +113,7 @@ make %{?_smp_mflags} check || (cat test-suite.log && false) %make_install install -d %{buildroot}/%{_sysconfdir}/dnsdist %{__mv} %{buildroot}%{_sysconfdir}/dnsdist/dnsdist.conf-dist %{buildroot}%{_sysconfdir}/dnsdist/dnsdist.conf +chgrp dnsdist %{buildroot}/%{_sysconfdir}/dnsdist/dnsdist.conf chmod 0640 %{buildroot}/%{_sysconfdir}/dnsdist/dnsdist.conf sed -i "s,/^\(ExecStart.*\)dnsdist\(.*\)\$,\1dnsdist -u dnsdist -g dnsdist\2," %{buildroot}/%{_unitdir}/dnsdist.service sed -i "s,/^\(ExecStart.*\)dnsdist\(.*\)\$,\1dnsdist -u dnsdist -g dnsdist\2," %{buildroot}/%{_unitdir}/dnsdist@.service From 7d0fefb4a58460bd2fc503df5b6c3fb4e94cb192 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 17 Jul 2023 12:16:47 +0200 Subject: [PATCH 426/909] auth: Apply Coverity's suggestions to move objects whenever possible --- ext/lmdb-safe/lmdb-typed.hh | 2 +- modules/geoipbackend/geoipbackend.cc | 4 ++-- modules/lmdbbackend/lmdbbackend.cc | 2 +- pdns/dnswasher.cc | 4 ++-- pdns/dynlistener.cc | 2 +- pdns/pdnsutil.cc | 5 +++-- pdns/webserver.cc | 2 +- pdns/ws-api.cc | 4 ++-- pdns/zoneparser-tng.hh | 2 +- 9 files changed, 14 insertions(+), 13 deletions(-) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index 45da5e00b5e3..3fcdcc74127b 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -242,7 +242,7 @@ class TypedDBI { public: TypedDBI(std::shared_ptr env, string_view name) - : d_env(env), d_name(name) + : d_env(std::move(env)), d_name(name) { d_main = d_env->openDB(name, MDB_CREATE); diff --git a/modules/geoipbackend/geoipbackend.cc b/modules/geoipbackend/geoipbackend.cc index 7c57b85b0d86..4ca8ed0a4766 100644 --- a/modules/geoipbackend/geoipbackend.cc +++ b/modules/geoipbackend/geoipbackend.cc @@ -194,7 +194,7 @@ void GeoIPBackend::initialize() string attr = iter->first.as(); if (attr == "content") { string content = iter->second.as(); - rr.content = content; + rr.content = std::move(content); } else if (attr == "weight") { rr.weight = iter->second.as(); @@ -215,7 +215,7 @@ void GeoIPBackend::initialize() } else { string content = rec->second.as(); - rr.content = content; + rr.content = std::move(content); rr.weight = 100; } rr.auth = 1; diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index a1b9594eecb2..d455cb7ca7f2 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -2440,7 +2440,7 @@ bool LMDBBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName lrr.ordername = hasOrderName; changed = true; } - newRRs.push_back(lrr); + newRRs.push_back(std::move(lrr)); } if (changed) { cursor.put(key, serToString(newRRs)); diff --git a/pdns/dnswasher.cc b/pdns/dnswasher.cc index 0d5dd1c86c13..f370ce36aee4 100644 --- a/pdns/dnswasher.cc +++ b/pdns/dnswasher.cc @@ -224,12 +224,12 @@ try cerr<<"Invalidly encoded base64 key provided"<()); - ipo = IPCipherObfuscator::make(key, doDecrypt); + ipo = IPCipherObfuscator::make(std::move(key), doDecrypt); } else { cerr<<"Can't specify both 'key' and 'passphrase'"<setJsonBody(doc); } @@ -130,7 +130,7 @@ void apiDiscoveryV1(HttpRequest* req, HttpResponse* resp) { { "server_url", "/api/v1/servers{/server}" }, { "api_features", Json::array {} } }; - Json doc = Json::array { version1 }; + Json doc = Json::array { std::move(version1) }; resp->setJsonBody(doc); diff --git a/pdns/zoneparser-tng.hh b/pdns/zoneparser-tng.hh index 1b7562766a27..b50e86ec6658 100644 --- a/pdns/zoneparser-tng.hh +++ b/pdns/zoneparser-tng.hh @@ -60,7 +60,7 @@ private: unsigned makeTTLFromZone(const std::string& str); struct filestate { - filestate(FILE* fp, string filename) : d_fp(fp), d_filename(filename), d_lineno(0){} + filestate(FILE* fp, string filename) : d_fp(fp), d_filename(std::move(filename)), d_lineno(0){} FILE *d_fp; string d_filename; int d_lineno; From ed5dfdee0ef7201a789e1f177e9c959d3e5ad7aa Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 17 Jul 2023 12:17:38 +0200 Subject: [PATCH 427/909] auth: Apply Coverity's suggestions to initialize field members --- modules/bindbackend/bindbackend2.hh | 14 +++++++------- modules/lua2backend/lua2api2.hh | 4 ++-- modules/remotebackend/remotebackend.hh | 2 +- pdns/dnsbackend.hh | 8 ++++---- pdns/dnsreplay.cc | 2 +- pdns/dnssecinfra.hh | 4 ++-- pdns/pkcs11signers.cc | 4 ++-- 7 files changed, 19 insertions(+), 19 deletions(-) diff --git a/modules/bindbackend/bindbackend2.hh b/modules/bindbackend/bindbackend2.hh index 5d35544fcde0..7bd14f7d0bf6 100644 --- a/modules/bindbackend/bindbackend2.hh +++ b/modules/bindbackend/bindbackend2.hh @@ -150,7 +150,7 @@ public: } DNSName d_name; //!< actual name of the domain - DomainInfo::DomainKind d_kind; //!< the kind of domain + DomainInfo::DomainKind d_kind{DomainInfo::Native}; //!< the kind of domain string d_filename; //!< full absolute filename of the zone on disk string d_status; //!< message describing status of a domain, for human consumption vector d_masters; //!< IP address of the master of this domain @@ -159,16 +159,16 @@ public: time_t d_ctime{0}; //!< last known ctime of the file on disk time_t d_lastcheck{0}; //!< last time domain was checked for freshness uint32_t d_lastnotified{0}; //!< Last serial number we notified our slaves of - unsigned int d_id; //!< internal id of the domain + unsigned int d_id{0}; //!< internal id of the domain mutable bool d_checknow; //!< if this domain has been flagged for a check - bool d_loaded; //!< if a domain is loaded + bool d_loaded{false}; //!< if a domain is loaded bool d_wasRejectedLastReload{false}; //!< if the domain was rejected during Bind2Backend::queueReloadAndStore bool d_nsec3zone{false}; NSEC3PARAMRecordContent d_nsec3param; private: time_t getCtime(); - time_t d_checkinterval; + time_t d_checkinterval{0}; }; class SSQLite3; @@ -268,10 +268,10 @@ private: DNSName qname; DNSName domain; - int id; + int id{-1}; QType qtype; - bool d_list; - bool mustlog; + bool d_list{false}; + bool mustlog{false}; private: bool get_normal(DNSResourceRecord&); diff --git a/modules/lua2backend/lua2api2.hh b/modules/lua2backend/lua2api2.hh index 1f11a9afd52d..649a808f1149 100644 --- a/modules/lua2backend/lua2api2.hh +++ b/modules/lua2backend/lua2api2.hh @@ -426,8 +426,8 @@ public: private: std::list d_result; - bool d_debug_log; - bool d_dnssec; + bool d_debug_log{false}; + bool d_dnssec{false}; lookup_call_t f_lookup; list_call_t f_list; diff --git a/modules/remotebackend/remotebackend.hh b/modules/remotebackend/remotebackend.hh index 97c683895321..078594e7f329 100644 --- a/modules/remotebackend/remotebackend.hh +++ b/modules/remotebackend/remotebackend.hh @@ -129,7 +129,7 @@ private: void connect(); std::string d_endpoint; int d_timeout; - int d_timespent; + int d_timespent{0}; std::map d_options; std::unique_ptr d_ctx; std::unique_ptr d_sock; diff --git a/pdns/dnsbackend.hh b/pdns/dnsbackend.hh index 5859c77dceb1..12e989ad99c0 100644 --- a/pdns/dnsbackend.hh +++ b/pdns/dnsbackend.hh @@ -212,10 +212,10 @@ public: struct KeyData { std::string content; - unsigned int id; - unsigned int flags; - bool active; - bool published; + unsigned int id{0}; + unsigned int flags{0}; + bool active{false}; + bool published{false}; }; virtual bool getDomainKeys(const DNSName& /* name */, std::vector& /* keys */) { return false; } diff --git a/pdns/dnsreplay.cc b/pdns/dnsreplay.cc index b270f45a43a8..1ba97da20440 100644 --- a/pdns/dnsreplay.cc +++ b/pdns/dnsreplay.cc @@ -175,7 +175,7 @@ struct QuestionData int d_assignedID; MOADNSParser::answers_t d_origAnswers, d_newAnswers; int d_origRcode, d_newRcode; - struct timeval d_resentTime; + struct timeval d_resentTime{}; bool d_norecursionavailable; bool d_origlate, d_newlate; }; diff --git a/pdns/dnssecinfra.hh b/pdns/dnssecinfra.hh index 2ba501764050..0ddb54eae6dc 100644 --- a/pdns/dnssecinfra.hh +++ b/pdns/dnssecinfra.hh @@ -248,8 +248,8 @@ private: DNSKEYRecordContent d_dnskey; std::shared_ptr d_key; - uint16_t d_flags; - uint8_t d_algorithm; + uint16_t d_flags{0}; + uint8_t d_algorithm{0}; }; diff --git a/pdns/pkcs11signers.cc b/pdns/pkcs11signers.cc index 9269c9e5f8af..5b944f2a1dff 100644 --- a/pdns/pkcs11signers.cc +++ b/pdns/pkcs11signers.cc @@ -79,8 +79,8 @@ using CkaValueType = enum { Attribute_Byte, Attribute_Long, Attribute_String }; class P11KitAttribute { private: CK_ATTRIBUTE_TYPE type; - CK_BYTE ckByte; - CK_ULONG ckLong; + CK_BYTE ckByte{0}; + CK_ULONG ckLong{0}; std::string ckString; CkaValueType ckType; std::unique_ptr buffer; From 43688b663716fba8840c60827aab4fedb3490f1f Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Mon, 17 Jul 2023 13:52:19 +0200 Subject: [PATCH 428/909] auth: DNSProxy: remove declaration without implementation --- pdns/dnsproxy.hh | 1 - 1 file changed, 1 deletion(-) diff --git a/pdns/dnsproxy.hh b/pdns/dnsproxy.hh index 1697c2cb5a13..1a2ff00b9afb 100644 --- a/pdns/dnsproxy.hh +++ b/pdns/dnsproxy.hh @@ -55,7 +55,6 @@ public: bool completePacket(std::unique_ptr& r, const DNSName& target,const DNSName& aname, const uint8_t scopeMask); void mainloop(); //!< this is the main loop that receives reply packets and sends them out again - bool recurseFor(DNSPacket* p); private: struct ConntrackEntry { From e3317fbc0c1462a4f679f4e7c8315eef095ffa33 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 17 Jul 2023 12:18:10 +0200 Subject: [PATCH 429/909] auth: Apply Coverity's suggestion to prevent copies in loops w/ auto --- modules/lmdbbackend/lmdbbackend.cc | 4 ++-- pdns/pdnsutil.cc | 2 +- pdns/ws-auth.cc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index d455cb7ca7f2..d47904815d52 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1173,7 +1173,7 @@ bool LMDBBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const Q if (!rrset.empty()) { vector adjustedRRSet; - for (auto rr : rrset) { + for (const auto& rr : rrset) { LMDBResourceRecord lrr(rr); lrr.content = serializeContent(lrr.qtype.getCode(), lrr.qname, lrr.content); lrr.qname.makeUsRelative(di.zone); @@ -2429,7 +2429,7 @@ bool LMDBBackend::updateDNSSECOrderNameAndAuth(uint32_t domain_id, const DNSName serFromString(val.get(), lrrs); bool changed = false; vector newRRs; - for (auto lrr : lrrs) { + for (auto& lrr : lrrs) { lrr.qtype = co.getQType(key.getNoStripHeader()); if (!needNSEC3 && qtype != QType::ANY) { needNSEC3 = (lrr.ordername && QType(qtype) != lrr.qtype); diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index ac46da046f82..54d02d35bb5b 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -872,7 +872,7 @@ static int checkAllZones(DNSSECKeeper &dk, bool exitOnError) B.getAllDomains(&domainInfo, true, true); int errors=0; - for(auto di : domainInfo) { + for (auto& di : domainInfo) { if (checkZone(dk, B, di.zone) > 0) { errors++; } diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index fe7fb50b0c33..070d8c602e6c 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1824,7 +1824,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { // will be overridden by updateDomainSettingsFromDocument, if given in document. di.backend->setDomainMetadataOne(zonename, "SOA-EDIT-API", "DEFAULT"); - for(auto rr : new_records) { + for(auto& rr : new_records) { rr.domain_id = di.id; di.backend->feedRecord(rr, DNSName()); } From 0d757bd2ccf0150e69ae630fdc1f78e998114205 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 17 Jul 2023 12:19:11 +0200 Subject: [PATCH 430/909] auth: Fix 'exceptions not caught' warnings from Coverity --- pdns/auth-main.cc | 28 +++++++++++++++++++++------- pdns/dnssecinfra.cc | 3 ++- 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index 38d81c56aaed..c28931fe3f2b 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -1470,11 +1470,15 @@ int main(int argc, char** argv) g_log << Logger::Error << "Fatal error: " << A.reason << endl; exit(1); } + catch (const std::exception& e) { + g_log << Logger::Error << "Fatal error: " << e.what() << endl; + exit(1); + } try { declareStats(); } - catch (PDNSException& PE) { + catch (const PDNSException& PE) { g_log << Logger::Error << "Exiting because: " << PE.reason << endl; exit(1); } @@ -1487,14 +1491,24 @@ int main(int argc, char** argv) try { mainthread(); } - catch (PDNSException& e) { - if (!::arg().mustDo("daemon")) - cerr << "Exiting because: " << e.reason << endl; + catch (const PDNSException& e) { + try { + if (!::arg().mustDo("daemon")) { + cerr << "Exiting because: " << e.reason << endl; + } + } + catch (const ArgException& A) { + } g_log << Logger::Error << "Exiting because: " << e.reason << endl; } - catch (std::exception& e) { - if (!::arg().mustDo("daemon")) - cerr << "Exiting because of STL error: " << e.what() << endl; + catch (const std::exception& e) { + try { + if (!::arg().mustDo("daemon")) { + cerr << "Exiting because of STL error: " << e.what() << endl; + } + } + catch (const ArgException& A) { + } g_log << Logger::Error << "Exiting because of STL error: " << e.what() << endl; } catch (...) { diff --git a/pdns/dnssecinfra.cc b/pdns/dnssecinfra.cc index 3e9056d71136..9024b0450263 100644 --- a/pdns/dnssecinfra.cc +++ b/pdns/dnssecinfra.cc @@ -526,8 +526,9 @@ string getMessageForRRSET(const DNSName& qname, const RRSIGRecordContent& rrc, c if (rrsig_labels < fqdn_labels) { DNSName choppedQname(qname); - while (choppedQname.countLabels() > rrsig_labels) + while (choppedQname.countLabels() > rrsig_labels) { choppedQname.chopOff(); + } nameToHash = "\x01*" + choppedQname.toDNSStringLC(); } else if (rrsig_labels > fqdn_labels) { // The RRSIG Labels field is a lie (or the qname is wrong) and the RRSIG From c83fe2ce2cee03aced85b5d7de6dc5b6e19ea695 Mon Sep 17 00:00:00 2001 From: Jan-Piet Mens Date: Mon, 17 Jul 2023 15:28:18 +0200 Subject: [PATCH 431/909] Typo in dnsupdate.rst --- docs/dnsupdate.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/dnsupdate.rst b/docs/dnsupdate.rst index e8efc0c87d67..f6787d7f20db 100644 --- a/docs/dnsupdate.rst +++ b/docs/dnsupdate.rst @@ -204,7 +204,7 @@ logic to change the SOA is not executed. .. note:: Powerdns will always use :ref:`metadata-soa-edit` when serving SOA - records, thus a query for the SOA record of the recently update domain, + records, thus a query for the SOA record of the recently updated domain, might have an unexpected result due to a SOA-EDIT setting. An example:: From 71996c157fab7066d58008d8d1df5ae1b1149d54 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 17 Jul 2023 16:27:04 +0200 Subject: [PATCH 432/909] rec: set TTL in getFakePTRRecords Alternative solution to #13011 --- pdns/recursordist/pdns_recursor.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 927cf06dd8e5..e0f78da2e3c6 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -768,14 +768,19 @@ int getFakePTRRecords(const DNSName& qname, vector& ret) } newquery += "in-addr.arpa."; + auto log = g_slog->withName("dns64")->withValues("method", Logging::Loggable("getPTR")); + vector answers; + int rcode = directResolve(DNSName(newquery), QType::PTR, QClass::IN, answers, t_pdl, log); + DNSRecord record; record.d_name = qname; record.d_type = QType::CNAME; record.setContent(std::make_shared(newquery)); + // Copy the TTL of the synhtesized CNAME from the actual answer + record.d_ttl = (rcode == RCode::NoError && !answers.empty()) ? answers.at(0).d_ttl : SyncRes::s_minimumTTL; ret.push_back(record); - auto log = g_slog->withName("dns64")->withValues("method", Logging::Loggable("getPTR")); - int rcode = directResolve(DNSName(newquery), QType::PTR, QClass::IN, ret, t_pdl, log); + ret.insert(ret.end(), answers.begin(), answers.end()); t_Counters.at(rec::Counter::dns64prefixanswers)++; return rcode; From 83b9a01c1791be10c47d8d9c0e950210c075d7b9 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 17 Jul 2023 17:00:04 +0200 Subject: [PATCH 433/909] Do not include year(s) in copyright messages. It's too hard to keep up-to-date and serves no real purpose. --- pdns/version.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/version.cc b/pdns/version.cc index 721439b2e4fe..3575303ca547 100644 --- a/pdns/version.cc +++ b/pdns/version.cc @@ -67,7 +67,7 @@ string productTypeApiType() { void showProductVersion() { - g_log< Date: Tue, 18 Jul 2023 10:09:32 +0200 Subject: [PATCH 434/909] Further removal op copyright years Fixes #13004 --- README.md | 2 +- docs/conf.py | 2 +- pdns/dnsdistdist/docs/conf.py | 2 +- pdns/recursordist/README.md | 2 +- pdns/recursordist/docs/conf.py | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index c54cffec4263..e427d37891ac 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -PowerDNS is copyright © 2001-2023 by PowerDNS.COM BV and lots of +PowerDNS is copyright © by PowerDNS.COM BV and lots of contributors, using the GNU GPLv2 license (see NOTICE for the exact license and exception used). diff --git a/docs/conf.py b/docs/conf.py index 73df1b2a4d34..cbb53411273b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,7 +52,7 @@ # General information about the project. project = 'PowerDNS Authoritative Server' -copyright = '2001-' + str(datetime.date.today().year) + ', PowerDNS.COM BV' +copyright = 'PowerDNS.COM BV' author = 'PowerDNS.COM BV' # The version info for the project you're documenting, acts as replacement for diff --git a/pdns/dnsdistdist/docs/conf.py b/pdns/dnsdistdist/docs/conf.py index 93f501c3d849..a6ae16bc09b0 100644 --- a/pdns/dnsdistdist/docs/conf.py +++ b/pdns/dnsdistdist/docs/conf.py @@ -49,7 +49,7 @@ # General information about the project. project = 'dnsdist' -copyright = '2015-' + str(datetime.date.today().year) + ', PowerDNS.COM BV and its contributors' +copyright = 'PowerDNS.COM BV and its contributors' author = 'PowerDNS.COM BV and its contributors' # The version info for the project you're documenting, acts as replacement for diff --git a/pdns/recursordist/README.md b/pdns/recursordist/README.md index 77ea681357d2..ebdc05cff4b7 100644 --- a/pdns/recursordist/README.md +++ b/pdns/recursordist/README.md @@ -14,7 +14,7 @@ reported. License ======= -PowerDNS is copyright © 2001-2023 by PowerDNS.COM BV and lots of +PowerDNS is copyright © by PowerDNS.COM BV and lots of contributors, using the GNU GPLv2 license (see NOTICE for the exact license and exception used). diff --git a/pdns/recursordist/docs/conf.py b/pdns/recursordist/docs/conf.py index 2c69d706f331..874ca6ef38a9 100644 --- a/pdns/recursordist/docs/conf.py +++ b/pdns/recursordist/docs/conf.py @@ -52,7 +52,7 @@ # General information about the project. project = 'PowerDNS Recursor' -copyright = '2001-' + str(datetime.date.today().year) + ', PowerDNS.COM BV' +copyright = 'PowerDNS.COM BV' author = 'PowerDNS.COM BV' # The version info for the project you're documenting, acts as replacement for From df96c2cab92bc864f05923594d7089005bf3cb4c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 18 Jul 2023 10:11:19 +0200 Subject: [PATCH 435/909] Update pdns/recursordist/pdns_recursor.cc Co-authored-by: Peter van Dijk --- pdns/recursordist/pdns_recursor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index e0f78da2e3c6..677bf39d971f 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -776,7 +776,7 @@ int getFakePTRRecords(const DNSName& qname, vector& ret) record.d_name = qname; record.d_type = QType::CNAME; record.setContent(std::make_shared(newquery)); - // Copy the TTL of the synhtesized CNAME from the actual answer + // Copy the TTL of the synthesized CNAME from the actual answer record.d_ttl = (rcode == RCode::NoError && !answers.empty()) ? answers.at(0).d_ttl : SyncRes::s_minimumTTL; ret.push_back(record); From ff0c01429111eb973a02b08798bf5da7eb556723 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 18 Jul 2023 10:18:31 +0200 Subject: [PATCH 436/909] Remove copyright years in webserver output; noted by @mind04 --- pdns/ws-auth.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index fe7fb50b0c33..25d1b2dc349a 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -287,7 +287,7 @@ void AuthWebServer::indexfunction(HttpRequest* req, HttpResponse* resp) printtable(ret,req->getvars["ring"],S.getRingTitle(req->getvars["ring"]),100); ret<<""<"<© 2013 - 2022 PowerDNS.COM BV."<"<© PowerDNS.COM BV."<"<body = ret.str(); From 7a5903e11ce3debe9904df58866765f5638c4523 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 18 Jul 2023 11:49:18 +0200 Subject: [PATCH 437/909] auth docs: pin pyyaml 6.0.1 specifically, see #13046 --- docs/requirements.in | 1 + docs/requirements.txt | 92 ++++++++++++++++++++++--------------------- 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/docs/requirements.in b/docs/requirements.in index 6356425f0ffb..20140c66a122 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -9,3 +9,4 @@ sphinxcontrib-fulltoc guzzle_sphinx_theme docutils!=0.15,<0.18 jinja2<3.1.0 +pyyaml==6.0.1 diff --git a/docs/requirements.txt b/docs/requirements.txt index 437cf275d528..7a4f05bf1819 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile with Python 3.9 +# This file is autogenerated by pip-compile with Python 3.11 # by the following command: # # pip-compile --generate-hashes requirements.in @@ -225,48 +225,50 @@ python-dateutil==2.8.2 \ --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 # via fake-factory -pyyaml==6.0 \ - --hash=sha256:01b45c0191e6d66c470b6cf1b9531a771a83c1c4208272ead47a3ae4f2f603bf \ - --hash=sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293 \ - --hash=sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b \ - --hash=sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57 \ - --hash=sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b \ - --hash=sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4 \ - --hash=sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07 \ - --hash=sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba \ - --hash=sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9 \ - --hash=sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287 \ - --hash=sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513 \ - --hash=sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0 \ - --hash=sha256:432557aa2c09802be39460360ddffd48156e30721f5e8d917f01d31694216782 \ - --hash=sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0 \ - --hash=sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92 \ - --hash=sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f \ - --hash=sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2 \ - --hash=sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc \ - --hash=sha256:81957921f441d50af23654aa6c5e5eaf9b06aba7f0a19c18a538dc7ef291c5a1 \ - --hash=sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c \ - --hash=sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86 \ - --hash=sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4 \ - --hash=sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c \ - --hash=sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34 \ - --hash=sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b \ - --hash=sha256:afa17f5bc4d1b10afd4466fd3a44dc0e245382deca5b3c353d8b757f9e3ecb8d \ - --hash=sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c \ - --hash=sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb \ - --hash=sha256:bfaef573a63ba8923503d27530362590ff4f576c626d86a9fed95822a8255fd7 \ - --hash=sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737 \ - --hash=sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3 \ - --hash=sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d \ - --hash=sha256:d4b0ba9512519522b118090257be113b9468d804b19d63c71dbcf4a48fa32358 \ - --hash=sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53 \ - --hash=sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78 \ - --hash=sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803 \ - --hash=sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a \ - --hash=sha256:dbad0e9d368bb989f4515da330b88a057617d16b6a8245084f1b05400f24609f \ - --hash=sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174 \ - --hash=sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5 - # via sphinxcontrib-openapi +pyyaml==6.0.1 \ + --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ + --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ + --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ + --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \ + --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ + --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ + --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \ + --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ + --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ + --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \ + --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \ + --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ + --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ + --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \ + --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ + --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ + --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \ + --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ + --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ + --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ + --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ + --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ + --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ + --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ + --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ + --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ + --hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \ + --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ + --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ + --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ + --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ + --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ + --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ + --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ + --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ + --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \ + --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ + --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ + --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ + --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f + # via + # -r requirements.in + # sphinxcontrib-openapi requests==2.31.0 \ --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \ --hash=sha256:942c5a758f98d790eaed1a29cb6eefc7ffb0d1cf7af05c3d2791656dbd6ad1e1 @@ -276,6 +278,7 @@ six==1.16.0 \ --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 # via # fake-factory + # python-dateutil # sphinx # sphinxcontrib-httpdomain snowballstemmer==2.2.0 \ @@ -319,5 +322,6 @@ urllib3==2.0.3 \ # via requests # WARNING: The following packages were not pinned, but pip requires them to be -# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag. +# pinned when the requirements file includes hashes and the requirement is not +# satisfied by a package already installed. Consider using the --allow-unsafe flag. # setuptools From 17b128295abd8e0000446c1970d7dd3ed995b907 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 18 Jul 2023 13:48:11 +0200 Subject: [PATCH 438/909] include errno to avoid: File "/__w/pdns/pdns/regression-tests.recursor-dnssec/test_RecDnstap.py", line 189, in FrameStreamUnixListener if e.errno in (errno.EBADF, errno.EPIPE): NameError: name 'errno' is not defined --- regression-tests.recursor-dnssec/test_RecDnstap.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/regression-tests.recursor-dnssec/test_RecDnstap.py b/regression-tests.recursor-dnssec/test_RecDnstap.py index 3f835a30dc60..5856a1bb00cc 100644 --- a/regression-tests.recursor-dnssec/test_RecDnstap.py +++ b/regression-tests.recursor-dnssec/test_RecDnstap.py @@ -1,3 +1,4 @@ +import errno import os import socket import struct @@ -216,7 +217,7 @@ def FrameStreamUnixListenerMain(cls, param): listener.setDaemon(True) listener.start() except socket.error as e: - if e.errno != 9: + if e.errno != errno.EBADF: sys.stderr.write("Socket error on accept: %s\n" % str(e)) else: break From c8c24bc135c62980463b220703184986ed3f13f3 Mon Sep 17 00:00:00 2001 From: Andreas Jakum Date: Wed, 19 Jul 2023 11:11:30 +0200 Subject: [PATCH 439/909] Add missing tools to pdns-tools package description (control). --- .../debian/authoritative/debian-buster/control | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/builder-support/debian/authoritative/debian-buster/control b/builder-support/debian/authoritative/debian-buster/control index 516014a4e9bf..3148aa707f83 100644 --- a/builder-support/debian/authoritative/debian-buster/control +++ b/builder-support/debian/authoritative/debian-buster/control @@ -65,16 +65,24 @@ Description: Tools for DNS debugging by PowerDNS This package contains several tools to debug DNS issues. These tools do not require any part of the PowerDNS server components to work. . + * calidns: Resolver benchmark tool * dnsbulktest: A resolver stress-tester * dnsgram: Show per 5-second statistics to study intermittent resolver issues + * dnspcap2calidns: PCAP conversion tool (calidns format) + * dnspcap2protobuf: PCAP conversion tool (protobuf format) * dnsreplay: Replay a pcap with DNS queries * dnsscan: Prints the query-type amounts in a pcap * dnsscope: Calculates statistics without replaying traffic * dnstcpbench: Perform TCP benchmarking of DNS servers * dnswasher: Clean a pcap of identifying IP information + * dumresp: Dummy DNS responder * ixplore: Explore diffs from IXFRs + * nproxy: DNS notification proxy * nsec3dig: Calculate the correctness of NSEC3 proofs + * pdns_notify: Simple tool for sending DNS notifies * saxfr: AXFR zones and show extra information + * sdig: dig-like tool supporting DoH, DoT, PROXY-protocol and XPF + * stubquery: Stub resolver query tool Package: pdns-ixfrdist Architecture: any From 799aa185934c388edb5cf2046637e67579ac0bce Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 20 Jul 2023 10:09:12 +0200 Subject: [PATCH 440/909] misc: `pdns::getMessageFromErrno()` does not depend on libcrypto This prevents compiling dnsdist when libcrypto is not available, which should be possible. --- pdns/misc.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/misc.hh b/pdns/misc.hh index 1a40a14d2bcf..179c27b508c5 100644 --- a/pdns/misc.hh +++ b/pdns/misc.hh @@ -49,7 +49,6 @@ class DNSName; typedef enum { TSIG_MD5, TSIG_SHA1, TSIG_SHA224, TSIG_SHA256, TSIG_SHA384, TSIG_SHA512, TSIG_GSS } TSIGHashEnum; namespace pdns { -#if defined(HAVE_LIBCRYPTO) /** * \brief Retrieves the errno-based error message in a reentrant way. * @@ -63,6 +62,7 @@ namespace pdns */ auto getMessageFromErrno(int errnum) -> std::string; +#if defined(HAVE_LIBCRYPTO) namespace OpenSSL { /** From 461f4b239c8e903d2b242ef9b3f3493451182c2d Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 12 Jul 2023 14:46:23 +0200 Subject: [PATCH 441/909] Regression test for pb tags coming out of packet cache or not --- pdns/recursordist/rec-main.cc | 4 +- .../test_Protobuf.py | 56 +++++++++++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 2d5dc826f5e3..2d46bbe94489 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -493,7 +493,7 @@ void protobufLogQuery(LocalStateHolder& luaconfsLocal, const boo msg.setRequestorId(requestorId); msg.setDeviceId(deviceId); msg.setDeviceName(deviceName); - + if (!policyTags.empty()) { msg.addPolicyTags(policyTags); } @@ -546,12 +546,14 @@ void protobufLogResponse(const struct dnsheader* header, LocalStateHolderprotobufExportConfig.logMappedFrom) { + pbMessage.setSocketFamily(source.sin4.sin_family); Netmask requestorNM(source, source.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); auto requestor = requestorNM.getMaskedNetwork(); pbMessage.setFrom(requestor); pbMessage.setFromPort(source.getPort()); } else { + pbMessage.setSocketFamily(mappedSource.sin4.sin_family); Netmask requestorNM(mappedSource, mappedSource.sin4.sin_family == AF_INET ? luaconfsLocal->protobufMaskV4 : luaconfsLocal->protobufMaskV6); auto requestor = requestorNM.getMaskedNetwork(); pbMessage.setFrom(requestor); diff --git a/regression-tests.recursor-dnssec/test_Protobuf.py b/regression-tests.recursor-dnssec/test_Protobuf.py index 5c6fd0b45160..698f5109d84d 100644 --- a/regression-tests.recursor-dnssec/test_Protobuf.py +++ b/regression-tests.recursor-dnssec/test_Protobuf.py @@ -960,6 +960,62 @@ def testTagged(self): self.checkProtobufTags(msg, tags) self.checkNoRemainingMessage() +class ProtobufTagCacheTest(TestRecursorProtobuf): + """ + This test makes sure that we correctly cache tags (actually not cache them) + """ + + _confdir = 'ProtobufTagCache' + _config_template = """ +auth-zones=example=configs/%s/example.zone""" % _confdir + _lua_config_file = """ + protobufServer({"127.0.0.1:%d", "127.0.0.1:%d"}, { logQueries=false, logResponses=true } ) + """ % (protobufServersParameters[0].port, protobufServersParameters[1].port) + _lua_dns_script_file = """ + function preresolve(dq) + if dq.qname:equal('tagged.example.') then + dq:addPolicyTag(''.. math.random()) + end + return false + end + """ + + def testTagged(self): + name = 'tagged.example.' + expected = dns.rrset.from_text(name, 0, dns.rdataclass.IN, 'A', '192.0.2.84') + query = dns.message.make_query(name, 'A', want_dnssec=True) + query.flags |= dns.flags.CD + res = self.sendUDPQuery(query) + self.assertRRsetInAnswer(res, expected) + + msg = self.getFirstProtobufMessage() + self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, res) + self.assertEqual(len(msg.response.rrs), 1) + rr = msg.response.rrs[0] + # we have max-cache-ttl set to 15 + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.84') + self.checkNoRemainingMessage() + self.assertEqual(len(msg.response.tags), 1) + ts1 = msg.response.tags[0] + print(ts1) + # Again + res = self.sendUDPQuery(query) + self.assertRRsetInAnswer(res, expected) + + msg = self.getFirstProtobufMessage() + self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, res) + self.assertEqual(len(msg.response.rrs), 1) + rr = msg.response.rrs[0] + # we have max-cache-ttl set to 15 + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.84') + self.checkNoRemainingMessage() + self.assertEqual(len(msg.response.tags), 1) + ts2 = msg.response.tags[0] + print(ts2) + self.assertNotEqual(ts1, ts2) + class ProtobufSelectedFromLuaTest(TestRecursorProtobuf): """ This test makes sure that we correctly export queries and responses but only if they have been selected from Lua. From c837140e1d39b9cec75ba75ed23487724d9a3a51 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 12 Jul 2023 14:58:53 +0200 Subject: [PATCH 442/909] Set the pb policy tags in the right places --- pdns/recursordist/pdns_recursor.cc | 4 ++-- pdns/recursordist/rec-main.cc | 7 ++++-- pdns/recursordist/rec-main.hh | 3 ++- pdns/recursordist/rec-tcp.cc | 2 +- .../test_Protobuf.py | 24 +++++++++---------- 5 files changed, 22 insertions(+), 18 deletions(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 927cf06dd8e5..1b982ab1f11f 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -1679,7 +1679,6 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi pbMessage.setAppliedPolicyHit(appliedPolicy.d_hit); pbMessage.setAppliedPolicyKind(appliedPolicy.d_kind); } - pbMessage.addPolicyTags(comboWriter->d_policyTags); pbMessage.setInBytes(packet.size()); pbMessage.setValidationState(resolver.getValidationState()); @@ -1775,6 +1774,7 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi pbMessage.setDeviceId(dnsQuestion.deviceId); pbMessage.setDeviceName(dnsQuestion.deviceName); pbMessage.setToPort(comboWriter->d_destination.getPort()); + pbMessage.addPolicyTags(comboWriter->d_policyTags); for (const auto& metaValue : dnsQuestion.meta) { pbMessage.setMeta(metaValue.first, metaValue.second.stringVal, metaValue.second.intVal); @@ -2243,7 +2243,7 @@ static string* doProcessUDPQuestion(const std::string& question, const ComboAddr eventTrace.add(RecEventTrace::AnswerSent); if (t_protobufServers.servers && logResponse && (!luaconfsLocal->protobufExportConfig.taggedOnly || !pbData || pbData->d_tagged)) { - protobufLogResponse(dnsheader, luaconfsLocal, pbData, tval, false, source, destination, mappedSource, ednssubnet, uniqueId, requestorId, deviceId, deviceName, meta, eventTrace); + protobufLogResponse(dnsheader, luaconfsLocal, pbData, tval, false, source, destination, mappedSource, ednssubnet, uniqueId, requestorId, deviceId, deviceName, meta, eventTrace, policyTags); } if (eventTrace.enabled() && (SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_log) != 0) { diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 2d46bbe94489..36b8517013d1 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -493,7 +493,7 @@ void protobufLogQuery(LocalStateHolder& luaconfsLocal, const boo msg.setRequestorId(requestorId); msg.setDeviceId(deviceId); msg.setDeviceName(deviceName); - + if (!policyTags.empty()) { msg.addPolicyTags(policyTags); } @@ -526,7 +526,8 @@ void protobufLogResponse(const struct dnsheader* header, LocalStateHolder& meta, - const RecEventTrace& eventTrace) + const RecEventTrace& eventTrace, + const std::unordered_set& policyTags) { pdns::ProtoZero::RecMessage pbMessage(pbData ? pbData->d_message : "", pbData ? pbData->d_response : "", 64, 10); // The extra bytes we are going to add // Normally we take the immutable string from the cache and append a few values, but if it's not there (can this happen?) @@ -581,6 +582,8 @@ void protobufLogResponse(const struct dnsheader* header, LocalStateHolder& meta, - const RecEventTrace& eventTrace); + const RecEventTrace& eventTrace, + const std::unordered_set& policyTags); void requestWipeCaches(const DNSName& canon); void startDoResolve(void*); bool expectProxyProtocol(const ComboAddress& from); diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 70c3f9595a0f..4b43326e05a4 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -577,7 +577,7 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v { 0, 0 }; - protobufLogResponse(dnsheader, luaconfsLocal, pbData, tval, true, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet, comboWriter->d_uuid, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta, comboWriter->d_eventTrace); + protobufLogResponse(dnsheader, luaconfsLocal, pbData, tval, true, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet, comboWriter->d_uuid, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta, comboWriter->d_eventTrace, comboWriter->d_policyTags); } if (comboWriter->d_eventTrace.enabled() && (SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_log) != 0) { diff --git a/regression-tests.recursor-dnssec/test_Protobuf.py b/regression-tests.recursor-dnssec/test_Protobuf.py index 698f5109d84d..5143a5b80509 100644 --- a/regression-tests.recursor-dnssec/test_Protobuf.py +++ b/regression-tests.recursor-dnssec/test_Protobuf.py @@ -94,19 +94,19 @@ class TestRecursorProtobuf(RecursorTest): def getFirstProtobufMessage(self, retries=1, waitTime=1): msg = None - print("in getFirstProtobufMessage") + #print("in getFirstProtobufMessage") for param in protobufServersParameters: print(param.port) failed = 0 while param.queue.empty: - print(failed) - print(retries) + #print(failed) + #print(retries) if failed >= retries: break failed = failed + 1 - print("waiting") + #print("waiting") time.sleep(waitTime) self.assertFalse(param.queue.empty()) @@ -118,7 +118,7 @@ def getFirstProtobufMessage(self, retries=1, waitTime=1): if oldmsg is not None: self.assertEqual(msg, oldmsg) - print(msg) + #print(msg) return msg def emptyProtoBufQueue(self): @@ -232,17 +232,17 @@ def checkProtobufPolicy(self, msg, policyType, reason, trigger, hit, kind): self.assertEqual(msg.response.appliedPolicyKind, kind) def checkProtobufTags(self, msg, tags): - print(tags) - print('---') - print(msg.response.tags) + #print(tags) + #print('---') + #print(msg.response.tags) self.assertEqual(len(msg.response.tags), len(tags)) for tag in msg.response.tags: self.assertTrue(tag in tags) def checkProtobufMetas(self, msg, metas): - print(metas) - print('---') - print(msg.meta) + #print(metas) + #print('---') + #print(msg.meta) self.assertEqual(len(msg.meta), len(metas)) for m in msg.meta: self.assertTrue(m.HasField('key')) @@ -277,7 +277,7 @@ def checkProtobufIncomingNetworkErrorResponse(self, msg, protocol, response, ini self.assertEqual(msg.response.rcode, 65536) def checkProtobufIdentity(self, msg, requestorId, deviceId, deviceName): - print(msg) + #print(msg) self.assertTrue((requestorId == '') == (not msg.HasField('requestorId'))) self.assertTrue((deviceId == b'') == (not msg.HasField('deviceId'))) self.assertTrue((deviceName == '') == (not msg.HasField('deviceName'))) From 80562e691257cb427597f628e4242751b1f2dfd2 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 12 Jul 2023 15:15:57 +0200 Subject: [PATCH 443/909] Use gettag --- regression-tests.recursor-dnssec/test_Protobuf.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/regression-tests.recursor-dnssec/test_Protobuf.py b/regression-tests.recursor-dnssec/test_Protobuf.py index 5143a5b80509..f2789e2efe1f 100644 --- a/regression-tests.recursor-dnssec/test_Protobuf.py +++ b/regression-tests.recursor-dnssec/test_Protobuf.py @@ -972,11 +972,11 @@ class ProtobufTagCacheTest(TestRecursorProtobuf): protobufServer({"127.0.0.1:%d", "127.0.0.1:%d"}, { logQueries=false, logResponses=true } ) """ % (protobufServersParameters[0].port, protobufServersParameters[1].port) _lua_dns_script_file = """ - function preresolve(dq) - if dq.qname:equal('tagged.example.') then - dq:addPolicyTag(''.. math.random()) + function gettag(remote, ednssubnet, localip, qname, qtype, ednsoptions, tcp) + if qname:equal('tagged.example.') then + return 0, { '' .. math.random() } end - return false + return 0 end """ @@ -998,7 +998,7 @@ def testTagged(self): self.checkNoRemainingMessage() self.assertEqual(len(msg.response.tags), 1) ts1 = msg.response.tags[0] - print(ts1) + #print(ts1) # Again res = self.sendUDPQuery(query) self.assertRRsetInAnswer(res, expected) @@ -1013,7 +1013,7 @@ def testTagged(self): self.checkNoRemainingMessage() self.assertEqual(len(msg.response.tags), 1) ts2 = msg.response.tags[0] - print(ts2) + #print(ts2) self.assertNotEqual(ts1, ts2) class ProtobufSelectedFromLuaTest(TestRecursorProtobuf): From a4d0f523387959023ac4514fe5c07223e184ff14 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 14 Jul 2023 12:52:08 +0200 Subject: [PATCH 444/909] Do not store tags set by gettag(_ffi) into the PC by keeping them separate. We do pass them to the other Lua functions, but take care to erase them aagin before creating the partial PB message stored into the cache. --- pdns/recursordist/pdns_recursor.cc | 16 ++++++++++- pdns/recursordist/rec-main.hh | 3 +- .../test_Protobuf.py | 28 ++++++++++++++++--- 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 1b982ab1f11f..ba9771580d7c 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -906,6 +906,18 @@ static uint32_t capPacketCacheTTL(const struct dnsheader& hdr, uint32_t ttl, boo return ttl; } +static void addPolicyTagsToPBMessageIfNeeded(DNSComboWriter& comboWriter, pdns::ProtoZero::RecMessage& pbMessage) +{ + if (!comboWriter.d_gettagPolicyTags.empty()) { + for (const auto& tag : comboWriter.d_gettagPolicyTags) { + comboWriter.d_policyTags.erase(tag); + } + } + if (!comboWriter.d_policyTags.empty()) { + pbMessage.addPolicyTags(comboWriter.d_policyTags); + } +} + void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 { auto comboWriter = std::unique_ptr(static_cast(arg)); @@ -1681,6 +1693,8 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi } pbMessage.setInBytes(packet.size()); pbMessage.setValidationState(resolver.getValidationState()); + // See if we want to store the policyTags into th PC + addPolicyTagsToPBMessageIfNeeded(*comboWriter, pbMessage); // Take s snap of the current protobuf buffer state to store in the PC pbDataForCache = boost::make_optional(RecursorPacketCache::PBData{ @@ -1774,7 +1788,7 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi pbMessage.setDeviceId(dnsQuestion.deviceId); pbMessage.setDeviceName(dnsQuestion.deviceName); pbMessage.setToPort(comboWriter->d_destination.getPort()); - pbMessage.addPolicyTags(comboWriter->d_policyTags); + pbMessage.addPolicyTags(comboWriter->d_gettagPolicyTags); for (const auto& metaValue : dnsQuestion.meta) { pbMessage.setMeta(metaValue.first, metaValue.second.stringVal, metaValue.second.intVal); diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index 6d7dbc78fa60..da2cd43cfa20 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -59,7 +59,7 @@ struct DNSComboWriter } DNSComboWriter(const std::string& query, const struct timeval& now, std::unordered_set&& policyTags, shared_ptr luaContext, LuaContext::LuaObject&& data, std::vector&& records) : - d_mdp(true, query), d_now(now), d_query(query), d_policyTags(std::move(policyTags)), d_records(std::move(records)), d_luaContext(std::move(luaContext)), d_data(std::move(data)) + d_mdp(true, query), d_now(now), d_query(query), d_policyTags(std::move(policyTags)), d_gettagPolicyTags(d_policyTags), d_records(std::move(records)), d_luaContext(std::move(luaContext)), d_data(std::move(data)) { } @@ -125,6 +125,7 @@ struct DNSComboWriter }; std::string d_query; std::unordered_set d_policyTags; + const std::unordered_set d_gettagPolicyTags; std::string d_routingTag; std::vector d_records; diff --git a/regression-tests.recursor-dnssec/test_Protobuf.py b/regression-tests.recursor-dnssec/test_Protobuf.py index f2789e2efe1f..79d57e45618d 100644 --- a/regression-tests.recursor-dnssec/test_Protobuf.py +++ b/regression-tests.recursor-dnssec/test_Protobuf.py @@ -96,7 +96,7 @@ def getFirstProtobufMessage(self, retries=1, waitTime=1): #print("in getFirstProtobufMessage") for param in protobufServersParameters: - print(param.port) + #print(param.port) failed = 0 while param.queue.empty: @@ -944,6 +944,27 @@ def testTagged(self): res = self.sendUDPQuery(query) self.assertRRsetInAnswer(res, expected) + # check the protobuf messages corresponding to the UDP query and answer + msg = self.getFirstProtobufMessage() + self.checkProtobufQuery(msg, dnsmessage_pb2.PBDNSMessage.UDP, query, dns.rdataclass.IN, dns.rdatatype.A, name) + self.checkProtobufTags(msg, [ self._tag_from_gettag ]) + # then the response + msg = self.getFirstProtobufMessage() + self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, res) + self.assertEqual(len(msg.response.rrs), 1) + rr = msg.response.rrs[0] + # we have max-cache-ttl set to 15 + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.84') + tags = [ self._tag_from_gettag ] + self._tags + #print(msg) + self.checkProtobufTags(msg, tags) + self.checkNoRemainingMessage() + + # Again to check PC case + res = self.sendUDPQuery(query) + self.assertRRsetInAnswer(res, expected) + # check the protobuf messages corresponding to the UDP query and answer msg = self.getFirstProtobufMessage() self.checkProtobufQuery(msg, dnsmessage_pb2.PBDNSMessage.UDP, query, dns.rdataclass.IN, dns.rdatatype.A, name) @@ -998,8 +1019,8 @@ def testTagged(self): self.checkNoRemainingMessage() self.assertEqual(len(msg.response.tags), 1) ts1 = msg.response.tags[0] - #print(ts1) - # Again + + # Again to check PC case res = self.sendUDPQuery(query) self.assertRRsetInAnswer(res, expected) @@ -1013,7 +1034,6 @@ def testTagged(self): self.checkNoRemainingMessage() self.assertEqual(len(msg.response.tags), 1) ts2 = msg.response.tags[0] - #print(ts2) self.assertNotEqual(ts1, ts2) class ProtobufSelectedFromLuaTest(TestRecursorProtobuf): From a89c3250138841961dbe21c34dc012711e615db2 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 17 Jul 2023 12:10:35 +0200 Subject: [PATCH 445/909] Apply suggestions from code review Co-authored-by: Remi Gacogne --- pdns/recursordist/pdns_recursor.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index ba9771580d7c..78cce382f5c8 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -908,6 +908,8 @@ static uint32_t capPacketCacheTTL(const struct dnsheader& hdr, uint32_t ttl, boo static void addPolicyTagsToPBMessageIfNeeded(DNSComboWriter& comboWriter, pdns::ProtoZero::RecMessage& pbMessage) { + /* we do _not_ want to store policy tags set by the gettag hook into the packet cache, + since the call to gettag for subsequent queries could yield the same PC tag but different policy tags */ if (!comboWriter.d_gettagPolicyTags.empty()) { for (const auto& tag : comboWriter.d_gettagPolicyTags) { comboWriter.d_policyTags.erase(tag); @@ -1693,7 +1695,7 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi } pbMessage.setInBytes(packet.size()); pbMessage.setValidationState(resolver.getValidationState()); - // See if we want to store the policyTags into th PC + // See if we want to store the policyTags into the PC addPolicyTagsToPBMessageIfNeeded(*comboWriter, pbMessage); // Take s snap of the current protobuf buffer state to store in the PC From 1b15151d249e3b5d379fcaf7cc9d249c1ea4a457 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 20 Jul 2023 11:17:27 +0200 Subject: [PATCH 446/909] dnsdist: Add suggestions from code review --- pdns/dnsdistdist/dnsdist-healthchecks.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index d8d73b4e2ad8..66f421479e71 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -190,11 +190,11 @@ static void healthCheckUDPCallback(int descriptor, FDMultiplexer::funcparam_t& p data->d_buffer.resize(512); // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - got = recvfrom(data->d_udpSocket.getHandle(), &data->d_buffer.at(0), data->d_buffer.size(), 0, reinterpret_cast(&from), &fromlen); + got = recvfrom(data->d_udpSocket.getHandle(), data->d_buffer.data(), data->d_buffer.size(), 0, reinterpret_cast(&from), &fromlen); if (got < 0) { int savederrno = errno; if (savederrno == EINTR) { - /* interrupted, let's try again */ + /* interrupted before any data was available, let's try again */ continue; } if (savederrno == EWOULDBLOCK || savederrno == EAGAIN) { @@ -250,7 +250,7 @@ static void healthCheckTCPCallback(int descriptor, FDMultiplexer::funcparam_t& p if (ioState == IOState::Done) { data->d_bufferPos = 0; uint16_t responseSize{0}; - memcpy(&responseSize, &data->d_buffer.at(0), sizeof(responseSize)); + memcpy(&responseSize, data->d_buffer.data(), sizeof(responseSize)); data->d_buffer.resize(ntohs(responseSize)); data->d_tcpState = HealthCheckData::TCPState::ReadingResponse; } From d2b8a997977712403cfaeb11ea2f22a9cefc2bc8 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 20 Jul 2023 13:56:35 +0200 Subject: [PATCH 447/909] rec: Don't check TTLs of records coming out of packet cache in regress tests That won't work on a slow system --- regression-tests.recursor-dnssec/test_Protobuf.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/regression-tests.recursor-dnssec/test_Protobuf.py b/regression-tests.recursor-dnssec/test_Protobuf.py index 79d57e45618d..347c918832a3 100644 --- a/regression-tests.recursor-dnssec/test_Protobuf.py +++ b/regression-tests.recursor-dnssec/test_Protobuf.py @@ -974,8 +974,8 @@ def testTagged(self): self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, res) self.assertEqual(len(msg.response.rrs), 1) rr = msg.response.rrs[0] - # we have max-cache-ttl set to 15 - self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + # time may have passed, so do not check TTL + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.84') tags = [ self._tag_from_gettag ] + self._tags self.checkProtobufTags(msg, tags) @@ -1028,8 +1028,8 @@ def testTagged(self): self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, res) self.assertEqual(len(msg.response.rrs), 1) rr = msg.response.rrs[0] - # we have max-cache-ttl set to 15 - self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15) + # time may have passed, so do not check TTL + self.checkProtobufResponseRecord(rr, dns.rdataclass.IN, dns.rdatatype.A, name, 15, checkTTL=False) self.assertEqual(socket.inet_ntop(socket.AF_INET, rr.rdata), '192.0.2.84') self.checkNoRemainingMessage() self.assertEqual(len(msg.response.tags), 1) From 204754fcdd92054c509d764982161c5cfabecb25 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 21 Jul 2023 12:05:05 +0200 Subject: [PATCH 448/909] channel unit tests: Actually retrieve the object after an overflow Not only this ensures that we can actually retrieve the submitted object, it prevents memory analysis tools from reporting a leak. --- pdns/test-channel.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pdns/test-channel.cc b/pdns/test-channel.cc index 6965eecdbf67..9a7e4e037b58 100644 --- a/pdns/test-channel.cc +++ b/pdns/test-channel.cc @@ -77,6 +77,11 @@ BOOST_AUTO_TEST_CASE(test_object_queue_full) auto obj = std::make_unique(); obj->a = 42U; BOOST_CHECK(sender.send(std::move(obj))); + /* and to get it */ + { + auto got = receiver.receive(); + BOOST_CHECK(got); + } } BOOST_AUTO_TEST_CASE(test_object_queue_throw_on_eof) From 26f5d6058d8b0cf4ad2f8da729cb906796c297a0 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 21 Jul 2023 13:43:57 +0200 Subject: [PATCH 449/909] Implement recomendationm from #13050: step 1 Revert #12660 --- ext/json11/json11.cpp | 10 +++++++++- pdns/webserver.cc | 2 +- regression-tests.api/test_Servers.py | 11 +---------- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/ext/json11/json11.cpp b/ext/json11/json11.cpp index 77bf0d7174e5..a0ed9645da16 100644 --- a/ext/json11/json11.cpp +++ b/ext/json11/json11.cpp @@ -93,10 +93,18 @@ static void dump(const string &value, string &out) { out += "\\r"; } else if (ch == '\t') { out += "\\t"; - } else if (static_cast(ch) <= 0x1f || static_cast(ch) >= 0x7f) { + } else if (static_cast(ch) <= 0x1f) { char buf[8]; snprintf(buf, sizeof buf, "\\u%04x", ch); out += buf; + } else if (static_cast(ch) == 0xe2 && static_cast(value[i+1]) == 0x80 + && static_cast(value[i+2]) == 0xa8) { + out += "\\u2028"; + i += 2; + } else if (static_cast(ch) == 0xe2 && static_cast(value[i+1]) == 0x80 + && static_cast(value[i+2]) == 0xa9) { + out += "\\u2029"; + i += 2; } else { out += ch; } diff --git a/pdns/webserver.cc b/pdns/webserver.cc index d221d37e16d2..92df3a8cf1bc 100644 --- a/pdns/webserver.cc +++ b/pdns/webserver.cc @@ -535,7 +535,7 @@ void WebServer::serveConnection(const std::shared_ptr& client) const { } if (d_loglevel >= WebServer::LogLevel::Normal) { - SLOG(g_log<info(Logr::Info, "Request", "remote", Logging::Loggable(remote), "method", Logging::Loggable(req.method), "urlpath", Logging::Loggable(req.url.path), "HTTPVersion", Logging::Loggable(req.versionStr(req.version)), "status", Logging::Loggable(resp.status), "respsize", Logging::Loggable(reply.size()))); diff --git a/regression-tests.api/test_Servers.py b/regression-tests.api/test_Servers.py index c9f59d19c1a0..47122ebb1593 100644 --- a/regression-tests.api/test_Servers.py +++ b/regression-tests.api/test_Servers.py @@ -2,7 +2,6 @@ import operator import requests import unittest -import socket from test_helper import ApiTestCase, is_auth, is_recursor, is_auth_lmdb @@ -42,18 +41,13 @@ def test_read_config(self): self.assertIn('daemon', data) def test_read_statistics(self): - # Use low-level API as we want to create an invalid request to test log line encoding - sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM); - sock.connect((self.server_address, self.server_port)) - sock.send(b'GET /binary\x00\x01\xeb HTTP/1.0\r\n') - sock.close() r = self.session.get(self.url("/api/v1/servers/localhost/statistics")) self.assert_success_json(r) data = r.json() self.assertIn('uptime', [e['name'] for e in data]) print(data) if is_auth(): - qtype_stats, respsize_stats, queries_stats, rcode_stats, logmessages = None, None, None, None, None + qtype_stats, respsize_stats, queries_stats, rcode_stats = None, None, None, None for elem in data: if elem['type'] == 'MapStatisticItem' and elem['name'] == 'response-by-qtype': qtype_stats = elem['value'] @@ -63,13 +57,10 @@ def test_read_statistics(self): queries_stats = elem['value'] elif elem['type'] == 'MapStatisticItem' and elem['name'] == 'response-by-rcode': rcode_stats = elem['value'] - elif elem['type'] == 'RingStatisticItem' and elem['name'] == 'logmessages': - logmessages = elem['value'] self.assertIn('A', [e['name'] for e in qtype_stats]) self.assertIn('80', [e['name'] for e in respsize_stats]) self.assertIn('example.com/A', [e['name'] for e in queries_stats]) self.assertIn('No Error', [e['name'] for e in rcode_stats]) - self.assertTrue(logmessages[0]['name'].startswith('[webserver]')) else: qtype_stats, respsize_stats, rcode_stats = None, None, None for elem in data: From a274da88e4025d7e0626390a3674defdf2d08383 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Fri, 21 Jul 2023 18:17:23 +0200 Subject: [PATCH 450/909] auth: add remote to logs when tcp thread dies --- pdns/tcpreceiver.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pdns/tcpreceiver.cc b/pdns/tcpreceiver.cc index 49a1b66f5dc8..77c7e784e8a1 100644 --- a/pdns/tcpreceiver.cc +++ b/pdns/tcpreceiver.cc @@ -422,20 +422,20 @@ void TCPNameserver::doConnection(int fd) } catch(PDNSException &ae) { s_P.lock()->reset(); // on next call, backend will be recycled - g_log<reset(); // on next call, backend will be recycled - g_log << Logger::Error << "TCP Connection Thread died because of STL error, cycling backend: " << e.what() << endl; + g_log << Logger::Error << "TCP Connection Thread for client " << remote << " died because of STL error, cycling backend: " << e.what() << endl; } catch( ... ) { s_P.lock()->reset(); // on next call, backend will be recycled - g_log << Logger::Error << "TCP Connection Thread caught unknown exception, cycling backend." << endl; + g_log << Logger::Error << "TCP Connection Thread for client " << remote << " caught unknown exception, cycling backend." << endl; } d_connectionroom_sem->post(); @@ -443,7 +443,7 @@ void TCPNameserver::doConnection(int fd) closesocket(fd); } catch(const PDNSException& e) { - g_log< Date: Mon, 24 Jul 2023 10:52:56 +0200 Subject: [PATCH 451/909] report which backend failed to instantiate --- pdns/dnsbackend.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pdns/dnsbackend.cc b/pdns/dnsbackend.cc index bd7645601b89..aef1b99a3a3b 100644 --- a/pdns/dnsbackend.cc +++ b/pdns/dnsbackend.cc @@ -188,8 +188,11 @@ vector BackendMakerClass::all(bool metadataOnly) ret.reserve(d_instances.size()); + std::string current; // to make the exception text more useful + try { for (const auto& instance : d_instances) { + current = instance.first + instance.second; DNSBackend *made = nullptr; if (metadataOnly) { @@ -207,7 +210,7 @@ vector BackendMakerClass::all(bool metadataOnly) } } catch(const PDNSException &ae) { - g_log< BackendMakerClass::all(bool metadataOnly) throw; } catch(...) { // and cleanup - g_log< Date: Mon, 24 Jul 2023 13:27:30 -0400 Subject: [PATCH 452/909] Clean up recursor-test * remove tabs * remove double quotes around a number -- if the value is empty it'd crash anyway --- regression-tests/recursor-test | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/regression-tests/recursor-test b/regression-tests/recursor-test index e75817b5204d..e5c4721901d7 100755 --- a/regression-tests/recursor-test +++ b/regression-tests/recursor-test @@ -85,10 +85,10 @@ touch failed_tests passed_tests ANANSWER=$[(100*(${DBT_QUEUED}-${DBT_ERRORS}-${DBT_TIMEOUTS}) )/${DBT_QUEUED}] -if [ "$ANANSWER" -ge $THRESHOLD ] +if [ $ANANSWER -ge $THRESHOLD ] then - echo recursor-bulktest >> passed_tests - RETVAL=0 + echo recursor-bulktest >> passed_tests + RETVAL=0 else echo recursor-bulktest >> failed_tests RETVAL=1 From 2a55eb7df1ca172c5f4ac50c69968950ae1b8c40 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Mon, 24 Jul 2023 13:40:08 -0400 Subject: [PATCH 453/909] Highlight why bulk test failed with github annotation --- regression-tests/recursor-test | 1 + 1 file changed, 1 insertion(+) diff --git a/regression-tests/recursor-test b/regression-tests/recursor-test index e5c4721901d7..ce4d41b716c4 100755 --- a/regression-tests/recursor-test +++ b/regression-tests/recursor-test @@ -90,6 +90,7 @@ then echo recursor-bulktest >> passed_tests RETVAL=0 else + echo "::error ::title=Recursor-bulktest::Bulk test failed: less than ${THRESHOLD}% of queries answered successfully" echo recursor-bulktest >> failed_tests RETVAL=1 fi From 35eb2fcffa40e7f70b716e99158efe72a0e864d9 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 21 Jul 2023 14:23:02 +0200 Subject: [PATCH 454/909] Check all chars in the URL are valid URL chars. Should probably (also) be done in YaHTTP::URL, though currently the return value of YaHTTP::URL::parse() is completely ignored, so there is no easy way to do. --- pdns/Makefile.am | 7 ++++- pdns/recursordist/ws-recursor.cc | 16 +++++----- pdns/test-webserver_cc.cc | 29 ++++++++++++++++++ pdns/webserver.cc | 52 ++++++++++++++++++++++++++++++++ pdns/webserver.hh | 2 ++ 5 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 pdns/test-webserver_cc.cc diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 5d188b1ce061..551b28429508 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1415,6 +1415,7 @@ testrunner_SOURCES = \ test-trusted-notification-proxy_cc.cc \ test-tsig.cc \ test-ueberbackend_cc.cc \ + test-webserver_cc.cc \ test-zonemd_cc.cc \ test-zoneparser_tng_cc.cc \ testrunner.cc \ @@ -1423,7 +1424,9 @@ testrunner_SOURCES = \ tsigverifier.cc tsigverifier.hh \ ueberbackend.cc ueberbackend.hh \ unix_utility.cc \ + uuid-utils.cc \ validate.hh \ + webserver.cc \ zonemd.cc zonemd.hh \ zoneparser-tng.cc zoneparser-tng.hh @@ -1438,7 +1441,9 @@ testrunner_LDADD = \ $(RT_LIBS) \ $(LUA_LIBS) \ $(LIBDL) \ - $(IPCRYPT_LIBS) + $(IPCRYPT_LIBS) \ + $(YAHTTP_LIBS) \ + $(JSON11_LIBS) if GSS_TSIG testrunner_LDADD += $(GSS_LIBS) diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index 46efe7a8c4ea..98e420bb2716 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -1476,6 +1476,9 @@ void AsyncWebServer::serveConnection(const std::shared_ptr& socket) cons req.d_slog->error(Logr::Warning, e.what(), "Unable to parse request")); } + if (!validURL(req.url)) { + throw PDNSException("Received request with invalid URL"); + } logRequest(req, remote); WebServer::handleRequest(req, resp); @@ -1492,6 +1495,12 @@ void AsyncWebServer::serveConnection(const std::shared_ptr& socket) cons req.d_slog->info(Logr::Error, "Failed sending reply to HTTP client")); } handler->close(); // needed to signal "done" to client + if (d_loglevel >= WebServer::LogLevel::Normal) { + SLOG(g_log << Logger::Notice << logprefix << remote << " \"" << req.method << " " << req.url.path << " HTTP/" << req.versionStr(req.version) << "\" " << resp.status << " " << reply.size() << endl, + req.d_slog->info(Logr::Info, "Request", "remote", Logging::Loggable(remote), "method", Logging::Loggable(req.method), + "urlpath", Logging::Loggable(req.url.path), "HTTPVersion", Logging::Loggable(req.versionStr(req.version)), + "status", Logging::Loggable(resp.status), "respsize", Logging::Loggable(reply.size()))); + } } catch (PDNSException& e) { SLOG(g_log << Logger::Error << logprefix << "Exception: " << e.reason << endl, @@ -1507,13 +1516,6 @@ void AsyncWebServer::serveConnection(const std::shared_ptr& socket) cons SLOG(g_log << Logger::Error << logprefix << "Unknown exception" << endl, req.d_slog->error(Logr::Error, "Exception handing request")) } - - if (d_loglevel >= WebServer::LogLevel::Normal) { - SLOG(g_log << Logger::Notice << logprefix << remote << " \"" << req.method << " " << req.url.path << " HTTP/" << req.versionStr(req.version) << "\" " << resp.status << " " << reply.size() << endl, - req.d_slog->info(Logr::Info, "Request", "remote", Logging::Loggable(remote), "method", Logging::Loggable(req.method), - "urlpath", Logging::Loggable(req.url.path), "HTTPVersion", Logging::Loggable(req.versionStr(req.version)), - "status", Logging::Loggable(resp.status), "respsize", Logging::Loggable(reply.size()))); - } } void AsyncWebServer::go() diff --git a/pdns/test-webserver_cc.cc b/pdns/test-webserver_cc.cc new file mode 100644 index 000000000000..785330f93282 --- /dev/null +++ b/pdns/test-webserver_cc.cc @@ -0,0 +1,29 @@ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_MAIN + +#include +#include "webserver.hh" + +BOOST_AUTO_TEST_SUITE(test_webserver_cc) + +BOOST_AUTO_TEST_CASE(test_validURL) +{ + // We cannot test\x00 as embedded NULs are not handled by YaHTTP other than stopping the parsing + const std::vector> urls = { + {"http://www.powerdns.com/?foo=123", true}, + {"http://ww.powerdns.com/?foo=%ff", true}, + {"http://\x01ww.powerdns.com/?foo=123", false}, + {"http://\xffwww.powerdns.com/?foo=123", false}, + {"http://www.powerdns.com/?foo=123\x01", false}, + {"http://www.powerdns.com/\x7f?foo=123", false}, + {"http://www.powerdns.com/\x80?foo=123", false}, + {"http://www.powerdns.com/?\xff", false}, + }; + + for (const auto& testcase : urls) { + cerr << testcase.first << endl; + BOOST_CHECK_EQUAL(WebServer::validURL(testcase.first), testcase.second); + } +} + +BOOST_AUTO_TEST_SUITE_END(); diff --git a/pdns/webserver.cc b/pdns/webserver.cc index 92df3a8cf1bc..aadea06b4379 100644 --- a/pdns/webserver.cc +++ b/pdns/webserver.cc @@ -36,6 +36,8 @@ #include "json.hh" #include "uuid-utils.hh" #include +#include +#include json11::Json HttpRequest::json() { @@ -461,6 +463,53 @@ void WebServer::logResponse(const HttpResponse& resp, const ComboAddress& /* rem } } + +struct ValidChars { + ValidChars() + { + // letter may be signed, but we only pass positive values + for (auto letter : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-._~:/?#[]@!$&'()*+,;=") { + set.set(letter); + } + } + std::bitset<127> set; +}; + +static const ValidChars validChars; + +static bool validURLChars(const string& str) +{ + for (auto iter = str.begin(); iter != str.end(); ++iter) { + if (*iter == '%') { + ++iter; + if (iter == str.end() || isxdigit(static_cast(*iter)) == 0) { + return false; + } + ++iter; + if (iter == str.end() || isxdigit(static_cast(*iter)) == 0) { + return false; + } + } + else if (static_cast(*iter) >= validChars.set.size() || !validChars.set[*iter]) { + return false; + } + } + return true; +} + +bool WebServer::validURL(const YaHTTP::URL& url) +{ + bool isOK = true; + isOK = isOK && validURLChars(url.protocol); + isOK = isOK && validURLChars(url.host); + isOK = isOK && validURLChars(url.username); + isOK = isOK && validURLChars(url.password); + isOK = isOK && validURLChars(url.path); + isOK = isOK && validURLChars(url.parameters); + isOK = isOK && validURLChars(url.anchor); + return isOK; +} + void WebServer::serveConnection(const std::shared_ptr& client) const { const auto unique = getUniqueID(); const string logprefix = d_logprefix + to_string(unique) + " "; @@ -504,6 +553,9 @@ void WebServer::serveConnection(const std::shared_ptr& client) const { d_slog->error(Logr::Warning, e.what(), "Unable to parse request")); } + if (!validURL(req.url)) { + throw PDNSException("Received request with invalid URL"); + } // Uses of `remote` below guarded by d_loglevel if (d_loglevel > WebServer::LogLevel::None) { client->getRemote(remote); diff --git a/pdns/webserver.hh b/pdns/webserver.hh index 3859117517df..c75dd99ad09a 100644 --- a/pdns/webserver.hh +++ b/pdns/webserver.hh @@ -213,6 +213,8 @@ public: d_acl = nmg; } + static bool validURL(const YaHTTP::URL& url); + void bind(); void go(); From 89234159462f36470b51b9e4de6876aa7e606b4e Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Mon, 24 Jul 2023 12:11:14 -0400 Subject: [PATCH 455/909] Use backticks in rec_control(1) --- .../docs/manpages/rec_control.1.rst | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/pdns/recursordist/docs/manpages/rec_control.1.rst b/pdns/recursordist/docs/manpages/rec_control.1.rst index 69817ea5e802..928694a12203 100644 --- a/pdns/recursordist/docs/manpages/rec_control.1.rst +++ b/pdns/recursordist/docs/manpages/rec_control.1.rst @@ -69,14 +69,14 @@ current-queries Shows the currently active queries. clear-dont-throttle-names NAME [NAME...] - Remove names that are not allowed to be throttled. If *NAME* is '*', remove all + Remove names that are not allowed to be throttled. If *NAME* is ``*``, remove all clear-dont-throttle-netmasks NETMASK [NETMASK...] - Remove netmasks that are not allowed to be throttled. If *NETMASK* is '*', remove all + Remove netmasks that are not allowed to be throttled. If *NETMASK* is ``*``, remove all clear-nta *DOMAIN*... Remove Negative Trust Anchor for one or more *DOMAIN*\ s. Set domain to - '*' to remove all NTA's. + ``*`` to remove all NTA's. clear-ta [*DOMAIN*]... Remove Trust Anchor for one or more *DOMAIN*\ s. Note that removing the @@ -220,8 +220,8 @@ set-carbon-server *CARBON SERVER* [*CARBON OURNAME*] not empty, also set the carbon-ourname setting to *CARBON OURNAME*. set-dnssec-log-bogus *SETTING* - Set dnssec-log-bogus setting to *SETTING*. Set to 'on' or 'yes' to log - DNSSEC validation failures and to 'no' or 'off' to disable logging these + Set dnssec-log-bogus setting to *SETTING*. Set to ``on`` or ``yes`` to log + DNSSEC validation failures and to ``no`` or ``off`` to disable logging these failures. set-ecs-minimum-ttl *NUM* @@ -241,7 +241,8 @@ set-minimum-ttl *NUM* Set minimum-ttl-override to *NUM*. set-event-trace-enabled *NUM* - Set logging of event trace messages, 0 = disabled, 1 = protobuf, 2 = log file, 3 = both. + Set logging of event trace messages, ``0`` = disabled, ``1`` = protobuf, + ``2`` = log file, ``3`` = protobuf and log file. top-queries Shows the top-20 queries. Statistics are over the last @@ -325,8 +326,8 @@ wipe-cache *DOMAIN* [*DOMAIN*] [...] Wipe entries for *DOMAIN* (exact name match) from the cache. This is useful if, for example, an important server has a new IP address, but the TTL has not yet expired. Multiple domain names can be passed. - *DOMAIN* can be suffixed with a '$'. to delete the whole tree from the - cache. i.e. 'powerdns.com$' will remove all cached entries under and + *DOMAIN* can be suffixed with a ``$``. to delete the whole tree from the + cache. i.e. ``powerdns.com$`` will remove all cached entries under and including the powerdns.com name. **Note**: this command also wipes the negative cache. From e7b8b52d401f21d72ec7621d8b5d8d1491e9cfd9 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Tue, 25 Jul 2023 06:13:28 -0400 Subject: [PATCH 456/909] Switch from deprecated ::set-output https://github.blog/changelog/2022-10-11-github-actions-deprecating-save-state-and-set-output-commands/ --- .github/workflows/build-packages.yml | 3 ++- .github/workflows/builder.yml | 3 ++- .github/workflows/documentation.yml | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index 958fed260632..6412075d84cf 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -86,7 +86,8 @@ jobs: # this builds packages and runs our unit tests (make check) - run: IS_RELEASE=${{ inputs.is_release}} builder/build.sh -v -m ${{ inputs.product }} ${{ matrix.os }} - name: Get version number - run: 'echo ::set-output name=version::$(readlink builder/tmp/latest)' + run: | + echo "version=$(readlink builder/tmp/latest)" >> $GITHUB_OUTPUT id: getversion - name: Upload packages as GH artifacts uses: actions/upload-artifact@v3 diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index f0edb1afc0d5..a81d0be78309 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -35,7 +35,8 @@ jobs: # this builds packages and runs our unit test (make check) - run: builder/build.sh -v -m ${{ matrix.product }} ${{ matrix.os }} - name: Get version number - run: 'echo ::set-output name=version::$(readlink builder/tmp/latest)' + run: | + echo "version=$(readlink builder/tmp/latest)" >> $GITHUB_OUTPUT id: getversion - name: Upload packages uses: actions/upload-artifact@v3 diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index a03c005273ea..25a89a6e9619 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -22,7 +22,8 @@ jobs: - run: inv install-doc-deps-pdf - id: get-version - run: echo "pdns_version=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT + run: | + echo "pdns_version=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT - id: setup-ssh run: |- From ea9310d2b44ec844311039ad19328a8ed95fe041 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Tue, 25 Jul 2023 08:27:30 -0400 Subject: [PATCH 457/909] Highlight why regression tests failed with github annotation --- regression-tests/runtests | 3 +++ 1 file changed, 3 insertions(+) diff --git a/regression-tests/runtests b/regression-tests/runtests index 9566e8bc49be..6ebf474edbb6 100755 --- a/regression-tests/runtests +++ b/regression-tests/runtests @@ -146,6 +146,9 @@ do echo >> test-results done +if [ $failed -gt 0 ]; then + echo -n "::error ::title=Regression-tests::Tests failed. " +fi echo -n $passed out of $[$passed+$failed] echo -n " (" res=$((echo scale=2; echo 100*$passed/\($passed+$failed\)) | bc ) From 7ab40a80547d112914b71919d8f4aa14cc24b047 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 26 Jul 2023 09:35:05 +0200 Subject: [PATCH 458/909] Add a few testcases for "incomplete" URLs --- pdns/test-webserver_cc.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pdns/test-webserver_cc.cc b/pdns/test-webserver_cc.cc index 785330f93282..5003dbb220c6 100644 --- a/pdns/test-webserver_cc.cc +++ b/pdns/test-webserver_cc.cc @@ -18,10 +18,16 @@ BOOST_AUTO_TEST_CASE(test_validURL) {"http://www.powerdns.com/\x7f?foo=123", false}, {"http://www.powerdns.com/\x80?foo=123", false}, {"http://www.powerdns.com/?\xff", false}, + {"/?foo=123&bar", true}, + {"/?foo=%ff&bar", true}, + {"/?\x01foo=123", false}, + {"/?foo=123\x01", false}, + {"/\x7f?foo=123", false}, + {"/\x80?foo=123", false}, + {"/?\xff", false}, }; for (const auto& testcase : urls) { - cerr << testcase.first << endl; BOOST_CHECK_EQUAL(WebServer::validURL(testcase.first), testcase.second); } } From 30a57c3d42e8007ba35c5a191230c0a78f71fdd8 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Wed, 26 Jul 2023 10:41:14 -0400 Subject: [PATCH 459/909] Remove timestamp CI systems provide their own timestamps This will make it easier for tests to use `::error` to talk to GitHub Actions --- build-scripts/test-auth | 92 +++++++++++++++++++------------------- regression-tests/timestamp | 5 --- tasks.py | 2 +- 3 files changed, 47 insertions(+), 52 deletions(-) delete mode 100755 regression-tests/timestamp diff --git a/build-scripts/test-auth b/build-scripts/test-auth index 095d6a8ee037..6812dd716584 100755 --- a/build-scripts/test-auth +++ b/build-scripts/test-auth @@ -58,53 +58,53 @@ EXITCODE=0 if [ -z "$context" ]; then export geoipregion=oc geoipregionip=1.2.3.4 - ./timestamp ./start-test-stop 5300 bind-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 bind-dnssec-both || EXITCODE=1 + ./start-test-stop 5300 bind-both || EXITCODE=1 + ./start-test-stop 5300 bind-dnssec-both || EXITCODE=1 # No PKCS#11 in packages - #SETUP_SOFTHSM=y ./timestamp ./start-test-stop 5300 bind-dnssec-pkcs11 || EXITCODE=1 - ./timestamp ./start-test-stop 5300 bind-dnssec-nsec3-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 bind-dnssec-nsec3-optout-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 bind-dnssec-nsec3-narrow || EXITCODE=1 - ./timestamp ./start-test-stop 5300 bind-hybrid-nsec3 || EXITCODE=1 + #SETUP_SOFTHSM=y ./start-test-stop 5300 bind-dnssec-pkcs11 || EXITCODE=1 + ./start-test-stop 5300 bind-dnssec-nsec3-both || EXITCODE=1 + ./start-test-stop 5300 bind-dnssec-nsec3-optout-both || EXITCODE=1 + ./start-test-stop 5300 bind-dnssec-nsec3-narrow || EXITCODE=1 + ./start-test-stop 5300 bind-hybrid-nsec3 || EXITCODE=1 # Adding extra IPs to docker containers in not supported :( - #./timestamp ./start-test-stop 5300 geoipbackend || EXITCODE=1 - #./timestamp ./start-test-stop 5300 geoipbackend-nsec3-narrow || EXITCODE=1 - - ./timestamp ./start-test-stop 5300 gmysql-nodnssec-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gmysql-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gmysql-nsec3-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gmysql-nsec3-optout-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gmysql-nsec3-narrow || EXITCODE=1 - - ./timestamp ./start-test-stop 5300 gpgsql-nodnssec-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gpgsql-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gpgsql-nsec3-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gpgsql-nsec3-optout-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gpgsql-nsec3-narrow || EXITCODE=1 - - ./timestamp ./start-test-stop 5300 gsqlite3-nodnssec-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gsqlite3-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gsqlite3-nsec3-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gsqlite3-nsec3-optout-both || EXITCODE=1 - ./timestamp ./start-test-stop 5300 gsqlite3-nsec3-narrow || EXITCODE=1 - - ./timestamp timeout 120s ./start-test-stop 5300 remotebackend-pipe || EXITCODE=1 - ./timestamp timeout 120s ./start-test-stop 5300 remotebackend-pipe-dnssec || EXITCODE=1 - ./timestamp timeout 120s ./start-test-stop 5300 remotebackend-unix || EXITCODE=1 - ./timestamp timeout 120s ./start-test-stop 5300 remotebackend-unix-dnssec || EXITCODE=1 - ./timestamp timeout 120s ./start-test-stop 5300 remotebackend-http || EXITCODE=1 - ./timestamp timeout 120s ./start-test-stop 5300 remotebackend-http-dnssec || EXITCODE=1 - - ./timestamp timeout 120s ./start-test-stop 5300 lua2 - ./timestamp timeout 120s ./start-test-stop 5300 lua2-dnssec + #./start-test-stop 5300 geoipbackend || EXITCODE=1 + #./start-test-stop 5300 geoipbackend-nsec3-narrow || EXITCODE=1 + + ./start-test-stop 5300 gmysql-nodnssec-both || EXITCODE=1 + ./start-test-stop 5300 gmysql-both || EXITCODE=1 + ./start-test-stop 5300 gmysql-nsec3-both || EXITCODE=1 + ./start-test-stop 5300 gmysql-nsec3-optout-both || EXITCODE=1 + ./start-test-stop 5300 gmysql-nsec3-narrow || EXITCODE=1 + + ./start-test-stop 5300 gpgsql-nodnssec-both || EXITCODE=1 + ./start-test-stop 5300 gpgsql-both || EXITCODE=1 + ./start-test-stop 5300 gpgsql-nsec3-both || EXITCODE=1 + ./start-test-stop 5300 gpgsql-nsec3-optout-both || EXITCODE=1 + ./start-test-stop 5300 gpgsql-nsec3-narrow || EXITCODE=1 + + ./start-test-stop 5300 gsqlite3-nodnssec-both || EXITCODE=1 + ./start-test-stop 5300 gsqlite3-both || EXITCODE=1 + ./start-test-stop 5300 gsqlite3-nsec3-both || EXITCODE=1 + ./start-test-stop 5300 gsqlite3-nsec3-optout-both || EXITCODE=1 + ./start-test-stop 5300 gsqlite3-nsec3-narrow || EXITCODE=1 + + timeout 120s ./start-test-stop 5300 remotebackend-pipe || EXITCODE=1 + timeout 120s ./start-test-stop 5300 remotebackend-pipe-dnssec || EXITCODE=1 + timeout 120s ./start-test-stop 5300 remotebackend-unix || EXITCODE=1 + timeout 120s ./start-test-stop 5300 remotebackend-unix-dnssec || EXITCODE=1 + timeout 120s ./start-test-stop 5300 remotebackend-http || EXITCODE=1 + timeout 120s ./start-test-stop 5300 remotebackend-http-dnssec || EXITCODE=1 + + timeout 120s ./start-test-stop 5300 lua2 + timeout 120s ./start-test-stop 5300 lua2-dnssec # No 0MQ in the PowerDNS packages - #./timestamp timeout 120s ./start-test-stop 5300 remotebackend-zeromq || EXITCODE=1 - #./timestamp timeout 120s ./start-test-stop 5300 remotebackend-zeromq-dnssec || EXITCODE=1 + #timeout 120s ./start-test-stop 5300 remotebackend-zeromq || EXITCODE=1 + #timeout 120s ./start-test-stop 5300 remotebackend-zeromq-dnssec || EXITCODE=1 - ./timestamp ./start-test-stop 5300 tinydns || EXITCODE=1 + ./start-test-stop 5300 tinydns || EXITCODE=1 cd ../regression-tests.nobackend/ @@ -133,15 +133,15 @@ __EOF__ . ~/.mssql-credentials set -x export GODBC_SQLITE3_DSN=pdns-sqlite3-1 - ./timestamp timeout 120s ./start-test-stop 5300 godbc_sqlite3-nodnssec || EXITCODE=1 + timeout 120s ./start-test-stop 5300 godbc_sqlite3-nodnssec || EXITCODE=1 export GODBC_MSSQL_DSN=pdns-mssql export GODBC_MSSQL_USERNAME export GODBC_MSSQL_PASSWORD - ./timestamp timeout 3600s ./start-test-stop 5300 godbc_mssql-nodnssec || EXITCODE=1 - ./timestamp timeout 3600s ./start-test-stop 5300 godbc_mssql || EXITCODE=1 - ./timestamp timeout 3600s ./start-test-stop 5300 godbc_mssql-nsec3 || EXITCODE=1 - ./timestamp timeout 3600s ./start-test-stop 5300 godbc_mssql-nsec3-optout || EXITCODE=1 - ./timestamp timeout 3600s ./start-test-stop 5300 godbc_mssql-nsec3-narrow || EXITCODE=1 + timeout 3600s ./start-test-stop 5300 godbc_mssql-nodnssec || EXITCODE=1 + timeout 3600s ./start-test-stop 5300 godbc_mssql || EXITCODE=1 + timeout 3600s ./start-test-stop 5300 godbc_mssql-nsec3 || EXITCODE=1 + timeout 3600s ./start-test-stop 5300 godbc_mssql-nsec3-optout || EXITCODE=1 + timeout 3600s ./start-test-stop 5300 godbc_mssql-nsec3-narrow || EXITCODE=1 fi exit $EXITCODE diff --git a/regression-tests/timestamp b/regression-tests/timestamp deleted file mode 100755 index 1a76f316af9d..000000000000 --- a/regression-tests/timestamp +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -"$@" 2>&1 | ts "[%F %T]" - -exit ${PIPESTATUS[0]} diff --git a/tasks.py b/tasks.py index e78e0a55212e..1da2c6bf92e7 100644 --- a/tasks.py +++ b/tasks.py @@ -805,7 +805,7 @@ def test_bulk_recursor(c, threads, mthreads, shards): c.run('curl -LO http://s3-us-west-1.amazonaws.com/umbrella-static/top-1m.csv.zip') c.run('unzip top-1m.csv.zip -d .') c.run('chmod +x /opt/pdns-recursor/bin/* /opt/pdns-recursor/sbin/*') - c.run(f'DNSBULKTEST=/usr/bin/dnsbulktest RECURSOR=/opt/pdns-recursor/sbin/pdns_recursor RECCONTROL=/opt/pdns-recursor/bin/rec_control THRESHOLD=95 TRACE=no ./timestamp ./recursor-test 5300 100 {threads} {mthreads} {shards}') + c.run(f'DNSBULKTEST=/usr/bin/dnsbulktest RECURSOR=/opt/pdns-recursor/sbin/pdns_recursor RECCONTROL=/opt/pdns-recursor/bin/rec_control THRESHOLD=95 TRACE=no ./recursor-test 5300 100 {threads} {mthreads} {shards}') @task def install_swagger_tools(c): From 56726eb113ab135ec890e79e94c0393986e9edad Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 31 Jul 2023 14:44:13 +0200 Subject: [PATCH 460/909] Test a few non-ASCII chars in comments --- regression-tests.api/test_Zones.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 46d92f552075..44e1f4c891f5 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -251,7 +251,7 @@ def test_create_zone_with_comments(self): "type": "soa", # test uppercasing of type, too. "comments": [{ "account": "test1", - "content": "blah blah", + "content": "blah blah and test a few non-ASCII chars: ö, € and 😀", "modified_at": 11112, }], }, From 93ad866b4e2f4afb017e8b3b08041598a2378ea5 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 31 Jul 2023 15:51:31 +0200 Subject: [PATCH 461/909] Skip smileys for now, they take 4 bytes to encode and out current mysql schema has 'utf8', which only handles 3 bytes max, should be changed to utf8mb4 one day. --- regression-tests.api/test_Zones.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 44e1f4c891f5..11e175438756 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -251,7 +251,7 @@ def test_create_zone_with_comments(self): "type": "soa", # test uppercasing of type, too. "comments": [{ "account": "test1", - "content": "blah blah and test a few non-ASCII chars: ö, € and 😀", + "content": "blah blah and test a few non-ASCII chars: ö, €", "modified_at": 11112, }], }, From 4cb908bcc5a2881014dd2b2efc315a55dcc5d7d1 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Mon, 31 Jul 2023 13:32:42 -0400 Subject: [PATCH 462/909] Add speed bumps to bug filing --- .github/ISSUE_TEMPLATE/bug_report.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 4d29e08a932f..4daf55b447a3 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -9,8 +9,8 @@ assignees: '' - - +- [ ] This is not a support question, I have read [about opensource](https://www.powerdns.com/opensource.html) and will send support questions to the mailinglist or ask them on IRC. +- [ ] I have read the ['out in the open' support policy](https://blog.powerdns.com/2016/01/18/open-source-support-out-in-the-open/) and am and will comply with it. - Program: Authoritative, Recursor, dnsdist From 2f3cfe6c16ecace72d33ab47cc06e9a2e47de80d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 09:56:40 +0200 Subject: [PATCH 463/909] dnsdist: Stop passing -u dnsdist -g dnsdist on systemd's ExecStart This is useless as long as @service_user@ and @service_group@ are set to 'dnsdist' (which is always true in our build system), and would not have worked otherwise because dnsdist would have rejected it with: ``` --gid/-g set on command-line, but dnsdist was started as a systemd service. Use the 'Group' setting in the systemd unit file to set the group to run as ``` --- builder-support/specs/dnsdist.spec | 5 ----- 1 file changed, 5 deletions(-) diff --git a/builder-support/specs/dnsdist.spec b/builder-support/specs/dnsdist.spec index 8089a0d6d0ea..dd11d3e6daa2 100644 --- a/builder-support/specs/dnsdist.spec +++ b/builder-support/specs/dnsdist.spec @@ -62,9 +62,6 @@ dnsdist is a high-performance DNS loadbalancer that is scriptable in Lua. %prep %autosetup -p1 -n %{name}-%{getenv:BUILDER_VERSION} -# run as dnsdist user -sed -i '/^ExecStart/ s/dnsdist/dnsdist -u dnsdist -g dnsdist/' dnsdist.service.in - %build %if 0%{?rhel} < 8 export CPPFLAGS=-I/usr/include/boost169 @@ -115,8 +112,6 @@ install -d %{buildroot}/%{_sysconfdir}/dnsdist %{__mv} %{buildroot}%{_sysconfdir}/dnsdist/dnsdist.conf-dist %{buildroot}%{_sysconfdir}/dnsdist/dnsdist.conf chgrp dnsdist %{buildroot}/%{_sysconfdir}/dnsdist/dnsdist.conf chmod 0640 %{buildroot}/%{_sysconfdir}/dnsdist/dnsdist.conf -sed -i "s,/^\(ExecStart.*\)dnsdist\(.*\)\$,\1dnsdist -u dnsdist -g dnsdist\2," %{buildroot}/%{_unitdir}/dnsdist.service -sed -i "s,/^\(ExecStart.*\)dnsdist\(.*\)\$,\1dnsdist -u dnsdist -g dnsdist\2," %{buildroot}/%{_unitdir}/dnsdist@.service %pre getent group dnsdist >/dev/null || groupadd -r dnsdist From 32c478585461060b993a414e074daea47de94b80 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 10:04:54 +0200 Subject: [PATCH 464/909] dnsdist: Fix the group of the dnsdist.conf file when installed via RPM I _hope_ the `%attr` directive does the right thing, based on http://ftp.rpm.org/max-rpm/s1-rpm-anywhere-specifying-file-attributes.html I'm using this directive instead of calling `chgrp` in `%post` because I'm told using `chgrp` would make `verify` complain about the ownership later. --- builder-support/specs/dnsdist.spec | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/builder-support/specs/dnsdist.spec b/builder-support/specs/dnsdist.spec index 8089a0d6d0ea..d1e4e0939ad0 100644 --- a/builder-support/specs/dnsdist.spec +++ b/builder-support/specs/dnsdist.spec @@ -113,7 +113,6 @@ make %{?_smp_mflags} check || (cat test-suite.log && false) %make_install install -d %{buildroot}/%{_sysconfdir}/dnsdist %{__mv} %{buildroot}%{_sysconfdir}/dnsdist/dnsdist.conf-dist %{buildroot}%{_sysconfdir}/dnsdist/dnsdist.conf -chgrp dnsdist %{buildroot}/%{_sysconfdir}/dnsdist/dnsdist.conf chmod 0640 %{buildroot}/%{_sysconfdir}/dnsdist/dnsdist.conf sed -i "s,/^\(ExecStart.*\)dnsdist\(.*\)\$,\1dnsdist -u dnsdist -g dnsdist\2," %{buildroot}/%{_unitdir}/dnsdist.service sed -i "s,/^\(ExecStart.*\)dnsdist\(.*\)\$,\1dnsdist -u dnsdist -g dnsdist\2," %{buildroot}/%{_unitdir}/dnsdist@.service @@ -156,5 +155,5 @@ systemctl daemon-reload ||: %{_bindir}/* %{_mandir}/man1/* %dir %{_sysconfdir}/dnsdist -%config(noreplace) %{_sysconfdir}/%{name}/dnsdist.conf +%attr(-, root, dnsdist) %config(noreplace) %{_sysconfdir}/%{name}/dnsdist.conf %{_unitdir}/dnsdist* From ba770e4f65aefdadc489a169ae66fd20c897162c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 12 Jul 2023 10:49:31 +0200 Subject: [PATCH 465/909] calidns: Fix setting an ECS source of 0 --- pdns/calidns.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/calidns.cc b/pdns/calidns.cc index 87bfbe57edba..9afdbe93afb0 100644 --- a/pdns/calidns.cc +++ b/pdns/calidns.cc @@ -121,7 +121,7 @@ static ComboAddress getRandomAddressFromRange(const Netmask& ecsRange) { ComboAddress result = ecsRange.getMaskedNetwork(); uint8_t bits = ecsRange.getBits(); - uint32_t mod = 1 << (32 - bits); + uint32_t mod = (bits > 0) ? (1 << (32 - bits)) : std::numeric_limits::max(); result.sin4.sin_addr.s_addr = result.sin4.sin_addr.s_addr + ntohl(dns_random(mod)); return result; } From 8ae32efc69244141d1f34cc8c658bba13d39353d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 12 Jul 2023 13:07:29 +0200 Subject: [PATCH 466/909] calidns: Use the full 32-bit range for 0.0.0.0/0, via Otto --- pdns/calidns.cc | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pdns/calidns.cc b/pdns/calidns.cc index 9afdbe93afb0..9a428ac4c35f 100644 --- a/pdns/calidns.cc +++ b/pdns/calidns.cc @@ -121,8 +121,14 @@ static ComboAddress getRandomAddressFromRange(const Netmask& ecsRange) { ComboAddress result = ecsRange.getMaskedNetwork(); uint8_t bits = ecsRange.getBits(); - uint32_t mod = (bits > 0) ? (1 << (32 - bits)) : std::numeric_limits::max(); - result.sin4.sin_addr.s_addr = result.sin4.sin_addr.s_addr + ntohl(dns_random(mod)); + if (bits > 0) { + uint32_t mod = 1 << (32 - bits); + result.sin4.sin_addr.s_addr = result.sin4.sin_addr.s_addr + ntohl(dns_random(mod)); + } + else { + result.sin4.sin_addr.s_addr = dns_random_uint32(); + } + return result; } From e6685c54988ec31c5dd43d80b7175dc6467218df Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 31 Jul 2023 17:43:07 +0200 Subject: [PATCH 467/909] calidns: Fix the use of `ntohl` instead of `htonl` in ECS handling --- pdns/calidns.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/calidns.cc b/pdns/calidns.cc index 9a428ac4c35f..65949df05760 100644 --- a/pdns/calidns.cc +++ b/pdns/calidns.cc @@ -123,7 +123,7 @@ static ComboAddress getRandomAddressFromRange(const Netmask& ecsRange) uint8_t bits = ecsRange.getBits(); if (bits > 0) { uint32_t mod = 1 << (32 - bits); - result.sin4.sin_addr.s_addr = result.sin4.sin_addr.s_addr + ntohl(dns_random(mod)); + result.sin4.sin_addr.s_addr = result.sin4.sin_addr.s_addr + htonl(dns_random(mod)); } else { result.sin4.sin_addr.s_addr = dns_random_uint32(); From 08635ef057dbe882fa2e71edf2439174bdc5e972 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 10:52:24 +0200 Subject: [PATCH 468/909] dnsdist: Fix indentation --- pdns/dnsdist-lua-rules.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdist-lua-rules.cc b/pdns/dnsdist-lua-rules.cc index 5ab1c476ef1b..860231ad0510 100644 --- a/pdns/dnsdist-lua-rules.cc +++ b/pdns/dnsdist-lua-rules.cc @@ -258,7 +258,7 @@ static boost::optional getRuleFromSelector(const std::vector& rules, const if (rule.d_name == *str) { return rule; } - } + } } } else if (auto pos = boost::get(&selector)) { From 92d022ed697ce85c33cd6396cfe6a780a9de786a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 10:55:16 +0200 Subject: [PATCH 469/909] dnsdist: Add a comment indicating we are fine with at() throwing --- pdns/dnsdist-lua-rules.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pdns/dnsdist-lua-rules.cc b/pdns/dnsdist-lua-rules.cc index 860231ad0510..2495b4a9ee8e 100644 --- a/pdns/dnsdist-lua-rules.cc +++ b/pdns/dnsdist-lua-rules.cc @@ -262,6 +262,8 @@ static boost::optional getRuleFromSelector(const std::vector& rules, const } } else if (auto pos = boost::get(&selector)) { + /* this will throw a std::out_of_range exception if the + supplied position is out of bounds, this is fine */ return rules.at(*pos); } return boost::none; From 5433828a81c50790068a95d7dbe5cfd3073d6a02 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 10:57:16 +0200 Subject: [PATCH 470/909] dnsdist: Fix a c/p mistake in the description of getSelfAnsweredResponseRule --- pdns/dnsdistdist/docs/rules-actions.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index 116c57b5982e..41f531c5e591 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -189,7 +189,7 @@ For Rules related to the incoming query: .. versionadded:: 1.9.0 - Return the cache-hit response rule corresponding to the selector, if any. + Return the cache-inserted response rule corresponding to the selector, if any. The selector can be the position of the rule in the list, as an integer, its name as a string or its UUID as a string as well. @@ -219,7 +219,7 @@ For Rules related to the incoming query: .. versionadded:: 1.9.0 - Return the cache-hit response rule corresponding to the selector, if any. + Return the self-answered response rule corresponding to the selector, if any. The selector can be the position of the rule in the list, as an integer, its name as a string or its UUID as a string as well. From 9cf951241e838fe846ffb5069f5b0fa10ec9b2de Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 1 Aug 2023 11:00:55 +0200 Subject: [PATCH 471/909] auth docs: remove domainmetadata/DNSSEC warning, has not been true for years --- docs/domainmetadata.rst | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/docs/domainmetadata.rst b/docs/domainmetadata.rst index 3fb72706398b..16ca81d9f9a7 100644 --- a/docs/domainmetadata.rst +++ b/docs/domainmetadata.rst @@ -5,13 +5,7 @@ Each served zone can have "metadata". Such metadata determines how this zone behaves in certain circumstances. .. warning:: - Domain metadata is only available for DNSSEC capable - backends! Make sure to enable the proper '-dnssec' setting to benefit. - -.. warning:: - When multiple backends are in use, domain metadata is only retrieved from - and written to the first DNSSEC-capable backend, no matter where the related - zones live. + When multiple backends are in use, domain metadata is only retrieved from and written to the first DNSSEC-capable or metadata-capable backend, no matter where the related zones live. For the BIND backend, this information is either stored in the :ref:`setting-bind-dnssec-db` or the hybrid database, From 5b06f2979dff69a0856033b17ece00775af1599f Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 13:49:50 +0200 Subject: [PATCH 472/909] lmdbbackend: Prevent a useless copy in LMDBBackend::getAllDomainsFiltered() Reported by Coverity as 1510936: AUTO_CAUSES_COPY. --- modules/lmdbbackend/lmdbbackend.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index d47904815d52..11168f326677 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -1722,9 +1722,9 @@ void LMDBBackend::getAllDomainsFiltered(vector* domains, const std:: zonemap[di.zone] = di; } - for (auto [k, v] : zonemap) { + for (auto& [k, v] : zonemap) { if (allow(v)) { - domains->push_back(v); + domains->push_back(std::move(v)); } } } From 68346dc4af859df1359eeede45b462f68bb5131e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 13:51:20 +0200 Subject: [PATCH 473/909] fuzzing: Add a missing cstdint header to the fuzzing targets --- pdns/fuzz_yahttp.cc | 2 +- pdns/standalone_fuzz_target_runner.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/fuzz_yahttp.cc b/pdns/fuzz_yahttp.cc index f0096f49964d..88ce42b70895 100644 --- a/pdns/fuzz_yahttp.cc +++ b/pdns/fuzz_yahttp.cc @@ -19,7 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - +#include #include extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); diff --git a/pdns/standalone_fuzz_target_runner.cc b/pdns/standalone_fuzz_target_runner.cc index 40a9a4b9b9c2..0ca91064b658 100644 --- a/pdns/standalone_fuzz_target_runner.cc +++ b/pdns/standalone_fuzz_target_runner.cc @@ -1,4 +1,4 @@ - +#include #include #include #include From 4d68f518670b9252e2ce3165d88595b94ac6d31f Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 13:51:52 +0200 Subject: [PATCH 474/909] speedtest: Make coverity happy (CID 1513038) --- pdns/speedtest.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/speedtest.cc b/pdns/speedtest.cc index 055cb44bed9d..741bc701b975 100644 --- a/pdns/speedtest.cc +++ b/pdns/speedtest.cc @@ -939,7 +939,7 @@ struct UUIDGenTest struct NSEC3HashTest { - explicit NSEC3HashTest(int iterations, string salt) : d_iterations(iterations), d_salt(salt) {} + explicit NSEC3HashTest(int iterations, string salt) : d_iterations(iterations), d_salt(std::move(salt)) {} string getName() const { From de5fb85119d07da2c91da20cbc270fb87ecb0be8 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 13:52:53 +0200 Subject: [PATCH 475/909] auth: Make Coverity happy about 'ifurlextup' (CID 1509357) --- pdns/lua-record.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/lua-record.cc b/pdns/lua-record.cc index 639653fede22..af27031a032a 100644 --- a/pdns/lua-record.cc +++ b/pdns/lua-record.cc @@ -896,7 +896,7 @@ static void setupLuaRecords(LuaContext& lua) auto checker = [](const ComboAddress& addr, const opts_t& opts) { return g_up.isUp(addr, opts); }; - return genericIfUp(ips, options, checker, port); + return genericIfUp(ips, std::move(options), checker, port); }); lua.writeFunction("ifurlextup", [](const vector >& ipurls, boost::optional options) { From 689df1f44b9fd5636a1d37e9f3152b397d4d6591 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 13:53:54 +0200 Subject: [PATCH 476/909] pkcs11signers: Fix a possibly unitialized variable Reported by Coverity as CID 1504120. --- pdns/pkcs11signers.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/pkcs11signers.cc b/pdns/pkcs11signers.cc index 1a412727d221..bfbb89a11967 100644 --- a/pdns/pkcs11signers.cc +++ b/pdns/pkcs11signers.cc @@ -288,7 +288,7 @@ class Pkcs11Token { CK_OBJECT_HANDLE d_public_key; CK_OBJECT_HANDLE d_private_key; CK_KEY_TYPE d_key_type; - bool d_always_auth; + bool d_always_auth{false}; CK_ULONG d_bits; std::string d_exponent; From 32b355c43a2dce77e500f02264b7a4c38fcd4d69 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 13:54:30 +0200 Subject: [PATCH 477/909] ixfrdist: Ensure exceptions are properly caught Reported by Coverity as CIDs 1504095, 1504097, 1504109, 1504112, 1504113, 1504114, 1504137 and 1504138. --- pdns/ixfrdist.cc | 349 ++++++++++++++++++++++++++--------------------- 1 file changed, 197 insertions(+), 152 deletions(-) diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index 81d7b03cef55..d4d319927d44 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -1186,6 +1186,8 @@ int main(int argc, char** argv) { g_log.disableSyslog(true); g_log.setTimestamps(false); po::variables_map g_vm; + std::string configPath; + try { po::options_description desc("IXFR distribution tool"); desc.add_options() @@ -1208,10 +1210,17 @@ int main(int argc, char** argv) { cout<<"ixfrdist "<(); + } + catch (const po::error &e) { g_log<(), config)) { - // parseAndCheckConfig already logged whatever was wrong - return EXIT_FAILURE; - } + try { + YAML::Node config; + if (!parseAndCheckConfig(configPath, config)) { + // parseAndCheckConfig already logged whatever was wrong + return EXIT_FAILURE; + } /* From hereon out, we known that all the values in config are valid. */ - for (auto const &domain : config["domains"]) { - set s; - s.insert(domain["master"].as()); - g_domainConfigs[domain["domain"].as()].masters = s; - if (domain["max-soa-refresh"]) { - g_domainConfigs[domain["domain"].as()].maxSOARefresh = domain["max-soa-refresh"].as(); + for (auto const &domain : config["domains"]) { + set s; + s.insert(domain["master"].as()); + g_domainConfigs[domain["domain"].as()].masters = s; + if (domain["max-soa-refresh"]) { + g_domainConfigs[domain["domain"].as()].maxSOARefresh = domain["max-soa-refresh"].as(); + } + g_stats.registerDomain(domain["domain"].as()); + } + + for (const auto &addr : config["acl"].as>()) { + try { + g_acl.addMask(addr); + } + catch (const std::exception& exp) { + g_log<()); - } - for (const auto &addr : config["acl"].as>()) { try { - g_acl.addMask(addr); - } catch (const NetmaskException &e) { - g_log<(); - if (g_compress) { - g_log<(); + if (g_compress) { + g_log< allSockets; - for (const auto& addr : config["listen"].as>()) { - for (const auto& stype : {SOCK_DGRAM, SOCK_STREAM}) { - try { - int s = SSocket(addr.sin4.sin_family, stype, 0); - setNonBlocking(s); - setReuseAddr(s); - SBind(s, addr); - if (stype == SOCK_STREAM) { - SListen(s, 30); // TODO make this configurable + set allSockets; + for (const auto& addr : config["listen"].as>()) { + for (const auto& stype : {SOCK_DGRAM, SOCK_STREAM}) { + try { + int s = SSocket(addr.sin4.sin_family, stype, 0); + setNonBlocking(s); + setReuseAddr(s); + SBind(s, addr); + if (stype == SOCK_STREAM) { + SListen(s, 30); // TODO make this configurable + } + fdm->addReadFD(s, stype == SOCK_DGRAM ? handleUDPRequest : handleTCPRequest); + allSockets.insert(s); + } + catch (const runtime_error& exp) { + g_log<addReadFD(s, stype == SOCK_DGRAM ? handleUDPRequest : handleTCPRequest); - allSockets.insert(s); - } catch(runtime_error &e) { - g_log<(); - if (!(newgid = atoi(gid.c_str()))) { - struct group *gr = getgrnam(gid.c_str()); - if (gr == nullptr) { - g_log<(); + if (!(newgid = atoi(gid.c_str()))) { + struct group *gr = getgrnam(gid.c_str()); + if (gr == nullptr) { + g_log<gr_gid; + } + } + g_log<gr_gid; } } - g_log<>()) { - wsACL.addMask(acl); + if (config["webserver-address"]) { + NetmaskGroup wsACL; + try { + wsACL.addMask("127.0.0.0/8"); + wsACL.addMask("::1/128"); + + if (config["webserver-acl"]) { + wsACL.clear(); + for (const auto &acl : config["webserver-acl"].as>()) { + wsACL.addMask(acl); + } + } + } + catch (const NetmaskException& ne) { + g_log<(); - } + string loglevel = "normal"; + if (config["webserver-loglevel"]) { + loglevel = config["webserver-loglevel"].as(); + } - // Launch the webserver! - try { - std::thread(&IXFRDistWebServer::go, IXFRDistWebServer(config["webserver-address"].as(), wsACL, loglevel)).detach(); - } catch (const PDNSException &e) { - g_log<(), wsACL, loglevel)).detach(); + } + catch (const std::exception& exp) { + g_log<(); + if (!(newuid = atoi(uid.c_str()))) { + struct passwd *pw = getpwnam(uid.c_str()); + if (pw == nullptr) { + g_log<pw_uid; + } + } - if (config["uid"]) { - string uid = config["uid"].as(); - if (!(newuid = atoi(uid.c_str()))) { - struct passwd *pw = getpwnam(uid.c_str()); + struct passwd *pw = getpwuid(newuid); if (pw == nullptr) { - g_log<pw_uid; + if (initgroups(pw->pw_name, newgid) < 0) { + g_log<pw_name, newgid) < 0) { - g_log<(), - config["keep"].as(), - config["axfr-timeout"].as(), - config["failed-soa-retry"].as(), - config["axfr-max-records"].as()); - vector tcpHandlers; - tcpHandlers.reserve(config["tcp-in-threads"].as()); - for (size_t i = 0; i < tcpHandlers.capacity(); ++i) { - tcpHandlers.push_back(std::thread(tcpWorker, i)); - } + // It all starts here + signal(SIGTERM, handleSignal); + signal(SIGINT, handleSignal); + signal(SIGPIPE, SIG_IGN); + + // Init the things we need + reportAllTypes(); + + std::thread ut(updateThread, + config["work-dir"].as(), + config["keep"].as(), + config["axfr-timeout"].as(), + config["failed-soa-retry"].as(), + config["axfr-max-records"].as()); + + vector tcpHandlers; + tcpHandlers.reserve(config["tcp-in-threads"].as()); + for (size_t i = 0; i < tcpHandlers.capacity(); ++i) { + tcpHandlers.push_back(std::thread(tcpWorker, i)); + } - struct timeval now; - for(;;) { - gettimeofday(&now, 0); - fdm->run(&now); - if (g_exiting) { - g_log<run(&now); + if (g_exiting) { + g_log< Date: Tue, 1 Aug 2023 13:56:03 +0200 Subject: [PATCH 478/909] pdnsutil: Set a proper umask before writing the temporary zone file This does not matter on Linux where mkstemp ensures that "the file is created with permissions 0600 that is, read plus write for owner only" but it might on other systems as POSIX does not require mkstemp to do so. Reported by Coverity as CID 1501165. --- pdns/pdnsutil.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index 54d02d35bb5b..bdf0d3347b97 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -32,6 +32,7 @@ #include #include #include +#include #include //termios, TCSANOW, ECHO, ICANON #include "opensslsigners.hh" #ifdef HAVE_LIBSODIUM @@ -1171,6 +1172,13 @@ static int editZone(const DNSName &zone, const PDNSColors& col) { cerr << "Zone '" << zone << "' not found!" << endl; return EXIT_FAILURE; } + + /* ensure that the temporary file will only + be accessible by the current user, not even + by other users in the same group, and certainly + not by other users. + */ + umask(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); vector pre, post; char tmpnam[]="/tmp/pdnsutil-XXXXXX"; int tmpfd=mkstemp(tmpnam); From 86867a80b19a40644e5d5d1c2dcacccb70695b85 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 15:09:25 +0200 Subject: [PATCH 479/909] rec: Prevent a copy in RecursorLua4::DNSQuestion::addAnswer Reported by Coverity as 1509322 --- pdns/recursordist/lua-recursor4.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/lua-recursor4.cc b/pdns/recursordist/lua-recursor4.cc index b35cfd0d9433..04c538025cd5 100644 --- a/pdns/recursordist/lua-recursor4.cc +++ b/pdns/recursordist/lua-recursor4.cc @@ -140,7 +140,7 @@ void RecursorLua4::DNSQuestion::addRecord(uint16_t type, const std::string& cont void RecursorLua4::DNSQuestion::addAnswer(uint16_t type, const std::string& content, boost::optional ttl, boost::optional name) { - addRecord(type, content, DNSResourceRecord::ANSWER, ttl, name); + addRecord(type, content, DNSResourceRecord::ANSWER, ttl, std::move(name)); } struct DynMetric From 42d6b18e42e529a0ff89b57dca1043d6df4041ee Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 15:09:59 +0200 Subject: [PATCH 480/909] rec: Prevent a copy when distributing UDP queries to workers Reported by Coverity as CID 1509301. --- pdns/recursordist/pdns_recursor.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 6087df604ffd..9f34d34c469a 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -2570,7 +2570,7 @@ static void handleNewUDPQuestion(int fileDesc, FDMultiplexer::funcparam_t& /* va if (RecThreadInfo::weDistributeQueries()) { std::string localdata = data; - distributeAsyncFunction(data, [localdata, fromaddr, destaddr, source, destination, mappedSource, tval, fileDesc, proxyProtocolValues, eventTrace]() mutable { + distributeAsyncFunction(data, [localdata = std::move(localdata), fromaddr, destaddr, source, destination, mappedSource, tval, fileDesc, proxyProtocolValues, eventTrace]() mutable { return doProcessUDPQuestion(localdata, fromaddr, destaddr, source, destination, mappedSource, tval, fileDesc, proxyProtocolValues, eventTrace); }); } From b16aa8e4d785babed1b4b45e8165fed9f473a86b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 16:17:49 +0200 Subject: [PATCH 481/909] ixfrdist: Fix the validation of 'max-soa-refresh' --- pdns/ixfrdist.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index 81d7b03cef55..91f7a6519b8d 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -1122,7 +1122,7 @@ static bool parseAndCheckConfig(const string& configpath, YAML::Node& config) { } if (domain["max-soa-refresh"]) { try { - config["max-soa-refresh"].as(); + domain["max-soa-refresh"].as(); } catch (const runtime_error &e) { g_log<()<<"': "< Date: Tue, 1 Aug 2023 16:20:50 +0200 Subject: [PATCH 482/909] ixfrdist: Reduce the complexity of the main function --- pdns/ixfrdist.cc | 235 ++++++++++++++++++++++++++++++----------------- 1 file changed, 151 insertions(+), 84 deletions(-) diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index d4d319927d44..08528e5082a5 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -1179,12 +1179,26 @@ static bool parseAndCheckConfig(const string& configpath, YAML::Node& config) { return retval; } -int main(int argc, char** argv) { - g_log.setLoglevel(Logger::Notice); - g_log.toConsole(Logger::Notice); - g_log.setPrefixed(true); - g_log.disableSyslog(true); - g_log.setTimestamps(false); +struct IXFRDistConfiguration +{ + set listeningSockets; + NetmaskGroup wsACL; + ComboAddress wsAddr; + std::string wsLogLevel{"normal"}; + std::string workDir; + uint32_t axfrMaxRecords{0}; + uint16_t keep{0}; + uint16_t axfrTimeout{0}; + uint16_t failedSOARetry{0}; + uint16_t tcpInThreads{0}; + uid_t uid{0}; + gid_t gid{0}; + bool done{false}; +}; + +static std::optional parseConfiguration(int argc, char** argv, FDMultiplexer& fdm) +{ + IXFRDistConfiguration configuration; po::variables_map g_vm; std::string configPath; @@ -1203,23 +1217,23 @@ int main(int argc, char** argv) { if (g_vm.count("help") > 0) { usage(desc); - return EXIT_SUCCESS; + return configuration; } if (g_vm.count("version") > 0) { cout<<"ixfrdist "<(); } catch (const po::error &e) { g_log< s; s.insert(domain["master"].as()); g_domainConfigs[domain["domain"].as()].masters = s; - if (domain["max-soa-refresh"]) { + if (domain["max-soa-refresh"].IsDefined()) { g_domainConfigs[domain["domain"].as()].maxSOARefresh = domain["max-soa-refresh"].as(); } g_stats.registerDomain(domain["domain"].as()); @@ -1276,20 +1290,13 @@ int main(int argc, char** argv) { g_log<(); if (g_compress) { g_log< allSockets; for (const auto& addr : config["listen"].as>()) { for (const auto& stype : {SOCK_DGRAM, SOCK_STREAM}) { try { @@ -1300,8 +1307,8 @@ int main(int argc, char** argv) { if (stype == SOCK_STREAM) { SListen(s, 30); // TODO make this configurable } - fdm->addReadFD(s, stype == SOCK_DGRAM ? handleUDPRequest : handleTCPRequest); - allSockets.insert(s); + fdm.addReadFD(s, stype == SOCK_DGRAM ? handleUDPRequest : handleTCPRequest); + configuration.listeningSockets.insert(s); } catch (const runtime_error& exp) { g_log<(); - if (!(newgid = atoi(gid.c_str()))) { - struct group *gr = getgrnam(gid.c_str()); + if (config["gid"].IsDefined()) { + auto gid = config["gid"].as(); + try { + configuration.gid = pdns::checked_stoi(gid); + } + catch (const std::exception& e) { + g_log<gr_gid; + configuration.gid = gr->gr_gid; } } - g_log<(); + try { - wsACL.addMask("127.0.0.0/8"); - wsACL.addMask("::1/128"); + configuration.wsACL.addMask("127.0.0.0/8"); + configuration.wsACL.addMask("::1/128"); - if (config["webserver-acl"]) { - wsACL.clear(); + if (config["webserver-acl"].IsDefined()) { + configuration.wsACL.clear(); for (const auto &acl : config["webserver-acl"].as>()) { - wsACL.addMask(acl); + configuration.wsACL.addMask(acl); } } } @@ -1354,95 +1363,153 @@ int main(int argc, char** argv) { had_error = true; } - string loglevel = "normal"; if (config["webserver-loglevel"]) { - loglevel = config["webserver-loglevel"].as(); + configuration.wsLogLevel = config["webserver-loglevel"].as(); } + } - // Launch the webserver! + if (config["uid"].IsDefined()) { + string uid = config["uid"].as(); try { - std::thread(&IXFRDistWebServer::go, IXFRDistWebServer(config["webserver-address"].as(), wsACL, loglevel)).detach(); + configuration.uid = pdns::checked_stoi(uid); } - catch (const std::exception& exp) { - g_log<(); - if (!(newuid = atoi(uid.c_str()))) { - struct passwd *pw = getpwnam(uid.c_str()); + if (configuration.uid != 0) { + //NOLINTNEXTLINE(concurrency-mt-unsafe): only one thread at this point + const struct passwd *pw = getpwnam(uid.c_str()); if (pw == nullptr) { g_log<pw_uid; + configuration.uid = pw->pw_uid; } } + } + + configuration.workDir = config["work-dir"].as(); + configuration.keep = config["keep"].as(); + configuration.axfrTimeout = config["axfr-timeout"].as(); + configuration.failedSOARetry = config["failed-soa-retry"].as(); + configuration.axfrMaxRecords = config["axfr-max-records"].as(); + configuration.tcpInThreads = config["tcp-in-threads"].as(); + + if (had_error) { + return std::nullopt; + } + return configuration; + } + catch (const YAML::Exception& exp) { + had_error = true; + g_log<(FDMultiplexer::getMultiplexerSilent()); + if (!fdm) { + g_log<done) { + return EXIT_SUCCESS; + } + + bool had_error = false; + try { + if (configuration->gid != 0) { + g_log<gid<gid) < 0) { + g_log<gid<<": "<wsAddr, configuration->wsACL, configuration->wsLogLevel)).detach(); + } + catch (const std::exception& exp) { + g_log<uid != 0) { + g_log<uid<uid) < 0) { + g_log<uid<<": "<uid); if (pw == nullptr) { if (setgroups(0, nullptr) < 0) { g_log<pw_name, newgid) < 0) { + if (initgroups(pw->pw_name, configuration->gid) < 0) { g_log<(), - config["keep"].as(), - config["axfr-timeout"].as(), - config["failed-soa-retry"].as(), - config["axfr-max-records"].as()); + configuration->workDir, + configuration->keep, + configuration->axfrTimeout, + configuration->failedSOARetry, + configuration->axfrMaxRecords); vector tcpHandlers; - tcpHandlers.reserve(config["tcp-in-threads"].as()); + tcpHandlers.reserve(configuration->tcpInThreads); for (size_t i = 0; i < tcpHandlers.capacity(); ++i) { tcpHandlers.push_back(std::thread(tcpWorker, i)); } struct timeval now; - for(;;) { + for (;;) { gettimeofday(&now, 0); fdm->run(&now); if (g_exiting) { g_log<listeningSockets) { try { closesocket(fd); - } catch(PDNSException &e) { + } catch (const PDNSException &e) { g_log< Date: Tue, 1 Aug 2023 17:26:04 +0200 Subject: [PATCH 483/909] Add a coding guidelines document to the public repository We have had an internal version of this document for a while now, but there is no reason not to make it available to external contributors as well. --- CODING_GUIDELINES.md | 582 +++++++++++++++++++++++++++++++++++++++++++ CONTRIBUTING.md | 21 +- 2 files changed, 596 insertions(+), 7 deletions(-) create mode 100644 CODING_GUIDELINES.md diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md new file mode 100644 index 000000000000..12f5058023a3 --- /dev/null +++ b/CODING_GUIDELINES.md @@ -0,0 +1,582 @@ +Coding guidelines for contributing to PowerDNS +---------------------------------------------- + +Thank you for you interest to contribute to the PowerDNS project. This document describes the general coding guidelines to keep in mind when contributing code to our code base. It does assume that you have already read the contributing document at [CONTRIBUTING.md](https://github.com/PowerDNS/pdns/blob/master/CONTRIBUTING.md). + +# High-level guidelines + +* Although the codebase does not consistently have them, [docblock](https://www.doxygen.nl/manual/docblocks.html)s on functions and classes are appreciated. +* Never hesitate to write comments on anything that might not be immediately clear just from reading the code. +* When adding whole new things, consider putting them in a `pdns::X` namespace. Look for `namespace pdns` in the codebase for examples. + +# Memory handling + +The memory model in C++, inherited from the C era, is very powerful but also very error-prone. Several features are available in modern (C++11) C++ to make it possible to avoid most of the pitfalls, while conserving the same level of performance. + +Most of the issues related to memory allocation (memory leaks, use-after-free) can be solved by using it via standard containers, or taking advantage of RAII and smart pointers, which take care of destructing the object when it's not used anymore. + +## Stack-based memory allocation + +Default allocations, when declaring a variable local to a function for example, is done on the stack instead of doing a dynamic allocation on the heap. Allocating objects on the stack is faster, especially in threaded programs, and provides the benefit that objects are automatically destroyed when the function is exited. + +One caveat is that the programmer needs to be wary about the size of the object in order not to exceed the space available on the stack, which would corrupt other objects in memory and could lead to a crash, or even execution of arbitrary code. This is especially true in the recursor which uses a custom stack-switching in user-space mechanism and thus has a reduced stack size. + +### Variable-Length Arrays + +In order to avoid smashing the stack, a special care should be taken to limit the depth of function calls that can grow quickly with recursion, for example. A second common source of smash stacking is the use of Variable-Length Arrays, whose size is determined at runtime and is therefore very hard to predict. The C++ language doesn't support VLAs but a lot of compilers inherit such a support from C99, so it's possible to use them by mistake. PowerDNS strictly forbids the use of VLAs, as does the Linux kernel, and enforce that with the `-Werror=vla` compiler flag. + +### C-style arrays + +While you might still find some in the existing code base, we are actively trying to get rid of C-style arrays like this one: + +```C++ +somestruct buffer[12]; +auto bufferSize = sizeof(buffer) / sizeof(*buffer); +auto& firstElement = buffer[0]; +``` + +It is immediately obvious that computing the actual number of elements is error-prone, as `sizeof()` does not return the number of elements but the total memory space used by the array. An other obvious issue is that accesses to the array are not bound-checked. These are not the only drawbacks of these arrays, but are bad enough already to justify getting rid of them. + +The modern C++ way is to use `std::array`s: + +```C++ +std::array buffer; +auto bufferSize = buffer.size(); +auto& firstElement = buffer.at(0); +``` + +### Alloca + +The use of `alloca()` is forbidden in the code base as it is much too easy to smash the stack. + +## RAII + +Resource acquisition is initialization (RAII) is one of the fundamental concept in C++. Resources are allocated during the construction of an object and destroyed when the object is itself destructed. It means that if an object is correctly designed, the resource associated to it can not survive its lifetime. Since objects that are allocated on the stack (local variables in a function, for example) are automatically destroyed when a function is exited, be it by reaching the last line, calling return or throwing an exception, it makes it possible to ensure that resources are always properly destroyed by wrapping them into an object. + +We describe the use of smart pointers, containers and other wrappers to that mean below, but first a few words of caution. Resources stored in a object are only tied to this object if the constructor finished properly. If an exception is raised in the constructor body, the object is not created and therefore the destructor will not get called. This means that if the object has non-object members holding resources, like naked file descriptors or naked pointers, they need to be explicitly released before raising the exception, otherwise they are lost. + +```C++ +class BadFileDescriptionWrapper +{ + BadFileDescriptionWrapper() + { + d_fd = open(...); + if (something) { + throw std::runtime_error(...); + } + ... + } + ~BadFileDescriptionWrapper() + { + if (d_fd > 0) { + close(d_fd); + d_fd = -1; + } + } + int getHandle() const + { + return d_fd; + } +private: + int d_fd{-1}; +}; +``` + +The use of smart pointers can be a solution to most resources leakage, but otherwise the only way is to be careful about exceptions in constructors: + +```C++ +BadFileDescriptionWrapper() +{ + d_fd = open(...); + if (something) { + close(d_fd); + throw std::runtime_error(...); + } + ... +} +``` + +## Smart pointers + +There is almost no good reason not to use a smart pointer when doing dynamic memory allocation. Smart pointers will keep track of whether the dynamically allocated object is still used, and destroy when the last user goes away. + +Using naked pointers quickly results in security issues, going from memory leaks to arbitrary code execution. Examples of such issues can be found in the following PowerDNS security advisories: + +* https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-07.html +* https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-04.html + +Most allocations should be wrapped in a `std::unique_pointer`, using `make_unique`. There can only be one owner at a given time, as opposed to shared pointers, but the ownership can be passed along using `std::move()` if needed. + +If the dynamically allocated object needs to be referenced in several places, the use of a `std::shared_pointer` is advised instead, via `std::make_shared`. + +The use of the `make_*` methods have three advantages: + +* they result in a single allocation for `shared_pointer`s, instead of two otherwise ; +* they avoid duplicating the type name twice ; +* they prevent a possible issue if an exception is raised with temporaries. + +They also make is easier to spot naked pointers by looking for "new" and "delete" throughout the code :) + +Please note however that while unique pointers are as cheap as naked pointers, shared pointers are much more expensive. That's because they need to use atomic operations to update their internal counters, so making a copy of a shared pointer is expensive. Passing one by reference is cheap, however. + +### Shared pointers + +An important thing to be aware of with shared pointers is that taking a new copy of a shared pointer or releasing, thus updating its internal reference counter, is atomic and therefore thread-safe. Altering the content of the object pointed to is not, though, and is subject to the usual locking methods. The often misunderstood part is that updating the target of the shared pointer is not thread-safe. Basically, you can copy the shared pointer from multiple threads at once, and then each thread can assign a new target to its own copy safely, like that: + +```C++ +auto ptr = std::make_shared(4); +for (auto idx = 0; idx < 10 ; idx++){ + std::thread([ptr]{ auto copy = ptr; }).detach(); //ok, only mutates the control block +} +``` + +But there is a race if one thread update the exact same smart pointer that another thread is trying to read: + +```c++ +auto ptr = std::make_shared(4); + +std::thread threadA([&ptr]{ + ptr = std::make_shared(10); +}); +std::thread threadB([&ptr]{ + ptr = std::make_shared(20); +}); +``` + +That unfortunately means that we still need some locking with shared pointers. C++11 defines atomic compare/exchange operations for `std::shared_ptr`, but they are implemented in `libstdc++` by global mutexes and are therefore not lock-free. + +### Wrapping C pointers + +Smart pointers can also be used to wrap C-pointers, such as `FILE*` pointers: + +```c++ +auto fp = std::unique_ptr(fopen(certificateFile.c_str(), "r"), fclose); +``` + +It also works with types from external C libraries, like OpenSSL: + +```c++ +auto cert = std::unique_ptr(PEM_read_X509_AUX(fp.get(), nullptr, nullptr, nullptr), X509_free); +``` + +Unfortunately there are a few cases where smart pointers cannot be used. In the PowerDNS products, these cases have been mostly reduced to a few select classes, like the `pdns::channel` ones, that are used to pass pointers to a different thread by writing them to a pipe, as is done for example by the queries distributors of the auth and the rec. + +When it happens, special care should be taken to: + +* make sure that every exit point frees the allocated memory (early return, goto, exceptions..) ; +* set the pointer to `nullptr` right after the deallocation, so we can't use it again (use-after-free) ; +* do not mix `malloc` with `delete`, `new` with `free` (destructors are not run, at the very least) ; +* do not mix array allocations (`new[]`) with a non-array `delete` (vs `delete[]`). + +## Pointer arithmetic + +It is very common to use pointer arithmetic to calculate a position in a buffer, or to test whether a given offset is outside of a given buffer. Unfortunately it is quite easy to trigger undefined behaviour when doing so, as the C++ standard does not allow pointer arithmetic pointing inside an object, except for arrays where it is also permitted to point one element past the end. Still that undefined behaviour is mostly harmless, but it might lead to real issue on some platforms. + +One such example occurred in dnsdist: https://dnsdist.org/security-advisories/powerdns-advisory-for-dnsdist-2017-01.html + +In that case, a pointer was set to the start of a buffer plus a given length, to see whether the result go past another pointer that was set to the end of the buffer. Unfortunately, if the start of the buffer is at a very high virtual address, the result of the addition might overflow and wrap around, causing the check to become true and leading to either a crash or the reading of unrelated memory. While very unlikely on a 64 bits platform, it could happen on 16 or 32 bits platform. + +This kind of issue is best avoided by the use of container to prevent the need of pointer arithmetic, or by very careful to only add checked offsets to a pointer. + +### Containers + +The use of containers like `vector`, `map` or `set` has several advantages in term of security: + +* memory allocations are handled by the container itself ; +* it prevents a disconnect between the actual size and the variable tracking that size ; +* it provides safe (and fast) operations like comparisons, iterators, etc.. + +One issue that could have been prevented by the use of a container can be found in the following advisory: https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-09.html + +The use of a container and its corresponding `at()` operator would have prevented an out-of-bounds read since calling `at()` on an invalid offset results in an exception being raised. The cost of using `at()` is negligible for most use cases, and can be avoided by using the `[]` operator in the rate case when the cost can't be afforded. Note that several Linux distributions now build with `-Wp,-D_GLIBCXX_ASSERTIONS` enabled by default, which turns on cheap range checks for C++ arrays, vectors, and strings anyway. + +Regarding performance, it is advised to `reserve()` the needed size in advance when a rough estimate is known to avoid reallocations and copies. Resizing in advance is not advised, though, as it makes it harder to know what is exactly in the container in case of early returns or exceptions. + +In C++11, move operations make it possible to cheaply get the content of a container into a different variable if needed. + +The need to pass a subset of a container without copying it often leads to passing a pointer to an array of chars along with a size. Introduced in C++14 but already available in PowerDNS via boost (see views.hh), views provides a nice way to borrow the content of a container to pass it to a function, without any copy or dynamic memory allocation. + +The basic `string_view` class provides that feature for a container of chars, but the same feature exists for other types, like `uint8_t`. + +# Threads and concurrency + +All of our products use threading to be able to take advantage of the increasing number of cores on modern CPUs. That inevitably leads to the question of how to synchronise data accesses between threads. Most objects, like containers, cannot be accessed from more than one thread at once. Even `const` methods on containers might not be thread-safe. For example getting the `size()` of a container might not be thread-safe if a different thread might be writing to the container. Some functions might also not be thread-safe, for example if they have a static non-const variable. + +We currently use three solutions, depending on the use-case. The first one is used when we only need to share some kind of counters or gauges, and involves the use of `std::atomic` which allows atomic operations to be performed from different threads without locking. More on that later. The second one is the "share nothing" approach, where each thread has its own data (using `thread_local`, for example), avoiding the need to data synchronization. When a thread needs to communicate with another one, it might use an pdns::channel to pass a pointer to that second thread. That works quite well but sometimes sharing data is much more efficient than the alternative. + +For these cases, we use the classic locking approach, using either a simple mutex or read-write lock, depending on the use case. + +## locks + +Locks allow a thread of execution to ensure that no other will try to access the code path or data they protect at the same time. + +There are a few pitfalls to avoid then using locks: + +* avoiding to release the lock, which can be avoided by wrappers like `std::lock_guard`, `std::unique_lock` and our own wrappers: look for `LockGuarded`, `SharedLockGuarded` in lock.hh ; +* high contention, where threads are blocked for a long time while waiting to acquire a lock. This can be solved by carefully examining the portion of code that really needs to hold the lock, making the critical path faster, or by using sharding which basically divide the data protected by the lock in several blocks, each one of them protected by its own lock ; +* starvation, which occurs for example when thread 1 acquires lock 1 and wants to acquire lock 2, which is already owned by thread 2, itself currently waiting to acquire lock 1. This can be avoided by a better design of the locking mechanism, and assuring that locks are always acquired in the same order if more than one lock is needed. + +There are more than one type of locks: + +* spinlock are very fast but are busy-waiting, meaning that they don't pause but repetitively try to get hold of the lock, using 100% of one core doing so unless preempted by the OS. So they are only suited for locks that are almost never contented ; +* a mutex is a very simple lock. In most implementations it's a very fast lock, implemented in user-space on recent Linux kernels and glibc ; +* a read-write lock allows several threads to acquire it in read mode, but only one thread can acquire it in write mode. This is suited when most accesses are read-only and writes are rare and don't take too long. Otherwise a mutex might actually be faster ; + +One quick word about condition variables, that allows a thread to notify one or more threads waiting for a condition to happen. A thread should acquire a mutex using a `std::unique_lock` and call the `wait()` method of the condition variable. This is a very useful mechanism but one must be careful about two things: + +* the producer thread can either wake only one thread or all threads waiting on the condition variable. Waking up several threads if only one has something to do (known as a "thundering herd") is bad practice, but there are some cases where it makes sense ; +* a consumer might be waken up spuriously, which can be avoided by passing a predicate (which can be as simple as a small lambda function) to `wait()`. + +Our wrappers, `LockGuarded`, `SharedLockGuarded` in lock.hh, should always be preferred over other solutions. They provide a way to wrap any data structure as protected by a lock (mutex or shared mutex), while making it immediately clear which data is protected by that lock, and preventing any access to the data without holding the lock. + +For example, to protect a set of integers with a simple mutex: + +```c++ +LockGuarded> d_data; +``` + +or with a shared mutex instead: + +```c+++ +SharedLockGuarded> d_data; +``` + +Then the only way to access the data is to call the `lock()`, `read_only_lock()` or `try_lock()` methods for the simple case, or the `read_lock()`, `write_lock()`, `try_read_lock()` or `try_write_lock()` for the shared one. +Doing so will return a "holder" object, which provides access to the protected data, checking that the lock has really been acquired if needed (`try_` cases). The data might be read-only if `read_lock()`, `try_read_lock()` or `read_only_lock()` was called. Access is provided by dereferencing the holder object via `*` or `->`, allowing a quick-access syntax: + +```c+++ +return d_data.lock()->size(); +``` + +Or when the lock needs to be kept for a bit longer: + +```c++ +{ + auto data = d_data.lock(); + data->clear(); + data->insert(42); +} +``` + +## atomic + +`std::atomic` provides a nice way to share a counter or gauge between threads without the need for locking. This is done by implementing operations like reading, increasing, decreasing or writing a value in an atomic way, using memory barriers, making sure that the value can't be updated from a different core during the operation. The default mode uses a sequentially consistent ordering memory model, which is quite expensive since it requires a full memory fence on all multi-core systems. A relaxed model can be used for certain very specific operations, but the default model has the advantage of being safe in all situations. + +## per-thread counters + +For generic per-thread counters, we have a class in tcounters.hh that should provide better performances by allowing each thread to independently update its own counter, the costly operation only happening when the counter needs to be read by one thread gathering metrics from all threads. + +# Dealing with untrusted data + +As a rule of thumb, any data received from outside the process should be considered as untrusted. That means data received on a socket, loaded from a file, retrieved from a database, etc.. Data received from an internal pipe might be excluded from that rule. + +Untrusted data should never be trusted to adhere to the expected format or specifications, and a strict checking of boundaries should be performed. It means for example that, after reading the length for a field inside the data, whether that length does not exceed the total length of the data should be checked. In the same way, if we expect a numerical type we should check whether it matches one we expect and understand. + +Anything unexpected should stop the processing and lead to the discarding of the complete data set. If a smaller data set can be safely discarded, and it is more important to load an incomplete set than to assure the integrity of the complete data set, only the faulty data set can be discarded instead. +alignment issues + +When structured, binary data is received from the network or read from a file, it might be tempting to map it to an existing structure directly to make the parsing easier. But one must be careful about alignment issues on some architectures: + +```c++ +struct my_struct { + uint32_t foo; + uint32_t bar; +}; +``` + +It might be tempting to directly cast the received data: + +```c++ +void func(char* data, size_t offset, size_t length) { + // bounds check left out! + const struct my_struct* tmp = reinterpret_cast(data + offset); + ... +} +``` + +Unfortunately this leads to undefined behaviour because the offset might not be aligned with the alignment requirement of the struct. One solution is to do a copy: + +```c++ +void func(char* data, size_t offset, size_t length) { + // bounds check left out! + struct my_struct tmp; + memcpy(&tmp, data + offset, sizeof(tmp)); + /* ... */ +} +``` + +## unsigned vs signed + +Signed integer might overflow, and the resulting value is unpredictable, as this is an undefined behaviour. That means that this code result in an unpredictable value: + +```c++ +int8_t a = std::numeric_limits::max(); +a++; +``` + +One such example led to https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2006-01.html + +It would be necessary to check that the value can't overflow first. Another possibility would be to instruct the compiler to treat signed overflow as it does for unsigned values, by wrapping. This can be done with `-fwrapv` with g++. + +An operation on an unsigned integer will never result in an overflow, because the value will simply wrap around. This might still result in an unexpected value, possibly bypassing a critical check: + +```c++ +void parse_untrusted_data(uint8_t* data, uint16_t length) +{ + /* parse a record, first two bytes are the size of the record data, second two bytes are the type of the record */ + if (length < 4) { + return; + } + /* read the first two bytes which hold the length of the next record */ + uint16_t recordLen = data[0] * 256 + data[1]; + /* let's assume that recordLen is equal to 65535 */ + uint16_t totalRecordLen = /* size of the type */ sizeof(uint16_t) + recordLen; // <-- this results in a wrapped value of 65535 + 2 = 65537 = 1 + if (totalRecordLen > length) { + return; + } + /* ... */ +} +``` + +A valid version to prevent the overflow: + +```c++ +void parse_untrusted_data(uint8_t* data, uint16_t length) +{ + /* parse a record, first two bytes are the size of the record data, second two bytes are the type of the record */ + if (length < 4) { + return; + } + /* read the first two bytes which hold the length of the next record */ + uint16_t recordLen = data[0] * 256 + data[1]; + if (recordLen > length || (length - recordLen) < sizeof(uint16_t)) { + return; + } + /* ... */ +} +``` + +Converting from unsigned to signed will lose the high order bytes, and should be avoided, or the value should be checked before-hand: + +```c++ +uint64_t u = std::numeric_limits::max(); +int64_t s = static_cast(u); /* Wrong, and the cast eliminates any warning */ +if (u <= std::numeric_limit::max()) { + int64_t s = static_cast(u); /* OK */ +} +``` + +The `pdns::checked_conv()` function can be used, ensuring that the conversion can safely be done and raising an exception otherwise. + +`-Wsign-conversion` can be used to warn about dangerous conversions (disabled by default in g++, and note that a cast disables the warning). + +## fuzzing + +Fuzzing is a very useful way to test a piece of code that parses untrusted data. Efficient fuzzers are often doing coverage-based fuzzing, where the code that they test have been compiled in a special way to allow the fuzzer to detect which branches are executed and which are not, so that the fuzzer can see the effect of mutating specific byte of the input on the code path. + +PowerDNS has a few fuzzing targets that can be used with libFuzzer or AFL in the pdns/ directory, and are built when `--enable-fuzzing-target` is passed to the configure. More information can be found in the [fuzzing/README.md](https://github.com/PowerDNS/pdns/blob/master/fuzzing/README.md) file. +The existing fuzzing targets are run on the OSS-Fuzz infrastructure for a short time every time a pull request is opened, and for a longer time on the HEAD of the repository. + +# Others potential issues + +## TOCTOU + +The time-of-check time-of-use vulnerability is a very easy mistake to make when dealing with files or directory. The gist of it is that there is a small race condition between the time where a program might check the ownership, permissions or even existence of a file and the time it will actually do something with it. This time might be enough to allow an attacker to create a symbolic link to a critical file at the place of that exact file, for example. Since the program has enough rights to edit this file, this might allow an attacker to trick the program into writing into a completely different file. + +This is hard to avoid in all cases, but some mitigations do help: + +* opening a file first (handling errors if that fails) then getting the needed metadata via the file descriptor instead of the path (`fstat`, `fchmod`, `fchown`) ; +* opening with the `O_NOFOLLOW` flag set, so that the operation will fail if the target exists and is a symbolic link ; +* always creating temporary files via the `mkstemp()` function, which guarantees that the file did not exist before and has been created with the right permissions ; +* using operations that are guaranteed to be atomic, like renaming a file on the same filesystem (for example in the same directory). + +## Secrets + +Try very hard not to load sensitive information in memory. And of course don't write to disk! + +If you have to: + +* use an object that can't be copied by deleting the copy constructors and assignments operators, +* try to lock the memory so it can't be swapped out to disk, or included in a core dump, via `sodium_malloc()` or `sodium_mlock()`, for example ; +* wipe the content before releasing the memory, so it won't linger around. Be careful that memset() is very often optimized out by the compiler, so function like `sodium_munlock()`, `explicit_bzero()` or `explicit_memset()` should be used instead. + +### Constant-time comparison + +Don't compare secret against data using a naive string comparison, as the timing of the operation will leak information against the content of the secret. Ideally, a constant-time comparison should be used instead (see `constantTimeStringEquals()` in the PowerDNS code base) but it's not easy to achieve. One option might be to compute a HMAC of the secret using a key randomly generated at startup, and compare it against a HMAC of the supplied data computed with the same key. + +## Virtual destructors + +Any class that is expected to be sub-classed should provide a virtual destructor. Not doing so will prevent the destructor of a derived class from being called if the object is held as the base type: + +```c++ +class Parent +{ + virtual void doVirtualCall(); +}; + +class Child: public Parent +{ + Child() + { + d_fd = fopen(..); + } + ~Child() + { + if (d_fd) { + fclose(d_fd); + f_fd = nullptr; + } + } + void doVirtualCall() override; +}; + +std::vector myObjects; +myObjects.push_back(Child()); +``` + +Be careful that defining a destructor will prevent the automatic creation of move operations for that class, since they are generated only if these conditions are met: + +* no copy operations are declared ; +* no move operations are declared ; +* no destructor is declared. + +If the Parent class holds data that is costly to copy, it might make sense to declare the move operations explicitly: + +```c++ +class Parent +{ + Parent(Parent&&) = default; + Parent& operator=(Parent&&) = default; + + virtual ~Parent() + { + } + + virtual void doVirtualCall(); +private: + FILE* d_fd{nullptr}; +}; +``` + +Note that declaring the move operations disables the copy operations, so if they are still needed: + +```c++ +class Parent +{ + Parent(Parent&&) = default; + Parent& operator=(Parent&&) = default; + + Parent(const Parent&) = default; + Parent& operator=(const Parent&) = default; + + virtual ~Parent() + { + } + + virtual void doVirtualCall(); +}; +``` + +On a related topic, virtual methods should not be called from constructors or destructors. While this is allowed under certain restrictions, it's very hard to know exactly which method (base or derived) will be called, and whether all sub-objects contained in the class would have been correctly constructed at that point. + +## Hash collisions + +Hashes are a very useful tool, used in `unordered_map` and `unordered_set` among others. They are also used in our caches. An important caveat that developers need to be aware about regarding hashes are that the probability of a collision is often a lot higher than expected. This is well-known as the birthday paradox, the fact that the probability of having to entries colliding is a lot higher than the probability of finding a collision for a specific entry. This means that it is important to verify that the entries are actually identical, and just not that they hash to the same value. + +This is especially important when hashing attacker-controlled values, as they can be specially crafted to trigger collisions to cause: + +* cache pollution (see https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-06.html) ; +* denial of service via hash table flooding (in a map, all entries that hash to the same value are often placed into a linked-list, making it possible to cause a linear scanning of entries by making all of them hash to the value). + +The first issue can be prevented by comparing the entries and not just the value they hash to. The second one can be used by using some sort of secret when computing the hash so that the result cannot be guessed by the attacker. That can be achieved by using an unpredictable seed for certain hash algorithms, or a secret for some other like `SipHash`. + +# Readability tips + +Some of these tips are actually enforced by `clang-tidy` nowadays, but it is still useful to keep them in mind. + +## Auto + +C++11 introduced automatic type deduction, using the auto keyword. In addition to saving the typing of a few more letters, using automatic type deduction prevents nasty surprises if the variable is initialized from another one, or from a function, and the other type is changed to a different one. The code might still compile while now involving a copy or worse. +Boolean expressions + +## Explicit comparisons + +* compare numerical values to `0` or `!= 0` explicitly ; +* compare to `false` explicitly, which is easier to read ; +* compare to `nullptr` for the same reason. + +## Initialization + +Use braced initialization for members as often as possible: + +* it does forbid narrowing conversions +* and avoids C++'s "move vexing parse" which is to declare a function instead of calling the default constructor: + +```c++ +Object a(); // declares a function named a that returns an object +``` + +## nullptr + +When representing a pointer, using `nullptr` makes it immediately obvious that we are dealing with a pointer, as opposed to the use of `0`. It also can't be silently taken as an integer, which can happens with `0` but also with `NULL`. + +## const-ness + +* Mark parameters and variables that should not be modified as `const`. This is especially true for references and pointers that comes from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later. +* Mark const methods as such (and make them thread-safe) +* Prefer using `at()` on containers so that no insertion can take place by mistake, and to get bounds checking. + +## static + +Functions that are only used inside a single file should be marked as `static`, so that: + +* the compiler knows that these functions will not be called from a different compilation unit and thus that no symbol needs to be generated, making it more likely for the function to be inlined ; +* the reader knows that this function is only used there and can be altered without causing an issue somewhere else. + +For the same reason, global variables that are only accessed from a single file should be marked static as well. + +## Variables + +Try to declare variables in the innermost scope possible and avoid uninitialized variables as much as possible. Declare and initialize them when the values needed to initialize them are available. + +## Exceptions + +Should be reserved to unexpected events (corrupted data, timeouts, ...) and should not be triggered in normal processing. + +Don't be afraid of using them, though, as the cost of an exception that is not thrown is usually very small, thanks to the zero-cost exception model. It might still force the compiler to refrain from some optimizations, so it might make sense to avoid them in some very performance-sensitive, narrow code paths. + +### Custom exceptions + +Exceptions defined by the standards should be used whenever possible, as they already cover a lot of use cases. + +If custom exceptions are necessary, to be able to catch them explicitly, they should still derive from `std::exception`, directly or indirectly, so that they can still be caught in a more generic way to prevent the program from terminating. For example, the main connection handling function of a server can catch `std::exception` and just terminate the current connection if an uncaught exception bubbles up. + +### Catching exceptions + +Catching exceptions should always be done by const reference: + +```c+++ +try { +} +catch (const std::exception& e) { + std::cerr << e.what() < Date: Tue, 1 Aug 2023 17:50:57 +0200 Subject: [PATCH 484/909] ixfrdist: Delint ixfrdist.cc a bit more --- pdns/ixfrdist.cc | 55 ++++++++++++++++++++++++++++++------------------ 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index 08528e5082a5..bab91205399e 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -1369,7 +1369,7 @@ static std::optional parseConfiguration(int argc, char** } if (config["uid"].IsDefined()) { - string uid = config["uid"].as(); + auto uid = config["uid"].as(); try { configuration.uid = pdns::checked_stoi(uid); } @@ -1409,30 +1409,38 @@ static std::optional parseConfiguration(int argc, char** } int main(int argc, char** argv) { - g_log.setLoglevel(Logger::Notice); - g_log.toConsole(Logger::Notice); - g_log.setPrefixed(true); - g_log.disableSyslog(true); - g_log.setTimestamps(false); + bool had_error = false; + std::optional configuration{std::nullopt}; + std::unique_ptr fdm{nullptr}; - auto fdm = std::unique_ptr(FDMultiplexer::getMultiplexerSilent()); - if (!fdm) { - g_log<(FDMultiplexer::getMultiplexerSilent()); + if (!fdm) { + g_log<done) { + return EXIT_SUCCESS; + } } - - if (configuration->done) { - return EXIT_SUCCESS; + catch (const YAML::Exception& exp) { + had_error = true; + g_log<gid != 0) { g_log<gid< Date: Mon, 31 Jul 2023 12:53:34 +0200 Subject: [PATCH 485/909] remove unused sysv init files - we don't ship them, and non-systemd downstream packages all have their own --- .github/actions/spell-check/allow.txt | 1 - builder-support/specs/pdns.init | 213 ------------------------- configure.ac | 1 - pdns/.gitignore | 1 - pdns/Makefile.am | 1 - pdns/pdns.init.in | 206 ------------------------ pdns/recursordist/pdns-recursor.init.d | 107 ------------- 7 files changed, 530 deletions(-) delete mode 100644 builder-support/specs/pdns.init delete mode 100755 pdns/pdns.init.in delete mode 100755 pdns/recursordist/pdns-recursor.init.d diff --git a/.github/actions/spell-check/allow.txt b/.github/actions/spell-check/allow.txt index cc0e68a3b3d8..73351a6e1701 100644 --- a/.github/actions/spell-check/allow.txt +++ b/.github/actions/spell-check/allow.txt @@ -427,7 +427,6 @@ checkrr checkzone chgrp childstat -chkconfig chmod chown chr diff --git a/builder-support/specs/pdns.init b/builder-support/specs/pdns.init deleted file mode 100644 index 7fd9b49296e4..000000000000 --- a/builder-support/specs/pdns.init +++ /dev/null @@ -1,213 +0,0 @@ - -# chkconfig: - 80 75 -# description: PDNS is a versatile high performance authoritative nameserver - -### BEGIN INIT INFO -# Provides: pdns -# Required-Start: $remote_fs $network $syslog -# Required-Stop: $remote_fs $network $syslog -# Should-Start: -# Should-Stop: -# Default-Start: -# Default-Stop: 0 1 6 -# Short-Description: PowerDNS authoritative server -# Description: PowerDNS authoritative server -### END INIT INFO - -set -e - -prefix=/usr -exec_prefix=/usr -BINARYPATH=/usr/bin -SBINARYPATH=/usr/sbin -SOCKETPATH=/var/run/pdns - -[ -f "$SBINARYPATH/pdns_server" ] || exit 0 - -[ -r /etc/default/pdns ] && . /etc/default/pdns - -mkdir -p $SOCKETPATH -cd $SOCKETPATH -suffix=$(basename $0 | cut -d- -f2- -s) -if [ -n "$suffix" ] -then - EXTRAOPTS=--config-name=$suffix - PROGNAME=pdns-$suffix -else - PROGNAME=pdns -fi - -pdns_server="$SBINARYPATH/pdns_server $EXTRAOPTS" - -doPC() -{ - ret=$($BINARYPATH/pdns_control $EXTRAOPTS $1 $2 2> /dev/null) -} - -NOTRUNNING=0 -doPC ping || NOTRUNNING=$? - -case "$1" in - status) - if test "$NOTRUNNING" = "0" - then - doPC status - echo $ret - else - echo "not running" - exit 3 - fi - ;; - - stop) - echo -n "Stopping PowerDNS authoritative nameserver: " - if test "$NOTRUNNING" = "0" - then - doPC quit - rm -f /var/lock/subsys/pdns - echo $ret - else - echo "not running" - fi - ;; - - - force-stop) - echo -n "Stopping PowerDNS authoritative nameserver: " - killall -v -9 pdns_server - rm -f /var/lock/subsys/pdns - echo "killed" - ;; - - start) - echo -n "Starting PowerDNS authoritative nameserver: " - if test "$NOTRUNNING" = "0" - then - echo "already running" - else - if $pdns_server --daemon --guardian=yes - then - touch /var/lock/subsys/pdns - echo "started" - else - echo "starting failed" - exit 1 - fi - fi - ;; - - condrestart) - if [ -f /var/lock/subsys/pdns ]; - then - echo "running, restarting" - $0 restart - else - echo "not running" - fi - ;; - - force-reload | restart) - echo -n "Restarting PowerDNS authoritative nameserver: " - if test "$NOTRUNNING" = "1" - then - echo "not running, starting" - else - - echo -n stopping and waiting.. - doPC quit - sleep 3 - echo done - fi - $0 start - ;; - - reload) - echo -n "Reloading PowerDNS authoritative nameserver: " - if test "$NOTRUNNING" = "0" - then - doPC cycle - echo requested reload - else - echo not running yet - $0 start - fi - ;; - - monitor) - if test "$NOTRUNNING" = "0" - then - echo "already running" - else - $pdns_server --daemon=no --guardian=no --control-console --loglevel=9 - fi - ;; - - dump) - if test "$NOTRUNNING" = "0" - then - doPC list - echo $ret - else - echo "not running" - fi - ;; - - show) - if [ $# -lt 2 ] - then - echo Insufficient parameters - exit - fi - if test "$NOTRUNNING" = "0" - then - echo -n "$2=" - doPC show $2 ; echo $ret - else - echo "not running" - fi - ;; - - mrtg) - if [ $# -lt 2 ] - then - echo Insufficient parameters - exit - fi - if test "$NOTRUNNING" = "0" - then - doPC show $2 ; echo $ret - if [ "$3x" != "x" ] - then - doPC show $3 ; echo $ret - else - echo 0 - fi - doPC uptime ; echo $ret - echo PowerDNS daemon - else - echo "not running" - fi - - ;; - - cricket) - if [ $# -lt 2 ] - then - echo Insufficient parameters - exit - fi - if test "$NOTRUNNING" = "0" - then - doPC show $2 ; echo $ret - else - echo "not running" - fi - - ;; - - *) - echo pdns [start|stop|condrestart|force-reload|reload|restart|status|dump|show|mrtg|cricket|monitor] - - ;; -esac - diff --git a/configure.ac b/configure.ac index d6ad04a3c527..66480b71aa39 100644 --- a/configure.ac +++ b/configure.ac @@ -346,7 +346,6 @@ AC_CONFIG_FILES([ pdns/Makefile codedocs/Makefile docs/Makefile - pdns/pdns.init ext/Makefile ext/arc4random/Makefile ext/ipcrypt/Makefile diff --git a/pdns/.gitignore b/pdns/.gitignore index 98d5c5cf5554..b7e90bd0cc1d 100644 --- a/pdns/.gitignore +++ b/pdns/.gitignore @@ -4,7 +4,6 @@ /comfun /config.h /mkbindist -/pdns.init /showvar /stamp-h /pdns_control diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 5d188b1ce061..a1ba58ec5030 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -115,7 +115,6 @@ endif apidocfiles.h: api-swagger.yaml api-swagger.json ./incfiles $^ > $@ -noinst_SCRIPTS = pdns.init sysconf_DATA = pdns.conf-dist sbin_PROGRAMS = pdns_server diff --git a/pdns/pdns.init.in b/pdns/pdns.init.in deleted file mode 100755 index 7aba99be05dc..000000000000 --- a/pdns/pdns.init.in +++ /dev/null @@ -1,206 +0,0 @@ -#!/bin/sh -# chkconfig: - 80 75 -# description: PDNS is a versatile high performance authoritative nameserver - -### BEGIN INIT INFO -# Provides: pdns -# Required-Start: $remote_fs $network $syslog -# Required-Stop: $remote_fs $network $syslog -# Should-Start: -# Should-Stop: -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: PowerDNS authoritative server -# Description: PowerDNS authoritative server -### END INIT INFO - -set -e - -exec_prefix=@exec_prefix@ -BINARYPATH=@bindir@ -SBINARYPATH=@sbindir@ -SOCKETPATH=@socketdir@/pdns -DAEMON_ARGS="" - -[ -f "$SBINARYPATH/pdns_server" ] || exit 0 - -[ -r /etc/default/pdns ] && . /etc/default/pdns - -[ "$START" = "no" ] && exit 0 - -# Make sure that /var/run exists -mkdir -p $SOCKETPATH -cd $SOCKETPATH -suffix=$(basename $0 | cut -d- -f2- -s) -if [ -n "$suffix" ] -then - EXTRAOPTS=--config-name=$suffix - PROGNAME=pdns-$suffix -else - PROGNAME=pdns -fi - -pdns_server="$SBINARYPATH/pdns_server $DAEMON_ARGS $EXTRAOPTS" - -doPC() -{ - ret=$($BINARYPATH/pdns_control $EXTRAOPTS $1 $2 2> /dev/null) -} - -NOTRUNNING=0 -doPC ping || NOTRUNNING=$? - -case "$1" in - status) - if test "$NOTRUNNING" = "0" - then - doPC status - echo $ret - else - echo "not running" - exit 3 - fi - ;; - - stop) - echo -n "Stopping PowerDNS authoritative nameserver: " - if test "$NOTRUNNING" = "0" - then - doPC quit - echo $ret - else - echo "not running" - fi - ;; - - - force-stop) - echo -n "Stopping PowerDNS authoritative nameserver: " - killall -v -9 pdns_server - echo "killed" - ;; - - start) - echo -n "Starting PowerDNS authoritative nameserver: " - if test "$NOTRUNNING" = "0" - then - echo "already running" - else - if $pdns_server --daemon --guardian=yes - then - echo "started" - else - echo "starting failed" - exit 1 - fi - fi - ;; - - force-reload | restart) - echo -n "Restarting PowerDNS authoritative nameserver: " - if test "$NOTRUNNING" = "1" - then - echo "not running, starting" - else - - echo -n stopping and waiting.. - doPC quit - sleep 3 - echo done - fi - $0 start - ;; - - reload) - echo -n "Reloading PowerDNS authoritative nameserver: " - if test "$NOTRUNNING" = "0" - then - doPC cycle - echo requested reload - else - echo not running yet - $0 start - fi - ;; - - monitor) - if test "$NOTRUNNING" = "0" - then - echo "already running" - else - $pdns_server --daemon=no --guardian=no --control-console --loglevel=9 - fi - ;; - - dump) - if test "$NOTRUNNING" = "0" - then - doPC list - echo $ret - else - echo "not running" - fi - ;; - - show) - if [ $# -lt 2 ] - then - echo Insufficient parameters - exit - fi - if test "$NOTRUNNING" = "0" - then - echo -n "$2=" - doPC show $2 ; echo $ret - else - echo "not running" - fi - ;; - - mrtg) - if [ $# -lt 2 ] - then - echo Insufficient parameters - exit - fi - if test "$NOTRUNNING" = "0" - then - doPC show $2 ; echo $ret - if [ "$3x" != "x" ] - then - doPC show $3 ; echo $ret - else - echo 0 - fi - doPC uptime ; echo $ret - echo PowerDNS daemon - else - echo "not running" - fi - - ;; - - cricket) - if [ $# -lt 2 ] - then - echo Insufficient parameters - exit - fi - if test "$NOTRUNNING" = "0" - then - doPC show $2 ; echo $ret - else - echo "not running" - fi - - ;; - - - - *) - echo pdns [start\|stop\|force-reload\|reload\|restart\|status\|dump\|show\|mrtg\|cricket\|monitor] - - ;; -esac - - diff --git a/pdns/recursordist/pdns-recursor.init.d b/pdns/recursordist/pdns-recursor.init.d deleted file mode 100755 index 538e58f1e3b6..000000000000 --- a/pdns/recursordist/pdns-recursor.init.d +++ /dev/null @@ -1,107 +0,0 @@ -#!/bin/sh -### BEGIN INIT INFO -# Provides: pdns-recursor -# Required-Start: $network $remote_fs $syslog -# Required-Stop: $network $remote_fs $syslog -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: PowerDNS Recursor -### END INIT INFO -# chkconfig: - 80 75 -# description: pdns_recursor is a versatile high performance recursing nameserver - -BINARYPATH=/usr/bin -SBINARYPATH=/usr/sbin -SOCKETPATH=/var/run - -pdns_server=$SBINARYPATH/pdns_recursor - -[ -f "$pdns_server" ] || exit 0 - -[ -r /etc/default/pdns-recursor ] && . /etc/default/pdns-recursor - -[ "$START" = "no" ] && exit 0 - -doPC() -{ - ret=`$BINARYPATH/rec_control $EXTRAOPTS $1 $2 2> /dev/null` -} - - -doPC ping -NOTRUNNING=$? - -case "$1" in - status) - if test "$NOTRUNNING" = "0" - then - echo "running" - exit 0 - else - echo "not running" - # Note: 3 is a white lie. We currently don't *really* - # know that it's not running, or if the ping failed for - # other reasons (= 4). - exit 3 - fi - ;; - - stop) - echo -n "Stopping PowerDNS recursing nameserver: " - if test "$NOTRUNNING" = "0" - then - doPC quit - echo $ret - else - echo "not running" - exit 1 - fi - ;; - - - force-stop) - echo -n "Stopping PowerDNS recursing nameserver: " - killall -v -9 $pdns_server - echo "killed" - ;; - - start) - echo -n "Starting PowerDNS recursing nameserver: " - if test "$NOTRUNNING" = "0" - then - echo "already running" - exit 1 - else - $pdns_server --daemon - if test "$?" = "0" - then - echo "started" - fi - fi - ;; - - force-reload | restart) - echo -n "Restarting PowerDNS recursing nameserver: " - echo -n stopping and waiting.. - doPC quit - sleep 3 - echo done - $0 start - ;; - - monitor) - if test "$NOTRUNNING" = "0" - then - echo "already running" - else - $pdns_server --daemon=no --quiet=no --loglevel=9 - fi - ;; - - *) - echo pdns [start\|stop\|force-reload\|restart\|status\|monitor] - - ;; -esac - - From e0e59b3868b4caf7a2e4f93e6d8a802b8d83eccd Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 2 Aug 2023 14:35:32 +0200 Subject: [PATCH 486/909] auth lmdb: when broadcasting indexes, -do- rewrite them even if they are unchanged --- ext/lmdb-safe/lmdb-typed.hh | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index 3fcdcc74127b..790fead2910b 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -164,10 +164,8 @@ struct LMDBIndexOps MDBOutVal currentvalue; - // check if the entry already exists, so we don't uselessly bump the timestamp - if (txn->get(d_idx, combined, currentvalue) == MDB_NOTFOUND) { - txn->put(d_idx, combined, empty, flags); - } + // if the entry existed already, this will just update the timestamp/txid in the LS header. This is intentional, so objects and their indexes always get synced together. + txn->put(d_idx, combined, empty, flags); } void del(MDBRWTransaction& txn, const Class& t, uint32_t id) From f2b1a9bcf9020e5be162d66b046c6889269ea16d Mon Sep 17 00:00:00 2001 From: Alexis Romero Date: Thu, 3 Aug 2023 10:10:46 +0200 Subject: [PATCH 487/909] GH actions. build-packages.yml: adding a hash verification for all targets --- .github/workflows/build-packages.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index 63fe7e1256b4..12bedec6cb98 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -136,6 +136,18 @@ jobs: echo "$HOSTKEY" > ~/.ssh/known_hosts rsync -4rlptD built_pkgs/* "$RSYNCTARGET" + check-hashes: + needs: build + name: Check if hashes were created for all requested targets + runs-on: ubuntu-20.04 + steps: + - name: Get list of outputs from build jobs + run: echo '${{ toJSON(needs.build.outputs) }}' | jq 'keys[]' | grep -v version | tee /tmp/build-outputs.txt + - name: Get list of OS inputs + run: for i in ${{ inputs.os }}; do echo "\"pkghashes-$i\""; done | sort | tee /tmp/os-inputs.txt; echo "\"srchashes\"" | tee -a /tmp/os-inputs.txt + - name: Fail if there is a hash missing + run: if ! diff -q /tmp/build-outputs.txt /tmp/os-inputs.txt; then exit 1; fi + provenance-pkgs: needs: [prepare, build] name: Generate provenance for ${{ inputs.product }} (${{ inputs.ref }}) for ${{ matrix.os }} From 651f8995b30d0bba6a25ffce756a2c59bf7ba0b4 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 3 Aug 2023 11:12:11 +0200 Subject: [PATCH 488/909] Expand the note on max-recursion-depth --- pdns/recursordist/docs/upgrade.rst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pdns/recursordist/docs/upgrade.rst b/pdns/recursordist/docs/upgrade.rst index 5f433dd30871..8d3f19be7f01 100644 --- a/pdns/recursordist/docs/upgrade.rst +++ b/pdns/recursordist/docs/upgrade.rst @@ -37,6 +37,8 @@ See :doc:`performance`, in particular the :ref:`worker_imbalance` section. - The :ref:`setting-reuseport` default has been changed to ``yes``. - The :ref:`setting-packetcache-ttl` default has been changed to 24 hours. - The :ref:`setting-max-recursion-depth` default has been changed to 16. Before it was, 40, but effectively the CNAME length chain limit (fixed at 16) took precedence. + If you increase :ref:`setting-max-recursion-depth`, you also have to increase :ref:`setting-stack-size`. + A starting point of 5k per recursion depth is suggested. Add some extra safety margin to avoid running out of stack. - The :ref:`setting-hint-file` setting gained a new special value to disable refreshing of root hints completely. See :ref:`handling-of-root-hints`. :program:`rec_control` From fa5f61e94e1bd354d42923a844c59b3be232c29f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 4 Aug 2023 13:07:59 +0200 Subject: [PATCH 489/909] rec: Do not assume the records are in a particular order when determining if an answer is NODATA. --- pdns/recursordist/pdns_recursor.cc | 22 ++-------------- pdns/recursordist/syncres.cc | 23 +++++++++++++++++ pdns/recursordist/syncres.hh | 2 ++ pdns/recursordist/test-syncres_cc10.cc | 35 ++++++++++++++++++++++++++ 4 files changed, 62 insertions(+), 20 deletions(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 6087df604ffd..097e7ca32968 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -786,30 +786,12 @@ int getFakePTRRecords(const DNSName& qname, vector& ret) return rcode; } -static bool answerIsNOData(uint16_t requestedType, int rcode, const std::vector& records) -{ - if (rcode != RCode::NoError) { - return false; - } - for (const auto& rec : records) { - if (rec.d_place != DNSResourceRecord::ANSWER) { - /* no records in the answer section */ - return true; - } - if (rec.d_type == requestedType) { - /* we have a record, of the right type, in the right section */ - return false; - } - } - return true; -} - // RFC 6147 section 5.1 all rcodes except NXDomain should be candidate for dns64 // for NoError, check if it is NoData static bool dns64Candidate(uint16_t requestedType, int rcode, const std::vector& records) { if (rcode == RCode::NoError) { - return answerIsNOData(requestedType, rcode, records); + return SyncRes::answerIsNOData(requestedType, rcode, records); } return rcode != RCode::NXDomain; } @@ -1310,7 +1292,7 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi bool luaHookHandled = false; if (comboWriter->d_luaContext) { PolicyResult policyResult = PolicyResult::NoAction; - if (answerIsNOData(comboWriter->d_mdp.d_qtype, res, ret)) { + if (SyncRes::answerIsNOData(comboWriter->d_mdp.d_qtype, res, ret)) { if (comboWriter->d_luaContext->nodata(dnsQuestion, res, resolver.d_eventTrace)) { luaHookHandled = true; shouldNotValidate = true; diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 5f415b8beebe..e0447a52cffe 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -5953,3 +5953,26 @@ int SyncRes::getRootNS(struct timeval now, asyncresolve_t asyncCallback, unsigne } return res; } + +bool SyncRes::answerIsNOData(uint16_t requestedType, int rcode, const std::vector& records) +{ + if (rcode != RCode::NoError) { + return false; + } + + // NOLINTNEXTLINE(readability-use-anyofallof) + for (const auto& rec : records) { + if (rec.d_place == DNSResourceRecord::ANSWER && rec.d_type == requestedType) { + /* we have a record, of the right type, in the right section */ + return false; + } + } + return true; +#if 0 + // This code should be equivalent to the code above, clang-tidy prefers any_of() + // I have doubts if that is easier to read + return !std::any_of(records.begin(), records.end(), [=](const DNSRecord& rec) { + return rec.d_place == DNSResourceRecord::ANSWER && rec.d_type == requestedType; + }); +#endif +} diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index c4a8bace6a93..d946577ab06a 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -498,6 +498,8 @@ public: return false; } + static bool answerIsNOData(uint16_t requestedType, int rcode, const std::vector& records); + static thread_local ThreadLocalStorage t_sstorage; static pdns::stat_t s_ecsqueries; diff --git a/pdns/recursordist/test-syncres_cc10.cc b/pdns/recursordist/test-syncres_cc10.cc index 4353d843fc44..474c8cf8f458 100644 --- a/pdns/recursordist/test-syncres_cc10.cc +++ b/pdns/recursordist/test-syncres_cc10.cc @@ -1958,4 +1958,39 @@ BOOST_AUTO_TEST_CASE(test_locked_nonauth_update_to_auth) BOOST_CHECK_GT(secondTTL, 0); } +BOOST_AUTO_TEST_CASE(test_nodata_ok) +{ + vector vec; + vec.emplace_back("nz.compass.com", nullptr, QType::CNAME, QClass::IN, 60, 0, DNSResourceRecord::ANSWER); + vec.emplace_back("nz.compass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::ANSWER); + vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::NSEC3, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY); + vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY); + + BOOST_CHECK(SyncRes::answerIsNOData(QType::A, RCode::NoError, vec)); +} + +BOOST_AUTO_TEST_CASE(test_nodata_not) +{ + vector vec; + vec.emplace_back("kc-pro.westeurope.cloudapp.azure.com", nullptr, QType::A, QClass::IN, 60, 0, DNSResourceRecord::ANSWER); + vec.emplace_back("nz.compass.com", nullptr, QType::CNAME, QClass::IN, 60, 0, DNSResourceRecord::ANSWER); + vec.emplace_back("nz.compass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::ANSWER); + vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::NSEC3, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY); + vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY); + + BOOST_CHECK(!SyncRes::answerIsNOData(QType::A, RCode::NoError, vec)); +} + +BOOST_AUTO_TEST_CASE(test_nodata_out_of_order) +{ + vector vec; + vec.emplace_back("nz.compass.com", nullptr, QType::CNAME, QClass::IN, 60, 0, DNSResourceRecord::ANSWER); + vec.emplace_back("nz.compass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::ANSWER); + vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::NSEC3, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY); + vec.emplace_back("kslicmitv6qe1behk70g8q7e572vabp0.kompass.com", nullptr, QType::RRSIG, QClass::IN, 60, 0, DNSResourceRecord::AUTHORITY); + vec.emplace_back("kc-pro.westeurope.cloudapp.azure.com", nullptr, QType::A, QClass::IN, 60, 0, DNSResourceRecord::ANSWER); + + BOOST_CHECK(!SyncRes::answerIsNOData(QType::A, RCode::NoError, vec)); +} + BOOST_AUTO_TEST_SUITE_END() From 8fb5bba04f7a211ac2eb815f5c340e69070dc3e0 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 7 Aug 2023 19:13:11 +0200 Subject: [PATCH 490/909] typo fix --- pdns/ixfr.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/ixfr.cc b/pdns/ixfr.cc index 9615d7c6b321..fb09e3503722 100644 --- a/pdns/ixfr.cc +++ b/pdns/ixfr.cc @@ -295,7 +295,7 @@ vector, vector>> getIXFRDeltas(const ComboAddr if(r.first.d_type == QType::OPT) continue; - throw std::runtime_error("Unexpected record (" +QType(r.first.d_type).toString()+") in non-answer section ("+std::to_string(r.first.d_place)+")in IXFR response for zone '"+zone.toLogString()+"' from primary '"+primary.toStringWithPort()); + throw std::runtime_error("Unexpected record (" +QType(r.first.d_type).toString()+") in non-answer section ("+std::to_string(r.first.d_place)+") in IXFR response for zone '"+zone.toLogString()+"' from primary '"+primary.toStringWithPort()); } r.first.d_name.makeUsRelative(zone); From 93b25e9613f252bc1798975dc1f7a475400f2996 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 8 Aug 2023 12:15:00 +0200 Subject: [PATCH 491/909] rec: replace data in the aggressive cache if it becomes available Currently, new data does not get recorded into the aggressive cache if there's an existing entry that matches. Together with the fact that in some cases pruning can be unfair (it scans the zones always in the same order and stops clearing when it has reached the goal) and/or not very active (when the recursor is lighlty loaded) this has the consequence that old expired records can remain in the cache that prevent new data to be recorded and used. --- pdns/recursordist/aggressive_nsec.cc | 10 +++++-- pdns/recursordist/test-aggressive_nsec_cc.cc | 30 ++++++++++++++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/aggressive_nsec.cc b/pdns/recursordist/aggressive_nsec.cc index 96c1c20359f3..e17bf2dd3aad 100644 --- a/pdns/recursordist/aggressive_nsec.cc +++ b/pdns/recursordist/aggressive_nsec.cc @@ -344,16 +344,22 @@ void AggressiveNSECCache::insertNSEC(const DNSName& zone, const DNSName& owner, /* the TTL is already a TTD by now */ if (!nsec3 && isWildcardExpanded(owner.countLabels(), *signatures.at(0))) { DNSName realOwner = getNSECOwnerName(owner, signatures); - auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, std::move(realOwner), std::move(next), record.d_ttl}); + auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, realOwner, next, record.d_ttl}); if (pair.second) { ++d_entriesCount; } + else { + zoneEntry->d_entries.replace(pair.first, {record.getContent(), signatures, realOwner, next, record.d_ttl}); + } } else { - auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, owner, std::move(next), record.d_ttl}); + auto pair = zoneEntry->d_entries.insert({record.getContent(), signatures, owner, next, record.d_ttl}); if (pair.second) { ++d_entriesCount; } + else { + zoneEntry->d_entries.replace(pair.first, {record.getContent(), signatures, owner, next, record.d_ttl}); + } } } } diff --git a/pdns/recursordist/test-aggressive_nsec_cc.cc b/pdns/recursordist/test-aggressive_nsec_cc.cc index f5424e608a76..1596ba333212 100644 --- a/pdns/recursordist/test-aggressive_nsec_cc.cc +++ b/pdns/recursordist/test-aggressive_nsec_cc.cc @@ -1234,6 +1234,36 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_dump) BOOST_CHECK_EQUAL(line, str); } + expected.clear(); + expected.push_back("; Zone powerdns.com.\n"); + expected.push_back("www.powerdns.com. 10 IN NSEC z.powerdns.com. A RRSIG NSEC\n"); + expected.push_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); + expected.push_back("z.powerdns.com. 30 IN NSEC zz.powerdns.com. AAAA RRSIG NSEC\n"); + expected.push_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); + expected.push_back("; Zone powerdns.org.\n"); + expected.push_back("www.powerdns.org. 10 IN NSEC3 1 0 50 ab HASG==== A RRSIG NSEC3\n"); + expected.push_back("- RRSIG NSEC3 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); + + rec.d_name = DNSName("z.powerdns.com"); + rec.d_type = QType::NSEC; + rec.d_ttl = now.tv_sec + 30; + rec.setContent(getRecordContent(QType::NSEC, "zz.powerdns.com. AAAA RRSIG NSEC")); + rrsig = std::make_shared("NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data"); + cache->insertNSEC(DNSName("powerdns.com"), rec.d_name, rec, {rrsig}, false); + + fp = std::unique_ptr(tmpfile(), fclose); + BOOST_CHECK_EQUAL(cache->dumpToFile(fp, now), 3U); + + rewind(fp.get()); + + for (auto str : expected) { + read = getline(&line, &len, fp.get()); + if (read == -1) { + BOOST_FAIL("Unable to read a line from the temp file"); + } + BOOST_CHECK_EQUAL(line, str); + } + /* getline() allocates a buffer when called with a nullptr, then reallocates it when needed, but we need to free the last allocation if any. */ From 90da636c01b23ca4401451940d64e5f773d042ec Mon Sep 17 00:00:00 2001 From: Winfried Angele Date: Tue, 8 Aug 2023 16:32:27 +0200 Subject: [PATCH 492/909] Update max-packetcache-entries setting doc Since 4.9.0, the packet cache is sharded and shared by all threads. --- pdns/recursordist/docs/settings.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 740c2e3a93c0..fc3f1e0c98cf 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -1250,8 +1250,7 @@ Maximum number of simultaneous MTasker threads. - Integer - Default: 500000 -Maximum number of Packet Cache entries. Each worker and each distributor thread has a packet cache instance. -This number will be divided by the number of worker plus the number of distributor threads to compute the maximum number of entries per cache instance. +Maximum number of Packet Cache entries. Sharded and shared by all threads since 4.9.0. .. _setting-max-qperq: From 8faf5a90992b2613cf5999c8dd5e26b0025050b7 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 7 Aug 2023 19:13:36 +0200 Subject: [PATCH 493/909] IXFR client: handle partial reads of the TCP chunk length header, plus: * add primarySOACount to exception text * add indicator of current state to exception text * a test --- pdns/ixfr.cc | 27 +++++++++++++++----- regression-tests.recursor-dnssec/test_RPZ.py | 7 ++++- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/pdns/ixfr.cc b/pdns/ixfr.cc index fb09e3503722..755fb1d155d4 100644 --- a/pdns/ixfr.cc +++ b/pdns/ixfr.cc @@ -123,6 +123,7 @@ vector, vector > > processIXFRRecords(const Co } // Returns pairs of "remove & add" vectors. If you get an empty remove, it means you got an AXFR! + // NOLINTNEXTLINE(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 vector, vector>> getIXFRDeltas(const ComboAddress& primary, const DNSName& zone, const DNSRecord& oursr, uint16_t xfrTimeout, bool totalTimeout, const TSIGTriplet& tt, const ComboAddress* laddr, size_t maxReceivedBytes) @@ -203,24 +204,36 @@ vector, vector>> getIXFRDeltas(const ComboAddr const unsigned int expectedSOAForIXFR = 3; unsigned int primarySOACount = 0; + std::string state; for (;;) { + state = "start"; // IXFR or AXFR style end reached? We don't want to process trailing data after the closing SOA if (style == AXFR && primarySOACount == expectedSOAForAXFR) { + state = "AXFRdone"; break; } - else if (style == IXFR && primarySOACount == expectedSOAForIXFR) { + if (style == IXFR && primarySOACount == expectedSOAForIXFR) { + state = "IXFRdone"; break; } elapsed = timeoutChecker(); - if (s.readWithTimeout(reinterpret_cast(&len), sizeof(len), static_cast(xfrTimeout - elapsed)) != sizeof(len)) { + try { + const struct timeval remainingTime = { .tv_sec = xfrTimeout - elapsed, .tv_usec = 0 }; + const struct timeval idleTime = remainingTime; + readn2WithTimeout(s.getHandle(), &len, sizeof(len), idleTime, remainingTime, false); + } + catch (const runtime_error& ex) { + state = ex.what(); break; } len = ntohs(len); if (len == 0) { + state = "zeroLen"; break; } + // Currently no more break statements after this if (maxReceivedBytes > 0 && (maxReceivedBytes - receivedBytes) < (size_t) len) { throw std::runtime_error("Reached the maximum number of received bytes in an IXFR delta for zone '"+zone.toLogString()+"' from primary "+primary.toStringWithPort()); @@ -229,9 +242,9 @@ vector, vector>> getIXFRDeltas(const ComboAddr reply.resize(len); elapsed = timeoutChecker(); - const struct timeval remainingTime = { .tv_sec = xfrTimeout - elapsed, .tv_usec = 0 }; + const struct timeval remainingTime = { .tv_sec = xfrTimeout - elapsed, .tv_usec = 0 }; const struct timeval idleTime = remainingTime; - readn2WithTimeout(s.getHandle(), &reply.at(0), len, idleTime, remainingTime, false); + readn2WithTimeout(s.getHandle(), reply.data(), len, idleTime, remainingTime, false); receivedBytes += len; MOADNSParser mdp(false, reply); @@ -306,16 +319,16 @@ vector, vector>> getIXFRDeltas(const ComboAddr switch (style) { case IXFR: if (primarySOACount != expectedSOAForIXFR) { - throw std::runtime_error("Incomplete IXFR transfer for '" + zone.toLogString() + "' from primary '" + primary.toStringWithPort()); + throw std::runtime_error("Incomplete IXFR transfer (primarySOACount=" + std::to_string(primarySOACount) + ") for '" + zone.toLogString() + "' from primary '" + primary.toStringWithPort() + " state=" + state); } break; case AXFR: if (primarySOACount != expectedSOAForAXFR){ - throw std::runtime_error("Incomplete AXFR style transfer for '" + zone.toLogString() + "' from primary '" + primary.toStringWithPort()); + throw std::runtime_error("Incomplete AXFR style transfer (primarySOACount=" + std::to_string(primarySOACount) + ") for '" + zone.toLogString() + "' from primary '" + primary.toStringWithPort() + " state=" + state); } break; case Unknown: - throw std::runtime_error("Incomplete XFR for '" + zone.toLogString() + "' from primary '" + primary.toStringWithPort()); + throw std::runtime_error("Incomplete XFR (primarySOACount=" + std::to_string(primarySOACount) + ") for '" + zone.toLogString() + "' from primary '" + primary.toStringWithPort() + " state=" + state); break; } diff --git a/regression-tests.recursor-dnssec/test_RPZ.py b/regression-tests.recursor-dnssec/test_RPZ.py index 4215eacd33fb..da865ea74cce 100644 --- a/regression-tests.recursor-dnssec/test_RPZ.py +++ b/regression-tests.recursor-dnssec/test_RPZ.py @@ -185,7 +185,12 @@ def _connectionHandler(self, conn): break wire = answer.to_wire() - conn.send(struct.pack("!H", len(wire))) + lenprefix = struct.pack("!H", len(wire)) + + for b in lenprefix: + conn.send(bytes([b])) + time.sleep(0.5) + conn.send(wire) self._currentSerial = serial break From dbda9e0435f0dfc0cb039c9edcdcaa8dc1dbf5c5 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 8 Aug 2023 23:11:47 +0200 Subject: [PATCH 494/909] Auth: Fix warnings in bind backend --- modules/bindbackend/binddnssec.cc | 37 +++++++++++++++---------------- 1 file changed, 18 insertions(+), 19 deletions(-) diff --git a/modules/bindbackend/binddnssec.cc b/modules/bindbackend/binddnssec.cc index ac11f7623911..c5b9bc7a4424 100644 --- a/modules/bindbackend/binddnssec.cc +++ b/modules/bindbackend/binddnssec.cc @@ -31,8 +31,9 @@ void Bind2Backend::setupDNSSEC() { - if (!getArg("dnssec-db").empty()) + if (!getArg("dnssec-db").empty()) { throw runtime_error("bind-dnssec-db requires building PowerDNS with SQLite3"); + } } bool Bind2Backend::doesDNSSEC() @@ -40,94 +41,92 @@ bool Bind2Backend::doesDNSSEC() return d_hybrid; } -bool Bind2Backend::getNSEC3PARAM(const DNSName& name, NSEC3PARAMRecordContent* ns3p) +bool Bind2Backend::getNSEC3PARAM(const DNSName& /* name */, NSEC3PARAMRecordContent* /* ns3p */) { return false; } -bool Bind2Backend::getNSEC3PARAMuncached(const DNSName& name, NSEC3PARAMRecordContent* ns3p) +bool Bind2Backend::getNSEC3PARAMuncached(const DNSName& /* name */, NSEC3PARAMRecordContent* /* ns3p */) { return false; } -bool Bind2Backend::getAllDomainMetadata(const DNSName& name, std::map>& meta) +bool Bind2Backend::getAllDomainMetadata(const DNSName& /* name */, std::map>& /* meta */) { return false; } -bool Bind2Backend::getDomainMetadata(const DNSName& name, const std::string& kind, std::vector& meta) +bool Bind2Backend::getDomainMetadata(const DNSName& /* name */, const std::string& /* kind */, std::vector& /* meta */) { return false; } -bool Bind2Backend::setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector& meta) +bool Bind2Backend::setDomainMetadata(const DNSName& /* name */, const std::string& /* kind */, const std::vector& /* meta */) { return false; } -bool Bind2Backend::getDomainKeys(const DNSName& name, std::vector& keys) +bool Bind2Backend::getDomainKeys(const DNSName& /* name */, std::vector& /* keys */) { return false; } -bool Bind2Backend::removeDomainKey(const DNSName& name, unsigned int id) +bool Bind2Backend::removeDomainKey(const DNSName& /* name */, unsigned int /* id */) { return false; } -bool Bind2Backend::addDomainKey(const DNSName& name, const KeyData& key, int64_t& id) +bool Bind2Backend::addDomainKey(const DNSName& /* name */, const KeyData& /* key */, int64_t& /* id */) { return false; } -bool Bind2Backend::activateDomainKey(const DNSName& name, unsigned int id) +bool Bind2Backend::activateDomainKey(const DNSName& /* name */, unsigned int /* id */) { return false; } -bool Bind2Backend::deactivateDomainKey(const DNSName& name, unsigned int id) +bool Bind2Backend::deactivateDomainKey(const DNSName& /* name */, unsigned int /* id */) { return false; } -bool Bind2Backend::publishDomainKey(const DNSName& name, unsigned int id) +bool Bind2Backend::publishDomainKey(const DNSName& /* name */, unsigned int /* id */) { return false; } -bool Bind2Backend::unpublishDomainKey(const DNSName& name, unsigned int id) +bool Bind2Backend::unpublishDomainKey(const DNSName& /* name */, unsigned int /* id */) { return false; } -bool Bind2Backend::getTSIGKey(const DNSName& name, DNSName& algorithm, string& content) +bool Bind2Backend::getTSIGKey(const DNSName& /* name */, DNSName& /* algorithm */, string& /* content */) { return false; } -bool Bind2Backend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const string& content) +bool Bind2Backend::setTSIGKey(const DNSName& /* name */, const DNSName& /* algorithm */, const string& /* content */) { return false; } -bool Bind2Backend::deleteTSIGKey(const DNSName& name) +bool Bind2Backend::deleteTSIGKey(const DNSName& /* name */) { return false; } -bool Bind2Backend::getTSIGKeys(std::vector& keys) +bool Bind2Backend::getTSIGKeys(std::vector& /* keys */) { return false; } void Bind2Backend::setupStatements() { - return; } void Bind2Backend::freeStatements() { - return; } #else From 8d3ab63b412fb4b9fd8732af47a5d1c18ba7e786 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 9 Aug 2023 10:09:36 +0200 Subject: [PATCH 495/909] remove redundant assignment --- pdns/ixfr.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/pdns/ixfr.cc b/pdns/ixfr.cc index 755fb1d155d4..28d773c2503e 100644 --- a/pdns/ixfr.cc +++ b/pdns/ixfr.cc @@ -206,7 +206,6 @@ vector, vector>> getIXFRDeltas(const ComboAddr std::string state; for (;;) { - state = "start"; // IXFR or AXFR style end reached? We don't want to process trailing data after the closing SOA if (style == AXFR && primarySOACount == expectedSOAForAXFR) { state = "AXFRdone"; From 993712a13a3b4d9faf7c4298412fbd2a6b3a7761 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 9 Aug 2023 13:45:12 +0200 Subject: [PATCH 496/909] Make clang-tidy happy --- pdns/recursordist/test-aggressive_nsec_cc.cc | 65 ++++++++++---------- 1 file changed, 33 insertions(+), 32 deletions(-) diff --git a/pdns/recursordist/test-aggressive_nsec_cc.cc b/pdns/recursordist/test-aggressive_nsec_cc.cc index 1596ba333212..8222a812a211 100644 --- a/pdns/recursordist/test-aggressive_nsec_cc.cc +++ b/pdns/recursordist/test-aggressive_nsec_cc.cc @@ -1181,17 +1181,19 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_dump) auto cache = make_unique(10000); std::vector expected; - expected.push_back("; Zone powerdns.com.\n"); - expected.push_back("www.powerdns.com. 10 IN NSEC z.powerdns.com. A RRSIG NSEC\n"); - expected.push_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); - expected.push_back("z.powerdns.com. 10 IN NSEC zz.powerdns.com. AAAA RRSIG NSEC\n"); - expected.push_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); - expected.push_back("; Zone powerdns.org.\n"); - expected.push_back("www.powerdns.org. 10 IN NSEC3 1 0 50 ab HASG==== A RRSIG NSEC3\n"); - expected.push_back("- RRSIG NSEC3 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); - - struct timeval now; - Utility::gettimeofday(&now, 0); + expected.emplace_back("; Zone powerdns.com.\n"); + expected.emplace_back("www.powerdns.com. 10 IN NSEC z.powerdns.com. A RRSIG NSEC\n"); + expected.emplace_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); + expected.emplace_back("z.powerdns.com. 10 IN NSEC zz.powerdns.com. AAAA RRSIG NSEC\n"); + expected.emplace_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); + expected.emplace_back("; Zone powerdns.org.\n"); + expected.emplace_back("www.powerdns.org. 10 IN NSEC3 1 0 50 ab HASG==== A RRSIG NSEC3\n"); + expected.emplace_back("- RRSIG NSEC3 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); + + struct timeval now + { + }; + Utility::gettimeofday(&now, nullptr); DNSRecord rec; rec.d_name = DNSName("www.powerdns.com"); @@ -1214,20 +1216,19 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_dump) BOOST_CHECK_EQUAL(cache->getEntriesCount(), 3U); - auto fp = std::unique_ptr(tmpfile(), fclose); - if (!fp) { + auto filePtr = std::unique_ptr(tmpfile(), fclose); + if (!filePtr) { BOOST_FAIL("Temporary file could not be opened"); } - BOOST_CHECK_EQUAL(cache->dumpToFile(fp, now), 3U); + BOOST_CHECK_EQUAL(cache->dumpToFile(filePtr, now), 3U); - rewind(fp.get()); + rewind(filePtr.get()); char* line = nullptr; size_t len = 0; - ssize_t read; - for (auto str : expected) { - read = getline(&line, &len, fp.get()); + for (const auto& str : expected) { + auto read = getline(&line, &len, filePtr.get()); if (read == -1) { BOOST_FAIL("Unable to read a line from the temp file"); } @@ -1235,14 +1236,14 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_dump) } expected.clear(); - expected.push_back("; Zone powerdns.com.\n"); - expected.push_back("www.powerdns.com. 10 IN NSEC z.powerdns.com. A RRSIG NSEC\n"); - expected.push_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); - expected.push_back("z.powerdns.com. 30 IN NSEC zz.powerdns.com. AAAA RRSIG NSEC\n"); - expected.push_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); - expected.push_back("; Zone powerdns.org.\n"); - expected.push_back("www.powerdns.org. 10 IN NSEC3 1 0 50 ab HASG==== A RRSIG NSEC3\n"); - expected.push_back("- RRSIG NSEC3 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); + expected.emplace_back("; Zone powerdns.com.\n"); + expected.emplace_back("www.powerdns.com. 10 IN NSEC z.powerdns.com. A RRSIG NSEC\n"); + expected.emplace_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); + expected.emplace_back("z.powerdns.com. 30 IN NSEC zz.powerdns.com. AAAA RRSIG NSEC\n"); + expected.emplace_back("- RRSIG NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); + expected.emplace_back("; Zone powerdns.org.\n"); + expected.emplace_back("www.powerdns.org. 10 IN NSEC3 1 0 50 ab HASG==== A RRSIG NSEC3\n"); + expected.emplace_back("- RRSIG NSEC3 5 3 10 20370101000000 20370101000000 24567 dummy. data\n"); rec.d_name = DNSName("z.powerdns.com"); rec.d_type = QType::NSEC; @@ -1251,13 +1252,13 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_dump) rrsig = std::make_shared("NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data"); cache->insertNSEC(DNSName("powerdns.com"), rec.d_name, rec, {rrsig}, false); - fp = std::unique_ptr(tmpfile(), fclose); - BOOST_CHECK_EQUAL(cache->dumpToFile(fp, now), 3U); + rewind(filePtr.get()); + BOOST_CHECK_EQUAL(cache->dumpToFile(filePtr, now), 3U); - rewind(fp.get()); + rewind(filePtr.get()); - for (auto str : expected) { - read = getline(&line, &len, fp.get()); + for (const auto& str : expected) { + auto read = getline(&line, &len, filePtr.get()); if (read == -1) { BOOST_FAIL("Unable to read a line from the temp file"); } @@ -1267,7 +1268,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_dump) /* getline() allocates a buffer when called with a nullptr, then reallocates it when needed, but we need to free the last allocation if any. */ - free(line); + free(line); // NOLINT: it's the API. } BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_rollover) From 0044dbdb607c6d054850b4d2363a6e1d3b62f20c Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 9 Aug 2023 17:27:07 +0200 Subject: [PATCH 497/909] formatting: one sentence per line. added ## to two things that looked like headings --- CODING_GUIDELINES.md | 239 +++++++++++++++++++++++++++++++------------ 1 file changed, 173 insertions(+), 66 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 12f5058023a3..bdc92159d403 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -1,29 +1,38 @@ Coding guidelines for contributing to PowerDNS ---------------------------------------------- -Thank you for you interest to contribute to the PowerDNS project. This document describes the general coding guidelines to keep in mind when contributing code to our code base. It does assume that you have already read the contributing document at [CONTRIBUTING.md](https://github.com/PowerDNS/pdns/blob/master/CONTRIBUTING.md). +Thank you for you interest to contribute to the PowerDNS project. +This document describes the general coding guidelines to keep in mind when contributing code to our code base. +It does assume that you have already read the contributing document at [CONTRIBUTING.md](https://github.com/PowerDNS/pdns/blob/master/CONTRIBUTING.md). # High-level guidelines * Although the codebase does not consistently have them, [docblock](https://www.doxygen.nl/manual/docblocks.html)s on functions and classes are appreciated. * Never hesitate to write comments on anything that might not be immediately clear just from reading the code. -* When adding whole new things, consider putting them in a `pdns::X` namespace. Look for `namespace pdns` in the codebase for examples. +* When adding whole new things, consider putting them in a `pdns::X` namespace. + Look for `namespace pdns` in the codebase for examples. # Memory handling -The memory model in C++, inherited from the C era, is very powerful but also very error-prone. Several features are available in modern (C++11) C++ to make it possible to avoid most of the pitfalls, while conserving the same level of performance. +The memory model in C++, inherited from the C era, is very powerful but also very error-prone. +Several features are available in modern (C++11) C++ to make it possible to avoid most of the pitfalls, while conserving the same level of performance. Most of the issues related to memory allocation (memory leaks, use-after-free) can be solved by using it via standard containers, or taking advantage of RAII and smart pointers, which take care of destructing the object when it's not used anymore. ## Stack-based memory allocation -Default allocations, when declaring a variable local to a function for example, is done on the stack instead of doing a dynamic allocation on the heap. Allocating objects on the stack is faster, especially in threaded programs, and provides the benefit that objects are automatically destroyed when the function is exited. +Default allocations, when declaring a variable local to a function for example, is done on the stack instead of doing a dynamic allocation on the heap. +Allocating objects on the stack is faster, especially in threaded programs, and provides the benefit that objects are automatically destroyed when the function is exited. -One caveat is that the programmer needs to be wary about the size of the object in order not to exceed the space available on the stack, which would corrupt other objects in memory and could lead to a crash, or even execution of arbitrary code. This is especially true in the recursor which uses a custom stack-switching in user-space mechanism and thus has a reduced stack size. +One caveat is that the programmer needs to be wary about the size of the object in order not to exceed the space available on the stack, which would corrupt other objects in memory and could lead to a crash, or even execution of arbitrary code. +This is especially true in the recursor which uses a custom stack-switching in user-space mechanism and thus has a reduced stack size. ### Variable-Length Arrays -In order to avoid smashing the stack, a special care should be taken to limit the depth of function calls that can grow quickly with recursion, for example. A second common source of smash stacking is the use of Variable-Length Arrays, whose size is determined at runtime and is therefore very hard to predict. The C++ language doesn't support VLAs but a lot of compilers inherit such a support from C99, so it's possible to use them by mistake. PowerDNS strictly forbids the use of VLAs, as does the Linux kernel, and enforce that with the `-Werror=vla` compiler flag. +In order to avoid smashing the stack, a special care should be taken to limit the depth of function calls that can grow quickly with recursion, for example. +A second common source of smash stacking is the use of Variable-Length Arrays, whose size is determined at runtime and is therefore very hard to predict. +The C++ language doesn't support VLAs but a lot of compilers inherit such a support from C99, so it's possible to use them by mistake. +PowerDNS strictly forbids the use of VLAs, as does the Linux kernel, and enforce that with the `-Werror=vla` compiler flag. ### C-style arrays @@ -35,7 +44,9 @@ auto bufferSize = sizeof(buffer) / sizeof(*buffer); auto& firstElement = buffer[0]; ``` -It is immediately obvious that computing the actual number of elements is error-prone, as `sizeof()` does not return the number of elements but the total memory space used by the array. An other obvious issue is that accesses to the array are not bound-checked. These are not the only drawbacks of these arrays, but are bad enough already to justify getting rid of them. +It is immediately obvious that computing the actual number of elements is error-prone, as `sizeof()` does not return the number of elements but the total memory space used by the array. +An other obvious issue is that accesses to the array are not bound-checked. +These are not the only drawbacks of these arrays, but are bad enough already to justify getting rid of them. The modern C++ way is to use `std::array`s: @@ -51,9 +62,15 @@ The use of `alloca()` is forbidden in the code base as it is much too easy to sm ## RAII -Resource acquisition is initialization (RAII) is one of the fundamental concept in C++. Resources are allocated during the construction of an object and destroyed when the object is itself destructed. It means that if an object is correctly designed, the resource associated to it can not survive its lifetime. Since objects that are allocated on the stack (local variables in a function, for example) are automatically destroyed when a function is exited, be it by reaching the last line, calling return or throwing an exception, it makes it possible to ensure that resources are always properly destroyed by wrapping them into an object. +Resource acquisition is initialization (RAII) is one of the fundamental concept in C++. +Resources are allocated during the construction of an object and destroyed when the object is itself destructed. +It means that if an object is correctly designed, the resource associated to it can not survive its lifetime. +Since objects that are allocated on the stack (local variables in a function, for example) are automatically destroyed when a function is exited, be it by reaching the last line, calling return or throwing an exception, it makes it possible to ensure that resources are always properly destroyed by wrapping them into an object. -We describe the use of smart pointers, containers and other wrappers to that mean below, but first a few words of caution. Resources stored in a object are only tied to this object if the constructor finished properly. If an exception is raised in the constructor body, the object is not created and therefore the destructor will not get called. This means that if the object has non-object members holding resources, like naked file descriptors or naked pointers, they need to be explicitly released before raising the exception, otherwise they are lost. +We describe the use of smart pointers, containers and other wrappers to that mean below, but first a few words of caution. +Resources stored in a object are only tied to this object if the constructor finished properly. +If an exception is raised in the constructor body, the object is not created and therefore the destructor will not get called. +This means that if the object has non-object members holding resources, like naked file descriptors or naked pointers, they need to be explicitly released before raising the exception, otherwise they are lost. ```C++ class BadFileDescriptionWrapper @@ -98,14 +115,17 @@ BadFileDescriptionWrapper() ## Smart pointers -There is almost no good reason not to use a smart pointer when doing dynamic memory allocation. Smart pointers will keep track of whether the dynamically allocated object is still used, and destroy when the last user goes away. +There is almost no good reason not to use a smart pointer when doing dynamic memory allocation. +Smart pointers will keep track of whether the dynamically allocated object is still used, and destroy when the last user goes away. -Using naked pointers quickly results in security issues, going from memory leaks to arbitrary code execution. Examples of such issues can be found in the following PowerDNS security advisories: +Using naked pointers quickly results in security issues, going from memory leaks to arbitrary code execution. +Examples of such issues can be found in the following PowerDNS security advisories: * https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-07.html * https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-04.html -Most allocations should be wrapped in a `std::unique_pointer`, using `make_unique`. There can only be one owner at a given time, as opposed to shared pointers, but the ownership can be passed along using `std::move()` if needed. +Most allocations should be wrapped in a `std::unique_pointer`, using `make_unique`. +There can only be one owner at a given time, as opposed to shared pointers, but the ownership can be passed along using `std::move()` if needed. If the dynamically allocated object needs to be referenced in several places, the use of a `std::shared_pointer` is advised instead, via `std::make_shared`. @@ -117,11 +137,16 @@ The use of the `make_*` methods have three advantages: They also make is easier to spot naked pointers by looking for "new" and "delete" throughout the code :) -Please note however that while unique pointers are as cheap as naked pointers, shared pointers are much more expensive. That's because they need to use atomic operations to update their internal counters, so making a copy of a shared pointer is expensive. Passing one by reference is cheap, however. +Please note however that while unique pointers are as cheap as naked pointers, shared pointers are much more expensive. +That's because they need to use atomic operations to update their internal counters, so making a copy of a shared pointer is expensive. +Passing one by reference is cheap, however. ### Shared pointers -An important thing to be aware of with shared pointers is that taking a new copy of a shared pointer or releasing, thus updating its internal reference counter, is atomic and therefore thread-safe. Altering the content of the object pointed to is not, though, and is subject to the usual locking methods. The often misunderstood part is that updating the target of the shared pointer is not thread-safe. Basically, you can copy the shared pointer from multiple threads at once, and then each thread can assign a new target to its own copy safely, like that: +An important thing to be aware of with shared pointers is that taking a new copy of a shared pointer or releasing, thus updating its internal reference counter, is atomic and therefore thread-safe. +Altering the content of the object pointed to is not, though, and is subject to the usual locking methods. +The often misunderstood part is that updating the target of the shared pointer is not thread-safe. +Basically, you can copy the shared pointer from multiple threads at once, and then each thread can assign a new target to its own copy safely, like that: ```C++ auto ptr = std::make_shared(4); @@ -143,7 +168,8 @@ std::thread threadB([&ptr]{ }); ``` -That unfortunately means that we still need some locking with shared pointers. C++11 defines atomic compare/exchange operations for `std::shared_ptr`, but they are implemented in `libstdc++` by global mutexes and are therefore not lock-free. +That unfortunately means that we still need some locking with shared pointers. +C++11 defines atomic compare/exchange operations for `std::shared_ptr`, but they are implemented in `libstdc++` by global mutexes and are therefore not lock-free. ### Wrapping C pointers @@ -159,7 +185,8 @@ It also works with types from external C libraries, like OpenSSL: auto cert = std::unique_ptr(PEM_read_X509_AUX(fp.get(), nullptr, nullptr, nullptr), X509_free); ``` -Unfortunately there are a few cases where smart pointers cannot be used. In the PowerDNS products, these cases have been mostly reduced to a few select classes, like the `pdns::channel` ones, that are used to pass pointers to a different thread by writing them to a pipe, as is done for example by the queries distributors of the auth and the rec. +Unfortunately there are a few cases where smart pointers cannot be used. +In the PowerDNS products, these cases have been mostly reduced to a few select classes, like the `pdns::channel` ones, that are used to pass pointers to a different thread by writing them to a pipe, as is done for example by the queries distributors of the auth and the rec. When it happens, special care should be taken to: @@ -170,11 +197,15 @@ When it happens, special care should be taken to: ## Pointer arithmetic -It is very common to use pointer arithmetic to calculate a position in a buffer, or to test whether a given offset is outside of a given buffer. Unfortunately it is quite easy to trigger undefined behaviour when doing so, as the C++ standard does not allow pointer arithmetic pointing inside an object, except for arrays where it is also permitted to point one element past the end. Still that undefined behaviour is mostly harmless, but it might lead to real issue on some platforms. +It is very common to use pointer arithmetic to calculate a position in a buffer, or to test whether a given offset is outside of a given buffer. +Unfortunately it is quite easy to trigger undefined behaviour when doing so, as the C++ standard does not allow pointer arithmetic pointing inside an object, except for arrays where it is also permitted to point one element past the end. +Still that undefined behaviour is mostly harmless, but it might lead to real issue on some platforms. One such example occurred in dnsdist: https://dnsdist.org/security-advisories/powerdns-advisory-for-dnsdist-2017-01.html -In that case, a pointer was set to the start of a buffer plus a given length, to see whether the result go past another pointer that was set to the end of the buffer. Unfortunately, if the start of the buffer is at a very high virtual address, the result of the addition might overflow and wrap around, causing the check to become true and leading to either a crash or the reading of unrelated memory. While very unlikely on a 64 bits platform, it could happen on 16 or 32 bits platform. +In that case, a pointer was set to the start of a buffer plus a given length, to see whether the result go past another pointer that was set to the end of the buffer. +Unfortunately, if the start of the buffer is at a very high virtual address, the result of the addition might overflow and wrap around, causing the check to become true and leading to either a crash or the reading of unrelated memory. +While very unlikely on a 64 bits platform, it could happen on 16 or 32 bits platform. This kind of issue is best avoided by the use of container to prevent the need of pointer arithmetic, or by very careful to only add checked offsets to a pointer. @@ -188,21 +219,35 @@ The use of containers like `vector`, `map` or `set` has several advantages in te One issue that could have been prevented by the use of a container can be found in the following advisory: https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-09.html -The use of a container and its corresponding `at()` operator would have prevented an out-of-bounds read since calling `at()` on an invalid offset results in an exception being raised. The cost of using `at()` is negligible for most use cases, and can be avoided by using the `[]` operator in the rate case when the cost can't be afforded. Note that several Linux distributions now build with `-Wp,-D_GLIBCXX_ASSERTIONS` enabled by default, which turns on cheap range checks for C++ arrays, vectors, and strings anyway. +The use of a container and its corresponding `at()` operator would have prevented an out-of-bounds read since calling `at()` on an invalid offset results in an exception being raised. +The cost of using `at()` is negligible for most use cases, and can be avoided by using the `[]` operator in the rate case when the cost can't be afforded. +Note that several Linux distributions now build with `-Wp,-D_GLIBCXX_ASSERTIONS` enabled by default, which turns on cheap range checks for C++ arrays, vectors, and strings anyway. -Regarding performance, it is advised to `reserve()` the needed size in advance when a rough estimate is known to avoid reallocations and copies. Resizing in advance is not advised, though, as it makes it harder to know what is exactly in the container in case of early returns or exceptions. +Regarding performance, it is advised to `reserve()` the needed size in advance when a rough estimate is known to avoid reallocations and copies. +Resizing in advance is not advised, though, as it makes it harder to know what is exactly in the container in case of early returns or exceptions. In C++11, move operations make it possible to cheaply get the content of a container into a different variable if needed. -The need to pass a subset of a container without copying it often leads to passing a pointer to an array of chars along with a size. Introduced in C++14 but already available in PowerDNS via boost (see views.hh), views provides a nice way to borrow the content of a container to pass it to a function, without any copy or dynamic memory allocation. +The need to pass a subset of a container without copying it often leads to passing a pointer to an array of chars along with a size. +Introduced in C++14 but already available in PowerDNS via boost (see views.hh), views provides a nice way to borrow the content of a container to pass it to a function, without any copy or dynamic memory allocation. The basic `string_view` class provides that feature for a container of chars, but the same feature exists for other types, like `uint8_t`. # Threads and concurrency -All of our products use threading to be able to take advantage of the increasing number of cores on modern CPUs. That inevitably leads to the question of how to synchronise data accesses between threads. Most objects, like containers, cannot be accessed from more than one thread at once. Even `const` methods on containers might not be thread-safe. For example getting the `size()` of a container might not be thread-safe if a different thread might be writing to the container. Some functions might also not be thread-safe, for example if they have a static non-const variable. +All of our products use threading to be able to take advantage of the increasing number of cores on modern CPUs. +That inevitably leads to the question of how to synchronise data accesses between threads. +Most objects, like containers, cannot be accessed from more than one thread at once. +Even `const` methods on containers might not be thread-safe. +For example getting the `size()` of a container might not be thread-safe if a different thread might be writing to the container. +Some functions might also not be thread-safe, for example if they have a static non-const variable. -We currently use three solutions, depending on the use-case. The first one is used when we only need to share some kind of counters or gauges, and involves the use of `std::atomic` which allows atomic operations to be performed from different threads without locking. More on that later. The second one is the "share nothing" approach, where each thread has its own data (using `thread_local`, for example), avoiding the need to data synchronization. When a thread needs to communicate with another one, it might use an pdns::channel to pass a pointer to that second thread. That works quite well but sometimes sharing data is much more efficient than the alternative. +We currently use three solutions, depending on the use-case. +The first one is used when we only need to share some kind of counters or gauges, and involves the use of `std::atomic` which allows atomic operations to be performed from different threads without locking. +More on that later. +The second one is the "share nothing" approach, where each thread has its own data (using `thread_local`, for example), avoiding the need to data synchronization. +When a thread needs to communicate with another one, it might use an pdns::channel to pass a pointer to that second thread. +That works quite well but sometimes sharing data is much more efficient than the alternative. For these cases, we use the classic locking approach, using either a simple mutex or read-write lock, depending on the use case. @@ -213,21 +258,31 @@ Locks allow a thread of execution to ensure that no other will try to access the There are a few pitfalls to avoid then using locks: * avoiding to release the lock, which can be avoided by wrappers like `std::lock_guard`, `std::unique_lock` and our own wrappers: look for `LockGuarded`, `SharedLockGuarded` in lock.hh ; -* high contention, where threads are blocked for a long time while waiting to acquire a lock. This can be solved by carefully examining the portion of code that really needs to hold the lock, making the critical path faster, or by using sharding which basically divide the data protected by the lock in several blocks, each one of them protected by its own lock ; -* starvation, which occurs for example when thread 1 acquires lock 1 and wants to acquire lock 2, which is already owned by thread 2, itself currently waiting to acquire lock 1. This can be avoided by a better design of the locking mechanism, and assuring that locks are always acquired in the same order if more than one lock is needed. +* high contention, where threads are blocked for a long time while waiting to acquire a lock. + This can be solved by carefully examining the portion of code that really needs to hold the lock, making the critical path faster, or by using sharding which basically divide the data protected by the lock in several blocks, each one of them protected by its own lock ; +* starvation, which occurs for example when thread 1 acquires lock 1 and wants to acquire lock 2, which is already owned by thread 2, itself currently waiting to acquire lock 1. + This can be avoided by a better design of the locking mechanism, and assuring that locks are always acquired in the same order if more than one lock is needed. There are more than one type of locks: -* spinlock are very fast but are busy-waiting, meaning that they don't pause but repetitively try to get hold of the lock, using 100% of one core doing so unless preempted by the OS. So they are only suited for locks that are almost never contented ; -* a mutex is a very simple lock. In most implementations it's a very fast lock, implemented in user-space on recent Linux kernels and glibc ; -* a read-write lock allows several threads to acquire it in read mode, but only one thread can acquire it in write mode. This is suited when most accesses are read-only and writes are rare and don't take too long. Otherwise a mutex might actually be faster ; +* spinlock are very fast but are busy-waiting, meaning that they don't pause but repetitively try to get hold of the lock, using 100% of one core doing so unless preempted by the OS. + So they are only suited for locks that are almost never contented ; +* a mutex is a very simple lock. + In most implementations it's a very fast lock, implemented in user-space on recent Linux kernels and glibc ; +* a read-write lock allows several threads to acquire it in read mode, but only one thread can acquire it in write mode. + This is suited when most accesses are read-only and writes are rare and don't take too long. + Otherwise a mutex might actually be faster ; -One quick word about condition variables, that allows a thread to notify one or more threads waiting for a condition to happen. A thread should acquire a mutex using a `std::unique_lock` and call the `wait()` method of the condition variable. This is a very useful mechanism but one must be careful about two things: +One quick word about condition variables, that allows a thread to notify one or more threads waiting for a condition to happen. +A thread should acquire a mutex using a `std::unique_lock` and call the `wait()` method of the condition variable. +This is a very useful mechanism but one must be careful about two things: -* the producer thread can either wake only one thread or all threads waiting on the condition variable. Waking up several threads if only one has something to do (known as a "thundering herd") is bad practice, but there are some cases where it makes sense ; +* the producer thread can either wake only one thread or all threads waiting on the condition variable. + Waking up several threads if only one has something to do (known as a "thundering herd") is bad practice, but there are some cases where it makes sense ; * a consumer might be waken up spuriously, which can be avoided by passing a predicate (which can be as simple as a small lambda function) to `wait()`. -Our wrappers, `LockGuarded`, `SharedLockGuarded` in lock.hh, should always be preferred over other solutions. They provide a way to wrap any data structure as protected by a lock (mutex or shared mutex), while making it immediately clear which data is protected by that lock, and preventing any access to the data without holding the lock. +Our wrappers, `LockGuarded`, `SharedLockGuarded` in lock.hh, should always be preferred over other solutions. +They provide a way to wrap any data structure as protected by a lock (mutex or shared mutex), while making it immediately clear which data is protected by that lock, and preventing any access to the data without holding the lock. For example, to protect a set of integers with a simple mutex: @@ -242,7 +297,9 @@ SharedLockGuarded> d_data; ``` Then the only way to access the data is to call the `lock()`, `read_only_lock()` or `try_lock()` methods for the simple case, or the `read_lock()`, `write_lock()`, `try_read_lock()` or `try_write_lock()` for the shared one. -Doing so will return a "holder" object, which provides access to the protected data, checking that the lock has really been acquired if needed (`try_` cases). The data might be read-only if `read_lock()`, `try_read_lock()` or `read_only_lock()` was called. Access is provided by dereferencing the holder object via `*` or `->`, allowing a quick-access syntax: +Doing so will return a "holder" object, which provides access to the protected data, checking that the lock has really been acquired if needed (`try_` cases). +The data might be read-only if `read_lock()`, `try_read_lock()` or `read_only_lock()` was called. +Access is provided by dereferencing the holder object via `*` or `->`, allowing a quick-access syntax: ```c+++ return d_data.lock()->size(); @@ -260,7 +317,10 @@ Or when the lock needs to be kept for a bit longer: ## atomic -`std::atomic` provides a nice way to share a counter or gauge between threads without the need for locking. This is done by implementing operations like reading, increasing, decreasing or writing a value in an atomic way, using memory barriers, making sure that the value can't be updated from a different core during the operation. The default mode uses a sequentially consistent ordering memory model, which is quite expensive since it requires a full memory fence on all multi-core systems. A relaxed model can be used for certain very specific operations, but the default model has the advantage of being safe in all situations. +`std::atomic` provides a nice way to share a counter or gauge between threads without the need for locking. +This is done by implementing operations like reading, increasing, decreasing or writing a value in an atomic way, using memory barriers, making sure that the value can't be updated from a different core during the operation. +The default mode uses a sequentially consistent ordering memory model, which is quite expensive since it requires a full memory fence on all multi-core systems. +A relaxed model can be used for certain very specific operations, but the default model has the advantage of being safe in all situations. ## per-thread counters @@ -268,14 +328,21 @@ For generic per-thread counters, we have a class in tcounters.hh that should pro # Dealing with untrusted data -As a rule of thumb, any data received from outside the process should be considered as untrusted. That means data received on a socket, loaded from a file, retrieved from a database, etc.. Data received from an internal pipe might be excluded from that rule. +As a rule of thumb, any data received from outside the process should be considered as untrusted. +That means data received on a socket, loaded from a file, retrieved from a database, etc.. +Data received from an internal pipe might be excluded from that rule. -Untrusted data should never be trusted to adhere to the expected format or specifications, and a strict checking of boundaries should be performed. It means for example that, after reading the length for a field inside the data, whether that length does not exceed the total length of the data should be checked. In the same way, if we expect a numerical type we should check whether it matches one we expect and understand. +Untrusted data should never be trusted to adhere to the expected format or specifications, and a strict checking of boundaries should be performed. +It means for example that, after reading the length for a field inside the data, whether that length does not exceed the total length of the data should be checked. +In the same way, if we expect a numerical type we should check whether it matches one we expect and understand. -Anything unexpected should stop the processing and lead to the discarding of the complete data set. If a smaller data set can be safely discarded, and it is more important to load an incomplete set than to assure the integrity of the complete data set, only the faulty data set can be discarded instead. -alignment issues +Anything unexpected should stop the processing and lead to the discarding of the complete data set. +If a smaller data set can be safely discarded, and it is more important to load an incomplete set than to assure the integrity of the complete data set, only the faulty data set can be discarded instead. -When structured, binary data is received from the network or read from a file, it might be tempting to map it to an existing structure directly to make the parsing easier. But one must be careful about alignment issues on some architectures: +## alignment issues + +When structured, binary data is received from the network or read from a file, it might be tempting to map it to an existing structure directly to make the parsing easier. +But one must be careful about alignment issues on some architectures: ```c++ struct my_struct { @@ -294,7 +361,8 @@ void func(char* data, size_t offset, size_t length) { } ``` -Unfortunately this leads to undefined behaviour because the offset might not be aligned with the alignment requirement of the struct. One solution is to do a copy: +Unfortunately this leads to undefined behaviour because the offset might not be aligned with the alignment requirement of the struct. +One solution is to do a copy: ```c++ void func(char* data, size_t offset, size_t length) { @@ -307,7 +375,8 @@ void func(char* data, size_t offset, size_t length) { ## unsigned vs signed -Signed integer might overflow, and the resulting value is unpredictable, as this is an undefined behaviour. That means that this code result in an unpredictable value: +Signed integer might overflow, and the resulting value is unpredictable, as this is an undefined behaviour. +That means that this code result in an unpredictable value: ```c++ int8_t a = std::numeric_limits::max(); @@ -316,9 +385,12 @@ a++; One such example led to https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2006-01.html -It would be necessary to check that the value can't overflow first. Another possibility would be to instruct the compiler to treat signed overflow as it does for unsigned values, by wrapping. This can be done with `-fwrapv` with g++. +It would be necessary to check that the value can't overflow first. +Another possibility would be to instruct the compiler to treat signed overflow as it does for unsigned values, by wrapping. +This can be done with `-fwrapv` with g++. -An operation on an unsigned integer will never result in an overflow, because the value will simply wrap around. This might still result in an unexpected value, possibly bypassing a critical check: +An operation on an unsigned integer will never result in an overflow, because the value will simply wrap around. +This might still result in an unexpected value, possibly bypassing a critical check: ```c++ void parse_untrusted_data(uint8_t* data, uint16_t length) @@ -372,16 +444,21 @@ The `pdns::checked_conv()` function can be used, ensuring that the conversion ca ## fuzzing -Fuzzing is a very useful way to test a piece of code that parses untrusted data. Efficient fuzzers are often doing coverage-based fuzzing, where the code that they test have been compiled in a special way to allow the fuzzer to detect which branches are executed and which are not, so that the fuzzer can see the effect of mutating specific byte of the input on the code path. +Fuzzing is a very useful way to test a piece of code that parses untrusted data. +Efficient fuzzers are often doing coverage-based fuzzing, where the code that they test have been compiled in a special way to allow the fuzzer to detect which branches are executed and which are not, so that the fuzzer can see the effect of mutating specific byte of the input on the code path. -PowerDNS has a few fuzzing targets that can be used with libFuzzer or AFL in the pdns/ directory, and are built when `--enable-fuzzing-target` is passed to the configure. More information can be found in the [fuzzing/README.md](https://github.com/PowerDNS/pdns/blob/master/fuzzing/README.md) file. +PowerDNS has a few fuzzing targets that can be used with libFuzzer or AFL in the pdns/ directory, and are built when `--enable-fuzzing-target` is passed to the configure. +More information can be found in the [fuzzing/README.md](https://github.com/PowerDNS/pdns/blob/master/fuzzing/README.md) file. The existing fuzzing targets are run on the OSS-Fuzz infrastructure for a short time every time a pull request is opened, and for a longer time on the HEAD of the repository. # Others potential issues ## TOCTOU -The time-of-check time-of-use vulnerability is a very easy mistake to make when dealing with files or directory. The gist of it is that there is a small race condition between the time where a program might check the ownership, permissions or even existence of a file and the time it will actually do something with it. This time might be enough to allow an attacker to create a symbolic link to a critical file at the place of that exact file, for example. Since the program has enough rights to edit this file, this might allow an attacker to trick the program into writing into a completely different file. +The time-of-check time-of-use vulnerability is a very easy mistake to make when dealing with files or directory. +The gist of it is that there is a small race condition between the time where a program might check the ownership, permissions or even existence of a file and the time it will actually do something with it. +This time might be enough to allow an attacker to create a symbolic link to a critical file at the place of that exact file, for example. +Since the program has enough rights to edit this file, this might allow an attacker to trick the program into writing into a completely different file. This is hard to avoid in all cases, but some mitigations do help: @@ -392,21 +469,26 @@ This is hard to avoid in all cases, but some mitigations do help: ## Secrets -Try very hard not to load sensitive information in memory. And of course don't write to disk! +Try very hard not to load sensitive information in memory. +And of course don't write to disk! If you have to: * use an object that can't be copied by deleting the copy constructors and assignments operators, * try to lock the memory so it can't be swapped out to disk, or included in a core dump, via `sodium_malloc()` or `sodium_mlock()`, for example ; -* wipe the content before releasing the memory, so it won't linger around. Be careful that memset() is very often optimized out by the compiler, so function like `sodium_munlock()`, `explicit_bzero()` or `explicit_memset()` should be used instead. +* wipe the content before releasing the memory, so it won't linger around. + Be careful that memset() is very often optimized out by the compiler, so function like `sodium_munlock()`, `explicit_bzero()` or `explicit_memset()` should be used instead. ### Constant-time comparison -Don't compare secret against data using a naive string comparison, as the timing of the operation will leak information against the content of the secret. Ideally, a constant-time comparison should be used instead (see `constantTimeStringEquals()` in the PowerDNS code base) but it's not easy to achieve. One option might be to compute a HMAC of the secret using a key randomly generated at startup, and compare it against a HMAC of the supplied data computed with the same key. +Don't compare secret against data using a naive string comparison, as the timing of the operation will leak information against the content of the secret. +Ideally, a constant-time comparison should be used instead (see `constantTimeStringEquals()` in the PowerDNS code base) but it's not easy to achieve. +One option might be to compute a HMAC of the secret using a key randomly generated at startup, and compare it against a HMAC of the supplied data computed with the same key. ## Virtual destructors -Any class that is expected to be sub-classed should provide a virtual destructor. Not doing so will prevent the destructor of a derived class from being called if the object is held as the base type: +Any class that is expected to be sub-classed should provide a virtual destructor. +Not doing so will prevent the destructor of a derived class from being called if the object is held as the base type: ```c++ class Parent @@ -477,18 +559,25 @@ class Parent }; ``` -On a related topic, virtual methods should not be called from constructors or destructors. While this is allowed under certain restrictions, it's very hard to know exactly which method (base or derived) will be called, and whether all sub-objects contained in the class would have been correctly constructed at that point. +On a related topic, virtual methods should not be called from constructors or destructors. +While this is allowed under certain restrictions, it's very hard to know exactly which method (base or derived) will be called, and whether all sub-objects contained in the class would have been correctly constructed at that point. ## Hash collisions -Hashes are a very useful tool, used in `unordered_map` and `unordered_set` among others. They are also used in our caches. An important caveat that developers need to be aware about regarding hashes are that the probability of a collision is often a lot higher than expected. This is well-known as the birthday paradox, the fact that the probability of having to entries colliding is a lot higher than the probability of finding a collision for a specific entry. This means that it is important to verify that the entries are actually identical, and just not that they hash to the same value. +Hashes are a very useful tool, used in `unordered_map` and `unordered_set` among others. +They are also used in our caches. +An important caveat that developers need to be aware about regarding hashes are that the probability of a collision is often a lot higher than expected. +This is well-known as the birthday paradox, the fact that the probability of having to entries colliding is a lot higher than the probability of finding a collision for a specific entry. +This means that it is important to verify that the entries are actually identical, and just not that they hash to the same value. This is especially important when hashing attacker-controlled values, as they can be specially crafted to trigger collisions to cause: * cache pollution (see https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-06.html) ; * denial of service via hash table flooding (in a map, all entries that hash to the same value are often placed into a linked-list, making it possible to cause a linear scanning of entries by making all of them hash to the value). -The first issue can be prevented by comparing the entries and not just the value they hash to. The second one can be used by using some sort of secret when computing the hash so that the result cannot be guessed by the attacker. That can be achieved by using an unpredictable seed for certain hash algorithms, or a secret for some other like `SipHash`. +The first issue can be prevented by comparing the entries and not just the value they hash to. +The second one can be used by using some sort of secret when computing the hash so that the result cannot be guessed by the attacker. +That can be achieved by using an unpredictable seed for certain hash algorithms, or a secret for some other like `SipHash`. # Readability tips @@ -496,8 +585,11 @@ Some of these tips are actually enforced by `clang-tidy` nowadays, but it is sti ## Auto -C++11 introduced automatic type deduction, using the auto keyword. In addition to saving the typing of a few more letters, using automatic type deduction prevents nasty surprises if the variable is initialized from another one, or from a function, and the other type is changed to a different one. The code might still compile while now involving a copy or worse. -Boolean expressions +C++11 introduced automatic type deduction, using the auto keyword. +In addition to saving the typing of a few more letters, using automatic type deduction prevents nasty surprises if the variable is initialized from another one, or from a function, and the other type is changed to a different one. +The code might still compile while now involving a copy or worse. + +## Boolean expressions ## Explicit comparisons @@ -518,11 +610,13 @@ Object a(); // declares a function named a that returns an object ## nullptr -When representing a pointer, using `nullptr` makes it immediately obvious that we are dealing with a pointer, as opposed to the use of `0`. It also can't be silently taken as an integer, which can happens with `0` but also with `NULL`. +When representing a pointer, using `nullptr` makes it immediately obvious that we are dealing with a pointer, as opposed to the use of `0`. +It also can't be silently taken as an integer, which can happens with `0` but also with `NULL`. ## const-ness -* Mark parameters and variables that should not be modified as `const`. This is especially true for references and pointers that comes from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later. +* Mark parameters and variables that should not be modified as `const`. + This is especially true for references and pointers that comes from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later. * Mark const methods as such (and make them thread-safe) * Prefer using `at()` on containers so that no insertion can take place by mistake, and to get bounds checking. @@ -537,19 +631,22 @@ For the same reason, global variables that are only accessed from a single file ## Variables -Try to declare variables in the innermost scope possible and avoid uninitialized variables as much as possible. Declare and initialize them when the values needed to initialize them are available. +Try to declare variables in the innermost scope possible and avoid uninitialized variables as much as possible. +Declare and initialize them when the values needed to initialize them are available. ## Exceptions Should be reserved to unexpected events (corrupted data, timeouts, ...) and should not be triggered in normal processing. -Don't be afraid of using them, though, as the cost of an exception that is not thrown is usually very small, thanks to the zero-cost exception model. It might still force the compiler to refrain from some optimizations, so it might make sense to avoid them in some very performance-sensitive, narrow code paths. +Don't be afraid of using them, though, as the cost of an exception that is not thrown is usually very small, thanks to the zero-cost exception model. +It might still force the compiler to refrain from some optimizations, so it might make sense to avoid them in some very performance-sensitive, narrow code paths. ### Custom exceptions Exceptions defined by the standards should be used whenever possible, as they already cover a lot of use cases. -If custom exceptions are necessary, to be able to catch them explicitly, they should still derive from `std::exception`, directly or indirectly, so that they can still be caught in a more generic way to prevent the program from terminating. For example, the main connection handling function of a server can catch `std::exception` and just terminate the current connection if an uncaught exception bubbles up. +If custom exceptions are necessary, to be able to catch them explicitly, they should still derive from `std::exception`, directly or indirectly, so that they can still be caught in a more generic way to prevent the program from terminating. +For example, the main connection handling function of a server can catch `std::exception` and just terminate the current connection if an uncaught exception bubbles up. ### Catching exceptions @@ -567,16 +664,26 @@ Not using a reference would result in the exception object being sliced, meaning ## Casts -C-style casts should be avoided, as the compiler does almost no check on the validity of the operation. They are also very hard to spot in a code. C++-style casts can easily be spotted in a code, which makes it easy to review them. - -* `const_cast` can be used to remove the const qualifier on a variable. It's usually a bad sign, but sometimes it is needed to call a function that will not modify the variable but lacks the const qualifier, for example. -* `dynamic_cast` can be used to cast a pointer to a derived class or to a base class, while checking that the operation is valid. If the casted object is not valid for the intended type, a nullptr value will be returned (or a bad_cast exception for references) so the result of the operation should be checked! Note that the RTTI check needed to verify that the casted object is valid has a non-negligible CPU cost. Not checking the return value might lead to remote denial of service by nullptr dereference, as happened with the issue described in this advisory: https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-08.html -* `static_cast` can perform downcast in place of `dynamic_cast`, with none of the cost associated to the check, but can only be done if the cast is known to be valid. It can also do implicit conversion between types (from `ssize_t` to `size_t`, AFTER checking that the value is greater or equal to zero). -* `reinterpret_cast` is quite dangerous, since it can be used to turn a type into a different one. It can't be be used to remove a const qualifier. When used to reinterpret the content of a buffer it can quickly lead to alignment issues, as described in the [alignment issues] section. +C-style casts should be avoided, as the compiler does almost no check on the validity of the operation. +They are also very hard to spot in a code. +C++-style casts can easily be spotted in a code, which makes it easy to review them. + +* `const_cast` can be used to remove the const qualifier on a variable. + It's usually a bad sign, but sometimes it is needed to call a function that will not modify the variable but lacks the const qualifier, for example. +* `dynamic_cast` can be used to cast a pointer to a derived class or to a base class, while checking that the operation is valid. + If the casted object is not valid for the intended type, a nullptr value will be returned (or a bad_cast exception for references) so the result of the operation should be checked! Note that the RTTI check needed to verify that the casted object is valid has a non-negligible CPU cost. + Not checking the return value might lead to remote denial of service by nullptr dereference, as happened with the issue described in this advisory: https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-08.html +* `static_cast` can perform downcast in place of `dynamic_cast`, with none of the cost associated to the check, but can only be done if the cast is known to be valid. + It can also do implicit conversion between types (from `ssize_t` to `size_t`, AFTER checking that the value is greater or equal to zero). +* `reinterpret_cast` is quite dangerous, since it can be used to turn a type into a different one. + It can't be be used to remove a const qualifier. + When used to reinterpret the content of a buffer it can quickly lead to alignment issues, as described in the [alignment issues] section. ## errno -`errno` is only guaranteed to be set on failing system calls and not set on succeeding system calls. A library call may clobber `errno`, even when it succeeds. Safe practise is: +`errno` is only guaranteed to be set on failing system calls and not set on succeeding system calls. +A library call may clobber `errno`, even when it succeeds. +Safe practise is: * Only look at `errno` on failing systems calls or when a library function is documented to set `errno`. * Immediately save the value of `errno` after a system call for later decision making in a local variable. From b638b4d2eff4d727e0f87c775e1ee755e46f9790 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 9 Aug 2023 19:15:04 +0200 Subject: [PATCH 498/909] add a few links; collection of small nits --- CODING_GUIDELINES.md | 185 ++++++++++++++++++++++--------------------- 1 file changed, 93 insertions(+), 92 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index bdc92159d403..6e13f29547f7 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -1,7 +1,7 @@ Coding guidelines for contributing to PowerDNS ---------------------------------------------- -Thank you for you interest to contribute to the PowerDNS project. +Thank you for you interest in contributing to the PowerDNS project. This document describes the general coding guidelines to keep in mind when contributing code to our code base. It does assume that you have already read the contributing document at [CONTRIBUTING.md](https://github.com/PowerDNS/pdns/blob/master/CONTRIBUTING.md). @@ -15,24 +15,24 @@ It does assume that you have already read the contributing document at [CONTRIBU # Memory handling The memory model in C++, inherited from the C era, is very powerful but also very error-prone. -Several features are available in modern (C++11) C++ to make it possible to avoid most of the pitfalls, while conserving the same level of performance. +Several features are available in modern (C++11 and up) C++ to make it possible to avoid most of the pitfalls, while conserving the same level of performance. -Most of the issues related to memory allocation (memory leaks, use-after-free) can be solved by using it via standard containers, or taking advantage of RAII and smart pointers, which take care of destructing the object when it's not used anymore. +Most of the issues related to memory allocation (memory leaks, use-after-free) can be solved by using standard containers, or taking advantage of RAII and smart pointers, which take care of destructing the object when it is not used anymore. ## Stack-based memory allocation -Default allocations, when declaring a variable local to a function for example, is done on the stack instead of doing a dynamic allocation on the heap. +Default allocations, when declaring a variable local to a function for example, are done on the stack instead of doing a dynamic allocation on the heap. Allocating objects on the stack is faster, especially in threaded programs, and provides the benefit that objects are automatically destroyed when the function is exited. -One caveat is that the programmer needs to be wary about the size of the object in order not to exceed the space available on the stack, which would corrupt other objects in memory and could lead to a crash, or even execution of arbitrary code. -This is especially true in the recursor which uses a custom stack-switching in user-space mechanism and thus has a reduced stack size. +One caveat is that the programmer needs to be wary of is the size of the object in order not to exceed the space available on the stack, which would corrupt other objects in memory and could lead to a crash, or even execution of arbitrary code. +This is especially true in the Recursor which uses a custom stack-switching in user-space mechanism and thus has a reduced stack size. ### Variable-Length Arrays -In order to avoid smashing the stack, a special care should be taken to limit the depth of function calls that can grow quickly with recursion, for example. +In order to avoid smashing the stack, special care should be taken to limit the depth of function calls that, for example, can grow quickly with recursion. A second common source of smash stacking is the use of Variable-Length Arrays, whose size is determined at runtime and is therefore very hard to predict. -The C++ language doesn't support VLAs but a lot of compilers inherit such a support from C99, so it's possible to use them by mistake. -PowerDNS strictly forbids the use of VLAs, as does the Linux kernel, and enforce that with the `-Werror=vla` compiler flag. +The C++ language does not support VLAs but a lot of compilers inherit such a support from C99, so it is possible to use them by accident. +PowerDNS strictly forbids the use of VLAs, as does the Linux kernel, and enforces that with the `-Werror=vla` compiler flag. ### C-style arrays @@ -45,7 +45,7 @@ auto& firstElement = buffer[0]; ``` It is immediately obvious that computing the actual number of elements is error-prone, as `sizeof()` does not return the number of elements but the total memory space used by the array. -An other obvious issue is that accesses to the array are not bound-checked. +Another obvious issue is that accesses to the array are not bound-checked. These are not the only drawbacks of these arrays, but are bad enough already to justify getting rid of them. The modern C++ way is to use `std::array`s: @@ -56,26 +56,26 @@ auto bufferSize = buffer.size(); auto& firstElement = buffer.at(0); ``` -### Alloca +### alloca The use of `alloca()` is forbidden in the code base as it is much too easy to smash the stack. ## RAII -Resource acquisition is initialization (RAII) is one of the fundamental concept in C++. +Resource acquisition is initialization ([RAII](https://en.cppreference.com/w/cpp/language/raii)) is one of the fundamental concepts in C++. Resources are allocated during the construction of an object and destroyed when the object is itself destructed. -It means that if an object is correctly designed, the resource associated to it can not survive its lifetime. +It means that if an object is correctly designed, the resources associated with it can not survive its lifetime. Since objects that are allocated on the stack (local variables in a function, for example) are automatically destroyed when a function is exited, be it by reaching the last line, calling return or throwing an exception, it makes it possible to ensure that resources are always properly destroyed by wrapping them into an object. -We describe the use of smart pointers, containers and other wrappers to that mean below, but first a few words of caution. +We describe the use of smart pointers, containers and other wrappers for that purpose below, but first a few words of caution. Resources stored in a object are only tied to this object if the constructor finished properly. If an exception is raised in the constructor body, the object is not created and therefore the destructor will not get called. This means that if the object has non-object members holding resources, like naked file descriptors or naked pointers, they need to be explicitly released before raising the exception, otherwise they are lost. ```C++ -class BadFileDescriptionWrapper +class BadFileDescriptorWrapper { - BadFileDescriptionWrapper() + BadFileDescriptorWrapper() { d_fd = open(...); if (something) { @@ -83,7 +83,7 @@ class BadFileDescriptionWrapper } ... } - ~BadFileDescriptionWrapper() + ~BadFileDescriptorWrapper() { if (d_fd > 0) { close(d_fd); @@ -102,7 +102,7 @@ private: The use of smart pointers can be a solution to most resources leakage, but otherwise the only way is to be careful about exceptions in constructors: ```C++ -BadFileDescriptionWrapper() +BadFileDescriptorWrapper() { d_fd = open(...); if (something) { @@ -116,29 +116,29 @@ BadFileDescriptionWrapper() ## Smart pointers There is almost no good reason not to use a smart pointer when doing dynamic memory allocation. -Smart pointers will keep track of whether the dynamically allocated object is still used, and destroy when the last user goes away. +Smart pointers will keep track of whether the dynamically allocated object is still used, and destroy it when the last user goes away. -Using naked pointers quickly results in security issues, going from memory leaks to arbitrary code execution. +Using naked pointers quickly results in security issues, ranging from memory leaks to arbitrary code execution. Examples of such issues can be found in the following PowerDNS security advisories: -* https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-07.html -* https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-04.html +* [2017-07: Memory leak in DNSSEC parsing](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-07.html) +* [2018-04: Crafted answer can cause a denial of service](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-04.html) -Most allocations should be wrapped in a `std::unique_pointer`, using `make_unique`. +Most allocations should be wrapped in a `std::unique_ptr`, using `make_unique`. There can only be one owner at a given time, as opposed to shared pointers, but the ownership can be passed along using `std::move()` if needed. -If the dynamically allocated object needs to be referenced in several places, the use of a `std::shared_pointer` is advised instead, via `std::make_shared`. +If the dynamically allocated object needs to be referenced in several places, the use of a `std::shared_ptr` is advised instead, via `std::make_shared`. -The use of the `make_*` methods have three advantages: +The use of the `make_*` methods has three advantages: -* they result in a single allocation for `shared_pointer`s, instead of two otherwise ; +* they result in a single allocation for `shared_ptr`s, instead of two otherwise ; * they avoid duplicating the type name twice ; * they prevent a possible issue if an exception is raised with temporaries. They also make is easier to spot naked pointers by looking for "new" and "delete" throughout the code :) Please note however that while unique pointers are as cheap as naked pointers, shared pointers are much more expensive. -That's because they need to use atomic operations to update their internal counters, so making a copy of a shared pointer is expensive. +That is because they need to use atomic operations to update their internal counters, so making a copy of a shared pointer is expensive. Passing one by reference is cheap, however. ### Shared pointers @@ -155,7 +155,7 @@ for (auto idx = 0; idx < 10 ; idx++){ } ``` -But there is a race if one thread update the exact same smart pointer that another thread is trying to read: +But there is a race if one thread updates the exact same smart pointer that another thread is trying to read: ```c++ auto ptr = std::make_shared(4); @@ -186,13 +186,13 @@ auto cert = std::unique_ptr(PEM_read_X509_AUX(fp.get ``` Unfortunately there are a few cases where smart pointers cannot be used. -In the PowerDNS products, these cases have been mostly reduced to a few select classes, like the `pdns::channel` ones, that are used to pass pointers to a different thread by writing them to a pipe, as is done for example by the queries distributors of the auth and the rec. +In the PowerDNS products, these cases have been mostly reduced to a few select classes, like the `pdns::channel` ones, that are used to pass pointers to a different thread by writing them to a pipe, as is done for example by the query distributors of the auth and the rec. -When it happens, special care should be taken to: +When smart pointers cannot be used, special care should be taken to: * make sure that every exit point frees the allocated memory (early return, goto, exceptions..) ; * set the pointer to `nullptr` right after the deallocation, so we can't use it again (use-after-free) ; -* do not mix `malloc` with `delete`, `new` with `free` (destructors are not run, at the very least) ; +* do not mix `malloc` with `delete`, or `new` with `free` (destructors are not run, at the very least) ; * do not mix array allocations (`new[]`) with a non-array `delete` (vs `delete[]`). ## Pointer arithmetic @@ -201,13 +201,13 @@ It is very common to use pointer arithmetic to calculate a position in a buffer, Unfortunately it is quite easy to trigger undefined behaviour when doing so, as the C++ standard does not allow pointer arithmetic pointing inside an object, except for arrays where it is also permitted to point one element past the end. Still that undefined behaviour is mostly harmless, but it might lead to real issue on some platforms. -One such example occurred in dnsdist: https://dnsdist.org/security-advisories/powerdns-advisory-for-dnsdist-2017-01.html +One such example occurred in dnsdist: [2017-01: Crafted backend responses can cause a denial of service](https://dnsdist.org/security-advisories/powerdns-advisory-for-dnsdist-2017-01.html) -In that case, a pointer was set to the start of a buffer plus a given length, to see whether the result go past another pointer that was set to the end of the buffer. +In that case, a pointer was set to the start of a buffer plus a given length, to see whether the result would go past another pointer that was set to the end of the buffer. Unfortunately, if the start of the buffer is at a very high virtual address, the result of the addition might overflow and wrap around, causing the check to become true and leading to either a crash or the reading of unrelated memory. While very unlikely on a 64 bits platform, it could happen on 16 or 32 bits platform. -This kind of issue is best avoided by the use of container to prevent the need of pointer arithmetic, or by very careful to only add checked offsets to a pointer. +This kind of issue is best avoided by the use of containers to avoid the need for pointer arithmetic, or by being very careful to only add checked offsets to a pointer. ### Containers @@ -217,16 +217,16 @@ The use of containers like `vector`, `map` or `set` has several advantages in te * it prevents a disconnect between the actual size and the variable tracking that size ; * it provides safe (and fast) operations like comparisons, iterators, etc.. -One issue that could have been prevented by the use of a container can be found in the following advisory: https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-09.html +One issue that could have been prevented by the use of a container can be found in the following advisory: [2018-09: Crafted query can cause a denial of service](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-09.html) The use of a container and its corresponding `at()` operator would have prevented an out-of-bounds read since calling `at()` on an invalid offset results in an exception being raised. -The cost of using `at()` is negligible for most use cases, and can be avoided by using the `[]` operator in the rate case when the cost can't be afforded. +The cost of using `at()` is negligible for most use cases, and can be avoided by using the `[]` operator in the rare case when the cost cannot be afforded. Note that several Linux distributions now build with `-Wp,-D_GLIBCXX_ASSERTIONS` enabled by default, which turns on cheap range checks for C++ arrays, vectors, and strings anyway. Regarding performance, it is advised to `reserve()` the needed size in advance when a rough estimate is known to avoid reallocations and copies. Resizing in advance is not advised, though, as it makes it harder to know what is exactly in the container in case of early returns or exceptions. -In C++11, move operations make it possible to cheaply get the content of a container into a different variable if needed. +In C++11, move operators make it possible to cheaply get the contents of a container into a different variable if needed. The need to pass a subset of a container without copying it often leads to passing a pointer to an array of chars along with a size. Introduced in C++14 but already available in PowerDNS via boost (see views.hh), views provides a nice way to borrow the content of a container to pass it to a function, without any copy or dynamic memory allocation. @@ -236,44 +236,44 @@ The basic `string_view` class provides that feature for a container of chars, bu # Threads and concurrency All of our products use threading to be able to take advantage of the increasing number of cores on modern CPUs. -That inevitably leads to the question of how to synchronise data accesses between threads. +This inevitably leads to the question of how to synchronise data accesses between threads. Most objects, like containers, cannot be accessed from more than one thread at once. Even `const` methods on containers might not be thread-safe. For example getting the `size()` of a container might not be thread-safe if a different thread might be writing to the container. Some functions might also not be thread-safe, for example if they have a static non-const variable. We currently use three solutions, depending on the use-case. -The first one is used when we only need to share some kind of counters or gauges, and involves the use of `std::atomic` which allows atomic operations to be performed from different threads without locking. +The first one is used when we only need to share some kind of counter or gauge, and involves the use of `std::atomic` which allows atomic operations to be performed from different threads without locking. More on that later. -The second one is the "share nothing" approach, where each thread has its own data (using `thread_local`, for example), avoiding the need to data synchronization. -When a thread needs to communicate with another one, it might use an pdns::channel to pass a pointer to that second thread. +The second one is the "share nothing" approach, where each thread has its own data (using `thread_local`, for example), avoiding the need for data synchronization. +When a thread needs to communicate with another one, it might use a `pdns::channel` to pass a pointer to that second thread. That works quite well but sometimes sharing data is much more efficient than the alternative. For these cases, we use the classic locking approach, using either a simple mutex or read-write lock, depending on the use case. -## locks +## Locks -Locks allow a thread of execution to ensure that no other will try to access the code path or data they protect at the same time. +Locks allow a thread of execution to ensure that no other thread will try to access the code path or data they protect at the same time. -There are a few pitfalls to avoid then using locks: +There are a few pitfalls to avoid when using locks: -* avoiding to release the lock, which can be avoided by wrappers like `std::lock_guard`, `std::unique_lock` and our own wrappers: look for `LockGuarded`, `SharedLockGuarded` in lock.hh ; +* failing to release the lock, which can be avoided by wrappers like `std::lock_guard`, `std::unique_lock` and our own wrappers: look for `LockGuarded`, `SharedLockGuarded` in lock.hh ; * high contention, where threads are blocked for a long time while waiting to acquire a lock. - This can be solved by carefully examining the portion of code that really needs to hold the lock, making the critical path faster, or by using sharding which basically divide the data protected by the lock in several blocks, each one of them protected by its own lock ; + This can be solved by carefully examining the portion of code that really needs to hold the lock, making the critical path faster, or by using sharding which basically divides the data protected by the lock into several blocks, each one of them protected by its own lock ; * starvation, which occurs for example when thread 1 acquires lock 1 and wants to acquire lock 2, which is already owned by thread 2, itself currently waiting to acquire lock 1. This can be avoided by a better design of the locking mechanism, and assuring that locks are always acquired in the same order if more than one lock is needed. -There are more than one type of locks: +There are several types of locks: -* spinlock are very fast but are busy-waiting, meaning that they don't pause but repetitively try to get hold of the lock, using 100% of one core doing so unless preempted by the OS. +* spinlocks are very fast but are busy-waiting, meaning that they do not pause, but instead repetitively try to get hold of the lock, using 100% of one core doing so unless preempted by the OS. So they are only suited for locks that are almost never contented ; * a mutex is a very simple lock. - In most implementations it's a very fast lock, implemented in user-space on recent Linux kernels and glibc ; + In most implementations it is a very fast lock, implemented in user-space on recent Linux kernels and glibc ; * a read-write lock allows several threads to acquire it in read mode, but only one thread can acquire it in write mode. - This is suited when most accesses are read-only and writes are rare and don't take too long. + This is suited when most accesses are read-only and writes are rare and do not take too long. Otherwise a mutex might actually be faster ; -One quick word about condition variables, that allows a thread to notify one or more threads waiting for a condition to happen. +One quick word about condition variables, that allow a thread to notify one or more threads waiting for a condition to happen. A thread should acquire a mutex using a `std::unique_lock` and call the `wait()` method of the condition variable. This is a very useful mechanism but one must be careful about two things: @@ -281,7 +281,7 @@ This is a very useful mechanism but one must be careful about two things: Waking up several threads if only one has something to do (known as a "thundering herd") is bad practice, but there are some cases where it makes sense ; * a consumer might be waken up spuriously, which can be avoided by passing a predicate (which can be as simple as a small lambda function) to `wait()`. -Our wrappers, `LockGuarded`, `SharedLockGuarded` in lock.hh, should always be preferred over other solutions. +Our wrappers, `LockGuarded`, `SharedLockGuarded` in `lock.hh`, should always be preferred over other solutions. They provide a way to wrap any data structure as protected by a lock (mutex or shared mutex), while making it immediately clear which data is protected by that lock, and preventing any access to the data without holding the lock. For example, to protect a set of integers with a simple mutex: @@ -318,18 +318,18 @@ Or when the lock needs to be kept for a bit longer: ## atomic `std::atomic` provides a nice way to share a counter or gauge between threads without the need for locking. -This is done by implementing operations like reading, increasing, decreasing or writing a value in an atomic way, using memory barriers, making sure that the value can't be updated from a different core during the operation. +This is done by implementing operations like reading, increasing, decreasing or writing a value in an atomic way, using memory barriers, making sure that the value cannot be updated from a different core during the operation. The default mode uses a sequentially consistent ordering memory model, which is quite expensive since it requires a full memory fence on all multi-core systems. A relaxed model can be used for certain very specific operations, but the default model has the advantage of being safe in all situations. ## per-thread counters -For generic per-thread counters, we have a class in tcounters.hh that should provide better performances by allowing each thread to independently update its own counter, the costly operation only happening when the counter needs to be read by one thread gathering metrics from all threads. +For generic per-thread counters, we have a class in `tcounters.hh` that should provide better performances by allowing each thread to independently update its own counter, the costly operation only happening when the counter needs to be read by one thread gathering metrics from all threads. # Dealing with untrusted data As a rule of thumb, any data received from outside the process should be considered as untrusted. -That means data received on a socket, loaded from a file, retrieved from a database, etc.. +That means data received on a socket, loaded from a file, retrieved from a database, etc. Data received from an internal pipe might be excluded from that rule. Untrusted data should never be trusted to adhere to the expected format or specifications, and a strict checking of boundaries should be performed. @@ -375,17 +375,17 @@ void func(char* data, size_t offset, size_t length) { ## unsigned vs signed -Signed integer might overflow, and the resulting value is unpredictable, as this is an undefined behaviour. -That means that this code result in an unpredictable value: +Signed integers might overflow, and the resulting value is unpredictable, as this overflow is undefined behaviour. +That means that this code results in an unpredictable value: ```c++ int8_t a = std::numeric_limits::max(); a++; ``` -One such example led to https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2006-01.html +One such example led to [2006-01: Malformed TCP queries can lead to a buffer overflow which might be exploitable](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2006-01.html). -It would be necessary to check that the value can't overflow first. +It would be necessary to check that the value cannot overflow first. Another possibility would be to instruct the compiler to treat signed overflow as it does for unsigned values, by wrapping. This can be done with `-fwrapv` with g++. @@ -445,17 +445,17 @@ The `pdns::checked_conv()` function can be used, ensuring that the conversion ca ## fuzzing Fuzzing is a very useful way to test a piece of code that parses untrusted data. -Efficient fuzzers are often doing coverage-based fuzzing, where the code that they test have been compiled in a special way to allow the fuzzer to detect which branches are executed and which are not, so that the fuzzer can see the effect of mutating specific byte of the input on the code path. +Efficient fuzzers are often doing coverage-based fuzzing, where the code that they test has been compiled in a special way to allow the fuzzer to detect which branches are executed and which are not, so that the fuzzer can see the effect of mutating specific bytes of the input on the code path. -PowerDNS has a few fuzzing targets that can be used with libFuzzer or AFL in the pdns/ directory, and are built when `--enable-fuzzing-target` is passed to the configure. +PowerDNS has a few fuzzing targets that can be used with libFuzzer or AFL in the `pdns/` directory, and are built when `--enable-fuzzing-target` is passed to `configure`. More information can be found in the [fuzzing/README.md](https://github.com/PowerDNS/pdns/blob/master/fuzzing/README.md) file. The existing fuzzing targets are run on the OSS-Fuzz infrastructure for a short time every time a pull request is opened, and for a longer time on the HEAD of the repository. -# Others potential issues +# Other potential issues ## TOCTOU -The time-of-check time-of-use vulnerability is a very easy mistake to make when dealing with files or directory. +The time-of-check to time-of-use vulnerability is a very easy mistake to make when dealing with files or directories. The gist of it is that there is a small race condition between the time where a program might check the ownership, permissions or even existence of a file and the time it will actually do something with it. This time might be enough to allow an attacker to create a symbolic link to a critical file at the place of that exact file, for example. Since the program has enough rights to edit this file, this might allow an attacker to trick the program into writing into a completely different file. @@ -469,20 +469,20 @@ This is hard to avoid in all cases, but some mitigations do help: ## Secrets -Try very hard not to load sensitive information in memory. -And of course don't write to disk! +Try very hard not to load sensitive information into memory. +And of course do not write to disk! If you have to: -* use an object that can't be copied by deleting the copy constructors and assignments operators, -* try to lock the memory so it can't be swapped out to disk, or included in a core dump, via `sodium_malloc()` or `sodium_mlock()`, for example ; -* wipe the content before releasing the memory, so it won't linger around. - Be careful that memset() is very often optimized out by the compiler, so function like `sodium_munlock()`, `explicit_bzero()` or `explicit_memset()` should be used instead. +* use an object that can't be copied, by deleting the copy constructors and assignments operators, +* try to lock the memory so it cannot be swapped out to disk, or included in a core dump, via `sodium_malloc()` or `sodium_mlock()`, for example ; +* wipe the content before releasing the memory, so it will not linger around. + Do note that `memset()` is very often optimized out by the compiler, so function like `sodium_munlock()`, `explicit_bzero()` or `explicit_memset()` should be used instead. ### Constant-time comparison -Don't compare secret against data using a naive string comparison, as the timing of the operation will leak information against the content of the secret. -Ideally, a constant-time comparison should be used instead (see `constantTimeStringEquals()` in the PowerDNS code base) but it's not easy to achieve. +Don't compare secret against data using a naive string comparison, as the timing of the operation will leak information about the content of the secret. +Ideally, a constant-time comparison should be used instead (see `constantTimeStringEquals()` in the PowerDNS code base) but it is not always easy to achieve. One option might be to compute a HMAC of the secret using a key randomly generated at startup, and compare it against a HMAC of the supplied data computed with the same key. ## Virtual destructors @@ -516,13 +516,13 @@ std::vector myObjects; myObjects.push_back(Child()); ``` -Be careful that defining a destructor will prevent the automatic creation of move operations for that class, since they are generated only if these conditions are met: +Note that defining a destructor will prevent the automatic creation of move operators for that class, since they are generated only if these conditions are met: -* no copy operations are declared ; -* no move operations are declared ; +* no copy operators are declared ; +* no move operators are declared ; * no destructor is declared. -If the Parent class holds data that is costly to copy, it might make sense to declare the move operations explicitly: +If the Parent class holds data that is costly to copy, it might make sense to declare the move operators explicitly: ```c++ class Parent @@ -540,7 +540,7 @@ private: }; ``` -Note that declaring the move operations disables the copy operations, so if they are still needed: +Note that declaring the move operators disables the copy operators, so if they are still needed: ```c++ class Parent @@ -560,20 +560,20 @@ class Parent ``` On a related topic, virtual methods should not be called from constructors or destructors. -While this is allowed under certain restrictions, it's very hard to know exactly which method (base or derived) will be called, and whether all sub-objects contained in the class would have been correctly constructed at that point. +While this is allowed under certain restrictions, it is very hard to know exactly which method (base or derived) will be called, and whether all sub-objects contained in the class would have been correctly constructed at that point. ## Hash collisions Hashes are a very useful tool, used in `unordered_map` and `unordered_set` among others. They are also used in our caches. An important caveat that developers need to be aware about regarding hashes are that the probability of a collision is often a lot higher than expected. -This is well-known as the birthday paradox, the fact that the probability of having to entries colliding is a lot higher than the probability of finding a collision for a specific entry. +This is well-known as the birthday paradox, the fact that the probability of having two entries colliding is a lot higher than the probability of finding a collision for a specific entry. This means that it is important to verify that the entries are actually identical, and just not that they hash to the same value. This is especially important when hashing attacker-controlled values, as they can be specially crafted to trigger collisions to cause: -* cache pollution (see https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-06.html) ; -* denial of service via hash table flooding (in a map, all entries that hash to the same value are often placed into a linked-list, making it possible to cause a linear scanning of entries by making all of them hash to the value). +* cache pollution (see [2018-06: Packet cache pollution via crafted query](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-06.html)) ; +* denial of service via hash table flooding (in a map, all entries that hash to the same value are often placed into a linked-list, making it possible to cause a linear scan of entries by making all of them hash to that same value). The first issue can be prevented by comparing the entries and not just the value they hash to. The second one can be used by using some sort of secret when computing the hash so that the result cannot be guessed by the attacker. @@ -583,9 +583,9 @@ That can be achieved by using an unpredictable seed for certain hash algorithms, Some of these tips are actually enforced by `clang-tidy` nowadays, but it is still useful to keep them in mind. -## Auto +## auto -C++11 introduced automatic type deduction, using the auto keyword. +C++11 introduced automatic type deduction, using the `auto` keyword. In addition to saving the typing of a few more letters, using automatic type deduction prevents nasty surprises if the variable is initialized from another one, or from a function, and the other type is changed to a different one. The code might still compile while now involving a copy or worse. @@ -593,7 +593,7 @@ The code might still compile while now involving a copy or worse. ## Explicit comparisons -* compare numerical values to `0` or `!= 0` explicitly ; +* compare numerical values with `== 0` or `!= 0` explicitly ; * compare to `false` explicitly, which is easier to read ; * compare to `nullptr` for the same reason. @@ -602,7 +602,7 @@ The code might still compile while now involving a copy or worse. Use braced initialization for members as often as possible: * it does forbid narrowing conversions -* and avoids C++'s "move vexing parse" which is to declare a function instead of calling the default constructor: +* and avoids C++'s "[most vexing parse](https://en.wikipedia.org/wiki/Most_vexing_parse)" which is to declare a function instead of calling the default constructor: ```c++ Object a(); // declares a function named a that returns an object @@ -611,12 +611,12 @@ Object a(); // declares a function named a that returns an object ## nullptr When representing a pointer, using `nullptr` makes it immediately obvious that we are dealing with a pointer, as opposed to the use of `0`. -It also can't be silently taken as an integer, which can happens with `0` but also with `NULL`. +It also cannot be silently taken as an integer, which can happens with `0` but also with `NULL`. ## const-ness * Mark parameters and variables that should not be modified as `const`. - This is especially true for references and pointers that comes from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later. + This is especially important for references and pointers that comes from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later. * Mark const methods as such (and make them thread-safe) * Prefer using `at()` on containers so that no insertion can take place by mistake, and to get bounds checking. @@ -636,9 +636,9 @@ Declare and initialize them when the values needed to initialize them are availa ## Exceptions -Should be reserved to unexpected events (corrupted data, timeouts, ...) and should not be triggered in normal processing. +Should be reserved for unexpected events (corrupted data, timeouts, ...) and should not be triggered in normal processing. -Don't be afraid of using them, though, as the cost of an exception that is not thrown is usually very small, thanks to the zero-cost exception model. +Do not be afraid of using them, though, as the cost of an exception that is not thrown is usually very small, thanks to the zero-cost exception model. It might still force the compiler to refrain from some optimizations, so it might make sense to avoid them in some very performance-sensitive, narrow code paths. ### Custom exceptions @@ -671,19 +671,20 @@ C++-style casts can easily be spotted in a code, which makes it easy to review t * `const_cast` can be used to remove the const qualifier on a variable. It's usually a bad sign, but sometimes it is needed to call a function that will not modify the variable but lacks the const qualifier, for example. * `dynamic_cast` can be used to cast a pointer to a derived class or to a base class, while checking that the operation is valid. - If the casted object is not valid for the intended type, a nullptr value will be returned (or a bad_cast exception for references) so the result of the operation should be checked! Note that the RTTI check needed to verify that the casted object is valid has a non-negligible CPU cost. + If the casted object is not valid for the intended type, a nullptr value will be returned (or a bad_cast exception for references) so the result of the operation should be checked! + Note that the RTTI check needed to verify that the casted object is valid has a non-negligible CPU cost. Not checking the return value might lead to remote denial of service by nullptr dereference, as happened with the issue described in this advisory: https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-08.html * `static_cast` can perform downcast in place of `dynamic_cast`, with none of the cost associated to the check, but can only be done if the cast is known to be valid. It can also do implicit conversion between types (from `ssize_t` to `size_t`, AFTER checking that the value is greater or equal to zero). * `reinterpret_cast` is quite dangerous, since it can be used to turn a type into a different one. - It can't be be used to remove a const qualifier. + It cannot be be used to remove a const qualifier. When used to reinterpret the content of a buffer it can quickly lead to alignment issues, as described in the [alignment issues] section. ## errno `errno` is only guaranteed to be set on failing system calls and not set on succeeding system calls. A library call may clobber `errno`, even when it succeeds. -Safe practise is: +Safe practice is: * Only look at `errno` on failing systems calls or when a library function is documented to set `errno`. -* Immediately save the value of `errno` after a system call for later decision making in a local variable. +* Immediately save the value of `errno` in a local variable after a system call for later decision making. From 5d22d822e4885e7bed58e9527d6aea40940e5df6 Mon Sep 17 00:00:00 2001 From: Frank Louwers Date: Thu, 10 Aug 2023 14:44:51 +0200 Subject: [PATCH 499/909] Document default for `webserver-loglevel` --- docs/settings.rst | 1 + pdns/recursordist/docs/settings.rst | 1 + 2 files changed, 2 insertions(+) diff --git a/docs/settings.rst b/docs/settings.rst index bff6068e968a..95d3956baad6 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -1906,6 +1906,7 @@ Note that this option only applies to credentials stored in the configuration as ---------------------- - String, one of "none", "normal", "detailed" +- Default: normal The amount of logging the webserver must do. "none" means no useful webserver information will be logged. When set to "normal", the webserver will log a line per request that should be familiar:: diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index fc3f1e0c98cf..85825b32bcb5 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -2515,6 +2515,7 @@ Note that this option only applies to credentials stored in the configuration as .. versionadded:: 4.2.0 - String, one of "none", "normal", "detailed" +- Default: normal The amount of logging the webserver must do. "none" means no useful webserver information will be logged. When set to "normal", the webserver will log a line per request that should be familiar:: From 1caeb33cdd0263cccc331b8c018f45f9e781dfde Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 10 Aug 2023 16:51:23 +0200 Subject: [PATCH 500/909] Coding Guidelines: Properly capitalize section names --- CODING_GUIDELINES.md | 64 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 6e13f29547f7..5d2518818778 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -1,25 +1,25 @@ -Coding guidelines for contributing to PowerDNS +Coding Guidelines for Contributing to PowerDNS ---------------------------------------------- Thank you for you interest in contributing to the PowerDNS project. This document describes the general coding guidelines to keep in mind when contributing code to our code base. It does assume that you have already read the contributing document at [CONTRIBUTING.md](https://github.com/PowerDNS/pdns/blob/master/CONTRIBUTING.md). -# High-level guidelines +# High-level Guidelines * Although the codebase does not consistently have them, [docblock](https://www.doxygen.nl/manual/docblocks.html)s on functions and classes are appreciated. * Never hesitate to write comments on anything that might not be immediately clear just from reading the code. * When adding whole new things, consider putting them in a `pdns::X` namespace. Look for `namespace pdns` in the codebase for examples. -# Memory handling +# Memory Handling The memory model in C++, inherited from the C era, is very powerful but also very error-prone. Several features are available in modern (C++11 and up) C++ to make it possible to avoid most of the pitfalls, while conserving the same level of performance. Most of the issues related to memory allocation (memory leaks, use-after-free) can be solved by using standard containers, or taking advantage of RAII and smart pointers, which take care of destructing the object when it is not used anymore. -## Stack-based memory allocation +## Stack-based Memory Allocation Default allocations, when declaring a variable local to a function for example, are done on the stack instead of doing a dynamic allocation on the heap. Allocating objects on the stack is faster, especially in threaded programs, and provides the benefit that objects are automatically destroyed when the function is exited. @@ -27,14 +27,14 @@ Allocating objects on the stack is faster, especially in threaded programs, and One caveat is that the programmer needs to be wary of is the size of the object in order not to exceed the space available on the stack, which would corrupt other objects in memory and could lead to a crash, or even execution of arbitrary code. This is especially true in the Recursor which uses a custom stack-switching in user-space mechanism and thus has a reduced stack size. -### Variable-Length Arrays +### Variable-Length Arrays (VLAs) In order to avoid smashing the stack, special care should be taken to limit the depth of function calls that, for example, can grow quickly with recursion. A second common source of smash stacking is the use of Variable-Length Arrays, whose size is determined at runtime and is therefore very hard to predict. The C++ language does not support VLAs but a lot of compilers inherit such a support from C99, so it is possible to use them by accident. PowerDNS strictly forbids the use of VLAs, as does the Linux kernel, and enforces that with the `-Werror=vla` compiler flag. -### C-style arrays +### C-style Arrays While you might still find some in the existing code base, we are actively trying to get rid of C-style arrays like this one: @@ -56,7 +56,7 @@ auto bufferSize = buffer.size(); auto& firstElement = buffer.at(0); ``` -### alloca +### `alloca` The use of `alloca()` is forbidden in the code base as it is much too easy to smash the stack. @@ -113,7 +113,7 @@ BadFileDescriptorWrapper() } ``` -## Smart pointers +## Smart Pointers There is almost no good reason not to use a smart pointer when doing dynamic memory allocation. Smart pointers will keep track of whether the dynamically allocated object is still used, and destroy it when the last user goes away. @@ -141,7 +141,7 @@ Please note however that while unique pointers are as cheap as naked pointers, s That is because they need to use atomic operations to update their internal counters, so making a copy of a shared pointer is expensive. Passing one by reference is cheap, however. -### Shared pointers +### Shared Pointers An important thing to be aware of with shared pointers is that taking a new copy of a shared pointer or releasing, thus updating its internal reference counter, is atomic and therefore thread-safe. Altering the content of the object pointed to is not, though, and is subject to the usual locking methods. @@ -171,7 +171,7 @@ std::thread threadB([&ptr]{ That unfortunately means that we still need some locking with shared pointers. C++11 defines atomic compare/exchange operations for `std::shared_ptr`, but they are implemented in `libstdc++` by global mutexes and are therefore not lock-free. -### Wrapping C pointers +### Wrapping C Pointers Smart pointers can also be used to wrap C-pointers, such as `FILE*` pointers: @@ -195,7 +195,7 @@ When smart pointers cannot be used, special care should be taken to: * do not mix `malloc` with `delete`, or `new` with `free` (destructors are not run, at the very least) ; * do not mix array allocations (`new[]`) with a non-array `delete` (vs `delete[]`). -## Pointer arithmetic +## Pointer Arithmetic It is very common to use pointer arithmetic to calculate a position in a buffer, or to test whether a given offset is outside of a given buffer. Unfortunately it is quite easy to trigger undefined behaviour when doing so, as the C++ standard does not allow pointer arithmetic pointing inside an object, except for arrays where it is also permitted to point one element past the end. @@ -233,7 +233,7 @@ Introduced in C++14 but already available in PowerDNS via boost (see views.hh), The basic `string_view` class provides that feature for a container of chars, but the same feature exists for other types, like `uint8_t`. -# Threads and concurrency +# Threads and Concurrency All of our products use threading to be able to take advantage of the increasing number of cores on modern CPUs. This inevitably leads to the question of how to synchronise data accesses between threads. @@ -315,18 +315,18 @@ Or when the lock needs to be kept for a bit longer: } ``` -## atomic +## Atomics `std::atomic` provides a nice way to share a counter or gauge between threads without the need for locking. This is done by implementing operations like reading, increasing, decreasing or writing a value in an atomic way, using memory barriers, making sure that the value cannot be updated from a different core during the operation. The default mode uses a sequentially consistent ordering memory model, which is quite expensive since it requires a full memory fence on all multi-core systems. A relaxed model can be used for certain very specific operations, but the default model has the advantage of being safe in all situations. -## per-thread counters +## Per-Thread Counters For generic per-thread counters, we have a class in `tcounters.hh` that should provide better performances by allowing each thread to independently update its own counter, the costly operation only happening when the counter needs to be read by one thread gathering metrics from all threads. -# Dealing with untrusted data +# Dealing with Untrusted Data As a rule of thumb, any data received from outside the process should be considered as untrusted. That means data received on a socket, loaded from a file, retrieved from a database, etc. @@ -339,7 +339,7 @@ In the same way, if we expect a numerical type we should check whether it matche Anything unexpected should stop the processing and lead to the discarding of the complete data set. If a smaller data set can be safely discarded, and it is more important to load an incomplete set than to assure the integrity of the complete data set, only the faulty data set can be discarded instead. -## alignment issues +## Alignment Issues When structured, binary data is received from the network or read from a file, it might be tempting to map it to an existing structure directly to make the parsing easier. But one must be careful about alignment issues on some architectures: @@ -373,7 +373,7 @@ void func(char* data, size_t offset, size_t length) { } ``` -## unsigned vs signed +## Signed vs. Unsigned Signed integers might overflow, and the resulting value is unpredictable, as this overflow is undefined behaviour. That means that this code results in an unpredictable value: @@ -442,7 +442,7 @@ The `pdns::checked_conv()` function can be used, ensuring that the conversion ca `-Wsign-conversion` can be used to warn about dangerous conversions (disabled by default in g++, and note that a cast disables the warning). -## fuzzing +## Fuzzing Fuzzing is a very useful way to test a piece of code that parses untrusted data. Efficient fuzzers are often doing coverage-based fuzzing, where the code that they test has been compiled in a special way to allow the fuzzer to detect which branches are executed and which are not, so that the fuzzer can see the effect of mutating specific bytes of the input on the code path. @@ -451,7 +451,7 @@ PowerDNS has a few fuzzing targets that can be used with libFuzzer or AFL in the More information can be found in the [fuzzing/README.md](https://github.com/PowerDNS/pdns/blob/master/fuzzing/README.md) file. The existing fuzzing targets are run on the OSS-Fuzz infrastructure for a short time every time a pull request is opened, and for a longer time on the HEAD of the repository. -# Other potential issues +# Other Potential Issues ## TOCTOU @@ -479,13 +479,13 @@ If you have to: * wipe the content before releasing the memory, so it will not linger around. Do note that `memset()` is very often optimized out by the compiler, so function like `sodium_munlock()`, `explicit_bzero()` or `explicit_memset()` should be used instead. -### Constant-time comparison +### Constant-Time Comparison Don't compare secret against data using a naive string comparison, as the timing of the operation will leak information about the content of the secret. Ideally, a constant-time comparison should be used instead (see `constantTimeStringEquals()` in the PowerDNS code base) but it is not always easy to achieve. One option might be to compute a HMAC of the secret using a key randomly generated at startup, and compare it against a HMAC of the supplied data computed with the same key. -## Virtual destructors +## Virtual Destructors Any class that is expected to be sub-classed should provide a virtual destructor. Not doing so will prevent the destructor of a derived class from being called if the object is held as the base type: @@ -562,7 +562,7 @@ class Parent On a related topic, virtual methods should not be called from constructors or destructors. While this is allowed under certain restrictions, it is very hard to know exactly which method (base or derived) will be called, and whether all sub-objects contained in the class would have been correctly constructed at that point. -## Hash collisions +## Hash Collisions Hashes are a very useful tool, used in `unordered_map` and `unordered_set` among others. They are also used in our caches. @@ -579,19 +579,19 @@ The first issue can be prevented by comparing the entries and not just the value The second one can be used by using some sort of secret when computing the hash so that the result cannot be guessed by the attacker. That can be achieved by using an unpredictable seed for certain hash algorithms, or a secret for some other like `SipHash`. -# Readability tips +# Readability Tips Some of these tips are actually enforced by `clang-tidy` nowadays, but it is still useful to keep them in mind. -## auto +## `auto` C++11 introduced automatic type deduction, using the `auto` keyword. In addition to saving the typing of a few more letters, using automatic type deduction prevents nasty surprises if the variable is initialized from another one, or from a function, and the other type is changed to a different one. The code might still compile while now involving a copy or worse. -## Boolean expressions +## Boolean Expressions -## Explicit comparisons +## Explicit Comparisons * compare numerical values with `== 0` or `!= 0` explicitly ; * compare to `false` explicitly, which is easier to read ; @@ -608,19 +608,19 @@ Use braced initialization for members as often as possible: Object a(); // declares a function named a that returns an object ``` -## nullptr +## `nullptr` When representing a pointer, using `nullptr` makes it immediately obvious that we are dealing with a pointer, as opposed to the use of `0`. It also cannot be silently taken as an integer, which can happens with `0` but also with `NULL`. -## const-ness +## `const`-ness * Mark parameters and variables that should not be modified as `const`. This is especially important for references and pointers that comes from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later. * Mark const methods as such (and make them thread-safe) * Prefer using `at()` on containers so that no insertion can take place by mistake, and to get bounds checking. -## static +## `static` Functions that are only used inside a single file should be marked as `static`, so that: @@ -641,14 +641,14 @@ Should be reserved for unexpected events (corrupted data, timeouts, ...) and sho Do not be afraid of using them, though, as the cost of an exception that is not thrown is usually very small, thanks to the zero-cost exception model. It might still force the compiler to refrain from some optimizations, so it might make sense to avoid them in some very performance-sensitive, narrow code paths. -### Custom exceptions +### Custom Exceptions Exceptions defined by the standards should be used whenever possible, as they already cover a lot of use cases. If custom exceptions are necessary, to be able to catch them explicitly, they should still derive from `std::exception`, directly or indirectly, so that they can still be caught in a more generic way to prevent the program from terminating. For example, the main connection handling function of a server can catch `std::exception` and just terminate the current connection if an uncaught exception bubbles up. -### Catching exceptions +### Catching Exceptions Catching exceptions should always be done by const reference: @@ -680,7 +680,7 @@ C++-style casts can easily be spotted in a code, which makes it easy to review t It cannot be be used to remove a const qualifier. When used to reinterpret the content of a buffer it can quickly lead to alignment issues, as described in the [alignment issues] section. -## errno +## `errno` `errno` is only guaranteed to be set on failing system calls and not set on succeeding system calls. A library call may clobber `errno`, even when it succeeds. From 4c7ea0937e41aadb239af63e47c7a9e1c5d70557 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 10 Aug 2023 16:54:18 +0200 Subject: [PATCH 501/909] Coding Guidelines: Rewording and typos --- CODING_GUIDELINES.md | 91 ++++++++++++++++++++++---------------------- 1 file changed, 45 insertions(+), 46 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 5d2518818778..beb2a1e15c62 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -15,28 +15,28 @@ It does assume that you have already read the contributing document at [CONTRIBU # Memory Handling The memory model in C++, inherited from the C era, is very powerful but also very error-prone. -Several features are available in modern (C++11 and up) C++ to make it possible to avoid most of the pitfalls, while conserving the same level of performance. +Several features are available in modern C++ (11 and up) to make it possible to avoid most of the pitfalls, while conserving the same level of performance. -Most of the issues related to memory allocation (memory leaks, use-after-free) can be solved by using standard containers, or taking advantage of RAII and smart pointers, which take care of destructing the object when it is not used anymore. +Most of the issues related to memory allocation (memory leaks, use-after-free) can be solved by using standard containers, or taking advantage of RAII and smart pointers, which take care of destroying objects when it is not used anymore. ## Stack-based Memory Allocation Default allocations, when declaring a variable local to a function for example, are done on the stack instead of doing a dynamic allocation on the heap. -Allocating objects on the stack is faster, especially in threaded programs, and provides the benefit that objects are automatically destroyed when the function is exited. +Allocating objects on the stack is faster, especially in threaded programs, and provides the benefit that objects are automatically destroyed when the function exits. -One caveat is that the programmer needs to be wary of is the size of the object in order not to exceed the space available on the stack, which would corrupt other objects in memory and could lead to a crash, or even execution of arbitrary code. -This is especially true in the Recursor which uses a custom stack-switching in user-space mechanism and thus has a reduced stack size. +One caveat that the programmer needs to be aware of is the size of the object in order to not exceed the space available on the stack, which would corrupt other objects in memory and could lead to a crash, or even execution of arbitrary code. +This is especially true in the Recursor which uses a custom mechanism for stack-switching in user-space and thus has a reduced stack size. ### Variable-Length Arrays (VLAs) In order to avoid smashing the stack, special care should be taken to limit the depth of function calls that, for example, can grow quickly with recursion. -A second common source of smash stacking is the use of Variable-Length Arrays, whose size is determined at runtime and is therefore very hard to predict. -The C++ language does not support VLAs but a lot of compilers inherit such a support from C99, so it is possible to use them by accident. +A second common source of stack smashing is the use of Variable-Length Arrays (VLAs), whose size is determined at runtime and is therefore very hard to predict. +The C++ language does not support VLAs but a lot of compilers inherit such support from C99, so it is possible to use them by accident. PowerDNS strictly forbids the use of VLAs, as does the Linux kernel, and enforces that with the `-Werror=vla` compiler flag. ### C-style Arrays -While you might still find some in the existing code base, we are actively trying to get rid of C-style arrays like this one: +While you might still find some uses of C-style arrays in the existing code base, we are actively trying to get rid of them. One example is as follows: ```C++ somestruct buffer[12]; @@ -44,9 +44,9 @@ auto bufferSize = sizeof(buffer) / sizeof(*buffer); auto& firstElement = buffer[0]; ``` -It is immediately obvious that computing the actual number of elements is error-prone, as `sizeof()` does not return the number of elements but the total memory space used by the array. +It is immediately obvious that computing the actual number of elements is error-prone, because `sizeof()` does not return the number of elements but the total memory space used by the array. Another obvious issue is that accesses to the array are not bound-checked. -These are not the only drawbacks of these arrays, but are bad enough already to justify getting rid of them. +These are not the only drawbacks of C-style arrays, but are bad enough already to justify getting rid of them. The modern C++ way is to use `std::array`s: @@ -58,19 +58,19 @@ auto& firstElement = buffer.at(0); ### `alloca` -The use of `alloca()` is forbidden in the code base as it is much too easy to smash the stack. +The use of `alloca()` is forbidden in the code base because it is too easy to smash the stack. ## RAII Resource acquisition is initialization ([RAII](https://en.cppreference.com/w/cpp/language/raii)) is one of the fundamental concepts in C++. Resources are allocated during the construction of an object and destroyed when the object is itself destructed. -It means that if an object is correctly designed, the resources associated with it can not survive its lifetime. -Since objects that are allocated on the stack (local variables in a function, for example) are automatically destroyed when a function is exited, be it by reaching the last line, calling return or throwing an exception, it makes it possible to ensure that resources are always properly destroyed by wrapping them into an object. +It means that if an object is correctly designed, the resources associated with it cannot survive its lifetime. In other words, the resources associated with a correctly designed object are owned by the object and cannot outlive it. +Since stack-allocated objects, like local variables in a function, are automatically destroyed when a function exits, be it by reaching the last line, calling return or throwing an exception, it makes it possible to ensure that resources are always properly destroyed by wrapping them in an object. We describe the use of smart pointers, containers and other wrappers for that purpose below, but first a few words of caution. -Resources stored in a object are only tied to this object if the constructor finished properly. -If an exception is raised in the constructor body, the object is not created and therefore the destructor will not get called. -This means that if the object has non-object members holding resources, like naked file descriptors or naked pointers, they need to be explicitly released before raising the exception, otherwise they are lost. +Resources stored in a object are only tied to this object if the constructor executes fully and completes properly. +If an exception is raised in the constructor's body, the object is not created and therefore the destructor will not be called. +This means that if the object has non-object members holding resources, like raw file descriptors or raw C-style pointers, they need to be explicitly released before raising the exception, otherwise they are lost or leaked. ```C++ class BadFileDescriptorWrapper @@ -99,7 +99,7 @@ private: }; ``` -The use of smart pointers can be a solution to most resources leakage, but otherwise the only way is to be careful about exceptions in constructors: +The use of smart pointers can be a solution to most resource leakage problems, but otherwise the only way is to be careful about exceptions in constructors: ```C++ BadFileDescriptorWrapper() @@ -115,35 +115,35 @@ BadFileDescriptorWrapper() ## Smart Pointers -There is almost no good reason not to use a smart pointer when doing dynamic memory allocation. +There is almost no good reason to not use a smart pointer when doing dynamic memory allocation. Smart pointers will keep track of whether the dynamically allocated object is still used, and destroy it when the last user goes away. -Using naked pointers quickly results in security issues, ranging from memory leaks to arbitrary code execution. +Using raw pointers quickly results in security issues, ranging from memory leaks to arbitrary code execution. Examples of such issues can be found in the following PowerDNS security advisories: * [2017-07: Memory leak in DNSSEC parsing](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-07.html) * [2018-04: Crafted answer can cause a denial of service](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-04.html) Most allocations should be wrapped in a `std::unique_ptr`, using `make_unique`. -There can only be one owner at a given time, as opposed to shared pointers, but the ownership can be passed along using `std::move()` if needed. +There can only be one owner at any given time, as opposed to shared pointers, but the ownership can be passed along using `std::move()` if needed. If the dynamically allocated object needs to be referenced in several places, the use of a `std::shared_ptr` is advised instead, via `std::make_shared`. -The use of the `make_*` methods has three advantages: +The use of `make_*` methods has three advantages: * they result in a single allocation for `shared_ptr`s, instead of two otherwise ; * they avoid duplicating the type name twice ; * they prevent a possible issue if an exception is raised with temporaries. -They also make is easier to spot naked pointers by looking for "new" and "delete" throughout the code :) +They also make is easier to spot raw pointers by searching or `grep`ping for "new" and "delete" throughout the code :) -Please note however that while unique pointers are as cheap as naked pointers, shared pointers are much more expensive. +Please note, however, that while unique pointers are as cheap as raw pointers, shared pointers are much more expensive. That is because they need to use atomic operations to update their internal counters, so making a copy of a shared pointer is expensive. Passing one by reference is cheap, however. ### Shared Pointers -An important thing to be aware of with shared pointers is that taking a new copy of a shared pointer or releasing, thus updating its internal reference counter, is atomic and therefore thread-safe. +An important thing to be aware of with shared pointers is that making a new copy or releasing a shared pointer, thus updating its internal reference counter, is atomic and therefore thread-safe. Altering the content of the object pointed to is not, though, and is subject to the usual locking methods. The often misunderstood part is that updating the target of the shared pointer is not thread-safe. Basically, you can copy the shared pointer from multiple threads at once, and then each thread can assign a new target to its own copy safely, like that: @@ -198,8 +198,8 @@ When smart pointers cannot be used, special care should be taken to: ## Pointer Arithmetic It is very common to use pointer arithmetic to calculate a position in a buffer, or to test whether a given offset is outside of a given buffer. -Unfortunately it is quite easy to trigger undefined behaviour when doing so, as the C++ standard does not allow pointer arithmetic pointing inside an object, except for arrays where it is also permitted to point one element past the end. -Still that undefined behaviour is mostly harmless, but it might lead to real issue on some platforms. +Unfortunately it is quite easy to trigger undefined behaviour when doing so because the C++ standard does not allow pointer arithmetic pointing inside an object, except for arrays where it is also permitted to point one element past the end. +Still, that undefined behaviour is mostly harmless, but it might lead to real issue on some platforms. One such example occurred in dnsdist: [2017-01: Crafted backend responses can cause a denial of service](https://dnsdist.org/security-advisories/powerdns-advisory-for-dnsdist-2017-01.html) @@ -211,7 +211,7 @@ This kind of issue is best avoided by the use of containers to avoid the need fo ### Containers -The use of containers like `vector`, `map` or `set` has several advantages in term of security: +The use of containers like `vector`, `map` or `set` has several advantages in terms of security: * memory allocations are handled by the container itself ; * it prevents a disconnect between the actual size and the variable tracking that size ; @@ -221,15 +221,15 @@ One issue that could have been prevented by the use of a container can be found The use of a container and its corresponding `at()` operator would have prevented an out-of-bounds read since calling `at()` on an invalid offset results in an exception being raised. The cost of using `at()` is negligible for most use cases, and can be avoided by using the `[]` operator in the rare case when the cost cannot be afforded. -Note that several Linux distributions now build with `-Wp,-D_GLIBCXX_ASSERTIONS` enabled by default, which turns on cheap range checks for C++ arrays, vectors, and strings anyway. +Note that several Linux distributions now build with `-Wp,-D_GLIBCXX_ASSERTIONS` enabled by default, which turns on cheap range checks for C++ arrays, vectors, and strings. Regarding performance, it is advised to `reserve()` the needed size in advance when a rough estimate is known to avoid reallocations and copies. -Resizing in advance is not advised, though, as it makes it harder to know what is exactly in the container in case of early returns or exceptions. +Resizing in advance is not advised, though, as it makes it harder to exactly know what is in the container in case of early returns or exceptions. In C++11, move operators make it possible to cheaply get the contents of a container into a different variable if needed. The need to pass a subset of a container without copying it often leads to passing a pointer to an array of chars along with a size. -Introduced in C++14 but already available in PowerDNS via boost (see views.hh), views provides a nice way to borrow the content of a container to pass it to a function, without any copy or dynamic memory allocation. +Introduced in C++14 but already available in PowerDNS via boost (see views.hh), `views` provide a nice way to borrow the content of a container to pass it to a function, without any copying or dynamic memory allocation. The basic `string_view` class provides that feature for a container of chars, but the same feature exists for other types, like `uint8_t`. @@ -243,8 +243,7 @@ For example getting the `size()` of a container might not be thread-safe if a di Some functions might also not be thread-safe, for example if they have a static non-const variable. We currently use three solutions, depending on the use-case. -The first one is used when we only need to share some kind of counter or gauge, and involves the use of `std::atomic` which allows atomic operations to be performed from different threads without locking. -More on that later. +The first one is used when we only need to share some kind of counter or gauge, and involves the use of `std::atomic` which allows atomic operations to be performed from different threads without locking. More on that later. The second one is the "share nothing" approach, where each thread has its own data (using `thread_local`, for example), avoiding the need for data synchronization. When a thread needs to communicate with another one, it might use a `pdns::channel` to pass a pointer to that second thread. That works quite well but sometimes sharing data is much more efficient than the alternative. @@ -320,24 +319,24 @@ Or when the lock needs to be kept for a bit longer: `std::atomic` provides a nice way to share a counter or gauge between threads without the need for locking. This is done by implementing operations like reading, increasing, decreasing or writing a value in an atomic way, using memory barriers, making sure that the value cannot be updated from a different core during the operation. The default mode uses a sequentially consistent ordering memory model, which is quite expensive since it requires a full memory fence on all multi-core systems. -A relaxed model can be used for certain very specific operations, but the default model has the advantage of being safe in all situations. +A relaxed model can be used for specific operations, but the default model has the advantage of being safe in all situations. ## Per-Thread Counters -For generic per-thread counters, we have a class in `tcounters.hh` that should provide better performances by allowing each thread to independently update its own counter, the costly operation only happening when the counter needs to be read by one thread gathering metrics from all threads. +For generic per-thread counters, we have a class in `tcounters.hh` that should provide better performance by allowing each thread to independently update its own counter, the costly operation only happens when the counter needs to be read by one thread gathering metrics from all threads. # Dealing with Untrusted Data -As a rule of thumb, any data received from outside the process should be considered as untrusted. -That means data received on a socket, loaded from a file, retrieved from a database, etc. +As a rule of thumb, any data received from outside the process should be considered untrusted. +This includes data received on a socket, loaded from a file, retrieved from a database, etc. Data received from an internal pipe might be excluded from that rule. Untrusted data should never be trusted to adhere to the expected format or specifications, and a strict checking of boundaries should be performed. It means for example that, after reading the length for a field inside the data, whether that length does not exceed the total length of the data should be checked. -In the same way, if we expect a numerical type we should check whether it matches one we expect and understand. +In the same way, if we expect a numerical type we should check whether it matches what we expect and understand. Anything unexpected should stop the processing and lead to the discarding of the complete data set. -If a smaller data set can be safely discarded, and it is more important to load an incomplete set than to assure the integrity of the complete data set, only the faulty data set can be discarded instead. +If a smaller data set can be safely discarded, and it is more important to load an incomplete set than to assure the integrity of the complete data set, only the faulty data can be discarded instead. ## Alignment Issues @@ -428,7 +427,7 @@ void parse_untrusted_data(uint8_t* data, uint16_t length) } ``` -Converting from unsigned to signed will lose the high order bytes, and should be avoided, or the value should be checked before-hand: +Converting from unsigned to signed will lose the high order bytes, and should be avoided, or the value should be checked beforehand: ```c++ uint64_t u = std::numeric_limits::max(); @@ -470,7 +469,7 @@ This is hard to avoid in all cases, but some mitigations do help: ## Secrets Try very hard not to load sensitive information into memory. -And of course do not write to disk! +And of course do not write this information to logs or to disk! If you have to: @@ -483,12 +482,12 @@ If you have to: Don't compare secret against data using a naive string comparison, as the timing of the operation will leak information about the content of the secret. Ideally, a constant-time comparison should be used instead (see `constantTimeStringEquals()` in the PowerDNS code base) but it is not always easy to achieve. -One option might be to compute a HMAC of the secret using a key randomly generated at startup, and compare it against a HMAC of the supplied data computed with the same key. +One option might be to compute an HMAC of the secret using a key that was randomly generated at startup, and compare it against a HMAC of the supplied data computed with the same key. ## Virtual Destructors Any class that is expected to be sub-classed should provide a virtual destructor. -Not doing so will prevent the destructor of a derived class from being called if the object is held as the base type: +Not doing so will prevent the destructor of any derived class from being called if the object is held as the base type: ```c++ class Parent @@ -522,7 +521,7 @@ Note that defining a destructor will prevent the automatic creation of move oper * no move operators are declared ; * no destructor is declared. -If the Parent class holds data that is costly to copy, it might make sense to declare the move operators explicitly: +If the parent class holds data that is costly to copy, it might make sense to declare the move operators explicitly: ```c++ class Parent @@ -566,7 +565,7 @@ While this is allowed under certain restrictions, it is very hard to know exactl Hashes are a very useful tool, used in `unordered_map` and `unordered_set` among others. They are also used in our caches. -An important caveat that developers need to be aware about regarding hashes are that the probability of a collision is often a lot higher than expected. +An important caveat that developers need to be aware of regarding hashes are that the probability of a collision is often a lot higher than expected. This is well-known as the birthday paradox, the fact that the probability of having two entries colliding is a lot higher than the probability of finding a collision for a specific entry. This means that it is important to verify that the entries are actually identical, and just not that they hash to the same value. @@ -586,7 +585,7 @@ Some of these tips are actually enforced by `clang-tidy` nowadays, but it is sti ## `auto` C++11 introduced automatic type deduction, using the `auto` keyword. -In addition to saving the typing of a few more letters, using automatic type deduction prevents nasty surprises if the variable is initialized from another one, or from a function, and the other type is changed to a different one. +Using automatic type deduction prevents nasty surprises if the variable is initialized from another one, or from a function, and the other type is changed to a different one. The code might still compile while now involving a copy or worse. ## Boolean Expressions @@ -686,5 +685,5 @@ C++-style casts can easily be spotted in a code, which makes it easy to review t A library call may clobber `errno`, even when it succeeds. Safe practice is: -* Only look at `errno` on failing systems calls or when a library function is documented to set `errno`. +* Only look at `errno` on failing system calls or when a library function is documented to set `errno`. * Immediately save the value of `errno` in a local variable after a system call for later decision making. From 1000a4c82783aed0e1a98e55e3d36117317c023d Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 10 Aug 2023 16:55:15 +0200 Subject: [PATCH 502/909] Coding Guidelines: Some code formatting and minor fixes --- CODING_GUIDELINES.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index beb2a1e15c62..45c89ffdcaf2 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -83,6 +83,7 @@ class BadFileDescriptorWrapper } ... } + ~BadFileDescriptorWrapper() { if (d_fd > 0) { @@ -90,12 +91,14 @@ class BadFileDescriptorWrapper d_fd = -1; } } + int getHandle() const { return d_fd; } + private: - int d_fd{-1}; + int d_fd{-1}; }; ``` @@ -151,7 +154,7 @@ Basically, you can copy the shared pointer from multiple threads at once, and th ```C++ auto ptr = std::make_shared(4); for (auto idx = 0; idx < 10 ; idx++){ - std::thread([ptr]{ auto copy = ptr; }).detach(); //ok, only mutates the control block + std::thread([ptr]{ auto copy = ptr; }).detach(); // ok, only mutates the control block } ``` @@ -163,6 +166,7 @@ auto ptr = std::make_shared(4); std::thread threadA([&ptr]{ ptr = std::make_shared(10); }); + std::thread threadB([&ptr]{ ptr = std::make_shared(20); }); @@ -398,13 +402,16 @@ void parse_untrusted_data(uint8_t* data, uint16_t length) if (length < 4) { return; } + /* read the first two bytes which hold the length of the next record */ uint16_t recordLen = data[0] * 256 + data[1]; + /* let's assume that recordLen is equal to 65535 */ uint16_t totalRecordLen = /* size of the type */ sizeof(uint16_t) + recordLen; // <-- this results in a wrapped value of 65535 + 2 = 65537 = 1 if (totalRecordLen > length) { return; } + /* ... */ } ``` @@ -418,11 +425,13 @@ void parse_untrusted_data(uint8_t* data, uint16_t length) if (length < 4) { return; } + /* read the first two bytes which hold the length of the next record */ uint16_t recordLen = data[0] * 256 + data[1]; if (recordLen > length || (length - recordLen) < sizeof(uint16_t)) { return; } + /* ... */ } ``` @@ -501,6 +510,7 @@ class Child: public Parent { d_fd = fopen(..); } + ~Child() { if (d_fd) { @@ -508,6 +518,7 @@ class Child: public Parent f_fd = nullptr; } } + void doVirtualCall() override; }; @@ -534,6 +545,7 @@ class Parent } virtual void doVirtualCall(); + private: FILE* d_fd{nullptr}; }; From 051e194aa030f612f35ca30220a490054b2e425a Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 10 Aug 2023 16:55:31 +0200 Subject: [PATCH 503/909] Coding Guidelines: BadFileDescriptorWrapper -> GoodFileDescriptorWrapper --- CODING_GUIDELINES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 45c89ffdcaf2..6bbf288094b8 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -105,7 +105,7 @@ private: The use of smart pointers can be a solution to most resource leakage problems, but otherwise the only way is to be careful about exceptions in constructors: ```C++ -BadFileDescriptorWrapper() +GoodFileDescriptorWrapper() { d_fd = open(...); if (something) { From 5fcab93111ad9ca86489ed4edda5f8166d20d851 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 10 Aug 2023 16:55:43 +0200 Subject: [PATCH 504/909] Coding Guidelines: Use decltype in code example --- CODING_GUIDELINES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 6bbf288094b8..6e7a54966ce3 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -180,7 +180,7 @@ C++11 defines atomic compare/exchange operations for `std::shared_ptr`, but they Smart pointers can also be used to wrap C-pointers, such as `FILE*` pointers: ```c++ -auto fp = std::unique_ptr(fopen(certificateFile.c_str(), "r"), fclose); +auto fp = std::unique_ptr(fopen(certificateFile.c_str(), "r"), std::fclose); ``` It also works with types from external C libraries, like OpenSSL: From 9b9555a9ba767bb30137be4b3d99d1320df255c9 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 10 Aug 2023 16:56:26 +0200 Subject: [PATCH 505/909] Coding Guidelines: Capitalize list items --- CODING_GUIDELINES.md | 82 ++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 6e7a54966ce3..7cfbf3950eed 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -134,9 +134,9 @@ If the dynamically allocated object needs to be referenced in several places, th The use of `make_*` methods has three advantages: -* they result in a single allocation for `shared_ptr`s, instead of two otherwise ; -* they avoid duplicating the type name twice ; -* they prevent a possible issue if an exception is raised with temporaries. +* They result in a single allocation for `shared_ptr`s, instead of two otherwise ; +* They avoid duplicating the type name ; +* They prevent a possible issue if an exception is raised with temporaries. They also make is easier to spot raw pointers by searching or `grep`ping for "new" and "delete" throughout the code :) @@ -194,10 +194,10 @@ In the PowerDNS products, these cases have been mostly reduced to a few select c When smart pointers cannot be used, special care should be taken to: -* make sure that every exit point frees the allocated memory (early return, goto, exceptions..) ; -* set the pointer to `nullptr` right after the deallocation, so we can't use it again (use-after-free) ; -* do not mix `malloc` with `delete`, or `new` with `free` (destructors are not run, at the very least) ; -* do not mix array allocations (`new[]`) with a non-array `delete` (vs `delete[]`). +* Make sure that every exit point frees the allocated memory (early return, goto, exceptions..) ; +* Set the pointer to `nullptr` right after the deallocation, so we can avoid use-after-free vulnerabilities and crash the program instead ; +* Do not mix `malloc` with `delete`, or `new` with `free` (destructors are, at the very least, not run in such cases) ; +* Do not mix array allocations (`new[]`) with a non-array `delete` (vs `delete[]`). ## Pointer Arithmetic @@ -217,9 +217,9 @@ This kind of issue is best avoided by the use of containers to avoid the need fo The use of containers like `vector`, `map` or `set` has several advantages in terms of security: -* memory allocations are handled by the container itself ; -* it prevents a disconnect between the actual size and the variable tracking that size ; -* it provides safe (and fast) operations like comparisons, iterators, etc.. +* Memory allocations are handled by the container itself ; +* It prevents a disconnect between the actual size and the variable tracking that size ; +* It provides safe (and fast) operations like comparisons, iterators, etc.. One issue that could have been prevented by the use of a container can be found in the following advisory: [2018-09: Crafted query can cause a denial of service](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-09.html) @@ -260,29 +260,29 @@ Locks allow a thread of execution to ensure that no other thread will try to acc There are a few pitfalls to avoid when using locks: -* failing to release the lock, which can be avoided by wrappers like `std::lock_guard`, `std::unique_lock` and our own wrappers: look for `LockGuarded`, `SharedLockGuarded` in lock.hh ; -* high contention, where threads are blocked for a long time while waiting to acquire a lock. - This can be solved by carefully examining the portion of code that really needs to hold the lock, making the critical path faster, or by using sharding which basically divides the data protected by the lock into several blocks, each one of them protected by its own lock ; -* starvation, which occurs for example when thread 1 acquires lock 1 and wants to acquire lock 2, which is already owned by thread 2, itself currently waiting to acquire lock 1. - This can be avoided by a better design of the locking mechanism, and assuring that locks are always acquired in the same order if more than one lock is needed. +* Failing to release a lock, which can be avoided by using wrappers like `std::lock_guard`, `std::unique_lock` and our own wrappers: `LockGuarded` and `SharedLockGuarded` in `lock.hh` ; +* High contention, where threads are blocked for a long time while waiting to acquire a lock. + This can be solved by carefully examining the portion of code that really needs to hold the lock, making the critical path shorter or faster, or by using sharding which basically divides the data protected by the lock into several pieces, each of them protected by its own lock ; +* Dead-locks, which occur for example when thread 1 acquires lock 1 and wants to acquire lock 2, which is already acquired by thread 2, itself currently waiting to acquire lock 1. + This can be avoided by a better design of the locking mechanism, and assuring that locks are always acquired in the same order if more than one lock is required. Abstracting multiple locks away into a class with a small state machine that locks and unlocks both in the correct sequence and checks that they are always in a valid in-tandem state may prove to be a less error-prone approach while also improving readability and ergonomics. There are several types of locks: -* spinlocks are very fast but are busy-waiting, meaning that they do not pause, but instead repetitively try to get hold of the lock, using 100% of one core doing so unless preempted by the OS. +* Spinlocks are very fast but are busy-waiting, meaning that they do not pause, but instead repetitively try to get hold of the lock, using 100% of one core, doing so unless preempted by the OS. So they are only suited for locks that are almost never contented ; -* a mutex is a very simple lock. +* A mutex is a very simple lock. In most implementations it is a very fast lock, implemented in user-space on recent Linux kernels and glibc ; -* a read-write lock allows several threads to acquire it in read mode, but only one thread can acquire it in write mode. +* A read-write lock (RW-lock) allows several threads to acquire it in read mode, but only one thread can acquire it in write mode. This is suited when most accesses are read-only and writes are rare and do not take too long. - Otherwise a mutex might actually be faster ; + Otherwise, a mutex might actually be faster ; One quick word about condition variables, that allow a thread to notify one or more threads waiting for a condition to happen. A thread should acquire a mutex using a `std::unique_lock` and call the `wait()` method of the condition variable. This is a very useful mechanism but one must be careful about two things: -* the producer thread can either wake only one thread or all threads waiting on the condition variable. +* The producer thread can either wake only one thread or all threads waiting on the condition variable. Waking up several threads if only one has something to do (known as a "thundering herd") is bad practice, but there are some cases where it makes sense ; -* a consumer might be waken up spuriously, which can be avoided by passing a predicate (which can be as simple as a small lambda function) to `wait()`. +* A consumer thread might be waken up spuriously, which can be avoided by passing a predicate (which can be as simple as a small lambda function) to `wait()`. Our wrappers, `LockGuarded`, `SharedLockGuarded` in `lock.hh`, should always be preferred over other solutions. They provide a way to wrap any data structure as protected by a lock (mutex or shared mutex), while making it immediately clear which data is protected by that lock, and preventing any access to the data without holding the lock. @@ -470,10 +470,10 @@ Since the program has enough rights to edit this file, this might allow an attac This is hard to avoid in all cases, but some mitigations do help: -* opening a file first (handling errors if that fails) then getting the needed metadata via the file descriptor instead of the path (`fstat`, `fchmod`, `fchown`) ; -* opening with the `O_NOFOLLOW` flag set, so that the operation will fail if the target exists and is a symbolic link ; -* always creating temporary files via the `mkstemp()` function, which guarantees that the file did not exist before and has been created with the right permissions ; -* using operations that are guaranteed to be atomic, like renaming a file on the same filesystem (for example in the same directory). +* Opening a file first (handling errors if that fails) then getting the needed metadata via the file descriptor instead of the path (`fstat`, `fchmod`, `fchown`) ; +* Opening with the `O_NOFOLLOW` flag set, so that the operation will fail if the target exists and is a symbolic link ; +* Always creating temporary files via the `mkstemp()` function, which guarantees that the file did not exist before and has been created with the right permissions ; +* Using operations that are guaranteed to be atomic, like renaming a file on the same filesystem (for example in the same directory). ## Secrets @@ -482,9 +482,9 @@ And of course do not write this information to logs or to disk! If you have to: -* use an object that can't be copied, by deleting the copy constructors and assignments operators, -* try to lock the memory so it cannot be swapped out to disk, or included in a core dump, via `sodium_malloc()` or `sodium_mlock()`, for example ; -* wipe the content before releasing the memory, so it will not linger around. +* Use an object that can't be copied, by deleting the copy constructors and assignments operators, +* Try to lock the memory so it cannot be swapped out to disk, or included in a core dump, via `sodium_malloc()` or `sodium_mlock()`, for example ; +* Wipe the content before releasing the memory, so it will not linger around. Do note that `memset()` is very often optimized out by the compiler, so function like `sodium_munlock()`, `explicit_bzero()` or `explicit_memset()` should be used instead. ### Constant-Time Comparison @@ -528,9 +528,9 @@ myObjects.push_back(Child()); Note that defining a destructor will prevent the automatic creation of move operators for that class, since they are generated only if these conditions are met: -* no copy operators are declared ; -* no move operators are declared ; -* no destructor is declared. +* No copy operators are declared ; +* No move operators are declared ; +* No destructor is declared. If the parent class holds data that is costly to copy, it might make sense to declare the move operators explicitly: @@ -583,8 +583,8 @@ This means that it is important to verify that the entries are actually identica This is especially important when hashing attacker-controlled values, as they can be specially crafted to trigger collisions to cause: -* cache pollution (see [2018-06: Packet cache pollution via crafted query](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-06.html)) ; -* denial of service via hash table flooding (in a map, all entries that hash to the same value are often placed into a linked-list, making it possible to cause a linear scan of entries by making all of them hash to that same value). +* Cache pollution (see [2018-06: Packet cache pollution via crafted query](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2018-06.html)) ; +* Denial of service via hash table flooding (in a map, all entries that hash to the same value are often placed into a linked-list, making it possible to cause a linear scan of entries by making all of them hash to that same value). The first issue can be prevented by comparing the entries and not just the value they hash to. The second one can be used by using some sort of secret when computing the hash so that the result cannot be guessed by the attacker. @@ -604,16 +604,16 @@ The code might still compile while now involving a copy or worse. ## Explicit Comparisons -* compare numerical values with `== 0` or `!= 0` explicitly ; -* compare to `false` explicitly, which is easier to read ; -* compare to `nullptr` for the same reason. +* Compare numerical values with `== 0` or `!= 0` explicitly ; +* Compare to `false` explicitly, which is easier to read ; +* Compare to `nullptr` for the same reason. ## Initialization Use braced initialization for members as often as possible: -* it does forbid narrowing conversions -* and avoids C++'s "[most vexing parse](https://en.wikipedia.org/wiki/Most_vexing_parse)" which is to declare a function instead of calling the default constructor: +* It does forbid narrowing conversions +* It avoids C++'s "[most vexing parse](https://en.wikipedia.org/wiki/Most_vexing_parse)" which is to declare a function instead of calling the default constructor: ```c++ Object a(); // declares a function named a that returns an object @@ -628,15 +628,15 @@ It also cannot be silently taken as an integer, which can happens with `0` but a * Mark parameters and variables that should not be modified as `const`. This is especially important for references and pointers that comes from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later. -* Mark const methods as such (and make them thread-safe) +* Mark `const` methods as such (and make them thread-safe) * Prefer using `at()` on containers so that no insertion can take place by mistake, and to get bounds checking. ## `static` Functions that are only used inside a single file should be marked as `static`, so that: -* the compiler knows that these functions will not be called from a different compilation unit and thus that no symbol needs to be generated, making it more likely for the function to be inlined ; -* the reader knows that this function is only used there and can be altered without causing an issue somewhere else. +* The compiler knows that these functions will not be called from a different compilation unit and thus that no symbol needs to be generated, making it more likely for the function to be inlined ; +* The reader knows that this function is only used there and can be altered without causing an issue somewhere else. For the same reason, global variables that are only accessed from a single file should be marked static as well. From c80f3f9ba4a4c11e9ced4380553bc7e3b2c404ec Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 10 Aug 2023 16:56:45 +0200 Subject: [PATCH 506/909] Coding Guidelines: More descriptive section titles --- CODING_GUIDELINES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 7cfbf3950eed..48cefc6e76f2 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -60,7 +60,7 @@ auto& firstElement = buffer.at(0); The use of `alloca()` is forbidden in the code base because it is too easy to smash the stack. -## RAII +## Resource Acquisition Is Initialization (RAII) Resource acquisition is initialization ([RAII](https://en.cppreference.com/w/cpp/language/raii)) is one of the fundamental concepts in C++. Resources are allocated during the construction of an object and destroyed when the object is itself destructed. @@ -461,7 +461,7 @@ The existing fuzzing targets are run on the OSS-Fuzz infrastructure for a short # Other Potential Issues -## TOCTOU +## Time-Of-Check to Time-Of-Use (TOCTOU) The time-of-check to time-of-use vulnerability is a very easy mistake to make when dealing with files or directories. The gist of it is that there is a small race condition between the time where a program might check the ownership, permissions or even existence of a file and the time it will actually do something with it. From c49d49b7fcf763715f01c054dc2aba12903df9c1 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 10 Aug 2023 16:57:18 +0200 Subject: [PATCH 507/909] Coding Guidelines: Some formatting of C++ keywords --- CODING_GUIDELINES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 48cefc6e76f2..cb3ab3238584 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -661,7 +661,7 @@ For example, the main connection handling function of a server can catch `std::e ### Catching Exceptions -Catching exceptions should always be done by const reference: +Catching exceptions should always be done by `const`-reference: ```c+++ try { From bdaed059db7d25c48b20e3256dc666d77e45dbb6 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 10 Aug 2023 16:57:34 +0200 Subject: [PATCH 508/909] Coding Guidelines: Formatting of the C++ casts bullet points --- CODING_GUIDELINES.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index cb3ab3238584..e366c9b32b09 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -679,17 +679,17 @@ C-style casts should be avoided, as the compiler does almost no check on the val They are also very hard to spot in a code. C++-style casts can easily be spotted in a code, which makes it easy to review them. -* `const_cast` can be used to remove the const qualifier on a variable. - It's usually a bad sign, but sometimes it is needed to call a function that will not modify the variable but lacks the const qualifier, for example. +* `const_cast` can be used to remove the `const` qualifier on a variable. + It's usually a bad sign, but is sometimes needed to call a function that will not modify the variable but lacks the `const` qualifier. * `dynamic_cast` can be used to cast a pointer to a derived class or to a base class, while checking that the operation is valid. - If the casted object is not valid for the intended type, a nullptr value will be returned (or a bad_cast exception for references) so the result of the operation should be checked! - Note that the RTTI check needed to verify that the casted object is valid has a non-negligible CPU cost. - Not checking the return value might lead to remote denial of service by nullptr dereference, as happened with the issue described in this advisory: https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-08.html + If the cast object is not valid for the intended type, a `nullptr` value will be returned (or a `bad_cast` exception for references) so the result of the operation should be checked! + Note that the RTTI check needed to verify that the cast object is valid has a non-negligible CPU cost. + Not checking the return value might lead to remote denial of service by `nullptr`-dereference, as happened with the issue described in this advisory: https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-08.html * `static_cast` can perform downcast in place of `dynamic_cast`, with none of the cost associated to the check, but can only be done if the cast is known to be valid. - It can also do implicit conversion between types (from `ssize_t` to `size_t`, AFTER checking that the value is greater or equal to zero). + It can also do implicit conversion between types (from `ssize_t` to `size_t`, **after** checking that the value is greater or equal to zero). * `reinterpret_cast` is quite dangerous, since it can be used to turn a type into a different one. - It cannot be be used to remove a const qualifier. - When used to reinterpret the content of a buffer it can quickly lead to alignment issues, as described in the [alignment issues] section. + It cannot be be used to remove a `const` qualifier. + When used to reinterpret the content of a buffer it can quickly lead to alignment issues, as described in the [Alignment Issues] section. ## `errno` From 2f3f66e437c8dbbbe56c7b5a065c9ddb6d4e40fe Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 16 Nov 2022 12:10:43 +0100 Subject: [PATCH 509/909] API tests: add put_zone helper --- regression-tests.api/test_Zones.py | 84 ++++++++++++------------------ 1 file changed, 33 insertions(+), 51 deletions(-) diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 46d92f552075..7440a2db3f74 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -82,6 +82,7 @@ def test_list_zones_with_dnssec(self): def test_list_zones_without_dnssec(self): self._test_list_zones(False) + class AuthZonesHelperMixin(object): def create_zone(self, name=None, **kwargs): if name is None: @@ -96,7 +97,7 @@ def create_zone(self, name=None, **kwargs): del payload[k] else: payload[k] = v - print("sending", payload) + print("Create zone", name, "with:", payload) r = self.session.post( self.url("/api/v1/servers/localhost/zones"), data=json.dumps(payload), @@ -107,6 +108,24 @@ def create_zone(self, name=None, **kwargs): print("reply", reply) return name, payload, reply + def put_zone(self, api_zone_id, payload, expect_error=None): + print("PUT zone", api_zone_id, "with:", payload) + r = self.session.put( + self.url("/api/v1/servers/localhost/zones/" + api_zone_id), + data=json.dumps(payload), + headers={'content-type': 'application/json'}) + + print("reply status code:", r.status_code) + if expect_error: + self.assertEqual(r.status_code, 422) + reply = r.json() + if expect_error is True: + pass + else: + self.assertIn(expect_error, reply['error']) + else: + # expect success (no content) + self.assertEqual(r.status_code, 204) @unittest.skipIf(not is_auth(), "Not applicable") class AuthZones(ApiTestCase, AuthZonesHelperMixin): @@ -491,8 +510,7 @@ def test_create_zone_with_dnssec_disable_dnssec(self): name = unique_zone_name() name, payload, data = self.create_zone(dnssec=True) - self.session.put(self.url("/api/v1/servers/localhost/zones/" + name), - data=json.dumps({'dnssec': False})) + self.put_zone(name, {'dnssec': False}) r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)) zoneinfo = r.json() @@ -566,8 +584,7 @@ def test_create_zone_with_nsec3param_switch_to_nsec(self): """ name, payload, data = self.create_zone(dnssec=True, nsec3param='1 0 1 ab') - self.session.put(self.url("/api/v1/servers/localhost/zones/" + name), - data=json.dumps({'nsec3param': ''})) + self.put_zone(name, {'nsec3param': ''}) r = self.session.get( self.url("/api/v1/servers/localhost/zones/" + name)) data = r.json() @@ -580,20 +597,14 @@ def test_create_zone_without_dnssec_unset_nsec3parm(self): Create a non dnssec zone and set an empty "nsec3param" """ name, payload, data = self.create_zone(dnssec=False) - r = self.session.put(self.url("/api/v1/servers/localhost/zones/" + name), - data=json.dumps({'nsec3param': ''})) - - self.assertEqual(r.status_code, 204) + self.put_zone(name, {'nsec3param': ''}) def test_create_zone_without_dnssec_set_nsec3parm(self): """ Create a non dnssec zone and set "nsec3param" """ name, payload, data = self.create_zone(dnssec=False) - r = self.session.put(self.url("/api/v1/servers/localhost/zones/" + name), - data=json.dumps({'nsec3param': '1 0 1 ab'})) - - self.assertEqual(r.status_code, 422) + self.put_zone(name, {'nsec3param': '1 0 1 ab'}, expect_error=True) def test_create_zone_dnssec_serial(self): """ @@ -605,8 +616,7 @@ def test_create_zone_dnssec_serial(self): soa_serial = get_first_rec(data, name, 'SOA')['content'].split(' ')[2] self.assertEqual(soa_serial[-2:], '01') - self.session.put(self.url("/api/v1/servers/localhost/zones/" + name), - data=json.dumps({'dnssec': True})) + self.put_zone(name, {'dnssec': True}) r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)) data = r.json() @@ -615,8 +625,7 @@ def test_create_zone_dnssec_serial(self): self.assertEqual(r.status_code, 200) self.assertEqual(soa_serial[-2:], '02') - self.session.put(self.url("/api/v1/servers/localhost/zones/" + name), - data=json.dumps({'dnssec': False})) + self.put_zone(name, {'dnssec': False}) r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)) data = r.json() @@ -1119,11 +1128,7 @@ def test_update_zone(self): 'soa_edit_api': 'EPOCH', 'soa_edit': 'EPOCH' } - r = self.session.put( - self.url("/api/v1/servers/localhost/zones/" + name), - data=json.dumps(payload), - headers={'content-type': 'application/json'}) - self.assert_success(r) + self.put_zone(name, payload) data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() for k in payload.keys(): self.assertIn(k, data) @@ -1135,11 +1140,7 @@ def test_update_zone(self): 'soa_edit_api': '', 'soa_edit': '' } - r = self.session.put( - self.url("/api/v1/servers/localhost/zones/" + name), - data=json.dumps(payload), - headers={'content-type': 'application/json'}) - self.assert_success(r) + self.put_zone(name, payload) data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() for k in payload.keys(): self.assertIn(k, data) @@ -2208,10 +2209,7 @@ def test_explicit_rectify_success(self): def test_explicit_rectify_slave(self): # Some users want to move a zone to kind=Slave and then rectify, without a re-transfer. name, _, data = self.create_zone = self.create_zone(api_rectify=False, dnssec=True, nsec3param='1 0 1 ab') - r = self.session.put(self.url("/api/v1/servers/localhost/zones/" + data['id']), - data=json.dumps({'kind': 'Slave'}), - headers={'content-type': 'application/json'}) - self.assertEqual(r.status_code, 204) + self.put_zone(data['id'], {'kind': 'Slave'}) r = self.session.put(self.url("/api/v1/servers/localhost/zones/" + data['id'] + "/rectify")) self.assertEqual(r.status_code, 200) if not is_auth_lmdb(): @@ -2299,11 +2297,7 @@ def test_put_master_tsig_key_ids_non_existent(self): payload = { 'master_tsig_key_ids': [keyname] } - r = self.session.put(self.url('/api/v1/servers/localhost/zones/' + name), - data=json.dumps(payload), - headers={'content-type': 'application/json'}) - self.assertEqual(r.status_code, 422) - self.assertIn('A TSIG key with the name', r.json()['error']) + self.put_zone(name, payload, expect_error='A TSIG key with the name') def test_put_slave_tsig_key_ids_non_existent(self): name = unique_zone_name() @@ -2312,11 +2306,7 @@ def test_put_slave_tsig_key_ids_non_existent(self): payload = { 'slave_tsig_key_ids': [keyname] } - r = self.session.put(self.url('/api/v1/servers/localhost/zones/' + name), - data=json.dumps(payload), - headers={'content-type': 'application/json'}) - self.assertEqual(r.status_code, 422) - self.assertIn('A TSIG key with the name', r.json()['error']) + self.put_zone(name, payload, expect_error='A TSIG key with the name') @unittest.skipIf(not is_auth(), "Not applicable") @@ -2364,11 +2354,7 @@ def test_update_zone(self): 'soa_edit_api': 'EPOCH', 'soa_edit': 'EPOCH' } - r = self.session.put( - self.url("/api/v1/servers/localhost/zones/" + zone_id), - data=json.dumps(payload), - headers={'content-type': 'application/json'}) - self.assert_success(r) + self.put_zone(zone_id, payload) data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + zone_id)).json() for k in payload.keys(): self.assertIn(k, data) @@ -2379,11 +2365,7 @@ def test_update_zone(self): 'soa_edit_api': '', 'soa_edit': '' } - r = self.session.put( - self.url("/api/v1/servers/localhost/zones/" + zone_id), - data=json.dumps(payload), - headers={'content-type': 'application/json'}) - self.assert_success(r) + self.put_zone(zone_id, payload) data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + zone_id)).json() for k in payload.keys(): self.assertIn(k, data) From c43b2d233f719fc27a350dc4f381b42eaf6f200e Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 16 Nov 2022 12:29:18 +0100 Subject: [PATCH 510/909] API tests: add get_zone helper --- regression-tests.api/test_Zones.py | 135 ++++++++++++++--------------- 1 file changed, 66 insertions(+), 69 deletions(-) diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 7440a2db3f74..2f5aa088155e 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -108,6 +108,29 @@ def create_zone(self, name=None, **kwargs): print("reply", reply) return name, payload, reply + def get_zone(self, api_zone_id, expect_error=None, **kwargs): + print("GET zone", api_zone_id, "args:", kwargs) + r = self.session.get( + self.url("/api/v1/servers/localhost/zones/" + api_zone_id), + params=kwargs + ) + + reply = r.json() + print("reply", reply) + + if expect_error: + self.assertEqual(r.status_code, 422) + if expect_error is True: + pass + else: + self.assertIn(expect_error, r.json()['error']) + else: + # expect success + self.assert_success_json(r) + self.assertEqual(r.status_code, 200) + + return reply + def put_zone(self, api_zone_id, payload, expect_error=None): print("PUT zone", api_zone_id, "with:", payload) r = self.session.put( @@ -227,8 +250,7 @@ def test_create_zone_with_soa_edit(self): self.url("/api/v1/servers/localhost/zones/" + data['id']), data=json.dumps(payload), headers={'content-type': 'application/json'}) - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + data['id'])) - data = r.json() + data = self.get_zone(data['id']) soa_serial = get_first_rec(data, name, 'SOA')['content'].split(' ')[2] self.assertEqual(soa_serial[-2:], '02') @@ -483,7 +505,7 @@ def test_create_zone_with_dnssec(self): name = unique_zone_name() name, payload, data = self.create_zone(dnssec=True) - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)) + self.get_zone(name) for k in ('dnssec', ): self.assertIn(k, data) @@ -511,11 +533,8 @@ def test_create_zone_with_dnssec_disable_dnssec(self): name, payload, data = self.create_zone(dnssec=True) self.put_zone(name, {'dnssec': False}) - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)) - - zoneinfo = r.json() - self.assertEqual(r.status_code, 200) + zoneinfo = self.get_zone(name) self.assertEqual(zoneinfo['dnssec'], False) r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name + '/cryptokeys')) @@ -533,7 +552,7 @@ def test_create_zone_with_nsec3param(self): nsec3param = '1 0 100 aabbccddeeff' name, payload, data = self.create_zone(dnssec=True, nsec3param=nsec3param) - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)) + self.get_zone(name) for k in ('dnssec', 'nsec3param'): self.assertIn(k, data) @@ -560,7 +579,7 @@ def test_create_zone_with_nsec3narrow(self): name, payload, data = self.create_zone(dnssec=True, nsec3param=nsec3param, nsec3narrow=True) - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)) + self.get_zone(name) for k in ('dnssec', 'nsec3param', 'nsec3narrow'): self.assertIn(k, data) @@ -585,11 +604,8 @@ def test_create_zone_with_nsec3param_switch_to_nsec(self): name, payload, data = self.create_zone(dnssec=True, nsec3param='1 0 1 ab') self.put_zone(name, {'nsec3param': ''}) - r = self.session.get( - self.url("/api/v1/servers/localhost/zones/" + name)) - data = r.json() - self.assertEqual(r.status_code, 200) + data = self.get_zone(name) self.assertEqual(data['nsec3param'], '') def test_create_zone_without_dnssec_unset_nsec3parm(self): @@ -617,25 +633,19 @@ def test_create_zone_dnssec_serial(self): self.assertEqual(soa_serial[-2:], '01') self.put_zone(name, {'dnssec': True}) - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)) - data = r.json() + data = self.get_zone(name) soa_serial = get_first_rec(data, name, 'SOA')['content'].split(' ')[2] - - self.assertEqual(r.status_code, 200) self.assertEqual(soa_serial[-2:], '02') self.put_zone(name, {'dnssec': False}) - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)) - data = r.json() + data = self.get_zone(name) soa_serial = get_first_rec(data, name, 'SOA')['content'].split(' ')[2] - - self.assertEqual(r.status_code, 200) self.assertEqual(soa_serial[-2:], '03') def test_zone_absolute_url(self): - name, payload, data = self.create_zone() + self.create_zone() r = self.session.get(self.url("/api/v1/servers/localhost/zones")) rdata = r.json() print(rdata[0]) @@ -712,8 +722,7 @@ def test_create_slave_zone(self): print("zonelist:", zonelist) self.assertIn(payload['name'], [zone['name'] for zone in zonelist]) # Also test that fetching the zone works. - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + data['id'])) - data = r.json() + data = self.get_zone(data['id']) print("zone (fetched):", data) for k in ('name', 'masters', 'kind'): self.assertIn(k, data) @@ -785,8 +794,7 @@ def test_get_zone_with_symbols(self): name, payload, data = self.create_zone(name='foo/bar.'+unique_zone_name()) name = payload['name'] zone_id = (name.replace('/', '=2F')) - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + zone_id)) - data = r.json() + data = self.get_zone(zone_id) for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial', 'dnssec'): self.assertIn(k, data) if k in payload: @@ -796,9 +804,7 @@ def test_get_zone(self): r = self.session.get(self.url("/api/v1/servers/localhost/zones")) domains = r.json() example_com = [domain for domain in domains if domain['name'] == u'example.com.'][0] - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + example_com['id'])) - self.assert_success_json(r) - data = r.json() + data = self.get_zone(example_com['id']) for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial'): self.assertIn(k, data) self.assertEqual(data['name'], 'example.com.') @@ -809,9 +815,7 @@ def test_get_zone_rrset(self): example_com = [domain for domain in domains if domain['name'] == u'example.com.'][0] # verify single record from name that has a single record - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + example_com['id'] + "?rrset_name=host-18000.example.com.")) - self.assert_success_json(r) - data = r.json() + data = self.get_zone(example_com['id'], rrset_name="host-18000.example.com.") for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial', 'rrsets'): self.assertIn(k, data) self.assertEqual(data['rrsets'], @@ -834,9 +838,7 @@ def test_get_zone_rrset(self): # verify two RRsets from a name that has two types with one record each powerdnssec_org = [domain for domain in domains if domain['name'] == u'powerdnssec.org.'][0] - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + powerdnssec_org['id'] + "?rrset_name=localhost.powerdnssec.org.")) - self.assert_success_json(r) - data = r.json() + data = self.get_zone(powerdnssec_org['id'], rrset_name="localhost.powerdnssec.org.") for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial', 'rrsets'): self.assertIn(k, data) self.assertEqual(sorted(data['rrsets'], key=operator.itemgetter('type')), @@ -871,9 +873,7 @@ def test_get_zone_rrset(self): ) # verify one RRset with one record from a name that has two, then filtered by type - r = self.session.get(self.url("/api/v1/servers/localhost/zones/" + powerdnssec_org['id'] + "?rrset_name=localhost.powerdnssec.org.&rrset_type=AAAA")) - self.assert_success_json(r) - data = r.json() + data = self.get_zone(powerdnssec_org['id'], rrset_name="localhost.powerdnssec.org.", rrset_type="AAAA") for k in ('id', 'url', 'name', 'masters', 'kind', 'last_check', 'notified_serial', 'serial', 'rrsets'): self.assertIn(k, data) self.assertEqual(data['rrsets'], @@ -1129,7 +1129,7 @@ def test_update_zone(self): 'soa_edit': 'EPOCH' } self.put_zone(name, payload) - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) for k in payload.keys(): self.assertIn(k, data) self.assertEqual(data[k], payload[k]) @@ -1141,7 +1141,7 @@ def test_update_zone(self): 'soa_edit': '' } self.put_zone(name, payload) - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) for k in payload.keys(): self.assertIn(k, data) self.assertEqual(data[k], payload[k]) @@ -1172,7 +1172,7 @@ def test_zone_rr_update(self): headers={'content-type': 'application/json'}) self.assert_success(r) # verify that (only) the new record is there - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) self.assertCountEqual(get_rrset(data, name, 'NS')['records'], rrset['records']) def test_zone_rr_update_mx(self): @@ -1198,7 +1198,7 @@ def test_zone_rr_update_mx(self): headers={'content-type': 'application/json'}) self.assert_success(r) # verify that (only) the new record is there - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) self.assertEqual(get_rrset(data, name, 'MX')['records'], rrset['records']) def test_zone_rr_update_invalid_mx(self): @@ -1223,7 +1223,7 @@ def test_zone_rr_update_invalid_mx(self): headers={'content-type': 'application/json'}) self.assertEqual(r.status_code, 422) self.assertIn('non-hostname content', r.json()['error']) - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) self.assertIsNone(get_rrset(data, name, 'MX')) def test_zone_rr_update_opt(self): @@ -1283,7 +1283,7 @@ def test_zone_rr_update_multiple_rrsets(self): headers={'content-type': 'application/json'}) self.assert_success(r) # verify that all rrsets have been updated - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) self.assertEqual(get_rrset(data, name, 'NS')['records'], rrset1['records']) self.assertEqual(get_rrset(data, name, 'MX')['records'], rrset2['records']) @@ -1359,7 +1359,7 @@ def test_zone_rr_delete(self): headers={'content-type': 'application/json'}) self.assert_success(r) # verify that the records are gone - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) self.assertIsNone(get_rrset(data, name, 'NS')) def test_zone_rr_update_rrset_combine_replace_and_delete(self): @@ -1388,7 +1388,7 @@ def test_zone_rr_update_rrset_combine_replace_and_delete(self): headers={'content-type': 'application/json'}) self.assert_success(r) # verify that (only) the new record is there - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) self.assertEqual(get_rrset(data, 'sub.' + name, 'CNAME')['records'], rrset2['records']) def test_zone_disable_reenable(self): @@ -1414,7 +1414,7 @@ def test_zone_disable_reenable(self): headers={'content-type': 'application/json'}) self.assert_success(r) # check SOA serial has been edited - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) soa_serial1 = get_first_rec(data, name, 'SOA')['content'].split()[2] self.assertNotEqual(soa_serial1, '1') # make sure domain is still in zone list (disabled SOA!) @@ -1432,7 +1432,7 @@ def test_zone_disable_reenable(self): headers={'content-type': 'application/json'}) self.assert_success(r) # check SOA serial has been edited again - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) soa_serial2 = get_first_rec(data, name, 'SOA')['content'].split()[2] self.assertNotEqual(soa_serial2, '1') self.assertNotEqual(soa_serial2, soa_serial1) @@ -1650,7 +1650,7 @@ def test_only_at_apex(self, qtype, content): headers={'content-type': 'application/json'}) self.assert_success(r) # verify that the new record is there - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) self.assertEqual(get_rrset(data, name, qtype)['records'], rrset['records']) rrset = { @@ -1670,7 +1670,7 @@ def test_only_at_apex(self, qtype, content): headers={'content-type': 'application/json'}) self.assertEqual(r.status_code, 422) self.assertIn('only allowed at apex', r.json()['error']) - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) self.assertIsNone(get_rrset(data, 'sub.' + name, qtype)) @parameterized.expand([ @@ -1695,7 +1695,7 @@ def test_not_allowed_at_apex(self, qtype, content): headers={'content-type': 'application/json'}) self.assertEqual(r.status_code, 422) self.assertIn('not allowed at apex', r.json()['error']) - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) self.assertIsNone(get_rrset(data, 'sub.' + name, qtype)) rrset = { @@ -1717,7 +1717,7 @@ def test_not_allowed_at_apex(self, qtype, content): headers={'content-type': 'application/json'}) self.assert_success(r) # verify that the new record is there - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) self.assertEqual(get_rrset(data, 'sub.' + name, qtype)['records'], rrset['records']) def test_rr_svcb(self): @@ -1885,7 +1885,7 @@ def test_zone_comment_create(self): self.assert_success(r) # make sure the comments have been set, and that the NS # records are still present - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) serverset = get_rrset(data, name, 'NS') print(serverset) self.assertNotEqual(serverset['records'], []) @@ -1911,7 +1911,7 @@ def test_zone_comment_delete(self): headers={'content-type': 'application/json'}) self.assert_success(r) # make sure the NS records are still present - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) serverset = get_rrset(data, name, 'NS') print(serverset) self.assertNotEqual(serverset['records'], []) @@ -1984,7 +1984,7 @@ def test_zone_comment_stay_intact(self): headers={'content-type': 'application/json'}) self.assert_success(r) # make sure the comments still exist - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + name)).json() + data = self.get_zone(name) serverset = get_rrset(data, name, 'NS') print(serverset) self.assertEqual(serverset['records'], rrset2['records']) @@ -2270,25 +2270,22 @@ def test_rrset_parameter_post_false(self): def test_rrset_false_parameter(self): name = unique_zone_name() self.create_zone(name=name, kind='Native') - r = self.session.get(self.url("/api/v1/servers/localhost/zones/"+name+"?rrsets=false")) - self.assert_success_json(r) - print(r.json()) - self.assertEqual(r.json().get('rrsets'), None) + data = self.get_zone(name, rrsets="false") + self.assertEqual(data.get('rrsets'), None) def test_rrset_true_parameter(self): name = unique_zone_name() self.create_zone(name=name, kind='Native') - r = self.session.get(self.url("/api/v1/servers/localhost/zones/"+name+"?rrsets=true")) - self.assert_success_json(r) - print(r.json()) - self.assertEqual(len(r.json().get('rrsets')), 2) + data = self.get_zone(name, rrsets="true") + self.assertEqual(len(data['rrsets']), 2) def test_wrong_rrset_parameter(self): name = unique_zone_name() self.create_zone(name=name, kind='Native') - r = self.session.get(self.url("/api/v1/servers/localhost/zones/"+name+"?rrsets=foobar")) - self.assertEqual(r.status_code, 422) - self.assertIn("'rrsets' request parameter value 'foobar' is not supported", r.json()['error']) + self.get_zone( + name, rrsets="foobar", + expect_error="'rrsets' request parameter value 'foobar' is not supported" + ) def test_put_master_tsig_key_ids_non_existent(self): name = unique_zone_name() @@ -2337,7 +2334,7 @@ def test_create_zone(self): # Also test that fetching the zone works. print("id:", data['id']) self.assertEqual(data['id'], '=2E') - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + data['id'])).json() + data = self.get_zone(data['id']) print("zone (fetched):", data) for k in ('name', 'kind'): self.assertIn(k, data) @@ -2355,7 +2352,7 @@ def test_update_zone(self): 'soa_edit': 'EPOCH' } self.put_zone(zone_id, payload) - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + zone_id)).json() + data = self.get_zone(zone_id) for k in payload.keys(): self.assertIn(k, data) self.assertEqual(data[k], payload[k]) @@ -2366,7 +2363,7 @@ def test_update_zone(self): 'soa_edit': '' } self.put_zone(zone_id, payload) - data = self.session.get(self.url("/api/v1/servers/localhost/zones/" + zone_id)).json() + data = self.get_zone(zone_id) for k in payload.keys(): self.assertIn(k, data) self.assertEqual(data[k], payload[k]) From 70f1db7c228e9ae8ca2b8aa1a250a0e6fc56b49e Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 12 Oct 2022 14:22:42 +0200 Subject: [PATCH 511/909] API Auth: replace zone contents In PUT on a specific zone it is now possible to set "rrsets", like in POST. --- pdns/ws-auth.cc | 72 ++++++++++++++++++++++++++++-- regression-tests.api/test_Zones.py | 67 +++++++++++++++++++++++++++ 2 files changed, 136 insertions(+), 3 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index af30c9a0a34e..fc8eaca2c849 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1899,10 +1899,76 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { } if(req->method == "PUT") { - // update domain settings + // update domain contents and/or settings + auto document = req->json(); - di.backend->startTransaction(zonename, -1); - updateDomainSettingsFromDocument(B, di, zonename, req->json(), false); + auto rrsets = document["rrsets"]; + bool zoneWasModified = false; + // if records/comments are given, load, check and insert them + if (rrsets.is_array()) { + zoneWasModified = true; + bool haveSoa = false; + string soaEditApiKind; + string soaEditKind; + di.backend->getDomainMetadataOne(zonename, "SOA-EDIT-API", soaEditApiKind); + di.backend->getDomainMetadataOne(zonename, "SOA-EDIT", soaEditKind); + + vector new_records; + vector new_comments; + + for (const auto& rrset : rrsets.array_items()) { + DNSName qname = apiNameToDNSName(stringFromJson(rrset, "name")); + apiCheckQNameAllowedCharacters(qname.toString()); + QType qtype; + qtype = stringFromJson(rrset, "type"); + if (qtype.getCode() == 0) { + throw ApiException("RRset "+qname.toString()+" IN "+stringFromJson(rrset, "type")+": unknown type given"); + } + if (rrset["records"].is_array()) { + int ttl = intFromJson(rrset, "ttl"); + gatherRecords(rrset, qname, qtype, ttl, new_records); + } + if (rrset["comments"].is_array()) { + gatherComments(rrset, qname, qtype, new_comments); + } + } + + for(auto& rr : new_records) { + rr.qname.makeUsLowerCase(); + if (!rr.qname.isPartOf(zonename) && rr.qname != zonename) + throw ApiException("RRset "+rr.qname.toString()+" IN "+rr.qtype.toString()+": Name is out of zone"); + apiCheckQNameAllowedCharacters(rr.qname.toString()); + + if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) { + haveSoa = true; + increaseSOARecord(rr, soaEditApiKind, soaEditKind); + } + } + + if (!haveSoa) { + // Require SOA regardless if this is a secondary zone or not. + // If clients want to "zero out" a secondary zone, they should still send a SOA with a, + // for their use case, "low enough" serial. + throw ApiException("Must give SOA record for zone when replacing all RR sets"); + } + + checkNewRecords(new_records, zonename); + + di.backend->startTransaction(zonename, di.id); + for(auto& rr : new_records) { + rr.domain_id = di.id; + di.backend->feedRecord(rr, DNSName()); + } + for(Comment& c : new_comments) { + c.domain_id = di.id; + di.backend->feedComment(c); + } + } else { + // avoid deleting current zone contents + di.backend->startTransaction(zonename, -1); + } + + updateDomainSettingsFromDocument(B, di, zonename, document, zoneWasModified); di.backend->commitTransaction(); resp->body = ""; diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 2f5aa088155e..050eef9ab94f 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -49,6 +49,12 @@ def eq_zone_rrsets(rrsets, expected): assert data_got == data_expected, "%r != %r" % (data_got, data_expected) +def assert_eq_rrsets(rrsets, expected): + """Assert rrsets sets are equal, ignoring sort order.""" + key = lambda rrset: (rrset['name'], rrset['type']) + assert sorted(rrsets, key=key) == sorted(expected, key=key) + + class Zones(ApiTestCase): def _test_list_zones(self, dnssec=True): @@ -2305,6 +2311,67 @@ def test_put_slave_tsig_key_ids_non_existent(self): } self.put_zone(name, payload, expect_error='A TSIG key with the name') + def test_zone_replace_rrsets_basic(self): + """Basic test: all automatic modification is off, on replace the new rrsets are ingested as is.""" + name, _, _ = self.create_zone(dnssec=False, soa_edit='', soa_edit_api='') + rrsets = [ + {'name': name, 'type': 'SOA', 'ttl': 3600, 'records': [{'content': 'invalid. hostmaster.invalid. 1 10800 3600 604800 3600'}]}, + {'name': name, 'type': 'NS', 'ttl': 3600, 'records': [{'content': 'ns1.example.org.'}, {'content': 'ns2.example.org.'}]}, + {'name': 'www.' + name, 'type': 'A', 'ttl': 3600, 'records': [{'content': '192.0.2.1'}]}, + {'name': 'sub.' + name, 'type': 'NS', 'ttl': 3600, 'records': [{'content': 'ns1.example.org.'}]}, + ] + self.put_zone(name, {'rrsets': rrsets}) + + data = self.get_zone(name) + for rrset in rrsets: + rrset.setdefault('comments', []) + for record in rrset['records']: + record.setdefault('disabled', False) + assert_eq_rrsets(data['rrsets'], rrsets) + + def test_zone_replace_rrsets_dnssec(self): + """With dnssec: check automatic rectify is done""" + name, _, _ = self.create_zone(dnssec=True) + rrsets = [ + {'name': name, 'type': 'SOA', 'ttl': 3600, 'records': [{'content': 'invalid. hostmaster.invalid. 1 10800 3600 604800 3600'}]}, + {'name': name, 'type': 'NS', 'ttl': 3600, 'records': [{'content': 'ns1.example.org.'}, {'content': 'ns2.example.org.'}]}, + {'name': 'www.' + name, 'type': 'A', 'ttl': 3600, 'records': [{'content': '192.0.2.1'}]}, + ] + self.put_zone(name, {'rrsets': rrsets}) + + if not is_auth_lmdb(): + # lmdb: skip, no get_db_records implementations + dbrecs = get_db_records(name, 'A') + assert dbrecs[0]['ordername'] is not None # default = rectify enabled + + def test_zone_replace_rrsets_with_soa_edit(self): + """SOA-EDIT was enabled before rrsets will be replaced""" + name, _, _ = self.create_zone(soa_edit='INCEPTION-INCREMENT', soa_edit_api='SOA-EDIT-INCREASE') + rrsets = [ + {'name': name, 'type': 'SOA', 'ttl': 3600, 'records': [{'content': 'invalid. hostmaster.invalid. 1 10800 3600 604800 3600'}]}, + {'name': name, 'type': 'NS', 'ttl': 3600, 'records': [{'content': 'ns1.example.org.'}, {'content': 'ns2.example.org.'}]}, + {'name': 'www.' + name, 'type': 'A', 'ttl': 3600, 'records': [{'content': '192.0.2.1'}]}, + {'name': 'sub.' + name, 'type': 'NS', 'ttl': 3600, 'records': [{'content': 'ns1.example.org.'}]}, + ] + self.put_zone(name, {'rrsets': rrsets}) + + data = self.get_zone(name) + soa = [rrset['records'][0]['content'] for rrset in data['rrsets'] if rrset['type'] == 'SOA'][0] + assert int(soa.split()[2]) > 1 # serial is larger than what we sent + + def test_zone_replace_rrsets_no_soa_primary(self): + """Replace all RRsets but supply no SOA. Should fail.""" + name, _, _ = self.create_zone() + rrsets = [ + {'name': name, 'type': 'NS', 'ttl': 3600, 'records': [{'content': 'ns1.example.org.'}, {'content': 'ns2.example.org.'}]} + ] + self.put_zone(name, {'rrsets': rrsets}, expect_error='Must give SOA record for zone when replacing all RR sets') + + def test_zone_replace_rrsets_no_soa_secondary(self): + """Replace all RRsets in a SECONDARY zone, but supply no SOA. Should still fail.""" + name, _, _ = self.create_zone(kind='Secondary', nameservers=None, masters=['127.0.0.2']) + self.put_zone(name, {'rrsets': []}, expect_error='Must give SOA record for zone when replacing all RR sets') + @unittest.skipIf(not is_auth(), "Not applicable") class AuthRootZone(ApiTestCase, AuthZonesHelperMixin): From cf17e6b8f8b6127abe38c458d15fb275724a7f01 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Fri, 3 Feb 2023 11:13:59 +0100 Subject: [PATCH 512/909] API Auth: forbid ttl < 0 --- pdns/json.cc | 83 +++++++++++++-------- pdns/json.hh | 2 + pdns/ws-auth.cc | 112 ++++++++++++++++------------- regression-tests.api/test_Zones.py | 8 ++- 4 files changed, 125 insertions(+), 80 deletions(-) diff --git a/pdns/json.cc b/pdns/json.cc index 929fc81cc1cc..285a953aefcb 100644 --- a/pdns/json.cc +++ b/pdns/json.cc @@ -28,36 +28,55 @@ using json11::Json; -int intFromJson(const Json& container, const std::string& key) +static inline int intFromJsonInternal(const Json& container, const std::string& key, const bool have_default, const int default_value) { auto val = container[key]; if (val.is_number()) { return val.int_value(); } else if (val.is_string()) { - return std::stoi(val.string_value()); + try { + return std::stoi(val.string_value()); + } catch (std::out_of_range&) { + throw JsonException("Key '" + string(key) + "' is out of range"); + } } else { + if (have_default) { + return default_value; + } throw JsonException("Key '" + string(key) + "' not an Integer or not present"); } } +int intFromJson(const Json& container, const std::string& key) +{ + return intFromJsonInternal(container, key, false, 0); +} + int intFromJson(const Json& container, const std::string& key, const int default_value) { - auto val = container[key]; - if (val.is_number()) { - return val.int_value(); - } else if (val.is_string()) { - try { - return std::stoi(val.string_value()); - } catch (std::out_of_range&) { - throw JsonException("Value for key '" + string(key) + "' is out of range"); - } - } else { - // TODO: check if value really isn't present - return default_value; + return intFromJsonInternal(container, key, true, default_value); +} + +static inline unsigned int uintFromJsonInternal(const Json& container, const std::string& key, const bool have_default, const unsigned int default_value) +{ + int intval = intFromJsonInternal(container, key, have_default, static_cast(default_value)); + if (intval >= 0) { + return intval; } + throw JsonException("Key '" + string(key) + "' is not a positive Integer"); } -double doubleFromJson(const Json& container, const std::string& key) +unsigned int uintFromJson(const Json& container, const std::string& key) +{ + return uintFromJsonInternal(container, key, false, 0); +} + +unsigned int uintFromJson(const Json& container, const std::string& key, const unsigned int default_value) +{ + return uintFromJsonInternal(container, key, true, default_value); +} + +static inline double doubleFromJsonInternal(const Json& container, const std::string& key, const bool have_default, const double default_value) { auto val = container[key]; if (val.is_number()) { @@ -69,21 +88,21 @@ double doubleFromJson(const Json& container, const std::string& key) throw JsonException("Value for key '" + string(key) + "' is out of range"); } } else { + if (have_default) { + return default_value; + } throw JsonException("Key '" + string(key) + "' not an Integer or not present"); } } +double doubleFromJson(const Json& container, const std::string& key) +{ + return doubleFromJsonInternal(container, key, false, 0); +} + double doubleFromJson(const Json& container, const std::string& key, const double default_value) { - auto val = container[key]; - if (val.is_number()) { - return val.number_value(); - } else if (val.is_string()) { - return std::stod(val.string_value()); - } else { - // TODO: check if value really isn't present - return default_value; - } + return doubleFromJsonInternal(container, key, true, default_value); } string stringFromJson(const Json& container, const std::string &key) @@ -96,20 +115,24 @@ string stringFromJson(const Json& container, const std::string &key) } } -bool boolFromJson(const Json& container, const std::string& key) +static inline bool boolFromJsonInternal(const Json& container, const std::string& key, const bool have_default, const bool default_value) { auto val = container[key]; if (val.is_bool()) { return val.bool_value(); } + if (have_default) { + return default_value; + } throw JsonException("Key '" + string(key) + "' not present or not a Bool"); } +bool boolFromJson(const Json& container, const std::string& key) +{ + return boolFromJsonInternal(container, key, false, false); +} + bool boolFromJson(const Json& container, const std::string& key, const bool default_value) { - auto val = container[key]; - if (val.is_bool()) { - return val.bool_value(); - } - return default_value; + return boolFromJsonInternal(container, key, true, default_value); } diff --git a/pdns/json.hh b/pdns/json.hh index db2703641bd3..ef5de1fbb1ea 100644 --- a/pdns/json.hh +++ b/pdns/json.hh @@ -27,6 +27,8 @@ int intFromJson(const json11::Json& container, const std::string& key); int intFromJson(const json11::Json& container, const std::string& key, const int default_value); +unsigned int uintFromJson(const json11::Json& container, const std::string& key); +unsigned int uintFromJson(const json11::Json& container, const std::string& key, const unsigned int default_value); double doubleFromJson(const json11::Json& container, const std::string& key); double doubleFromJson(const json11::Json& container, const std::string& key, const double default_value); std::string stringFromJson(const json11::Json& container, const std::string &key); diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index fc8eaca2c849..bb854c91be48 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -583,8 +583,8 @@ static void gatherComments(const Json& container, const DNSName& qname, const QT time_t now = time(nullptr); for (const auto& comment : container["comments"].array_items()) { - // FIXME this is converting to a *signed* int, 2036 issue - c.modified_at = intFromJson(comment, "modified_at", now); + // FIXME 2036 issue internally in uintFromJson + c.modified_at = uintFromJson(comment, "modified_at", now); c.content = stringFromJson(comment, "content"); c.account = stringFromJson(comment, "account"); new_comments.push_back(c); @@ -1718,25 +1718,30 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { vector new_records; vector new_comments; - if (rrsets.is_array()) { - for (const auto& rrset : rrsets.array_items()) { - DNSName qname = apiNameToDNSName(stringFromJson(rrset, "name")); - apiCheckQNameAllowedCharacters(qname.toString()); - QType qtype; - qtype = stringFromJson(rrset, "type"); - if (qtype.getCode() == 0) { - throw ApiException("RRset "+qname.toString()+" IN "+stringFromJson(rrset, "type")+": unknown type given"); - } - if (rrset["records"].is_array()) { - int ttl = intFromJson(rrset, "ttl"); - gatherRecords(rrset, qname, qtype, ttl, new_records); - } - if (rrset["comments"].is_array()) { - gatherComments(rrset, qname, qtype, new_comments); + try { + if (rrsets.is_array()) { + for (const auto& rrset : rrsets.array_items()) { + DNSName qname = apiNameToDNSName(stringFromJson(rrset, "name")); + apiCheckQNameAllowedCharacters(qname.toString()); + QType qtype; + qtype = stringFromJson(rrset, "type"); + if (qtype.getCode() == 0) { + throw ApiException("RRset "+qname.toString()+" IN "+stringFromJson(rrset, "type")+": unknown type given"); + } + if (rrset["records"].is_array()) { + int ttl = uintFromJson(rrset, "ttl"); + gatherRecords(rrset, qname, qtype, ttl, new_records); + } + if (rrset["comments"].is_array()) { + gatherComments(rrset, qname, qtype, new_comments); + } } + } else if (zonestring != "") { + gatherRecordsFromZone(zonestring, new_records, zonename); } - } else if (zonestring != "") { - gatherRecordsFromZone(zonestring, new_records, zonename); + } + catch (const JsonException& e) { + throw ApiException("New RRsets are invalid: " + string(e.what())); } for(auto& rr : new_records) { @@ -1916,22 +1921,27 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { vector new_records; vector new_comments; - for (const auto& rrset : rrsets.array_items()) { - DNSName qname = apiNameToDNSName(stringFromJson(rrset, "name")); - apiCheckQNameAllowedCharacters(qname.toString()); - QType qtype; - qtype = stringFromJson(rrset, "type"); - if (qtype.getCode() == 0) { - throw ApiException("RRset "+qname.toString()+" IN "+stringFromJson(rrset, "type")+": unknown type given"); - } - if (rrset["records"].is_array()) { - int ttl = intFromJson(rrset, "ttl"); - gatherRecords(rrset, qname, qtype, ttl, new_records); - } - if (rrset["comments"].is_array()) { - gatherComments(rrset, qname, qtype, new_comments); + try { + for (const auto& rrset : rrsets.array_items()) { + DNSName qname = apiNameToDNSName(stringFromJson(rrset, "name")); + apiCheckQNameAllowedCharacters(qname.toString()); + QType qtype; + qtype = stringFromJson(rrset, "type"); + if (qtype.getCode() == 0) { + throw ApiException("RRset "+qname.toString()+" IN "+stringFromJson(rrset, "type")+": unknown type given"); + } + if (rrset["records"].is_array()) { + int ttl = uintFromJson(rrset, "ttl"); + gatherRecords(rrset, qname, qtype, ttl, new_records); + } + if (rrset["comments"].is_array()) { + gatherComments(rrset, qname, qtype, new_comments); + } } } + catch (const JsonException& e) { + throw ApiException("New RRsets are invalid: " + string(e.what())); + } for(auto& rr : new_records) { rr.qname.makeUsLowerCase(); @@ -2177,28 +2187,32 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { new_records.clear(); new_comments.clear(); - if (replace_records) { - // ttl shouldn't be part of DELETE, and it shouldn't be required if we don't get new records. - int ttl = intFromJson(rrset, "ttl"); - - gatherRecords(rrset, qname, qtype, ttl, new_records); - - for(DNSResourceRecord& rr : new_records) { - rr.domain_id = di.id; - if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) { - soa_edit_done = increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind); + try { + if (replace_records) { + // ttl shouldn't be part of DELETE, and it shouldn't be required if we don't get new records. + int ttl = uintFromJson(rrset, "ttl"); + gatherRecords(rrset, qname, qtype, ttl, new_records); + + for(DNSResourceRecord& rr : new_records) { + rr.domain_id = di.id; + if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) { + soa_edit_done = increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind); + } } + checkNewRecords(new_records, zonename); } - checkNewRecords(new_records, zonename); - } - if (replace_comments) { - gatherComments(rrset, qname, qtype, new_comments); + if (replace_comments) { + gatherComments(rrset, qname, qtype, new_comments); - for(Comment& c : new_comments) { - c.domain_id = di.id; + for(Comment& c : new_comments) { + c.domain_id = di.id; + } } } + catch (const JsonException& e) { + throw ApiException("New RRsets are invalid: " + string(e.what())); + } if (replace_records) { bool ent_present = false; diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 050eef9ab94f..18d39643e782 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -1945,7 +1945,7 @@ def test_zone_comment_out_of_range_modified_at(self): data=json.dumps(payload), headers={'content-type': 'application/json'}) self.assertEqual(r.status_code, 422) - self.assertIn("Value for key 'modified_at' is out of range", r.json()['error']) + self.assertIn("Key 'modified_at' is out of range", r.json()['error']) @unittest.skipIf(is_auth_lmdb(), "No comments in LMDB") def test_zone_comment_stay_intact(self): @@ -2372,6 +2372,12 @@ def test_zone_replace_rrsets_no_soa_secondary(self): name, _, _ = self.create_zone(kind='Secondary', nameservers=None, masters=['127.0.0.2']) self.put_zone(name, {'rrsets': []}, expect_error='Must give SOA record for zone when replacing all RR sets') + def test_zone_replace_rrsets_negative_ttl(self): + name, _, _ = self.create_zone(dnssec=False, soa_edit='', soa_edit_api='') + rrsets = [ + {'name': name, 'type': 'SOA', 'ttl': -1, 'records': [{'content': 'invalid. hostmaster.invalid. 1 10800 3600 604800 3600'}]}, + ] + self.put_zone(name, {'rrsets': rrsets}, expect_error="Key 'ttl' is not a positive Integer") @unittest.skipIf(not is_auth(), "Not applicable") class AuthRootZone(ApiTestCase, AuthZonesHelperMixin): From db82ebded9967448da94d42b840939dd36d843f4 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Mon, 27 Mar 2023 09:37:10 +0200 Subject: [PATCH 513/909] API Auth: clear auth cache in PUT --- pdns/ws-auth.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index bb854c91be48..bd35a8aad667 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1981,6 +1981,8 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { updateDomainSettingsFromDocument(B, di, zonename, document, zoneWasModified); di.backend->commitTransaction(); + purgeAuthCaches(zonename.toString() + "$"); + resp->body = ""; resp->status = 204; // No Content, but indicate success return; From 78335d4ffa0dad7ba2f9f0c563326035a44cbbfd Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Mon, 27 Mar 2023 09:36:56 +0200 Subject: [PATCH 514/909] API Auth: increase SOA serial only once in PUT Already done by updateDomainSettingsFromDocument. --- pdns/ws-auth.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index bd35a8aad667..d736c09ffdfa 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1951,7 +1951,6 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) { haveSoa = true; - increaseSOARecord(rr, soaEditApiKind, soaEditKind); } } @@ -1978,6 +1977,7 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { di.backend->startTransaction(zonename, -1); } + // updateDomainSettingsFromDocument will rectify the zone and update SOA serial. updateDomainSettingsFromDocument(B, di, zonename, document, zoneWasModified); di.backend->commitTransaction(); From de39cad718fe83f9e32a67cc80eafc34dacd2eee Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 7 Jun 2023 14:34:24 +0200 Subject: [PATCH 515/909] Add static_cast to hide long-standing internal API design bugs --- pdns/ws-auth.cc | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index d736c09ffdfa..57c9bad4af6d 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1824,17 +1824,17 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { if(!B.getDomainInfo(zonename, di)) throw ApiException("Creating domain '"+zonename.toString()+"' failed: lookup of domain ID failed"); - di.backend->startTransaction(zonename, di.id); + di.backend->startTransaction(zonename, static_cast(di.id)); // will be overridden by updateDomainSettingsFromDocument, if given in document. di.backend->setDomainMetadataOne(zonename, "SOA-EDIT-API", "DEFAULT"); for(auto& rr : new_records) { - rr.domain_id = di.id; + rr.domain_id = static_cast(di.id); di.backend->feedRecord(rr, DNSName()); } for(Comment& c : new_comments) { - c.domain_id = di.id; + c.domain_id = static_cast(di.id); if (!di.backend->feedComment(c)) { throw ApiException("Hosting backend does not support editing comments."); } @@ -1844,7 +1844,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { di.backend->commitTransaction(); - g_zoneCache.add(zonename, di.id); // make new zone visible + g_zoneCache.add(zonename, static_cast(di.id)); // make new zone visible fillZone(B, zonename, resp, req); resp->status = 201; @@ -1963,13 +1963,13 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { checkNewRecords(new_records, zonename); - di.backend->startTransaction(zonename, di.id); + di.backend->startTransaction(zonename, static_cast(di.id)); for(auto& rr : new_records) { - rr.domain_id = di.id; + rr.domain_id = static_cast(di.id); di.backend->feedRecord(rr, DNSName()); } for(Comment& c : new_comments) { - c.domain_id = di.id; + c.domain_id = static_cast(di.id); di.backend->feedComment(c); } } else { @@ -2196,7 +2196,7 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { gatherRecords(rrset, qname, qtype, ttl, new_records); for(DNSResourceRecord& rr : new_records) { - rr.domain_id = di.id; + rr.domain_id = static_cast(di.id); if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) { soa_edit_done = increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind); } @@ -2208,7 +2208,7 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { gatherComments(rrset, qname, qtype, new_comments); for(Comment& c : new_comments) { - c.domain_id = di.id; + c.domain_id = static_cast(di.id); } } } @@ -2434,7 +2434,7 @@ static void apiServerCacheFlush(HttpRequest* req, HttpResponse* resp) { if (B.getDomainInfo(canon, di, false)) { // zone exists (uncached), add/update it in the zone cache. // Handle this first, to avoid concurrent queries re-populating the other caches. - g_zoneCache.add(di.zone, di.id); + g_zoneCache.add(di.zone, static_cast(di.id)); } else { g_zoneCache.remove(di.zone); From b9ecbd3b14531015f8b0577a7a43eaa696b44e1c Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 7 Jun 2023 18:32:21 +0200 Subject: [PATCH 516/909] API Auth: split apiServersZone to lower readability-function-cognitive-complexity --- pdns/ws-auth.cc | 282 +++++++++++++++++++++++++----------------------- 1 file changed, 148 insertions(+), 134 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 57c9bad4af6d..1bc88b14abf9 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1686,174 +1686,174 @@ static void apiServerAutoprimaries(HttpRequest* req, HttpResponse* resp) { } } -static void apiServerZones(HttpRequest* req, HttpResponse* resp) { +// create new zone +static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { UeberBackend B; DNSSECKeeper dk(&B); - if (req->method == "POST") { - DomainInfo di; - auto document = req->json(); - DNSName zonename = apiNameToDNSName(stringFromJson(document, "name")); - apiCheckNameAllowedCharacters(zonename.toString()); - zonename.makeUsLowerCase(); + DomainInfo di; + auto document = req->json(); + DNSName zonename = apiNameToDNSName(stringFromJson(document, "name")); + apiCheckNameAllowedCharacters(zonename.toString()); + zonename.makeUsLowerCase(); - bool exists = B.getDomainInfo(zonename, di); - if(exists) - throw HttpConflictException(); + bool exists = B.getDomainInfo(zonename, di); + if(exists) + throw HttpConflictException(); - // validate 'kind' is set - DomainInfo::DomainKind zonekind = DomainInfo::stringToKind(stringFromJson(document, "kind")); + // validate 'kind' is set + DomainInfo::DomainKind zonekind = DomainInfo::stringToKind(stringFromJson(document, "kind")); - string zonestring = document["zone"].string_value(); - auto rrsets = document["rrsets"]; - if (rrsets.is_array() && zonestring != "") - throw ApiException("You cannot give rrsets AND zone data as text"); + string zonestring = document["zone"].string_value(); + auto rrsets = document["rrsets"]; + if (rrsets.is_array() && zonestring != "") + throw ApiException("You cannot give rrsets AND zone data as text"); - auto nameservers = document["nameservers"]; - if (!nameservers.is_null() && !nameservers.is_array() && zonekind != DomainInfo::Slave && zonekind != DomainInfo::Consumer) - throw ApiException("Nameservers is not a list"); + auto nameservers = document["nameservers"]; + if (!nameservers.is_null() && !nameservers.is_array() && zonekind != DomainInfo::Slave && zonekind != DomainInfo::Consumer) + throw ApiException("Nameservers is not a list"); - // if records/comments are given, load and check them - bool have_soa = false; - bool have_zone_ns = false; - vector new_records; - vector new_comments; + // if records/comments are given, load and check them + bool have_soa = false; + bool have_zone_ns = false; + vector new_records; + vector new_comments; - try { - if (rrsets.is_array()) { - for (const auto& rrset : rrsets.array_items()) { - DNSName qname = apiNameToDNSName(stringFromJson(rrset, "name")); - apiCheckQNameAllowedCharacters(qname.toString()); - QType qtype; - qtype = stringFromJson(rrset, "type"); - if (qtype.getCode() == 0) { - throw ApiException("RRset "+qname.toString()+" IN "+stringFromJson(rrset, "type")+": unknown type given"); - } - if (rrset["records"].is_array()) { - int ttl = uintFromJson(rrset, "ttl"); - gatherRecords(rrset, qname, qtype, ttl, new_records); - } - if (rrset["comments"].is_array()) { - gatherComments(rrset, qname, qtype, new_comments); - } + try { + if (rrsets.is_array()) { + for (const auto& rrset : rrsets.array_items()) { + DNSName qname = apiNameToDNSName(stringFromJson(rrset, "name")); + apiCheckQNameAllowedCharacters(qname.toString()); + QType qtype; + qtype = stringFromJson(rrset, "type"); + if (qtype.getCode() == 0) { + throw ApiException("RRset "+qname.toString()+" IN "+stringFromJson(rrset, "type")+": unknown type given"); + } + if (rrset["records"].is_array()) { + int ttl = uintFromJson(rrset, "ttl"); + gatherRecords(rrset, qname, qtype, ttl, new_records); + } + if (rrset["comments"].is_array()) { + gatherComments(rrset, qname, qtype, new_comments); } - } else if (zonestring != "") { - gatherRecordsFromZone(zonestring, new_records, zonename); } + } else if (zonestring != "") { + gatherRecordsFromZone(zonestring, new_records, zonename); } - catch (const JsonException& e) { - throw ApiException("New RRsets are invalid: " + string(e.what())); - } + } + catch (const JsonException& e) { + throw ApiException("New RRsets are invalid: " + string(e.what())); + } - for(auto& rr : new_records) { - rr.qname.makeUsLowerCase(); - if (!rr.qname.isPartOf(zonename) && rr.qname != zonename) - throw ApiException("RRset "+rr.qname.toString()+" IN "+rr.qtype.toString()+": Name is out of zone"); - apiCheckQNameAllowedCharacters(rr.qname.toString()); + for(auto& rr : new_records) { + rr.qname.makeUsLowerCase(); + if (!rr.qname.isPartOf(zonename) && rr.qname != zonename) + throw ApiException("RRset "+rr.qname.toString()+" IN "+rr.qtype.toString()+": Name is out of zone"); + apiCheckQNameAllowedCharacters(rr.qname.toString()); - if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) { - have_soa = true; - } - if (rr.qtype.getCode() == QType::NS && rr.qname==zonename) { - have_zone_ns = true; - } + if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) { + have_soa = true; } + if (rr.qtype.getCode() == QType::NS && rr.qname==zonename) { + have_zone_ns = true; + } + } - // synthesize RRs as needed - DNSResourceRecord autorr; - autorr.qname = zonename; - autorr.auth = true; - autorr.ttl = ::arg().asNum("default-ttl"); + // synthesize RRs as needed + DNSResourceRecord autorr; + autorr.qname = zonename; + autorr.auth = true; + autorr.ttl = ::arg().asNum("default-ttl"); - if (!have_soa && zonekind != DomainInfo::Slave && zonekind != DomainInfo::Consumer) { - // synthesize a SOA record so the zone "really" exists - string soa = ::arg()["default-soa-content"]; - boost::replace_all(soa, "@", zonename.toStringNoDot()); - SOAData sd; - fillSOAData(soa, sd); - sd.serial=document["serial"].int_value(); - autorr.qtype = QType::SOA; - autorr.content = makeSOAContent(sd)->getZoneRepresentation(true); - // updateDomainSettingsFromDocument will apply SOA-EDIT-API as needed - new_records.push_back(autorr); - } - - // create NS records if nameservers are given - for (const auto& value : nameservers.array_items()) { - const string& nameserver = value.string_value(); - if (nameserver.empty()) - throw ApiException("Nameservers must be non-empty strings"); - if (!isCanonical(nameserver)) - throw ApiException("Nameserver is not canonical: '" + nameserver + "'"); - try { - // ensure the name parses - autorr.content = DNSName(nameserver).toStringRootDot(); - } catch (...) { - throw ApiException("Unable to parse DNS Name for NS '" + nameserver + "'"); - } - autorr.qtype = QType::NS; - new_records.push_back(autorr); - if (have_zone_ns) { - throw ApiException("Nameservers list MUST NOT be mixed with zone-level NS in rrsets"); - } + if (!have_soa && zonekind != DomainInfo::Slave && zonekind != DomainInfo::Consumer) { + // synthesize a SOA record so the zone "really" exists + string soa = ::arg()["default-soa-content"]; + boost::replace_all(soa, "@", zonename.toStringNoDot()); + SOAData sd; + fillSOAData(soa, sd); + sd.serial=document["serial"].int_value(); + autorr.qtype = QType::SOA; + autorr.content = makeSOAContent(sd)->getZoneRepresentation(true); + // updateDomainSettingsFromDocument will apply SOA-EDIT-API as needed + new_records.push_back(autorr); + } + + // create NS records if nameservers are given + for (const auto& value : nameservers.array_items()) { + const string& nameserver = value.string_value(); + if (nameserver.empty()) + throw ApiException("Nameservers must be non-empty strings"); + if (!isCanonical(nameserver)) + throw ApiException("Nameserver is not canonical: '" + nameserver + "'"); + try { + // ensure the name parses + autorr.content = DNSName(nameserver).toStringRootDot(); + } catch (...) { + throw ApiException("Unable to parse DNS Name for NS '" + nameserver + "'"); + } + autorr.qtype = QType::NS; + new_records.push_back(autorr); + if (have_zone_ns) { + throw ApiException("Nameservers list MUST NOT be mixed with zone-level NS in rrsets"); } + } - checkNewRecords(new_records, zonename); + checkNewRecords(new_records, zonename); - if (boolFromJson(document, "dnssec", false)) { - checkDefaultDNSSECAlgos(); + if (boolFromJson(document, "dnssec", false)) { + checkDefaultDNSSECAlgos(); - if(document["nsec3param"].string_value().length() > 0) { - NSEC3PARAMRecordContent ns3pr(document["nsec3param"].string_value()); - string error_msg = ""; - if (!dk.checkNSEC3PARAM(ns3pr, error_msg)) { - throw ApiException("NSEC3PARAMs provided for zone '"+zonename.toString()+"' are invalid. " + error_msg); - } + if(document["nsec3param"].string_value().length() > 0) { + NSEC3PARAMRecordContent ns3pr(document["nsec3param"].string_value()); + string error_msg = ""; + if (!dk.checkNSEC3PARAM(ns3pr, error_msg)) { + throw ApiException("NSEC3PARAMs provided for zone '"+zonename.toString()+"' are invalid. " + error_msg); } } + } - boost::optional kind; - boost::optional> masters; - boost::optional catalog; - boost::optional account; - extractDomainInfoFromDocument(document, kind, masters, catalog, account); + boost::optional kind; + boost::optional> masters; + boost::optional catalog; + boost::optional account; + extractDomainInfoFromDocument(document, kind, masters, catalog, account); - // no going back after this - if(!B.createDomain(zonename, kind.get_value_or(DomainInfo::Native), masters.get_value_or(vector()), account.get_value_or(""))) - throw ApiException("Creating domain '"+zonename.toString()+"' failed: backend refused"); + // no going back after this + if(!B.createDomain(zonename, kind.get_value_or(DomainInfo::Native), masters.get_value_or(vector()), account.get_value_or(""))) + throw ApiException("Creating domain '"+zonename.toString()+"' failed: backend refused"); - if(!B.getDomainInfo(zonename, di)) - throw ApiException("Creating domain '"+zonename.toString()+"' failed: lookup of domain ID failed"); + if(!B.getDomainInfo(zonename, di)) + throw ApiException("Creating domain '"+zonename.toString()+"' failed: lookup of domain ID failed"); - di.backend->startTransaction(zonename, static_cast(di.id)); + di.backend->startTransaction(zonename, static_cast(di.id)); - // will be overridden by updateDomainSettingsFromDocument, if given in document. - di.backend->setDomainMetadataOne(zonename, "SOA-EDIT-API", "DEFAULT"); + // will be overridden by updateDomainSettingsFromDocument, if given in document. + di.backend->setDomainMetadataOne(zonename, "SOA-EDIT-API", "DEFAULT"); - for(auto& rr : new_records) { - rr.domain_id = static_cast(di.id); - di.backend->feedRecord(rr, DNSName()); - } - for(Comment& c : new_comments) { - c.domain_id = static_cast(di.id); - if (!di.backend->feedComment(c)) { - throw ApiException("Hosting backend does not support editing comments."); - } + for(auto& rr : new_records) { + rr.domain_id = static_cast(di.id); + di.backend->feedRecord(rr, DNSName()); + } + for(Comment& c : new_comments) { + c.domain_id = static_cast(di.id); + if (!di.backend->feedComment(c)) { + throw ApiException("Hosting backend does not support editing comments."); } + } - updateDomainSettingsFromDocument(B, di, zonename, document, !new_records.empty()); + updateDomainSettingsFromDocument(B, di, zonename, document, !new_records.empty()); - di.backend->commitTransaction(); + di.backend->commitTransaction(); - g_zoneCache.add(zonename, static_cast(di.id)); // make new zone visible + g_zoneCache.add(zonename, static_cast(di.id)); // make new zone visible - fillZone(B, zonename, resp, req); - resp->status = 201; - return; - } - - if(req->method != "GET") - throw HttpMethodNotAllowedException(); + fillZone(B, zonename, resp, req); + resp->status = 201; +} +// list known zones +static void apiServerZonesGet(HttpRequest* req, HttpResponse* resp) { + UeberBackend B; + DNSSECKeeper dk(&B); vector domains; if (req->getvars.count("zone")) { @@ -1890,6 +1890,20 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) { resp->setJsonBody(doc); } +static void apiServerZones(HttpRequest* req, HttpResponse* resp) { + if (req->method == "POST") { + apiServerZonesPost(req, resp); + return; + } + + if (req->method == "GET") { + apiServerZonesGet(req, resp); + return; + } + + throw HttpMethodNotAllowedException(); +} + static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { DNSName zonename = apiZoneIdToName(req->parameters["id"]); From a253ceb8d0e971965f67c43e6611fc1fdb17d011 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 7 Jun 2023 14:40:44 +0200 Subject: [PATCH 517/909] API Auth: use empty() --- pdns/ws-auth.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 1bc88b14abf9..ad6f4e12c691 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1705,7 +1705,7 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { string zonestring = document["zone"].string_value(); auto rrsets = document["rrsets"]; - if (rrsets.is_array() && zonestring != "") + if (rrsets.is_array() && !zonestring.empty()) throw ApiException("You cannot give rrsets AND zone data as text"); auto nameservers = document["nameservers"]; @@ -1736,7 +1736,7 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { gatherComments(rrset, qname, qtype, new_comments); } } - } else if (zonestring != "") { + } else if (!zonestring.empty()) { gatherRecordsFromZone(zonestring, new_records, zonename); } } From 66ade8acd57214c690a74aad96dc2b34cff6569b Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 7 Jun 2023 14:42:03 +0200 Subject: [PATCH 518/909] API Auth: add missing braces to conditional statements --- pdns/ws-auth.cc | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index ad6f4e12c691..8a7ad9bf5aaf 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1697,20 +1697,23 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { zonename.makeUsLowerCase(); bool exists = B.getDomainInfo(zonename, di); - if(exists) + if (exists) { throw HttpConflictException(); + } // validate 'kind' is set DomainInfo::DomainKind zonekind = DomainInfo::stringToKind(stringFromJson(document, "kind")); string zonestring = document["zone"].string_value(); auto rrsets = document["rrsets"]; - if (rrsets.is_array() && !zonestring.empty()) + if (rrsets.is_array() && !zonestring.empty()) { throw ApiException("You cannot give rrsets AND zone data as text"); + } auto nameservers = document["nameservers"]; - if (!nameservers.is_null() && !nameservers.is_array() && zonekind != DomainInfo::Slave && zonekind != DomainInfo::Consumer) + if (!nameservers.is_null() && !nameservers.is_array() && zonekind != DomainInfo::Slave && zonekind != DomainInfo::Consumer) { throw ApiException("Nameservers is not a list"); + } // if records/comments are given, load and check them bool have_soa = false; @@ -1746,14 +1749,16 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { for(auto& rr : new_records) { rr.qname.makeUsLowerCase(); - if (!rr.qname.isPartOf(zonename) && rr.qname != zonename) + if (!rr.qname.isPartOf(zonename) && rr.qname != zonename) { throw ApiException("RRset "+rr.qname.toString()+" IN "+rr.qtype.toString()+": Name is out of zone"); + } + apiCheckQNameAllowedCharacters(rr.qname.toString()); - if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) { + if (rr.qtype.getCode() == QType::SOA && rr.qname == zonename) { have_soa = true; } - if (rr.qtype.getCode() == QType::NS && rr.qname==zonename) { + if (rr.qtype.getCode() == QType::NS && rr.qname == zonename) { have_zone_ns = true; } } @@ -1780,10 +1785,12 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { // create NS records if nameservers are given for (const auto& value : nameservers.array_items()) { const string& nameserver = value.string_value(); - if (nameserver.empty()) + if (nameserver.empty()) { throw ApiException("Nameservers must be non-empty strings"); - if (!isCanonical(nameserver)) + } + if (!isCanonical(nameserver)) { throw ApiException("Nameserver is not canonical: '" + nameserver + "'"); + } try { // ensure the name parses autorr.content = DNSName(nameserver).toStringRootDot(); @@ -1818,11 +1825,13 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { extractDomainInfoFromDocument(document, kind, masters, catalog, account); // no going back after this - if(!B.createDomain(zonename, kind.get_value_or(DomainInfo::Native), masters.get_value_or(vector()), account.get_value_or(""))) + if(!B.createDomain(zonename, kind.get_value_or(DomainInfo::Native), masters.get_value_or(vector()), account.get_value_or(""))) { throw ApiException("Creating domain '"+zonename.toString()+"' failed: backend refused"); + } - if(!B.getDomainInfo(zonename, di)) + if(!B.getDomainInfo(zonename, di)) { throw ApiException("Creating domain '"+zonename.toString()+"' failed: lookup of domain ID failed"); + } di.backend->startTransaction(zonename, static_cast(di.id)); @@ -1959,11 +1968,12 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { for(auto& rr : new_records) { rr.qname.makeUsLowerCase(); - if (!rr.qname.isPartOf(zonename) && rr.qname != zonename) + if (!rr.qname.isPartOf(zonename) && rr.qname != zonename) { throw ApiException("RRset "+rr.qname.toString()+" IN "+rr.qtype.toString()+": Name is out of zone"); + } apiCheckQNameAllowedCharacters(rr.qname.toString()); - if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) { + if (rr.qtype.getCode() == QType::SOA && rr.qname == zonename) { haveSoa = true; } } @@ -2211,7 +2221,7 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { for(DNSResourceRecord& rr : new_records) { rr.domain_id = static_cast(di.id); - if (rr.qtype.getCode() == QType::SOA && rr.qname==zonename) { + if (rr.qtype.getCode() == QType::SOA && rr.qname == zonename) { soa_edit_done = increaseSOARecord(rr, soa_edit_api_kind, soa_edit_kind); } } From 83c8688a2ce019bd9893da21b44e0919ab8d69b7 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 7 Jun 2023 14:43:20 +0200 Subject: [PATCH 519/909] API Auth: ttl in gatherRecords needs to be unsigned --- pdns/ws-auth.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 8a7ad9bf5aaf..66fa76f0dd16 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -536,7 +536,7 @@ static void validateGatheredRRType(const DNSResourceRecord& rr) { } } -static void gatherRecords(const Json& container, const DNSName& qname, const QType& qtype, const int ttl, vector& new_records) { +static void gatherRecords(const Json& container, const DNSName& qname, const QType& qtype, const uint32_t ttl, vector& new_records) { DNSResourceRecord rr; rr.qname = qname; rr.qtype = qtype; @@ -1732,7 +1732,7 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { throw ApiException("RRset "+qname.toString()+" IN "+stringFromJson(rrset, "type")+": unknown type given"); } if (rrset["records"].is_array()) { - int ttl = uintFromJson(rrset, "ttl"); + uint32_t ttl = uintFromJson(rrset, "ttl"); gatherRecords(rrset, qname, qtype, ttl, new_records); } if (rrset["comments"].is_array()) { @@ -1954,7 +1954,7 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { throw ApiException("RRset "+qname.toString()+" IN "+stringFromJson(rrset, "type")+": unknown type given"); } if (rrset["records"].is_array()) { - int ttl = uintFromJson(rrset, "ttl"); + uint32_t ttl = uintFromJson(rrset, "ttl"); gatherRecords(rrset, qname, qtype, ttl, new_records); } if (rrset["comments"].is_array()) { @@ -2216,7 +2216,7 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { try { if (replace_records) { // ttl shouldn't be part of DELETE, and it shouldn't be required if we don't get new records. - int ttl = uintFromJson(rrset, "ttl"); + uint32_t ttl = uintFromJson(rrset, "ttl"); gatherRecords(rrset, qname, qtype, ttl, new_records); for(DNSResourceRecord& rr : new_records) { From 994a94ce41490b638cce6aa4b35420382fadb2cd Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 7 Jun 2023 14:45:18 +0200 Subject: [PATCH 520/909] API Auth: ignore readability-function-cognitive-complexity for patchZone --- pdns/ws-auth.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 66fa76f0dd16..8defb84f7a1d 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -2146,7 +2146,8 @@ static void apiServerZoneRectify(HttpRequest* req, HttpResponse* resp) { resp->setSuccessResult("Rectified"); } -static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) { +static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) // NOLINT(readability-function-cognitive-complexity) +{ bool zone_disabled; SOAData sd; DomainInfo di; From 0e3e5d0be56f56ec5f15a87408f722b6660503bc Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Wed, 7 Jun 2023 18:23:27 +0200 Subject: [PATCH 521/909] API Auth: remove redundant string initialization --- pdns/ws-auth.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 8defb84f7a1d..cc5ba2417d4a 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1811,7 +1811,7 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { if(document["nsec3param"].string_value().length() > 0) { NSEC3PARAMRecordContent ns3pr(document["nsec3param"].string_value()); - string error_msg = ""; + string error_msg; if (!dk.checkNSEC3PARAM(ns3pr, error_msg)) { throw ApiException("NSEC3PARAMs provided for zone '"+zonename.toString()+"' are invalid. " + error_msg); } From fcac4417defa05614619f8c4e9df8af382545d74 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Fri, 11 Aug 2023 13:19:49 +0200 Subject: [PATCH 522/909] API Auth: improve error message consistency --- pdns/ws-auth.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index cc5ba2417d4a..26f248966243 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1490,7 +1490,7 @@ static void checkNewRecords(vector& records, const DNSName& z try { checkHostnameCorrectness(rec); } catch (const std::exception& e) { - throw ApiException("RRset "+rec.qname.toString()+" IN "+rec.qtype.toString() + " " + e.what()); + throw ApiException("RRset "+rec.qname.toString()+" IN "+rec.qtype.toString() + ": " + e.what()); } previous = rec; From acbb2efdbdb5e46f4573a8f62a71271363e3d7d7 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Fri, 11 Aug 2023 13:20:10 +0200 Subject: [PATCH 523/909] API Auth: add invalid RRset test for PUT zone with rrsets --- regression-tests.api/test_Zones.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 18d39643e782..48049ae9d528 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -2379,6 +2379,24 @@ def test_zone_replace_rrsets_negative_ttl(self): ] self.put_zone(name, {'rrsets': rrsets}, expect_error="Key 'ttl' is not a positive Integer") + @parameterized.expand([ + ("IN MX: non-hostname content", [{'name': '$NAME$', 'type': 'MX', 'ttl': 3600, 'records': [{"content": "10 mail@mx.example.org."}]}]), + ("out of zone", [{'name': 'not-in-zone.', 'type': 'NS', 'ttl': 3600, 'records': [{"content": "ns1.example.org."}]}]), + ("contains unsupported characters", [{'name': 'test:.$NAME$', 'type': 'NS', 'ttl': 3600, 'records': [{"content": "ns1.example.org."}]}]), + ("unknown type", [{'name': '$NAME$', 'type': 'INVALID', 'ttl': 3600, 'records': [{"content": "192.0.2.1"}]}]), + ("Conflicts with another RRset", [{'name': '$NAME$', 'type': 'CNAME', 'ttl': 3600, 'records': [{"content": "example.org."}]}]), + ]) + def test_zone_replace_rrsets_invalid(self, expected_error, invalid_rrsets): + """Test validation of RRsets before replacing them""" + name, _, _ = self.create_zone(dnssec=False, soa_edit='', soa_edit_api='') + base_rrsets = [ + {'name': name, 'type': 'SOA', 'ttl': 3600, 'records': [{'content': 'invalid. hostmaster.invalid. 1 10800 3600 604800 3600'}]}, + {'name': name, 'type': 'NS', 'ttl': 3600, 'records': [{'content': 'ns1.example.org.'}, {'content': 'ns2.example.org.'}]}, + ] + rrsets = base_rrsets + [rrset | {"name": rrset["name"].replace('$NAME$', name)} for rrset in invalid_rrsets] + self.put_zone(name, {'rrsets': rrsets}, expect_error=expected_error) + + @unittest.skipIf(not is_auth(), "Not applicable") class AuthRootZone(ApiTestCase, AuthZonesHelperMixin): From 26636b05e7299c22ea0b79733c92dfbcc61228c9 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Fri, 11 Aug 2023 13:48:16 +0200 Subject: [PATCH 524/909] API Auth: Support emptying out secondary zone without new SOA --- pdns/ws-auth.cc | 22 ++++++++++++++------ regression-tests.api/test_Zones.py | 33 +++++++++++++++++++++++++----- 2 files changed, 44 insertions(+), 11 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 26f248966243..21a4efea63c1 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -658,7 +658,7 @@ static void extractDomainInfoFromDocument(const Json& document, boost::optional< } // Must be called within backend transaction. -static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo& di, const DNSName& zonename, const Json& document, bool zoneWasModified) { +static void updateDomainSettingsFromDocument(UeberBackend& B, DomainInfo& di, const DNSName& zonename, const Json& document, bool zoneWasModified) { boost::optional kind; boost::optional> masters; boost::optional catalog; @@ -668,6 +668,7 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo& if (kind) { di.backend->setKind(zonename, *kind); + di.kind = *kind; } if (masters) { di.backend->setMasters(zonename, *masters); @@ -804,7 +805,8 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, const DomainInfo& if (api_rectify == "1") { string info; string error_msg; - if (!dk.rectifyZone(zonename, error_msg, info, false)) { + if (!dk.rectifyZone(zonename, error_msg, info, false) && !di.isSecondaryType()) { + // for Secondary zones, it is possible that rectifying was not needed (example: empty zone). throw ApiException("Failed to rectify '" + zonename.toString() + "' " + error_msg); } } @@ -1932,6 +1934,12 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { auto rrsets = document["rrsets"]; bool zoneWasModified = false; + bool zoneWillBeSecondary = di.isSecondaryType(); + if (document["kind"].is_string()) { + DomainInfo::DomainKind newKind = DomainInfo::stringToKind(stringFromJson(document, "kind")); + zoneWillBeSecondary = (newKind == DomainInfo::Slave || newKind == DomainInfo::Consumer); + } + // if records/comments are given, load, check and insert them if (rrsets.is_array()) { zoneWasModified = true; @@ -1978,10 +1986,8 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { } } - if (!haveSoa) { - // Require SOA regardless if this is a secondary zone or not. - // If clients want to "zero out" a secondary zone, they should still send a SOA with a, - // for their use case, "low enough" serial. + if (!haveSoa && !zoneWillBeSecondary) { + // Require SOA if this is a primary zone. throw ApiException("Must give SOA record for zone when replacing all RR sets"); } @@ -1996,6 +2002,10 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { c.domain_id = static_cast(di.id); di.backend->feedComment(c); } + + if (!haveSoa && zoneWillBeSecondary) { + di.backend->setStale(di.id); + } } else { // avoid deleting current zone contents di.backend->startTransaction(zonename, -1); diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 48049ae9d528..d9bcc9005b50 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -55,6 +55,26 @@ def assert_eq_rrsets(rrsets, expected): assert sorted(rrsets, key=key) == sorted(expected, key=key) +def templated_rrsets(rrsets: list, zonename: str): + """ + Replace $NAME$ in `name` and `content` of given rrsets with `zonename`. + Will return a copy. Original rrsets should stay unmodified. + """ + new_rrsets = [] + for rrset in rrsets: + new_rrset = rrset | {"name": rrset["name"].replace('$NAME$', zonename)} + + if "records" in rrset: + records = [] + for record in rrset["records"]: + records.append(record | {"content": record["content"].replace('$NAME$', zonename)}) + new_rrset["records"] = records + + new_rrsets.append(new_rrset) + + return new_rrsets + + class Zones(ApiTestCase): def _test_list_zones(self, dnssec=True): @@ -146,7 +166,7 @@ def put_zone(self, api_zone_id, payload, expect_error=None): print("reply status code:", r.status_code) if expect_error: - self.assertEqual(r.status_code, 422) + self.assertEqual(r.status_code, 422, r.content) reply = r.json() if expect_error is True: pass @@ -154,7 +174,7 @@ def put_zone(self, api_zone_id, payload, expect_error=None): self.assertIn(expect_error, reply['error']) else: # expect success (no content) - self.assertEqual(r.status_code, 204) + self.assertEqual(r.status_code, 204, r.content) @unittest.skipIf(not is_auth(), "Not applicable") class AuthZones(ApiTestCase, AuthZonesHelperMixin): @@ -2368,9 +2388,12 @@ def test_zone_replace_rrsets_no_soa_primary(self): self.put_zone(name, {'rrsets': rrsets}, expect_error='Must give SOA record for zone when replacing all RR sets') def test_zone_replace_rrsets_no_soa_secondary(self): - """Replace all RRsets in a SECONDARY zone, but supply no SOA. Should still fail.""" + """ + Replace all RRsets in a SECONDARY zone, but supply no SOA. + Should succeed, also setting zone stale (but cannot assert this here). + """ name, _, _ = self.create_zone(kind='Secondary', nameservers=None, masters=['127.0.0.2']) - self.put_zone(name, {'rrsets': []}, expect_error='Must give SOA record for zone when replacing all RR sets') + self.put_zone(name, {'rrsets': []}) def test_zone_replace_rrsets_negative_ttl(self): name, _, _ = self.create_zone(dnssec=False, soa_edit='', soa_edit_api='') @@ -2393,7 +2416,7 @@ def test_zone_replace_rrsets_invalid(self, expected_error, invalid_rrsets): {'name': name, 'type': 'SOA', 'ttl': 3600, 'records': [{'content': 'invalid. hostmaster.invalid. 1 10800 3600 604800 3600'}]}, {'name': name, 'type': 'NS', 'ttl': 3600, 'records': [{'content': 'ns1.example.org.'}, {'content': 'ns2.example.org.'}]}, ] - rrsets = base_rrsets + [rrset | {"name": rrset["name"].replace('$NAME$', name)} for rrset in invalid_rrsets] + rrsets = base_rrsets + templated_rrsets(invalid_rrsets, name) self.put_zone(name, {'rrsets': rrsets}, expect_error=expected_error) From 8db3d7a68ed343513d329badae31d93d0da420ef Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Fri, 11 Aug 2023 16:24:21 +0200 Subject: [PATCH 525/909] API Auth: restrict RRset modification for Consumer zones --- pdns/ws-auth.cc | 41 +++++++++---- regression-tests.api/test_Zones.py | 97 ++++++++++++++++++++++++------ 2 files changed, 106 insertions(+), 32 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 21a4efea63c1..d650a5d2dbc8 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1703,8 +1703,17 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { throw HttpConflictException(); } + boost::optional kind; + boost::optional> masters; + boost::optional catalog; + boost::optional account; + extractDomainInfoFromDocument(document, kind, masters, catalog, account); + // validate 'kind' is set - DomainInfo::DomainKind zonekind = DomainInfo::stringToKind(stringFromJson(document, "kind")); + if (!kind) { + throw JsonException("Key 'kind' not present or not a String"); + } + DomainInfo::DomainKind zonekind = *kind; string zonestring = document["zone"].string_value(); auto rrsets = document["rrsets"]; @@ -1749,6 +1758,10 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { throw ApiException("New RRsets are invalid: " + string(e.what())); } + if (zonekind == DomainInfo::Consumer && !new_records.empty()) { + throw ApiException("Zone data MUST NOT be given for Consumer zones"); + } + for(auto& rr : new_records) { rr.qname.makeUsLowerCase(); if (!rr.qname.isPartOf(zonename) && rr.qname != zonename) { @@ -1790,6 +1803,9 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { if (nameserver.empty()) { throw ApiException("Nameservers must be non-empty strings"); } + if (zonekind == DomainInfo::Consumer) { + throw ApiException("Nameservers MUST NOT be given for Consumer zones"); + } if (!isCanonical(nameserver)) { throw ApiException("Nameserver is not canonical: '" + nameserver + "'"); } @@ -1820,12 +1836,6 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { } } - boost::optional kind; - boost::optional> masters; - boost::optional catalog; - boost::optional account; - extractDomainInfoFromDocument(document, kind, masters, catalog, account); - // no going back after this if(!B.createDomain(zonename, kind.get_value_or(DomainInfo::Native), masters.get_value_or(vector()), account.get_value_or(""))) { throw ApiException("Creating domain '"+zonename.toString()+"' failed: backend refused"); @@ -1934,10 +1944,9 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { auto rrsets = document["rrsets"]; bool zoneWasModified = false; - bool zoneWillBeSecondary = di.isSecondaryType(); + DomainInfo::DomainKind newKind = di.kind; if (document["kind"].is_string()) { - DomainInfo::DomainKind newKind = DomainInfo::stringToKind(stringFromJson(document, "kind")); - zoneWillBeSecondary = (newKind == DomainInfo::Slave || newKind == DomainInfo::Consumer); + newKind = DomainInfo::stringToKind(stringFromJson(document, "kind")); } // if records/comments are given, load, check and insert them @@ -1986,10 +1995,14 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { } } - if (!haveSoa && !zoneWillBeSecondary) { + if (!haveSoa && newKind != DomainInfo::Slave && newKind != DomainInfo::Consumer) { // Require SOA if this is a primary zone. throw ApiException("Must give SOA record for zone when replacing all RR sets"); } + if (newKind == DomainInfo::Consumer && !new_records.empty()) { + // Allow deleting all RRsets, just not modifying them. + throw ApiException("Modifying RRsets in Consumer zones is unsupported"); + } checkNewRecords(new_records, zonename); @@ -2003,7 +2016,7 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) { di.backend->feedComment(c); } - if (!haveSoa && zoneWillBeSecondary) { + if (!haveSoa && (newKind == DomainInfo::Slave || newKind == DomainInfo::Consumer)) { di.backend->setStale(di.id); } } else { @@ -2282,6 +2295,10 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) // if (dname_seen && ns_seen && qname != zonename) { throw ApiException("RRset "+qname.toString()+" IN "+qtype.toString()+": Cannot have both NS and DNAME except in zone apex"); } + if (!new_records.empty() && di.kind == DomainInfo::Consumer) { + // Allow deleting all RRsets, just not modifying them. + throw ApiException("Modifying RRsets in Consumer zones is unsupported"); + } if (!new_records.empty() && ent_present) { QType qt_ent{0}; if (!di.backend->replaceRRSet(di.id, qname, qt_ent, new_records)) { diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index d9bcc9005b50..d4529375c159 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -110,28 +110,42 @@ def test_list_zones_without_dnssec(self): class AuthZonesHelperMixin(object): - def create_zone(self, name=None, **kwargs): + def create_zone(self, name=None, expect_error=None, **kwargs): if name is None: name = unique_zone_name() payload = { - 'name': name, - 'kind': 'Native', - 'nameservers': ['ns1.example.com.', 'ns2.example.com.'] + "name": name, + "kind": "Native", + "nameservers": ["ns1.example.com.", "ns2.example.com."] } for k, v in kwargs.items(): if v is None: del payload[k] else: payload[k] = v + if "zone" in payload: + payload["zone"] = payload["zone"].replace("$NAME$", payload["name"]) + if "rrsets" in payload: + payload["rrsets"] = templated_rrsets(payload["rrsets"], payload["name"]) + print("Create zone", name, "with:", payload) r = self.session.post( self.url("/api/v1/servers/localhost/zones"), data=json.dumps(payload), - headers={'content-type': 'application/json'}) - self.assert_success_json(r) - self.assertEqual(r.status_code, 201) - reply = r.json() - print("reply", reply) + headers={"content-type": "application/json"}) + + if expect_error: + self.assertEqual(r.status_code, 422, r.content) + reply = r.json() + if expect_error is True: + pass + else: + self.assertIn(expect_error, reply["error"]) + else: + # expect success + self.assertEqual(r.status_code, 201, r.content) + reply = r.json() + return name, payload, reply def get_zone(self, api_zone_id, expect_error=None, **kwargs): @@ -357,11 +371,11 @@ def test_create_zone_with_comments(self): ] if is_auth_lmdb(): - with self.assertRaises(requests.exceptions.HTTPError): # No comments in LMDB - self.create_zone(name=name, rrsets=rrsets) + # No comments in LMDB + self.create_zone(name=name, rrsets=rrsets, expect_error="Hosting backend does not support editing comments.") return - name, payload, data = self.create_zone(name=name, rrsets=rrsets) + name, _, data = self.create_zone(name=name, rrsets=rrsets) # NS records have been created self.assertEqual(len(data['rrsets']), len(rrsets) + 1) # check our comment has appeared @@ -758,10 +772,7 @@ def test_create_slave_zone(self): def test_create_consumer_zone(self): # Test that nameservers can be absent for consumer zones. - name, payload, data = self.create_zone(kind='Consumer', nameservers=None, masters=['127.0.0.2']) - for k in ('name', 'masters', 'kind'): - self.assertIn(k, data) - self.assertEqual(data[k], payload[k]) + _, payload, data = self.create_zone(kind='Consumer', nameservers=None, masters=['127.0.0.2']) print("payload:", payload) print("data:", data) # Because consumer zones don't get a SOA, we need to test that they'll show up in the zone list. @@ -779,6 +790,23 @@ def test_create_consumer_zone(self): self.assertEqual(data['serial'], 0) self.assertEqual(data['rrsets'], []) + def test_create_consumer_zone_no_nameservers(self): + """nameservers must be absent for Consumer zones""" + self.create_zone(kind="Consumer", nameservers=["127.0.0.1"], expect_error="Nameservers MUST NOT be given for Consumer zones") + + def test_create_consumer_zone_no_rrsets(self): + """rrsets must be absent for Consumer zones""" + rrsets = [{ + "name": "$NAME$", + "type": "SOA", + "ttl": 3600, + "records": [{ + "content": "ns1.example.net. testmaster@example.net. 10 10800 3600 604800 3600", + "disabled": False, + }], + }] + self.create_zone(kind="Consumer", nameservers=None, rrsets=rrsets, expect_error="Zone data MUST NOT be given for Consumer zones") + def test_find_zone_by_name(self): name = 'foo/' + unique_zone_name() name, payload, data = self.create_zone(name=name) @@ -1129,6 +1157,18 @@ def test_export_zone_json(self): ' 0 10800 3600 604800 3600'] self.assertCountEqual(data['zone'].strip().split('\n'), expected_data) + def test_import_zone_consumer(self): + zonestring = """ +$NAME$ 1D IN SOA ns1.example.org. hostmaster.example.org. ( + 2002022401 ; serial + 3H ; refresh + 15 ; retry + 1w ; expire + 3h ; minimum + ) + """ + self.create_zone(kind="Consumer", nameservers=[], zone=zonestring, expect_error="Zone data MUST NOT be given for Consumer zones") + def test_export_zone_text(self): name, payload, zone = self.create_zone(nameservers=['ns1.foo.com.', 'ns2.foo.com.'], soa_edit_api='') # export it @@ -2387,13 +2427,30 @@ def test_zone_replace_rrsets_no_soa_primary(self): ] self.put_zone(name, {'rrsets': rrsets}, expect_error='Must give SOA record for zone when replacing all RR sets') - def test_zone_replace_rrsets_no_soa_secondary(self): + @parameterized.expand([ + (None, []), + (None, [ + {'name': '$NAME$', 'type': 'SOA', 'ttl': 3600, 'records': [{'content': 'invalid. hostmaster.invalid. 1 10800 3600 604800 3600'}]}, + ]), + ]) + def test_zone_replace_rrsets_secondary(self, expected_error, rrsets): """ - Replace all RRsets in a SECONDARY zone, but supply no SOA. - Should succeed, also setting zone stale (but cannot assert this here). + Replace all RRsets in a SECONDARY zone. + + If no SOA is given, this should still succeed, also setting zone stale (but cannot assert this here). """ name, _, _ = self.create_zone(kind='Secondary', nameservers=None, masters=['127.0.0.2']) - self.put_zone(name, {'rrsets': []}) + self.put_zone(name, {'rrsets': templated_rrsets(rrsets, name)}, expect_error=expected_error) + + @parameterized.expand([ + (None, []), + ("Modifying RRsets in Consumer zones is unsupported", [ + {'name': '$NAME$', 'type': 'SOA', 'ttl': 3600, 'records': [{'content': 'invalid. hostmaster.invalid. 1 10800 3600 604800 3600'}]}, + ]), + ]) + def test_zone_replace_rrsets_consumer(self, expected_error, rrsets): + name, _, _ = self.create_zone(kind='Consumer', nameservers=None, masters=['127.0.0.2']) + self.put_zone(name, {'rrsets': templated_rrsets(rrsets, name)}, expect_error=expected_error) def test_zone_replace_rrsets_negative_ttl(self): name, _, _ = self.create_zone(dnssec=False, soa_edit='', soa_edit_api='') From c67dfcb4e0361201e16546a928588749967f45a6 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Sat, 12 Aug 2023 13:36:00 +0200 Subject: [PATCH 526/909] API Auth: dedup code in updateDomainSettingsFromDocument --- pdns/ws-auth.cc | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index d650a5d2dbc8..dfd6e627c106 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -657,6 +657,23 @@ static void extractDomainInfoFromDocument(const Json& document, boost::optional< } } +/* + * Build vector of TSIG Key ids from domain update document. + * jsonArray: JSON array element to extract TSIG key ids from. + * metadata: returned list of domain key ids for setDomainMetadata +*/ +static void extractJsonTSIGKeyIds(UeberBackend& B, const Json& jsonArray, vector& metadata) { + for(const auto& value : jsonArray.array_items()) { + auto keyname(apiZoneIdToName(value.string_value())); + DNSName keyAlgo; + string keyContent; + if (!B.getTSIGKey(keyname, keyAlgo, keyContent)) { + throw ApiException("A TSIG key with the name '"+keyname.toLogString()+"' does not exist"); + } + metadata.push_back(keyname.toString()); + } +} + // Must be called within backend transaction. static void updateDomainSettingsFromDocument(UeberBackend& B, DomainInfo& di, const DNSName& zonename, const Json& document, bool zoneWasModified) { boost::optional kind; @@ -833,30 +850,14 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, DomainInfo& di, co if (!document["master_tsig_key_ids"].is_null()) { vector metadata; - for(const auto& value : document["master_tsig_key_ids"].array_items()) { - auto keyname(apiZoneIdToName(value.string_value())); - DNSName keyAlgo; - string keyContent; - if (!B.getTSIGKey(keyname, keyAlgo, keyContent)) { - throw ApiException("A TSIG key with the name '"+keyname.toLogString()+"' does not exist"); - } - metadata.push_back(keyname.toString()); - } + extractJsonTSIGKeyIds(B, document["master_tsig_key_ids"], metadata); if (!di.backend->setDomainMetadata(zonename, "TSIG-ALLOW-AXFR", metadata)) { throw HttpInternalServerErrorException("Unable to set new TSIG master keys for zone '" + zonename.toLogString() + "'"); } } if (!document["slave_tsig_key_ids"].is_null()) { vector metadata; - for(const auto& value : document["slave_tsig_key_ids"].array_items()) { - auto keyname(apiZoneIdToName(value.string_value())); - DNSName keyAlgo; - string keyContent; - if (!B.getTSIGKey(keyname, keyAlgo, keyContent)) { - throw ApiException("A TSIG key with the name '"+keyname.toLogString()+"' does not exist"); - } - metadata.push_back(keyname.toString()); - } + extractJsonTSIGKeyIds(B, document["slave_tsig_key_ids"], metadata); if (!di.backend->setDomainMetadata(zonename, "AXFR-MASTER-TSIG", metadata)) { throw HttpInternalServerErrorException("Unable to set new TSIG slave keys for zone '" + zonename.toLogString() + "'"); } From 8ea32ea1a48eeeb936a3fa763d4ccbcd47275f75 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Sat, 12 Aug 2023 13:40:06 +0200 Subject: [PATCH 527/909] API Auth: extract addDefaultDNSSECKeys out of updateDomainSettingsFromDocument --- pdns/ws-auth.cc | 46 ++++++++++++++++++++++++++-------------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index dfd6e627c106..6e0b25de2758 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -618,6 +618,31 @@ static void throwUnableToSecure(const DNSName& zonename) { + "capable backends are loaded, or because the backends have DNSSEC disabled. Check your configuration."); } +/* + * Add KSK and ZSK to an existing zone. Algorithms and sizes will be chosen per configuration. +*/ +static void addDefaultDNSSECKeys(DNSSECKeeper& dk, const DNSName& zonename) { + checkDefaultDNSSECAlgos(); + int k_algo = DNSSECKeeper::shorthand2algorithm(::arg()["default-ksk-algorithm"]); + int z_algo = DNSSECKeeper::shorthand2algorithm(::arg()["default-zsk-algorithm"]); + int k_size = arg().asNum("default-ksk-size"); + int z_size = arg().asNum("default-zsk-size"); + + if (k_algo != -1) { + int64_t id; + if (!dk.addKey(zonename, true, k_algo, id, k_size)) { + throwUnableToSecure(zonename); + } + } + + if (z_algo != -1) { + int64_t id; + if (!dk.addKey(zonename, false, z_algo, id, z_size)) { + throwUnableToSecure(zonename); + } + } +} + static void extractDomainInfoFromDocument(const Json& document, boost::optional& kind, boost::optional>& masters, boost::optional& catalog, boost::optional& account) { if (document["kind"].is_string()) { @@ -737,26 +762,7 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, DomainInfo& di, co if (dnssecInJSON) { if (dnssecDocVal) { if (!isDNSSECZone) { - checkDefaultDNSSECAlgos(); - - int k_algo = DNSSECKeeper::shorthand2algorithm(::arg()["default-ksk-algorithm"]); - int z_algo = DNSSECKeeper::shorthand2algorithm(::arg()["default-zsk-algorithm"]); - int k_size = arg().asNum("default-ksk-size"); - int z_size = arg().asNum("default-zsk-size"); - - if (k_algo != -1) { - int64_t id; - if (!dk.addKey(zonename, true, k_algo, id, k_size)) { - throwUnableToSecure(zonename); - } - } - - if (z_algo != -1) { - int64_t id; - if (!dk.addKey(zonename, false, z_algo, id, z_size)) { - throwUnableToSecure(zonename); - } - } + addDefaultDNSSECKeys(dk, zonename); // Used later for NSEC3PARAM isDNSSECZone = dk.isSecuredZone(zonename); From d71d2c883cf144712220ca3538b816cdf19fda93 Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Sat, 12 Aug 2023 13:44:46 +0200 Subject: [PATCH 528/909] API Auth: dedup "is API-RECTIFY enabled" code --- pdns/ws-auth.cc | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-) diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index 6e0b25de2758..8f6775c6e1b2 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -643,6 +643,15 @@ static void addDefaultDNSSECKeys(DNSSECKeeper& dk, const DNSName& zonename) { } } +static bool isZoneApiRectifyEnabled(const DomainInfo& di) { + string api_rectify; + di.backend->getDomainMetadataOne(di.zone, "API-RECTIFY", api_rectify); + if (api_rectify.empty() && ::arg().mustDo("default-api-rectify")) { + api_rectify = "1"; + } + return api_rectify == "1"; +} + static void extractDomainInfoFromDocument(const Json& document, boost::optional& kind, boost::optional>& masters, boost::optional& catalog, boost::optional& account) { if (document["kind"].is_string()) { @@ -818,14 +827,7 @@ static void updateDomainSettingsFromDocument(UeberBackend& B, DomainInfo& di, co if (shouldRectify && !isPresigned) { // Rectify - string api_rectify; - di.backend->getDomainMetadataOne(zonename, "API-RECTIFY", api_rectify); - if (api_rectify.empty()) { - if (::arg().mustDo("default-api-rectify")) { - api_rectify = "1"; - } - } - if (api_rectify == "1") { + if (isZoneApiRectifyEnabled(di)) { string info; string error_msg; if (!dk.rectifyZone(zonename, error_msg, info, false) && !di.isSecondaryType()) { @@ -2350,17 +2352,11 @@ static void patchZone(UeberBackend& B, HttpRequest* req, HttpResponse* resp) // // Rectify DNSSECKeeper dk(&B); - if (!zone_disabled && !dk.isPresigned(zonename)) { - string api_rectify; - if (!di.backend->getDomainMetadataOne(zonename, "API-RECTIFY", api_rectify) && ::arg().mustDo("default-api-rectify")) { - api_rectify = "1"; - } - if (api_rectify == "1") { - string info; - string error_msg; - if (!dk.rectifyZone(zonename, error_msg, info, false)) { - throw ApiException("Failed to rectify '" + zonename.toString() + "' " + error_msg); - } + if (!zone_disabled && !dk.isPresigned(zonename) && isZoneApiRectifyEnabled(di)) { + string info; + string error_msg; + if (!dk.rectifyZone(zonename, error_msg, info, false)) { + throw ApiException("Failed to rectify '" + zonename.toString() + "' " + error_msg); } } From 62a46a7990f4dd0d0003f5b6c7c0e8fae841334b Mon Sep 17 00:00:00 2001 From: Chris Hofstaedtler Date: Sat, 12 Aug 2023 15:31:44 +0200 Subject: [PATCH 529/909] Auth: always initialize id passed to dk.addKey --- pdns/pdnsutil.cc | 11 +++++------ pdns/ws-auth.cc | 4 ++-- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index bdf0d3347b97..52ea3bd029dc 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -2265,7 +2265,7 @@ static bool showZone(DNSSECKeeper& dk, const DNSName& zone, bool exportDS = fals static bool secureZone(DNSSECKeeper& dk, const DNSName& zone) { // temp var for addKey - int64_t id; + int64_t id{-1}; // parse attribute string k_algo = ::arg()["default-ksk-algorithm"]; @@ -3068,7 +3068,7 @@ try return EXIT_FAILURE; } } - int64_t id; + int64_t id{-1}; if (!dk.addKey(zone, keyOrZone, algorithm, id, bits, active, published)) { cerr<<"Adding key failed, perhaps DNSSEC not enabled in configuration?"< Date: Mon, 14 Aug 2023 10:56:21 +0200 Subject: [PATCH 530/909] dnsdist: Properly handle short reads on backend upgrade discovery --- pdns/dnsdistdist/dnsdist-discovery.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-discovery.cc b/pdns/dnsdistdist/dnsdist-discovery.cc index 66ac1c070a65..de76a42ff17f 100644 --- a/pdns/dnsdistdist/dnsdist-discovery.cc +++ b/pdns/dnsdistdist/dnsdist-discovery.cc @@ -272,8 +272,9 @@ bool ServiceDiscovery::getDiscoveredConfig(const UpgradeableBackend& upgradeable sock.writenWithTimeout(reinterpret_cast(packet.data()), packet.size(), backend->d_config.tcpSendTimeout); + const struct timeval remainingTime = { .tv_sec = backend->d_config.tcpRecvTimeout, .tv_usec = 0 }; uint16_t responseSize = 0; - auto got = sock.readWithTimeout(reinterpret_cast(&responseSize), sizeof(responseSize), backend->d_config.tcpRecvTimeout); + auto got = readn2WithTimeout(sock.getHandle(), &responseSize, sizeof(responseSize), remainingTime); if (got < 0 || static_cast(got) != sizeof(responseSize)) { if (g_verbose) { warnlog("Error while waiting for the ADD upgrade response size from backend %s: %d", addr.toStringWithPort(), got); @@ -283,7 +284,7 @@ bool ServiceDiscovery::getDiscoveredConfig(const UpgradeableBackend& upgradeable packet.resize(ntohs(responseSize)); - got = sock.readWithTimeout(reinterpret_cast(packet.data()), packet.size(), backend->d_config.tcpRecvTimeout); + got = readn2WithTimeout(sock.getHandle(), packet.data(), packet.size(), remainingTime); if (got < 0 || static_cast(got) != packet.size()) { if (g_verbose) { warnlog("Error while waiting for the ADD upgrade response from backend %s: %d", addr.toStringWithPort(), got); From 9c3ff201bc70cc426170e23a7b99a14a4405c896 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 14 Aug 2023 10:56:53 +0200 Subject: [PATCH 531/909] sstuff: Document that Socket::readWithTimeout() does not handle partial reads --- pdns/sstuff.hh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pdns/sstuff.hh b/pdns/sstuff.hh index adecbe5ec917..208697cc2bb8 100644 --- a/pdns/sstuff.hh +++ b/pdns/sstuff.hh @@ -351,6 +351,11 @@ public: return static_cast(res); } + /** Read a bock of data from the socket to a block of memory, + * waiting at most 'timeout' seconds for the data to become + * available. Be aware that this does _NOT_ handle partial reads + * for you. + */ ssize_t readWithTimeout(char* buffer, size_t n, int timeout) { int err = waitForRWData(d_socket, true, timeout, 0); From e572dbf5b545924785207ff6c6c95f441668a3f1 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 14 Aug 2023 10:57:38 +0200 Subject: [PATCH 532/909] dnsdist: Add a 'partial read' case to the backend upgrade tests --- regression-tests.dnsdist/dnsdisttests.py | 16 +++++++++++----- .../test_BackendDiscovery.py | 3 ++- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index ce3e3ccf819d..1cd53af708bd 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -296,7 +296,7 @@ def UDPResponder(cls, port, fromQueue, toQueue, trailingDataResponse=False, call sock.close() @classmethod - def handleTCPConnection(cls, conn, fromQueue, toQueue, trailingDataResponse=False, multipleResponses=False, callback=None): + def handleTCPConnection(cls, conn, fromQueue, toQueue, trailingDataResponse=False, multipleResponses=False, callback=None, partialWrite=False): ignoreTrailing = trailingDataResponse is True data = conn.recv(2) if not data: @@ -328,7 +328,13 @@ def handleTCPConnection(cls, conn, fromQueue, toQueue, trailingDataResponse=Fals conn.close() return - conn.send(struct.pack("!H", len(wire))) + wireLen = struct.pack("!H", len(wire)) + if partialWrite: + for b in wireLen: + conn.send(bytes([b])) + time.sleep(0.5) + else: + conn.send(wireLen) conn.send(wire) while multipleResponses: @@ -355,7 +361,7 @@ def handleTCPConnection(cls, conn, fromQueue, toQueue, trailingDataResponse=Fals conn.close() @classmethod - def TCPResponder(cls, port, fromQueue, toQueue, trailingDataResponse=False, multipleResponses=False, callback=None, tlsContext=None, multipleConnections=False, listeningAddr='127.0.0.1'): + def TCPResponder(cls, port, fromQueue, toQueue, trailingDataResponse=False, multipleResponses=False, callback=None, tlsContext=None, multipleConnections=False, listeningAddr='127.0.0.1', partialWrite=False): cls._backgroundThreads[threading.get_native_id()] = True # trailingDataResponse=True means "ignore trailing data". # Other values are either False (meaning "raise an exception") @@ -394,11 +400,11 @@ def TCPResponder(cls, port, fromQueue, toQueue, trailingDataResponse=False, mult if multipleConnections: thread = threading.Thread(name='TCP Connection Handler', target=cls.handleTCPConnection, - args=[conn, fromQueue, toQueue, trailingDataResponse, multipleResponses, callback]) + args=[conn, fromQueue, toQueue, trailingDataResponse, multipleResponses, callback, partialWrite]) thread.setDaemon(True) thread.start() else: - cls.handleTCPConnection(conn, fromQueue, toQueue, trailingDataResponse, multipleResponses, callback) + cls.handleTCPConnection(conn, fromQueue, toQueue, trailingDataResponse, multipleResponses, callback, partialWrite) sock.close() diff --git a/regression-tests.dnsdist/test_BackendDiscovery.py b/regression-tests.dnsdist/test_BackendDiscovery.py index df54c74e3815..0521523ae1f8 100644 --- a/regression-tests.dnsdist/test_BackendDiscovery.py +++ b/regression-tests.dnsdist/test_BackendDiscovery.py @@ -268,7 +268,8 @@ def startResponders(cls): TCPNoUpgradeResponder.setDaemon(True) TCPNoUpgradeResponder.start() - TCPUpgradeToDoTResponder = threading.Thread(name='TCP upgrade to DoT Responder', target=cls.TCPResponder, args=[cls._svcUpgradeDoTBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.UpgradeDoTCallback]) + # this one is special, does partial writes! + TCPUpgradeToDoTResponder = threading.Thread(name='TCP upgrade to DoT Responder', target=cls.TCPResponder, args=[cls._svcUpgradeDoTBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.UpgradeDoTCallback, None, False, '127.0.0.1', True]) TCPUpgradeToDoTResponder.setDaemon(True) TCPUpgradeToDoTResponder.start() # and the corresponding DoT responder From 514e10c770c96be6bd39eb79c75ab0dc9d3a94d8 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 14 Aug 2023 11:01:41 +0200 Subject: [PATCH 533/909] dnsdist: Uglify the code to make the formatter happy --- pdns/dnsdistdist/dnsdist-discovery.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-discovery.cc b/pdns/dnsdistdist/dnsdist-discovery.cc index de76a42ff17f..ead9daf55f1f 100644 --- a/pdns/dnsdistdist/dnsdist-discovery.cc +++ b/pdns/dnsdistdist/dnsdist-discovery.cc @@ -272,7 +272,7 @@ bool ServiceDiscovery::getDiscoveredConfig(const UpgradeableBackend& upgradeable sock.writenWithTimeout(reinterpret_cast(packet.data()), packet.size(), backend->d_config.tcpSendTimeout); - const struct timeval remainingTime = { .tv_sec = backend->d_config.tcpRecvTimeout, .tv_usec = 0 }; + const struct timeval remainingTime = {.tv_sec = backend->d_config.tcpRecvTimeout, .tv_usec = 0}; uint16_t responseSize = 0; auto got = readn2WithTimeout(sock.getHandle(), &responseSize, sizeof(responseSize), remainingTime); if (got < 0 || static_cast(got) != sizeof(responseSize)) { From 32b50c94382eceb1f6425d771c68520328a4e90d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 14 Aug 2023 12:09:00 +0200 Subject: [PATCH 534/909] auth: Fix coverity CID 1030024: Uninitialized scalar field --- pdns/packethandler.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/packethandler.hh b/pdns/packethandler.hh index 3bd0511fc317..be224dcca5e7 100644 --- a/pdns/packethandler.hh +++ b/pdns/packethandler.hh @@ -113,7 +113,7 @@ private: bool d_logDNSDetails; bool d_doDNAME; bool d_doExpandALIAS; - bool d_dnssec; + bool d_dnssec{false}; SOAData d_sd; std::unique_ptr d_pdl; std::unique_ptr d_update_policy_lua; From 8fb381e1d67bcd5bc60e984572834cfb1c638d88 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 14 Aug 2023 12:09:40 +0200 Subject: [PATCH 535/909] auth: Fix Coverity CID 1504120: Uninitialized scalar field --- pdns/pkcs11signers.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pdns/pkcs11signers.cc b/pdns/pkcs11signers.cc index bfbb89a11967..db8c78702a94 100644 --- a/pdns/pkcs11signers.cc +++ b/pdns/pkcs11signers.cc @@ -285,9 +285,9 @@ class Pkcs11Token { private: std::shared_ptr> d_slot; - CK_OBJECT_HANDLE d_public_key; - CK_OBJECT_HANDLE d_private_key; - CK_KEY_TYPE d_key_type; + CK_OBJECT_HANDLE d_public_key{0}; + CK_OBJECT_HANDLE d_private_key{0}; + CK_KEY_TYPE d_key_type{0}; bool d_always_auth{false}; CK_ULONG d_bits; From b862ecc96e67e581aded6b08af6f3930978ee7b7 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 14 Aug 2023 12:15:53 +0200 Subject: [PATCH 536/909] ixfrdist: Call `getpwuid()` before going multi-threaded --- pdns/ixfrdist.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index bab91205399e..d5fb1953547c 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -1186,6 +1186,7 @@ struct IXFRDistConfiguration ComboAddress wsAddr; std::string wsLogLevel{"normal"}; std::string workDir; + const struct passwd* userInfo{nullptr}; uint32_t axfrMaxRecords{0}; uint16_t keep{0}; uint16_t axfrTimeout{0}; @@ -1386,6 +1387,8 @@ static std::optional parseConfiguration(int argc, char** } else { configuration.uid = pw->pw_uid; } + //NOLINTNEXTLINE(concurrency-mt-unsafe): only one thread at this point + configuration.userInfo = getpwuid(configuration.uid); } } @@ -1475,14 +1478,13 @@ int main(int argc, char** argv) { g_log<uid<<": "<uid); - if (pw == nullptr) { + if (configuration->userInfo == nullptr) { if (setgroups(0, nullptr) < 0) { g_log<pw_name, configuration->gid) < 0) { + if (initgroups(configuration->userInfo->pw_name, configuration->gid) < 0) { g_log< Date: Mon, 14 Aug 2023 13:22:48 +0200 Subject: [PATCH 537/909] Coding Guidelines: Apply suggestions from review --- CODING_GUIDELINES.md | 54 +++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index e366c9b32b09..b239963388d1 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -79,7 +79,7 @@ class BadFileDescriptorWrapper { d_fd = open(...); if (something) { - throw std::runtime_error(...); + throw std::runtime_error(...); // WRONG, DO NOT DO THIS! } ... } @@ -209,7 +209,7 @@ One such example occurred in dnsdist: [2017-01: Crafted backend responses can ca In that case, a pointer was set to the start of a buffer plus a given length, to see whether the result would go past another pointer that was set to the end of the buffer. Unfortunately, if the start of the buffer is at a very high virtual address, the result of the addition might overflow and wrap around, causing the check to become true and leading to either a crash or the reading of unrelated memory. -While very unlikely on a 64 bits platform, it could happen on 16 or 32 bits platform. +While very unlikely on a 64 bits platform, it could happen on 32 bits platform. This kind of issue is best avoided by the use of containers to avoid the need for pointer arithmetic, or by being very careful to only add checked offsets to a pointer. @@ -227,13 +227,13 @@ The use of a container and its corresponding `at()` operator would have prevente The cost of using `at()` is negligible for most use cases, and can be avoided by using the `[]` operator in the rare case when the cost cannot be afforded. Note that several Linux distributions now build with `-Wp,-D_GLIBCXX_ASSERTIONS` enabled by default, which turns on cheap range checks for C++ arrays, vectors, and strings. -Regarding performance, it is advised to `reserve()` the needed size in advance when a rough estimate is known to avoid reallocations and copies. +Regarding performance, it is advised to `reserve()` the needed size in advance when a rough estimate is known to avoid reallocations and copies. It usually triggers the allocation of enough memory to hold the requested number of items but does not increase the size of the container as reported by `size()`. Resizing in advance is not advised, though, as it makes it harder to exactly know what is in the container in case of early returns or exceptions. In C++11, move operators make it possible to cheaply get the contents of a container into a different variable if needed. The need to pass a subset of a container without copying it often leads to passing a pointer to an array of chars along with a size. -Introduced in C++14 but already available in PowerDNS via boost (see views.hh), `views` provide a nice way to borrow the content of a container to pass it to a function, without any copying or dynamic memory allocation. +Introduced in C++14, `views` provide a nice way to borrow the content of a container to pass it to a function, without any copying or dynamic memory allocation. The basic `string_view` class provides that feature for a container of chars, but the same feature exists for other types, like `uint8_t`. @@ -252,7 +252,7 @@ The second one is the "share nothing" approach, where each thread has its own da When a thread needs to communicate with another one, it might use a `pdns::channel` to pass a pointer to that second thread. That works quite well but sometimes sharing data is much more efficient than the alternative. -For these cases, we use the classic locking approach, using either a simple mutex or read-write lock, depending on the use case. +For cases where sharing the data between threads is needed, we use the classic locking approach, using either a simple mutex or read-write lock, depending on the use case. ## Locks @@ -268,13 +268,13 @@ There are a few pitfalls to avoid when using locks: There are several types of locks: -* Spinlocks are very fast but are busy-waiting, meaning that they do not pause, but instead repetitively try to get hold of the lock, using 100% of one core, doing so unless preempted by the OS. +* Spinlocks are very fast but are busy-waiting, meaning that they do not pause, but instead repetitively try to get hold of the lock, using 100% of one core, doing so unless preempted by the OS ; So they are only suited for locks that are almost never contented ; * A mutex is a very simple lock. In most implementations it is a very fast lock, implemented in user-space on recent Linux kernels and glibc ; * A read-write lock (RW-lock) allows several threads to acquire it in read mode, but only one thread can acquire it in write mode. This is suited when most accesses are read-only and writes are rare and do not take too long. - Otherwise, a mutex might actually be faster ; + Otherwise, a mutex might actually be faster. One quick word about condition variables, that allow a thread to notify one or more threads waiting for a condition to happen. A thread should acquire a mutex using a `std::unique_lock` and call the `wait()` method of the condition variable. @@ -600,8 +600,6 @@ C++11 introduced automatic type deduction, using the `auto` keyword. Using automatic type deduction prevents nasty surprises if the variable is initialized from another one, or from a function, and the other type is changed to a different one. The code might still compile while now involving a copy or worse. -## Boolean Expressions - ## Explicit Comparisons * Compare numerical values with `== 0` or `!= 0` explicitly ; @@ -612,7 +610,7 @@ The code might still compile while now involving a copy or worse. Use braced initialization for members as often as possible: -* It does forbid narrowing conversions +* It does forbid narrowing conversions : * It avoids C++'s "[most vexing parse](https://en.wikipedia.org/wiki/Most_vexing_parse)" which is to declare a function instead of calling the default constructor: ```c++ @@ -627,17 +625,37 @@ It also cannot be silently taken as an integer, which can happens with `0` but a ## `const`-ness * Mark parameters and variables that should not be modified as `const`. - This is especially important for references and pointers that comes from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later. -* Mark `const` methods as such (and make them thread-safe) + This is especially important for references and pointers that comes from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later ; +* Mark `const` methods as such (and make them thread-safe) ; * Prefer using `at()` on containers so that no insertion can take place by mistake, and to get bounds checking. -## `static` +## Unnamed Namespace -Functions that are only used inside a single file should be marked as `static`, so that: +Functions that are only used inside a single file should be put into an unnamed namespace, so that: * The compiler knows that these functions will not be called from a different compilation unit and thus that no symbol needs to be generated, making it more likely for the function to be inlined ; * The reader knows that this function is only used there and can be altered without causing an issue somewhere else. +```c++ +namespace { + +bool thisFunctionIsOnlyUsableFromThisTranslationUnit() +{ +} + +} +``` + +These functions used to be marked `static` in the past, so you might still encounter this form in the code base instead: + +```c++ +static bool thisOneAsWell() +{ +} +``` + +but the unnamed namespace form is now preferred. + For the same reason, global variables that are only accessed from a single file should be marked static as well. ## Variables @@ -680,13 +698,13 @@ They are also very hard to spot in a code. C++-style casts can easily be spotted in a code, which makes it easy to review them. * `const_cast` can be used to remove the `const` qualifier on a variable. - It's usually a bad sign, but is sometimes needed to call a function that will not modify the variable but lacks the `const` qualifier. + It's usually a bad sign, but is sometimes needed to call a function that will not modify the variable but lacks the `const` qualifier ; * `dynamic_cast` can be used to cast a pointer to a derived class or to a base class, while checking that the operation is valid. If the cast object is not valid for the intended type, a `nullptr` value will be returned (or a `bad_cast` exception for references) so the result of the operation should be checked! Note that the RTTI check needed to verify that the cast object is valid has a non-negligible CPU cost. - Not checking the return value might lead to remote denial of service by `nullptr`-dereference, as happened with the issue described in this advisory: https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-08.html + Not checking the return value might lead to remote denial of service by `nullptr`-dereference, as happened with the issue described in this advisory: [2017-08: Crafted CNAME answer can cause a denial of service](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-08.html) ; * `static_cast` can perform downcast in place of `dynamic_cast`, with none of the cost associated to the check, but can only be done if the cast is known to be valid. - It can also do implicit conversion between types (from `ssize_t` to `size_t`, **after** checking that the value is greater or equal to zero). + It can also do implicit conversion between types (from `ssize_t` to `size_t`, **after** checking that the value is greater or equal to zero) ; * `reinterpret_cast` is quite dangerous, since it can be used to turn a type into a different one. It cannot be be used to remove a `const` qualifier. When used to reinterpret the content of a buffer it can quickly lead to alignment issues, as described in the [Alignment Issues] section. @@ -697,5 +715,5 @@ C++-style casts can easily be spotted in a code, which makes it easy to review t A library call may clobber `errno`, even when it succeeds. Safe practice is: -* Only look at `errno` on failing system calls or when a library function is documented to set `errno`. +* Only look at `errno` on failing system calls or when a library function is documented to set `errno` ; * Immediately save the value of `errno` in a local variable after a system call for later decision making. From e99ddfb839de71297ef2b5a6bb7fb5425d0dae2c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 14 Aug 2023 14:38:04 +0200 Subject: [PATCH 538/909] Coding Guidelines: More suggestions from Chris Hofstaedtler (thanks!) --- CODING_GUIDELINES.md | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index b239963388d1..79e5623b100a 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -587,7 +587,7 @@ This is especially important when hashing attacker-controlled values, as they ca * Denial of service via hash table flooding (in a map, all entries that hash to the same value are often placed into a linked-list, making it possible to cause a linear scan of entries by making all of them hash to that same value). The first issue can be prevented by comparing the entries and not just the value they hash to. -The second one can be used by using some sort of secret when computing the hash so that the result cannot be guessed by the attacker. +The second one can be avoided by using some sort of secret when computing the hash so that the result cannot be guessed by the attacker. That can be achieved by using an unpredictable seed for certain hash algorithms, or a secret for some other like `SipHash`. # Readability Tips @@ -598,7 +598,7 @@ Some of these tips are actually enforced by `clang-tidy` nowadays, but it is sti C++11 introduced automatic type deduction, using the `auto` keyword. Using automatic type deduction prevents nasty surprises if the variable is initialized from another one, or from a function, and the other type is changed to a different one. -The code might still compile while now involving a copy or worse. +Without `auto`, code might still compile but trigger a copy or worse. ## Explicit Comparisons @@ -625,7 +625,7 @@ It also cannot be silently taken as an integer, which can happens with `0` but a ## `const`-ness * Mark parameters and variables that should not be modified as `const`. - This is especially important for references and pointers that comes from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later ; + This is especially important for references and pointers that come from outside the function, but it also makes sense to do it for local variables or parameters passed by value because it might help detect a logic error later ; * Mark `const` methods as such (and make them thread-safe) ; * Prefer using `at()` on containers so that no insertion can take place by mistake, and to get bounds checking. @@ -661,21 +661,25 @@ For the same reason, global variables that are only accessed from a single file ## Variables Try to declare variables in the innermost scope possible and avoid uninitialized variables as much as possible. -Declare and initialize them when the values needed to initialize them are available. +Declare and initialize variables when the values needed to initialize them are available. ## Exceptions -Should be reserved for unexpected events (corrupted data, timeouts, ...) and should not be triggered in normal processing. +Exceptions should be reserved for events that interrupt the normal processing flow (corrupted data, timeouts, ...), and should not be triggered in the general case. -Do not be afraid of using them, though, as the cost of an exception that is not thrown is usually very small, thanks to the zero-cost exception model. -It might still force the compiler to refrain from some optimizations, so it might make sense to avoid them in some very performance-sensitive, narrow code paths. +For example, it would be better for a function checking a password or an API key to return a boolean or a `enum` indicating whether the check was successful than to throw an exception if the credentials are not valid, because the return value makes it clear that the check can and will fail, while otherwise the caller might not be aware that an exception can be raised. + +This does not mean that we should be afraid of using exceptions, though, but we need to keep in mind that they involve hidden complexity for the programmer that needs to keep a mental map of all the possible exceptions that can be raised. + +As far as performance goes the cost of an exception that is not thrown is usually very small, thanks to the zero-cost exception model. It might still force the compiler to refrain from some optimizations, so it might make sense to avoid them in some very performance-sensitive, narrow code paths, and to mark these paths as `noexcept` whenever possible. ### Custom Exceptions -Exceptions defined by the standards should be used whenever possible, as they already cover a lot of use cases. +When exceptions are used, the ones defined by the standards should be used whenever possible, as they already cover a lot of use cases. + +If custom exceptions are necessary, to be able to catch them explicitly, they should derive from `std::exception`, directly or indirectly, so that they can be caught in a more generic way to prevent the program from terminating. -If custom exceptions are necessary, to be able to catch them explicitly, they should still derive from `std::exception`, directly or indirectly, so that they can still be caught in a more generic way to prevent the program from terminating. -For example, the main connection handling function of a server can catch `std::exception` and just terminate the current connection if an uncaught exception bubbles up. +For example, the main connection handling function of a server can catch `std::exception` and terminate the current connection if an uncaught exception bubbles up, without having to worry about all the possible cases. ### Catching Exceptions @@ -693,7 +697,7 @@ Not using a reference would result in the exception object being sliced, meaning ## Casts -C-style casts should be avoided, as the compiler does almost no check on the validity of the operation. +C-style casts should be avoided, as the compiler does almost no checking on the validity of the operation. They are also very hard to spot in a code. C++-style casts can easily be spotted in a code, which makes it easy to review them. From 18deed4c11334951ef2610afacf289c85580436f Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 14 Aug 2023 15:32:30 +0200 Subject: [PATCH 539/909] ixfrdist: after --help or --version, exit (includes var rename) --- pdns/ixfrdist.cc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index d5fb1953547c..29b16ff13eec 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -1194,7 +1194,7 @@ struct IXFRDistConfiguration uint16_t tcpInThreads{0}; uid_t uid{0}; gid_t gid{0}; - bool done{false}; + bool shouldExit{false}; }; static std::optional parseConfiguration(int argc, char** argv, FDMultiplexer& fdm) @@ -1218,11 +1218,13 @@ static std::optional parseConfiguration(int argc, char** if (g_vm.count("help") > 0) { usage(desc); + configuration.shouldExit = true; return configuration; } if (g_vm.count("version") > 0) { cout<<"ixfrdist "<done) { + if (configuration->shouldExit) { return EXIT_SUCCESS; } } From 70c48a66eaae58f8c2044a18e9ecf68ad9a1cffb Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 14 Aug 2023 16:55:02 +0200 Subject: [PATCH 540/909] ixfrdist: switch testing to pytest --- regression-tests.ixfrdist/requirements.txt | 2 +- regression-tests.ixfrdist/runtests | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/regression-tests.ixfrdist/requirements.txt b/regression-tests.ixfrdist/requirements.txt index 645f9614b694..9be8421d1b68 100644 --- a/regression-tests.ixfrdist/requirements.txt +++ b/regression-tests.ixfrdist/requirements.txt @@ -1,4 +1,4 @@ dnspython==2.1.0 -nose>=1.3.7 +pytest git+https://github.com/PowerDNS/xfrserver.git@0.1 requests diff --git a/regression-tests.ixfrdist/runtests b/regression-tests.ixfrdist/runtests index e8b5d9d9915e..b43cca6c942d 100755 --- a/regression-tests.ixfrdist/runtests +++ b/regression-tests.ixfrdist/runtests @@ -22,4 +22,4 @@ fi rm -rf ixfrdist.dir mkdir ixfrdist.dir -nosetests --with-xunit $@ +pytest --junitxml=pytest.xml $@ From 2be955a17cd79d92dd5ab3975481c4a53c6369a1 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 14 Aug 2023 17:02:39 +0200 Subject: [PATCH 541/909] dnsdist: Add a DNSHeader:getTC() Lua binding --- pdns/dnsdist-lua-bindings.cc | 6 ++- pdns/dnsdistdist/docs/reference/dq.rst | 6 +++ regression-tests.dnsdist/test_Lua.py | 53 ++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdist-lua-bindings.cc b/pdns/dnsdist-lua-bindings.cc index 225f48b9556f..35a950590bc3 100644 --- a/pdns/dnsdist-lua-bindings.cc +++ b/pdns/dnsdist-lua-bindings.cc @@ -192,10 +192,14 @@ void setupLuaBindings(LuaContext& luaCtx, bool client) return (bool)dh.cd; }); - luaCtx.registerFunction("getID", [](const dnsheader& dh) { + luaCtx.registerFunction("getID", [](const dnsheader& dh) { return ntohs(dh.id); }); + luaCtx.registerFunction("getTC", [](const dnsheader& dh) { + return (bool)dh.tc; + }); + luaCtx.registerFunction("setTC", [](dnsheader& dh, bool v) { dh.tc=v; if(v) dh.ra = dh.rd; // you'll always need this, otherwise TC=1 gets ignored diff --git a/pdns/dnsdistdist/docs/reference/dq.rst b/pdns/dnsdistdist/docs/reference/dq.rst index 6025c64e166a..f90d67ac1b93 100644 --- a/pdns/dnsdistdist/docs/reference/dq.rst +++ b/pdns/dnsdistdist/docs/reference/dq.rst @@ -504,6 +504,12 @@ DNSHeader (``dh``) object Get recursion desired flag. + .. method:: DNSHeader:getTC() -> int + + .. versionadded:: 1.8.1 + + Get the TC flag. + .. method:: DNSHeader:setAA(aa) Set authoritative answer flag. diff --git a/regression-tests.dnsdist/test_Lua.py b/regression-tests.dnsdist/test_Lua.py index 656c287ec9d1..3d689477c220 100644 --- a/regression-tests.dnsdist/test_Lua.py +++ b/regression-tests.dnsdist/test_Lua.py @@ -1,6 +1,7 @@ #!/usr/bin/env python import base64 +import dns import time import unittest from dnsdisttests import DNSDistTest @@ -40,3 +41,55 @@ def testLuaThreadCounter(self): time.sleep(3) count2 = self.sendConsoleCommand('counter') self.assertTrue(count2 > count1) + +class TestLuaDNSHeaderBindings(DNSDistTest): + _config_template = """ + newServer{address="127.0.0.1:%s"} + + function checkTCSet(dq) + local tc = dq.dh:getTC() + if not tc then + return DNSAction.Spoof, 'tc-not-set.check-tc.lua-dnsheaders.tests.powerdns.com.' + end + return DNSAction.Allow + end + + addAction('check-tc.lua-dnsheaders.tests.powerdns.com.', LuaAction(checkTCSet)) + """ + + def testLuaGetTC(self): + """ + LuaDNSHeaders: TC + """ + name = 'notset.check-tc.lua-dnsheaders.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + # dnsdist set RA = RD for spoofed responses + query.flags &= ~dns.flags.RD + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.CNAME, + 'tc-not-set.check-tc.lua-dnsheaders.tests.powerdns.com.') + response.answer.append(rrset) + for method in ("sendUDPQuery", "sendTCPQuery"): + sender = getattr(self, method) + (_, receivedResponse) = sender(query, response=None, useQueue=False) + self.assertEqual(response, receivedResponse) + + name = 'set.check-tc.lua-dnsheaders.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '127.0.0.1') + response.answer.append(rrset) + query.flags |= dns.flags.TC + for method in ("sendUDPQuery", "sendTCPQuery"): + sender = getattr(self, method) + (receivedQuery, receivedResponse) = sender(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) From 255ec835c0c0475f86ec81ed838dd3014d365043 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 14 Aug 2023 17:10:10 +0200 Subject: [PATCH 542/909] eqdnsmessage: adjust to type changes in dnspython --- contrib/assert-equal-DNSMessage/eqdnsmessage.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/assert-equal-DNSMessage/eqdnsmessage.py b/contrib/assert-equal-DNSMessage/eqdnsmessage.py index 99a6784c993a..9a3605e0fce1 100644 --- a/contrib/assert-equal-DNSMessage/eqdnsmessage.py +++ b/contrib/assert-equal-DNSMessage/eqdnsmessage.py @@ -26,5 +26,6 @@ def assertEqualDNSMessage(self, first, second, msg=None): def setUp(self): self.addTypeEqualityFunc(dns.message.Message, self.assertEqualDNSMessage) + self.addTypeEqualityFunc(dns.message.QueryMessage, self.assertEqualDNSMessage) - super(AssertEqualDNSMessageMixin, self).setUp() \ No newline at end of file + super(AssertEqualDNSMessageMixin, self).setUp() From 63f3e97b0def39e0199a3c1c28d611ec7f74a686 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 14 Aug 2023 16:52:27 +0200 Subject: [PATCH 543/909] ixfrdist: set AA=1 on SOA responses --- pdns/ixfrdist.cc | 1 + regression-tests.ixfrdist/test_IXFR.py | 1 + 2 files changed, 2 insertions(+) diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index f4b386a118fb..764099d55752 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -532,6 +532,7 @@ static bool makeSOAPacket(const MOADNSParser& mdp, vector& packet) { pw.getHeader()->id = mdp.d_header.id; pw.getHeader()->rd = mdp.d_header.rd; pw.getHeader()->qr = 1; + pw.getHeader()->aa = 1; pw.startRecord(mdp.d_qname, QType::SOA, zoneInfo->soaTTL); zoneInfo->soa->toPacket(pw); diff --git a/regression-tests.ixfrdist/test_IXFR.py b/regression-tests.ixfrdist/test_IXFR.py index 35f0a30c8eca..c0788f874a2a 100644 --- a/regression-tests.ixfrdist/test_IXFR.py +++ b/regression-tests.ixfrdist/test_IXFR.py @@ -194,6 +194,7 @@ def test_a_XFR(self): def test_b_UDP_SOA_existing(self): query = dns.message.make_query('example.', 'SOA') expected = dns.message.make_response(query) + expected.flags |= dns.flags.AA expected.answer.append(xfrServer._getSOAForSerial(2)) response = self.sendUDPQuery(query) From dfd90e05d024dbc7c5a01975fc4e753cad03e77d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 14 Aug 2023 17:50:52 +0200 Subject: [PATCH 544/909] dnsdist: Fix the documented return value of DNSHeader:getTC() --- pdns/dnsdistdist/docs/reference/dq.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/reference/dq.rst b/pdns/dnsdistdist/docs/reference/dq.rst index f90d67ac1b93..ef9c531b3e7b 100644 --- a/pdns/dnsdistdist/docs/reference/dq.rst +++ b/pdns/dnsdistdist/docs/reference/dq.rst @@ -504,7 +504,7 @@ DNSHeader (``dh``) object Get recursion desired flag. - .. method:: DNSHeader:getTC() -> int + .. method:: DNSHeader:getTC() -> bool .. versionadded:: 1.8.1 From d86200ac489e08be1831b524d2268b2a1b0f222f Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 15 Aug 2023 10:28:46 +0200 Subject: [PATCH 545/909] coverity CID 398388: useless <0 check on unsigned value --- pdns/dnsdistdist/dnsdist-discovery.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-discovery.cc b/pdns/dnsdistdist/dnsdist-discovery.cc index ead9daf55f1f..2d3c66e722cd 100644 --- a/pdns/dnsdistdist/dnsdist-discovery.cc +++ b/pdns/dnsdistdist/dnsdist-discovery.cc @@ -275,7 +275,7 @@ bool ServiceDiscovery::getDiscoveredConfig(const UpgradeableBackend& upgradeable const struct timeval remainingTime = {.tv_sec = backend->d_config.tcpRecvTimeout, .tv_usec = 0}; uint16_t responseSize = 0; auto got = readn2WithTimeout(sock.getHandle(), &responseSize, sizeof(responseSize), remainingTime); - if (got < 0 || static_cast(got) != sizeof(responseSize)) { + if (static_cast(got) != sizeof(responseSize)) { if (g_verbose) { warnlog("Error while waiting for the ADD upgrade response size from backend %s: %d", addr.toStringWithPort(), got); } From 018778e502797576fc8b66e81a198908e58296d8 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 15 Aug 2023 13:22:51 +0200 Subject: [PATCH 546/909] Makefile whitespace --- pdns/Makefile.am | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/Makefile.am b/pdns/Makefile.am index a1ba58ec5030..625bc1e04414 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -789,7 +789,7 @@ ixplore_SOURCES = \ dnsrecords.cc \ dnssecinfra.cc \ dnswriter.cc dnswriter.hh \ - gss_context.cc gss_context.hh \ + gss_context.cc gss_context.hh \ iputils.cc \ ixfr.cc ixfr.hh \ ixfrutils.cc ixfrutils.hh \ @@ -1351,7 +1351,7 @@ testrunner_SOURCES = \ ednsoptions.cc ednsoptions.hh \ ednssubnet.cc \ gettime.cc gettime.hh \ - gss_context.cc gss_context.hh \ + gss_context.cc gss_context.hh \ histogram.hh \ ipcipher.cc ipcipher.hh \ iputils.cc \ From ea0d7afd806674b76d75c4e543483c0d482c08ab Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 15 Aug 2023 13:22:34 +0200 Subject: [PATCH 547/909] gettime: fix minor compilation warnings --- pdns/gettime.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/gettime.cc b/pdns/gettime.cc index b6d95a4ed29f..e7b37b65d43f 100644 --- a/pdns/gettime.cc +++ b/pdns/gettime.cc @@ -36,8 +36,9 @@ int gettime(struct timespec *tp, bool needRealTime) #else #include +#include -int gettime(struct timespec *tp, bool needRealTime) +int gettime(struct timespec *tp, bool /* needRealTime */) { struct timeval tv; From 6f0a2aec1d935a59f71ac8dfb6b8c174726071c2 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 15 Aug 2023 18:07:52 +0200 Subject: [PATCH 548/909] dnsdist: Remove a second useless check, useless static casts --- pdns/dnsdistdist/dnsdist-discovery.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-discovery.cc b/pdns/dnsdistdist/dnsdist-discovery.cc index 2d3c66e722cd..5bb61ba45091 100644 --- a/pdns/dnsdistdist/dnsdist-discovery.cc +++ b/pdns/dnsdistdist/dnsdist-discovery.cc @@ -275,7 +275,7 @@ bool ServiceDiscovery::getDiscoveredConfig(const UpgradeableBackend& upgradeable const struct timeval remainingTime = {.tv_sec = backend->d_config.tcpRecvTimeout, .tv_usec = 0}; uint16_t responseSize = 0; auto got = readn2WithTimeout(sock.getHandle(), &responseSize, sizeof(responseSize), remainingTime); - if (static_cast(got) != sizeof(responseSize)) { + if (got != sizeof(responseSize)) { if (g_verbose) { warnlog("Error while waiting for the ADD upgrade response size from backend %s: %d", addr.toStringWithPort(), got); } @@ -285,7 +285,7 @@ bool ServiceDiscovery::getDiscoveredConfig(const UpgradeableBackend& upgradeable packet.resize(ntohs(responseSize)); got = readn2WithTimeout(sock.getHandle(), packet.data(), packet.size(), remainingTime); - if (got < 0 || static_cast(got) != packet.size()) { + if (got != packet.size()) { if (g_verbose) { warnlog("Error while waiting for the ADD upgrade response from backend %s: %d", addr.toStringWithPort(), got); } From 78dd55be86cca8e51c09834dc0a4a637582f7421 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 16 Aug 2023 09:36:21 +0200 Subject: [PATCH 549/909] Coding Guidelines: Mention reserve()/resize() explicitly, with links --- CODING_GUIDELINES.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 79e5623b100a..64c2f8b1f11d 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -227,8 +227,8 @@ The use of a container and its corresponding `at()` operator would have prevente The cost of using `at()` is negligible for most use cases, and can be avoided by using the `[]` operator in the rare case when the cost cannot be afforded. Note that several Linux distributions now build with `-Wp,-D_GLIBCXX_ASSERTIONS` enabled by default, which turns on cheap range checks for C++ arrays, vectors, and strings. -Regarding performance, it is advised to `reserve()` the needed size in advance when a rough estimate is known to avoid reallocations and copies. It usually triggers the allocation of enough memory to hold the requested number of items but does not increase the size of the container as reported by `size()`. -Resizing in advance is not advised, though, as it makes it harder to exactly know what is in the container in case of early returns or exceptions. +Regarding performance, it is advised to [`reserve()`](https://en.cppreference.com/w/cpp/container/vector/reserve) the needed size in advance when a rough estimate is known to avoid reallocations and copies. It usually triggers the allocation of enough memory to hold the requested number of items but does not increase the size of the container as reported by `size()`. +Calling [`resize()`](https://en.cppreference.com/w/cpp/container/vector/resize) in advance is not advised, though, as it makes it harder to exactly know what is in the container in case of early returns or exceptions. In C++11, move operators make it possible to cheaply get the contents of a container into a different variable if needed. From 699fac79855b7b520a6bf84cf647668668d87d1d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 16 Aug 2023 10:14:25 +0200 Subject: [PATCH 550/909] calidns: Fix Coverity CID 1401679: Uncaught exception --- pdns/calidns.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pdns/calidns.cc b/pdns/calidns.cc index fb888bf4689c..f0a898905e88 100644 --- a/pdns/calidns.cc +++ b/pdns/calidns.cc @@ -531,8 +531,13 @@ try // t1.detach(); } - catch(std::exception& e) +catch (const std::exception& exp) { - cerr<<"Fatal error: "< Date: Wed, 16 Aug 2023 10:15:07 +0200 Subject: [PATCH 551/909] dnsbulktest: Fix Coverity CID 1401681 and 1401676 --- pdns/Makefile.am | 1 + pdns/dnsbulktest.cc | 94 ++++++++++++++++++++++----------------------- 2 files changed, 48 insertions(+), 47 deletions(-) diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 625bc1e04414..43a464f8ab96 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -984,6 +984,7 @@ dnsbulktest_SOURCES = \ dnsparser.cc \ dnsrecords.cc \ dnswriter.cc \ + iputils.cc iputils.hh \ logger.cc \ misc.cc \ nsecrecords.cc \ diff --git a/pdns/dnsbulktest.cc b/pdns/dnsbulktest.cc index 0cba797fa230..b6fbc7bcbf38 100644 --- a/pdns/dnsbulktest.cc +++ b/pdns/dnsbulktest.cc @@ -56,7 +56,7 @@ bool g_envoutput=false; struct DNSResult { vector ips; - int rcode; + int rcode{0}; bool seenauthsoa{false}; }; @@ -69,42 +69,40 @@ struct TypedQuery struct SendReceive { - typedef int Identifier; - typedef DNSResult Answer; // ip - int d_socket; + using Identifier = int; + using Answer = DNSResult; // ip + Socket d_socket; std::deque d_idqueue; - typedef accumulator_set< + using acc_t = accumulator_set< double , stats - > acc_t; + >; unique_ptr d_acc; + + static constexpr std::array s_probs{{0.001,0.01, 0.025, 0.1, 0.25,0.5,0.75,0.9,0.975, 0.99,0.9999}}; + unsigned int d_errors{0}; + unsigned int d_nxdomains{0}; + unsigned int d_nodatas{0}; + unsigned int d_oks{0}; + unsigned int d_unknowns{0}; + unsigned int d_received{0}; + unsigned int d_receiveerrors{0}; + unsigned int d_senderrors{0}; - boost::array d_probs; - - SendReceive(const std::string& remoteAddr, uint16_t port) : d_probs({{0.001,0.01, 0.025, 0.1, 0.25,0.5,0.75,0.9,0.975, 0.99,0.9999}}) + SendReceive(const std::string& remoteAddr, uint16_t port) : + d_socket(AF_INET, SOCK_DGRAM), + d_acc(make_unique(acc_t(boost::accumulators::tag::extended_p_square::probabilities=s_probs))) { - d_acc = make_unique(acc_t(boost::accumulators::tag::extended_p_square::probabilities=d_probs)); - // - //d_acc = acc_t - d_socket = socket(AF_INET, SOCK_DGRAM, 0); - int val=1; - setsockopt(d_socket, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); - + d_socket.setReuseAddr(); ComboAddress remote(remoteAddr, port); - connect(d_socket, (struct sockaddr*)&remote, remote.getSocklen()); - d_oks = d_errors = d_nodatas = d_nxdomains = d_unknowns = 0; - d_received = d_receiveerrors = d_senderrors = 0; - for(unsigned int id =0 ; id < std::numeric_limits::max(); ++id) + d_socket.connect(remote); + for (unsigned int id =0 ; id < std::numeric_limits::max(); ++id) { d_idqueue.push_back(id); - } - - ~SendReceive() - { - close(d_socket); + } } Identifier send(TypedQuery& domain) @@ -116,7 +114,7 @@ struct SendReceive DNSPacketWriter pw(packet, domain.name, domain.type); - if(d_idqueue.empty()) { + if (d_idqueue.empty()) { cerr<<"Exhausted ids!"<rd = 1; pw.getHeader()->qr = 0; - if(::send(d_socket, &*packet.begin(), packet.size(), 0) < 0) + if (::send(d_socket.getHandle(), &*packet.begin(), packet.size(), 0) < 0) { d_senderrors++; + } - if(!g_quiet) + if (!g_quiet) { cout<<"Sent out query for '"<id<id; } bool receive(Identifier& id, DNSResult& dr) { - if(waitForData(d_socket, 0, 500000) > 0) { - char buf[512]; + if (waitForData(d_socket.getHandle(), 0, 500000) > 0) { + std::array buf; - int len = recv(d_socket, buf, sizeof(buf), 0); - if(len < 0) { + auto len = recv(d_socket.getHandle(), buf.data(), buf.size(), 0); + if (len < 0) { d_receiveerrors++; - return 0; - } - else { - d_received++; + return false; } + d_received++; // parse packet, set 'id', fill out 'ip' - MOADNSParser mdp(false, string(buf, len)); + MOADNSParser mdp(false, string(buf.data(), static_cast(len))); if(!g_quiet) { cout<<"Reply to question for qname='"< Date: Wed, 16 Aug 2023 10:15:42 +0200 Subject: [PATCH 552/909] ixfrdist: Fix Coverity CID 1504137: Uncaught exception --- pdns/ixfrdist.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pdns/ixfrdist.cc b/pdns/ixfrdist.cc index 8fcd1c51c62a..8fba8199c3e3 100644 --- a/pdns/ixfrdist.cc +++ b/pdns/ixfrdist.cc @@ -1366,6 +1366,10 @@ static std::optional parseConfiguration(int argc, char** g_log<(); From 299c66819d18aa195613e28a7392c901c799532a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 16 Aug 2023 11:13:09 +0200 Subject: [PATCH 553/909] dnsgram: Fix Coverity CID 1401647 --- pdns/dnsgram.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsgram.cc b/pdns/dnsgram.cc index 2b93f43eb8f5..bfa899889c4d 100644 --- a/pdns/dnsgram.cc +++ b/pdns/dnsgram.cc @@ -163,7 +163,7 @@ try } if(mdp.d_header.rd && !mdp.d_header.qr) { - rdqcounts[pr.d_pheader.ts.tv_sec + 0.01*(pr.d_pheader.ts.tv_usec/10000)]++; + rdqcounts[pr.d_pheader.ts.tv_sec + 0.01*(pr.d_pheader.ts.tv_usec/10000.0)]++; g_lastquestionTime=pr.d_pheader.ts; g_clientQuestions++; totalQueries++; @@ -171,7 +171,7 @@ try questions.emplace(mdp.d_qname, mdp.d_qtype); } else if(mdp.d_header.rd && mdp.d_header.qr) { - rdacounts[pr.d_pheader.ts.tv_sec + 0.01*(pr.d_pheader.ts.tv_usec/10000)]++; + rdacounts[pr.d_pheader.ts.tv_sec + 0.01*(pr.d_pheader.ts.tv_usec/10000.0)]++; g_lastanswerTime=pr.d_pheader.ts; g_clientResponses++; answers.emplace(mdp.d_qname, mdp.d_qtype); From 04856fed2e35de3ad176f21958ce3aa42f85bb2a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 16 Aug 2023 11:18:25 +0200 Subject: [PATCH 554/909] channel: Fix redundant redeclaration warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit g++ reports: ``` In file included from channel.cc:23: channel.hh:38:17: warning: redundant redeclaration of ‘void __tsan_acquire(void*)’ in same scope [-Wredundant-decls] 38 | extern "C" void __tsan_acquire(void* addr); | ^~~~~~~~~~~~~~ In file included from /usr/include/c++/13.2.1/bits/shared_ptr_atomic.h:37, from /usr/include/c++/13.2.1/memory:81, from channel.hh:23: /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/include/sanitizer/tsan_interface.h:24:6: note: previous declaration of ‘void __tsan_acquire(void*)’ 24 | void __tsan_acquire(void *addr); | ^~~~~~~~~~~~~~ channel.hh:39:17: warning: redundant redeclaration of ‘void __tsan_release(void*)’ in same scope [-Wredundant-decls] 39 | extern "C" void __tsan_release(void* addr); | ^~~~~~~~~~~~~~ /usr/lib/gcc/x86_64-pc-linux-gnu/13.2.1/include/sanitizer/tsan_interface.h:25:6: note: previous declaration of ‘void __tsan_release(void*)’ 25 | void __tsan_release(void *addr); ``` --- pdns/channel.hh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/pdns/channel.hh b/pdns/channel.hh index 6947d3b26d4b..b06ff03e48d6 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -35,9 +35,18 @@ #endif #if __SANITIZE_THREAD__ +#if defined __has_include +#if __has_include() +#include +#else /* __has_include() */ extern "C" void __tsan_acquire(void* addr); extern "C" void __tsan_release(void* addr); -#endif +#endif /* __has_include() */ +#else /* defined __has_include */ +extern "C" void __tsan_acquire(void* addr); +extern "C" void __tsan_release(void* addr); +#endif /* defined __has_include */ +#endif /* __SANITIZE_THREAD__ */ namespace pdns { From 50a3b8f9e709e100965dadca1f380a7533f3878d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 16 Aug 2023 11:45:49 +0200 Subject: [PATCH 555/909] calidns: Fix warnings from clang-tidy --- pdns/calidns.cc | 101 ++++++++++++++++++++++++++---------------------- 1 file changed, 55 insertions(+), 46 deletions(-) diff --git a/pdns/calidns.cc b/pdns/calidns.cc index f0a898905e88..ccf4af8831d5 100644 --- a/pdns/calidns.cc +++ b/pdns/calidns.cc @@ -204,6 +204,58 @@ static void usage(po::options_description &desc) { cerr<>>& unknown, bool useECSFromFile, bool wantRecursion, bool addECS) +{ + ifstream ifs(queryFile); + string line; + std::vector fields; + fields.reserve(3); + + while (getline(ifs, line)) { + vector packet; + DNSPacketWriter::optvect_t ednsOptions; + boost::trim(line); + if (line.empty() || line.at(0) == '#') { + continue; + } + + fields.clear(); + stringtok(fields, line, "\t "); + if ((useECSFromFile && fields.size() < 3) || fields.size() < 2) { + cerr<<"Skipping invalid line '"<rd = wantRecursion; + packetWriter.getHeader()->id = dns_random_uint16(); + + if (!subnet.empty() || addECS) { + EDNSSubnetOpts opt; + opt.source = Netmask(subnet.empty() ? "0.0.0.0/32" : subnet); + ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt)); + } + + if (!ednsOptions.empty() || (packetWriter.getHeader()->id % 2) != 0) { + packetWriter.addOpt(1500, 0, EDNSOpts::DNSSECOK, ednsOptions); + packetWriter.commit(); + } + unknown.push_back(std::make_shared>(packet)); + } + + shuffle(unknown.begin(), unknown.end(), pdns::dns_random_engine()); +} +} + /* New plan. Set cache hit percentage, which we achieve on a per second basis. So we start with 10000 qps for example, and for 90% cache hit ratio means @@ -340,54 +392,11 @@ try } #endif - ifstream ifs(g_vm["query-file"].as()); - string line; reportAllTypes(); - vector > > unknown, known; - std::vector fields; - fields.reserve(3); - - while(getline(ifs, line)) { - vector packet; - DNSPacketWriter::optvect_t ednsOptions; - boost::trim(line); - if (line.empty() || line.at(0) == '#') { - continue; - } - - fields.clear(); - stringtok(fields, line, "\t "); - if ((useECSFromFile && fields.size() < 3) || fields.size() < 2) { - cerr<<"Skipping invalid line '"<>> unknown; + vector>> known; + parseQueryFile(g_vm["query-file"].as(), unknown, useECSFromFile, wantRecursion, !ecsRange.empty()); - const std::string& qname = fields.at(0); - const std::string& qtype = fields.at(1); - std::string subnet; - - if (useECSFromFile) { - subnet = fields.at(2); - } - - DNSPacketWriter pw(packet, DNSName(qname), DNSRecordContent::TypeToNumber(qtype)); - pw.getHeader()->rd=wantRecursion; - pw.getHeader()->id=dns_random_uint16(); - - if(!subnet.empty() || !ecsRange.empty()) { - EDNSSubnetOpts opt; - opt.source = Netmask(subnet.empty() ? "0.0.0.0/32" : subnet); - ednsOptions.emplace_back(EDNSOptionCode::ECS, makeEDNSSubnetOptsString(opt)); - } - - if(!ednsOptions.empty() || pw.getHeader()->id % 2) { - pw.addOpt(1500, 0, EDNSOpts::DNSSECOK, ednsOptions); - pw.commit(); - } - unknown.push_back(std::make_shared>(packet)); - } - - shuffle(unknown.begin(), unknown.end(), pdns::dns_random_engine()); if (!g_quiet) { cout<<"Generated "< Date: Wed, 16 Aug 2023 11:49:23 +0200 Subject: [PATCH 556/909] dnsdist: Try to fix a data race warning reported by TSAN --- pdns/dnsdist-cache.hh | 16 ++++++++-------- regression-tests.dnsdist/test_Metrics.py | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pdns/dnsdist-cache.hh b/pdns/dnsdist-cache.hh index d8837bec5dc3..5b2ba2c78d4f 100644 --- a/pdns/dnsdist-cache.hh +++ b/pdns/dnsdist-cache.hh @@ -45,15 +45,15 @@ public: bool isFull(); string toString(); uint64_t getSize(); - uint64_t getHits() const { return d_hits; } - uint64_t getMisses() const { return d_misses; } - uint64_t getDeferredLookups() const { return d_deferredLookups; } - uint64_t getDeferredInserts() const { return d_deferredInserts; } - uint64_t getLookupCollisions() const { return d_lookupCollisions; } - uint64_t getInsertCollisions() const { return d_insertCollisions; } + uint64_t getHits() const { return d_hits.load(); } + uint64_t getMisses() const { return d_misses.load(); } + uint64_t getDeferredLookups() const { return d_deferredLookups.load(); } + uint64_t getDeferredInserts() const { return d_deferredInserts.load(); } + uint64_t getLookupCollisions() const { return d_lookupCollisions.load(); } + uint64_t getInsertCollisions() const { return d_insertCollisions.load(); } uint64_t getMaxEntries() const { return d_maxEntries; } - uint64_t getTTLTooShorts() const { return d_ttlTooShorts; } - uint64_t getCleanupCount() const { return d_cleanupCount; } + uint64_t getTTLTooShorts() const { return d_ttlTooShorts.load(); } + uint64_t getCleanupCount() const { return d_cleanupCount.load(); } uint64_t getEntriesCount(); uint64_t dump(int fd); diff --git a/regression-tests.dnsdist/test_Metrics.py b/regression-tests.dnsdist/test_Metrics.py index 5a70d0d8cefd..28fd1565df88 100644 --- a/regression-tests.dnsdist/test_Metrics.py +++ b/regression-tests.dnsdist/test_Metrics.py @@ -148,7 +148,7 @@ def testCacheMetrics(self): def testServFailMetrics(self): """ - Metrics: Check that servfail metrics are correctly updated for cache misses and hits + Metrics: Check that servfail metrics are correctly updated for server failures """ for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHQueryWrapper"): From e2ecb4401685f0c043010ce921bebf72c7bed5c8 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 16 Aug 2023 11:46:03 +0200 Subject: [PATCH 557/909] dnsbulktest: Fix warnings from clang-tidy --- pdns/dnsbulktest.cc | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pdns/dnsbulktest.cc b/pdns/dnsbulktest.cc index b6fbc7bcbf38..085a644d5712 100644 --- a/pdns/dnsbulktest.cc +++ b/pdns/dnsbulktest.cc @@ -136,6 +136,7 @@ struct SendReceive bool receive(Identifier& id, DNSResult& dr) { if (waitForData(d_socket.getHandle(), 0, 500000) > 0) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init): no need to initialize the buffer std::array buf; auto len = recv(d_socket.getHandle(), buf.data(), buf.size(), 0); @@ -352,7 +353,7 @@ try boost::format statfmt("Time < %6.03f ms %|30t|%6.03f%% cumulative\n"); for (unsigned int i = 0; i < SendReceive::s_probs.size(); ++i) { - cerr << statfmt % extended_p_square(*sr.d_acc)[i] % (100*SendReceive::s_probs[i]); + cerr << statfmt % extended_p_square(*sr.d_acc)[i] % (100*SendReceive::s_probs.at(i)); } if (g_envoutput) { @@ -373,9 +374,9 @@ try catch (const PDNSException& exp) { cerr<<"Fatal error: "< Date: Wed, 16 Aug 2023 15:16:33 +0200 Subject: [PATCH 558/909] Fix building our fuzzing targets from a dist tarball Until now all of our fuzzing targets where built with the authoritative server, even though one of them is specific to dnsdist. This made it easy to build all of them at once, especially for OSS-Fuzz and CI-Fuzz, but had the unfortunate drawback of pulling several dnsdist-specific files into the main pdns/ directory for no good reason. It also prevented building the fuzzing targets from a dist tarball/directory. This commit moves the dnsdist-specific fuzzing target to the dnsdist build process, and ensure that the standalone_fuzz_target_runner.cc file is part of the dist tarball, making it possible to build the fuzzing targets from the dist. It does not move the dnsdist-specific files to the pdns/dnsdistdist/ directory yet because this would conflict with existing PRs. --- fuzzing/README.md | 23 +++++--- pdns/Makefile.am | 27 +-------- pdns/dnsdistdist/Makefile.am | 55 ++++++++++++++++++ pdns/dnsdistdist/configure.ac | 1 + pdns/{ => dnsdistdist}/fuzz_dnsdistcache.cc | 0 pdns/dnsdistdist/fuzz_target_dnsdistcache | Bin 0 -> 10957216 bytes .../m4/pdns_enable_fuzz_targets.m4 | 1 + .../standalone_fuzz_target_runner.cc | 1 + tasks.py | 3 +- 9 files changed, 77 insertions(+), 34 deletions(-) rename pdns/{ => dnsdistdist}/fuzz_dnsdistcache.cc (100%) create mode 100755 pdns/dnsdistdist/fuzz_target_dnsdistcache create mode 120000 pdns/dnsdistdist/m4/pdns_enable_fuzz_targets.m4 create mode 120000 pdns/dnsdistdist/standalone_fuzz_target_runner.cc diff --git a/fuzzing/README.md b/fuzzing/README.md index c2637d433830..f8ec89d19067 100644 --- a/fuzzing/README.md +++ b/fuzzing/README.md @@ -5,21 +5,24 @@ This repository contains several fuzzing targets that can be used with generic fuzzing engines like AFL and libFuzzer. These targets are built by passing the --enable-fuzz-targets option to the -configure, then building as usual. You can also build only these targets -by going into the pdns/ directory and issuing a 'make fuzz_targets' command. +configure of the authoritative server and dnsdist, then building them as usual. +You can also build only these targets manually by going into the pdns/ directory +and issuing a 'make fuzz_targets' command for the authoritative server, +or going into the pdns/dnsdistdist and issuing a 'make fuzz_targets' command for +dnsdist. The current targets cover: -- the auth, dnsdist and rec packet caches (fuzz_target_packetcache and - fuzz_target_dnsdistcache) ; +- the auth and rec packet cache (fuzz_target_packetcache) ; - MOADNSParser (fuzz_target_moadnsparser) ; - the Proxy Protocol parser (fuzz_target_proxyprotocol) ; - the HTTP parser we use (YaHTTP, fuzz_target_yahttp) ; - ZoneParserTNG (fuzz_target_zoneparsertng). - Parts of the ragel-generated parser (parseRFC1035CharString in - fuzz_target_dnslabeltext) + fuzz_target_dnslabeltext) ; +- the dnsdist packet cache (fuzz_target_dnsdistcache). By default the targets are linked against a standalone target, -pdns/standalone_fuzz_target_runner.cc, which does no fuzzing but makes it easy +standalone_fuzz_target_runner.cc, which does no fuzzing but makes it easy to check a given test file, or just that the fuzzing targets can be built properly. This behaviour can be changed via the LIB_FUZZING_ENGINE variable, for example @@ -59,7 +62,7 @@ in the fuzzing/corpus/zones/ directory. Quickly getting started (using clang 11) ---------------------------------------- -First, confgure: +First, configure the authoritative server: ``` LIB_FUZZING_ENGINE="/usr/lib/clang/11.0.1/lib/linux/libclang_rt.fuzzer-x86_64.a" \ @@ -70,6 +73,12 @@ LIB_FUZZING_ENGINE="/usr/lib/clang/11.0.1/lib/linux/libclang_rt.fuzzer-x86_64.a" ./configure --without-dynmodules --with-modules= --disable-lua-records --disable-ixfrdist --enable-fuzz-targets --disable-dependency-tracking --disable-silent-rules --enable-asan --enable-ubsan ``` +If you build the fuzzing targets only, you will need to issue the following commands first: +``` +make -j2 -C ext/arc4random/ +make -j2 -C ext/yahttp/ +``` + Then build: ``` diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 625bc1e04414..502a2e33a150 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -63,6 +63,7 @@ EXTRA_DIST = \ lua-record.cc \ minicurl.cc \ minicurl.hh \ + standalone_fuzz_target_runner.cc \ api-swagger.yaml \ api-swagger.json \ requirements.txt \ @@ -1527,7 +1528,6 @@ LIB_FUZZING_ENGINE ?= standalone_fuzz_target_runner.o standalone_fuzz_target_runner.o: standalone_fuzz_target_runner.cc fuzz_targets_programs = \ - fuzz_target_dnsdistcache \ fuzz_target_moadnsparser \ fuzz_target_packetcache \ fuzz_target_proxyprotocol \ @@ -1601,31 +1601,6 @@ fuzz_target_proxyprotocol_DEPENDENCIES = $(fuzz_targets_deps) fuzz_target_proxyprotocol_LDFLAGS = $(fuzz_targets_ldflags) fuzz_target_proxyprotocol_LDADD = $(fuzz_targets_libs) -fuzz_target_dnsdistcache_SOURCES = \ - channel.hh channel.cc \ - dns.cc dns.hh \ - dnsdist-cache.cc dnsdist-cache.hh \ - dnsdist-ecs.cc dnsdist-ecs.hh \ - dnsdist-idstate.hh \ - dnsdist-protocols.cc dnsdist-protocols.hh \ - dnslabeltext.cc \ - dnsname.cc dnsname.hh \ - dnsparser.cc dnsparser.hh \ - dnswriter.cc dnswriter.hh \ - doh.hh \ - ednsoptions.cc ednsoptions.hh \ - ednssubnet.cc ednssubnet.hh \ - fuzz_dnsdistcache.cc \ - iputils.cc iputils.hh \ - misc.cc misc.hh \ - packetcache.hh \ - qtype.cc qtype.hh \ - svc-records.cc svc-records.hh - -fuzz_target_dnsdistcache_DEPENDENCIES = $(fuzz_targets_deps) -fuzz_target_dnsdistcache_LDFLAGS = $(fuzz_targets_ldflags) -fuzz_target_dnsdistcache_LDADD = $(fuzz_targets_libs) - fuzz_target_yahttp_SOURCES = \ fuzz_yahttp.cc diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 9b951a586694..57ecaaa26e53 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -106,6 +106,7 @@ EXTRA_DIST=COPYING \ kqueuemplexer.cc \ portsmplexer.cc \ cdb.cc cdb.hh \ + standalone_fuzz_target_runner.cc \ ext/lmdb-safe/lmdb-safe.cc ext/lmdb-safe/lmdb-safe.hh \ ext/protozero/include/* \ builder-support/gen-version @@ -451,6 +452,60 @@ testrunner_SOURCES += \ portsmplexer.cc endif +if FUZZ_TARGETS + +LIB_FUZZING_ENGINE ?= standalone_fuzz_target_runner.o + +standalone_fuzz_target_runner.o: standalone_fuzz_target_runner.cc + +fuzz_targets_programs = \ + fuzz_target_dnsdistcache + +fuzz_targets: $(ARC4RANDOM_LIBS) $(fuzz_targets_programs) + +bin_PROGRAMS += \ + $(fuzz_targets_programs) + +fuzz_targets_libs = \ + $(LIBCRYPTO_LIBS) \ + $(LIB_FUZZING_ENGINE) + +fuzz_targets_ldflags = \ + $(AM_LDFLAGS) \ + $(DYNLINKFLAGS) \ + $(LIBCRYPTO_LDFLAGS) \ + $(FUZZING_LDFLAGS) + +# we need the mockup runner to be built, but not linked if a real fuzzing engine is used +fuzz_targets_deps = standalone_fuzz_target_runner.o + +fuzz_target_dnsdistcache_SOURCES = \ + channel.hh channel.cc \ + dns.cc dns.hh \ + dnsdist-cache.cc dnsdist-cache.hh \ + dnsdist-ecs.cc dnsdist-ecs.hh \ + dnsdist-idstate.hh \ + dnsdist-protocols.cc dnsdist-protocols.hh \ + dnslabeltext.cc \ + dnsname.cc dnsname.hh \ + dnsparser.cc dnsparser.hh \ + dnswriter.cc dnswriter.hh \ + doh.hh \ + ednsoptions.cc ednsoptions.hh \ + ednssubnet.cc ednssubnet.hh \ + fuzz_dnsdistcache.cc \ + iputils.cc iputils.hh \ + misc.cc misc.hh \ + packetcache.hh \ + qtype.cc qtype.hh \ + svc-records.cc svc-records.hh + +fuzz_target_dnsdistcache_DEPENDENCIES = $(fuzz_targets_deps) +fuzz_target_dnsdistcache_LDFLAGS = $(fuzz_targets_ldflags) +fuzz_target_dnsdistcache_LDADD = $(fuzz_targets_libs) + +endif + MANPAGES=dnsdist.1 dist_man_MANS=$(MANPAGES) diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index aa7ffbf7a44e..57856ee8e4f0 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -35,6 +35,7 @@ AC_FUNC_STRERROR_R BOOST_REQUIRE([1.42]) PDNS_ENABLE_UNIT_TESTS +PDNS_ENABLE_FUZZ_TARGETS PDNS_WITH_RE2 DNSDIST_ENABLE_DNSCRYPT PDNS_WITH_EBPF diff --git a/pdns/fuzz_dnsdistcache.cc b/pdns/dnsdistdist/fuzz_dnsdistcache.cc similarity index 100% rename from pdns/fuzz_dnsdistcache.cc rename to pdns/dnsdistdist/fuzz_dnsdistcache.cc diff --git a/pdns/dnsdistdist/fuzz_target_dnsdistcache b/pdns/dnsdistdist/fuzz_target_dnsdistcache new file mode 100755 index 0000000000000000000000000000000000000000..8eb51b815d0b178f871190daa9ec08073bfdba34 GIT binary patch literal 10957216 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�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%0D>LvI~@nQsUzL0>;248O@U@t zb9kCnJ#%}4cn;p&cIA(w3FvEfY$zHzr`-B(Yu5%d|B)%U#K;S|(b?jSCl>h&`e1T^ zm4*buSm|=oMx$9QmVb?d74M_jI#XrT`tI8NU&-_6(FDwP4G)G47G90xR9vn#d-pW5 z=fTg%IIua|{JinXs9w}zb#k|K%8?C;d7?;1NyBQ^_a1Em17pt6PTt3zf<92X3@)@FiU@#+@rGyI$7)L-_nfCqfyE_YR%~625Mw|I87 zykw;VR41d+7}8)CVnqyJJ2imWmj?s{ajM_mi}i$&8kggwD?j|?hq^8(&3+#1b$hx<5wy)f>8 zm?+!0g?jA%7geeATvxt?-7m1pkMbod0jHsg|JY69%A*4TqhmB22~cbFcilEBkha63 zrmmf=GdHu!)af3!x^%l_ot4mIP638{sETL50=zC}AzV8G);b<}!Ai@B!qY^HRQNEn zGFz0$ooL{OV!*x4jBKlcn_EpHmIcnN8P2a^qof%mKE(Lr5jiq67d@B|n=AT8`X zv*bMFGFk4&Th-EP_Yw2^oO=o!jg17ciEv{i&gL6a9qEJ387j^eB(b+nU_bklvo? zA8ju`IiRRKbp|9r5cZBU@nH7~>fh5ZnEaGDm*93(bCu`~jpcE_yD_R3qzY3AWehZb z{6H6uvC@ehHT&gg=QjMcUW!HDn8h+~QV4a+X<#5LE9j>CgNKA7N80T}K-Sa#eHlL- zg1FCjiJk_!KUi5jzuVap46WXX{r0I;K)0=oYRaF>AM9N~rF@qm0?kxS__uvAc#f3z zQUKeP@%MG}-C=x!*=HyXxkE!Rx z1i@(&(r0BPPm1SGH0MLDsmDONxZ^EjM&(|tbZ#PuoaCm;25*@{d?s_X3U&>ZT^}y) zk8+TPCQ&^RNcJSo;M5M=n>{@n#pC^TPC8F|vdH99hVnTP+aW#^g;SA0qWnB(=o+cq zaF)hg+aql8;;HH^vlgbnre4X!7mfv>1M4~Wg_^?3ZFHW@i^(#4LtB@~?o&X0VkN0_fW+$v~L5q@(GF0OVzZs7Qw`%8XH z;irp5tD_gkoXydR@!a$pgO0mx=P`e`fefC)#L1QiAxkkZnUMu`oKuZw_*rC+;H_Sp z4b`k0I1P8YIs!F|jIEe;Ch-oyY}t2sIDH>a=jTTI`vmtcGO=-IzrUrgbr+hnA;Fx| z6SIB3z*8(V1`2x5xhY~-BsO~5j3hza{qE=-NiRH-Qq4#N z1{1SpR)ukh@VOFe8N4i(l|ElW?IU!;t#adhWBeqNCt=cjZf+Z+dD;KB#d(vk~7?m8|Wh#PZI+aVNBy zT@lm`cKw)5-^^+L8zP`>+q76mfI{v=2Cvq3p^#bIRo3-}*=EI>o#7+eDnj3h2%Z6D z>_Ir9M)b38S`FkR+5BS^+vR1OCpx?1xpT@d!Vk_`dO^@ydKsF=ir_jD{n}ov2tHyh zd)>~RUk*Dz>&&jnhHj+V$_dm3N3~(*rRKY9iHN{~#Q%1uwe(u^?d$qB_?pUnoP$_f za;?o#a8zo0d2MU>udstBhBUtgIm@NXkD_nN@bK-@DU3AiEwi?|OOM zBMpj|O=w`3l*-xVr z{x$a}-_O$ZtVxg}QcZ z+s@uNa@}wTk)ExE;~0oSR4>%dYd_?bg!3X^j~#i=w#GdN+lT?y-^A8RpsQ|Fx~H&# zHJTwx#w&KN9HyN&Mtap4*=?o2O~2?6+jDrY@EJkI$N|xok>y5a8rhe8m8-X7xnp3g zh+ZTiFv4E1kxKVIO%75V1nYVed<5BS;@Ef?zuxBzEO-R~?O>Oirl?A>*dIga6%X%m z|HFI@xEh^L#hlBaQoe7@oPk5dkH+X(w_k!J>o?U-N?3| z$?t?xuz0-lcwt@Hxshksk=LyBi-KhMH64-=9EcAc&=T*@{30qQM#v71AQiFj+eld( zov)w^-k$h41LKlNkKO{O3H<}aEA|29Cbu_o9Et_sR&hJk9lVi%Tl@1v=!D>EWsawl ze8o2n0VA(5d>0-ioLb0l2(&bG=N~5lzzwip5xjxlBlOU%Uk3bwFR~XHC?-A}53@M} zWlo+3z#mru0odFgbQjI$zr!C;DSw*4?gTJ~|9}=pAUWN<41ZU*P%Vy7@QY z5_7nChJEYzf>G8Iqh*d~;3Kz7po{+&FPau`n=r?Rg?dh1Hz1IlOBN;v$yp>T0?DiG zoNl?@jNURg<48SR(tJa(GLR(Z$DCn^KdjUuzU4SFA&9bj&JkF+aQu0C);xkv1dn(? z1g}2$bW^H3ocx3|rs2K7wf}66cdZ|;U614$s!3mmbq#D%Z~ip03x<0gxg$<}=?x3!DK=W}ZY!Uxz1H zufiZbAh!n$m-<^khn7WyM7@a$cyzHdvPIuH!&$w;k@ZgS(8c;E&0WuizejWrQJhFRmwY6U1vCH$g0zop{*+bA^ky4>s?w zzV@TeW}{0;9OG8SE+Ta_6$XpU1|1L$I^py>}rs z%X@E=vpKbjO=@&463*B2XOQjni-?)DwL)z@aiFd`Q9i;%*Ku0C+B@pY-c~F53chf= ze=RgzonOsiw?J>;Qr-XwQ`^|E4qqYWfY9iJXMYS&;X$0+tflh@V>Ld+4(7$O?6a2b zi*tuj`A-aXUQ zwyGk$&b~bsE)O|7o1BS*RB0){GVvnk5!R$R`RpHjtq3{J;|5onH8693I`N{uG>GVv zF$K^GuZk&t=N4W<0w&iCisvpK%>9ng+D%qUQbkdQ8k|{o3~31dS!<&#A4X2mojgddk`l$xNRqh&w;*0fbbdVUVPn1J<1{v~{onFTAWGwPeIZQ5_pda>g4t{-b zZU|Al+_d0& zL&ERZbLx5-lKsNVHkM;|df63Zf0swT8;Tj1o=Q6T#Lv~qi|8LTK08=uErnfTii+lD zXb-SbTbWQp{t=US`D_8?|BQUmdv<^sN0^D(JZrYKG!Z-^cmO6nY-Nt}iW?1GYLJ&W zTH8r2{It1c@RFsJ&)?$arzTIw4uW({K7X)L#L|nu_}U1crE9Bk3RHP z%`Vus4zQF=qUWFG%_H195mQmunt5C;VMS_wT_7=XIfR$FxYhV_72#lI?!znsdtp^s z00&1%uice8Rk;K16Z3F+9U{Prj=Bo6pm%km*K8c);rYf_lOExv$JR-iaI^x_R=T&o zj`ghS(2=VHy2VLyFzPld{b|T%Q)(W3!IAvH4;^@SK`3FHcbxp#);MGGfC$-~ zH$i`fCKg)iXfwVSwGl>B^U4EWU~v>ljWhsvaxEh#l^npIiLmh773aOJ&3r$~GoH(_ zSvIw`SBQRD%hs!A8#;o2tAgy*EFVh8gS*(v>hx5f8#y?3`D4biuZxSir6;IsKCsfd z`6fC6x8=V4RrQ-n6o08E>s>G)b~w1!-M~9*Y0`)-*Be_weQ`gz^sk{DfnZPou$HwV z2%Pyq?RNA~$&Z*Tzt~T`b_V$E+*oMGSmskteYQH@?+Wf`xx&=9bYw`<(G9A3K-3iS z>h2_9^~_@pKxoJt_9j-w?RJDfRNrflrrL@5$N;>6mn9Vsq2fX&w03mJeRCQ)<-kSb z*ha#9NKc~82l^$4DuP`gY^AqTqVS>D$5zVH1%fF!&k6c~+x?aQJzM8m80@t~fMzSq z$6!efoNHV2GQS4s9=~1~xI2pv4ZG~kM=}3W<=@6`DNaZTD1<7K&M`kx+9RE83llI# zg>)XhTclI>23|y`5}}h3-PGv-Q)6cVi`kS6QCg_#IMv578gU+T=g-o8gOJ?(k0i|y z;@7rHV-Y*yXteWIO1^RiC5nIu{@s1xD1H%btGu8}LFza-Y zt}1LBtKARLR@Zmkw^5;r4_i)8dI;8Mpd&xL$k9W}Z4 zsyYZx3-SU3?-F|B5gRWUEIezqF$6NF$U_JajIorbZ&v^wg56cJCO7)enAxU(u4gX1 zt3Wu<<#^sQePN(7FRk!anXY6t7Ok+Old%C76tHT=??D%B;CW03apeouODHyDfY!5; z<4{kR>$sPj%w>v*h@u>PsBx+xc{$I;7LA5@nGsDG#Pp2 z>kMVOf{$S^LQ}1!=}wcNeqoW8k?1w z$RhC?PN~1`^j^`1Wgm=>rhF9X(hcnJ@Ut7Ys;hh(PzVnqEvXB35I?W!UKd*Yu7XzT zk?q`KTw0|+!R@?7S%W%lr{I=dD21nI0Tw#gOf3#5bBgJm7n?|qv8D>yOv>k13LE^9 zcyjN%8=V>Prc2~+sTb%XHMf}iyF6HGpi>LI;&!?NMzceYluf5qeGj}1UsDJU;18CP zGxAx80`T#=pL#wB2x3kvb;SgiL7nkIs2O_(N7a5%ssa$eAy}qDl?8Cn*?dirpNGD+ z^Z)6nlw|=ZtPoQHw@!~=?%F;=S{b2JetZeOdF>j!bK2;fLAv`W)f?#)vhRz1Al)6I zX3F*ep--ga%vYQvW3geR1kbs1Uh?qGT880$Q;=Oxn3w)-59WO`Sj4>Z%-jm)iqZKOZ3eHTS~5mxX_5wuQ^7=Y@avAVN$OP_BT7f@Ue+6(K?<^u!yZ2~_Uw zgGl%}z8YE2Z$U4TSBL5f1hRmC@)tinzZ8sF)MRF{K&!!SJmfEtP~|A{sqHmjJ!cm#2&0% zbO7QE4S*gRQI;XZMXZ#Ux9H*j0(_JeR-gFz7AWE2<7+&*KmIBB_zF+|5`3KT!QtbP z8iU~{j0&QUvxg*weVjcOnet{*Q8S2)XaWgj(4Fv&!6D@p?(Co7|Ib6$&%{<#LvSAr zuLDU=fZ&o*seK*Z*1?t#u7g05I!o9m^i#a*g`c@!EEETfSn5^w*q5zak89>UD$n`uE=J{rtEe@?Kx9*Sc(ouW$8U zZ_w*E{*$SlP0J<1Rmp$R>+SZ>_?#T$q5fh@xvi4H0U>JP8f^C~2w&h&$BMVA7(APs zvWFB{)d4zGJ3Dpk9nd_wRySJ64U*)s+45Ss+hTBF4uGC~PRZIa@wFi`%ROAD)#LolFl_$aSX63G zPXn0q+{=7mj*!l6z*jYKl-3ClXNQi=G`W}@3s(?oux2!4ys|hM_a03@jpon~ z`kOvg^nBFcH1eF+qj&kJ+~yvf|7lQY*cGI!mctuHf#fDjv+B~zLEykfY4()Il9S-#c0Ib`|X3aRN?z6L$D zf=`1v@o9jay{(2XDfBZ_L)bJ;g9h`9i&$l>u%Q)uObO0pa?}NB7;frsf_bt+;T3R@iF6BR_&K2$F4S#EvSBoK3^uEsfE}$P4 zX6XUTTWDFcObZms@mIb-K5v0L-mR4rkau`+r6Z~reCw0VC8~p3^Ow6JDYldINQ$Yk zKpPy>R~D(DnSTQp)y^(gF%^gihm~!J@Nqo3>;D5HERIO~eIM}mI_T3h51b`u z+`<&7cG@?Ei&NnB)W4(Cn}Q!3$(ab4UsNaqv0I`|(O==%tHyH=Z&rp!*mPdVNQ;&K z6?mq8zSp`a?|WVROc?F$jXmokr=IlmeLSh2%}qnF!npuH#dT3bE&kcyFHcb++M}q^ zt3Vj6Ww)v0Ukfs(%riV?bAQ%AvP;ZPeM?+AOtYRYV`)VvxnJ9&E}0yo`lAka^C@Ni z(!$h1H8YF;(sIw(RkEgbo2n1q>+^=?F!bX+_QQ98=?9O8ou-$E;2~BXJ{}^*NB@AQ zv++m$m*C+kGzotJGHCYSl@6FiQ&?*U(E*_bbigZ8paaUxZ}LRK&~H%LN9v~3!(#As zf@^@XS^=mZh9?gqBfF4h%b1+Thm}U5iIp>rGCSiAViQzT8ya_NDJ~_lT?G<+o zYB?NEVKxp}sh6p*2W1M?9FIn)z-*)ycjUeHh)R_y9({_u(|UuDhNkxH5qG}#8oD#U z=!#?GR0={V0i_1a=x1o5kOFYzmsQs7AT)BUI17~{ypyBNNu4=T~0 zSBpMyerAa2zz4LC{JOZ00FFuz92NQz8`nU~9yreA$t_zX*QtEx&JS>3djYL^fxn%% z9Gv@&>B(%m>GkAlp4>U#W@5gqr&qseWKw5MN9e?z#Vm-^j@xQPRtd7)`3|qK7n+W^ zj9(wweN4}Pjod|j$$OfdCE7{fL+tZM#6GghN6GF!Sx~)mXNlNH+db7_Wzd({#|VXFV&DmefPz`7PG&LX z0ft%2eTscfaeF9UMrX!DSHZi9eb!LAhxU15pBd%F8hG_T68r2loj647^CxASl?(j~ zxL+XNe15HZfPDXFBAdbdMf`midCxold*wZ5O%`N2&oNns$$uJ=R-f{o6}5xk zUJU<}@}A%MAN=2u_f&3R)%J*gf+XKV-t!}@(+jLc=Kq)X^k|ot{4bLC{OM+>@BjPq z9_@xcS?gQgqqukf>*PJ#R%<7F|MH$Y5RCdq;V7>7&qXhBufsdl&ngOh{{C-0C*ri! zVLitiH@2l@QN1Ck9eN`EJK67tfB)Yk@3}Ao9{$X9{9hn<{MX5Q5cG(pGlCuoHH#7+ z>BRECG!mZoJe&TjD z!iu6`rMKYSh*{F+-fcN~93ql(_m4bCV)>_ahaz-CRS81x>rJ13fzL+~p|`Q%`=HN% zHDvC+3E^&X*VIVk7N4jOV>8x(&a*}k>s7|vS;FXen^@-ewfw&*RVA=?=7>7~T0K(AWUz_{J5WJeX)_Ue_iGo%J zSOs>l-81yQK`u_u#dBAL2GnB!HdvA&r?L!Q~lkeS7|9IkBdCW z!~50kXYwXemWHK1A*4=lqr0sQnUT>gVj0Et-1v0Kx4x(^k50g{VuSG!*~N&Uh3{x^ za=5E0F^a0^ZnjpNSjBX)k^yn&l@4~HP|=dheSu{r?@DJiuG^)qmA{yKpga96H$G$) z4r}~i4Ih6){WLk_@tmUa9#j7z^s~l`D7V^ub+#sCZT?Oqf*yYN^7mTPEGPC}-JD~L zw+O;gG%#B(_f$9Z4b6IwKiLlXMRY?v@NdX`R|Lt#j^!)nkGLT6fJn6tvcvlc5jHcd zPR=QI(#jmBg`3*e?7=fSCHf`buSn*p1B@>PdMMQ>0~j5>eYb&oqX$yD{OwF?`(mnIk+ywk2P z_+MNc@2RSRFxak^k!7Hp} zJ;)#t2lgG*>DE2n-A%<>QBj9*I}HIEkff=jZUD6g+Fq~*Jpo3SH7$67_MWKSWbhf6 z1YES8NyN5(!CI(zjdFDv8V?d`vMo`L?OO$1x6=PEx|!>L{iGqVLtKS}v)70+T|kZB z87s{5=9~Q52N(JYOKRD8Rrt?rC_ChL1q)*aRct;(BZM% z!q;g*?EdjI&Lk+_L6T3k_u5^D&LFBV+ zR$njOj~Uy~<_`(vWp?l38FBGFMDuXheXvd)u`;tLVGu6=b)MWOW_mRHhqpi)de%e1 zzlYFGBG9^Ue1v8@ds&4%DR_jcjwWO}gDj;SX)d^xCd;hNg0E;yWXJf5CQi|-TTP)7 zOTzQzA3sg5qK!^R)Y;8Nngz$!A72fCa=K01x7KY{yo#!sKaD;R0HdN0 zDsmuE(h&d0L*w|1hmiX%Lu1w3%Wlqn4l2Iqv zQ#ROq!@Qq$;}Af|97n9oi$+L)9$1ZOpfEMAP?t-{jYT?zrL8`eD(afTY13P|UHa~` zvjKN>&tI)&=azMxZB{`%cXeodRV(^iXGc?8edyeZ)Rult3!a~kzw}I~dm^OUKZZ6B zS_fGxqi>^yx|4(~);fkint72s6Mdhm94|%YG%`(E52SUQsY&aB^qfLk52Tw5X+3E5 zOx5_S^=G_$h0rDET?}b(l+a>;$^FY$1yKLuNL(q50-_MH_bmGa-Sw!rpu78P7IwH- zHxY0i*9(=4=k5xb8DqaAq*vM`Fi#G;OB1wqP%Xv*v>A|z#Eg5;J1*~VKdK7*D!QH) zRn#sP-FanSMG5Egl3#T6gG{68=Gs1sVm7uJB6>d5fhFTwcL)Hdk3g zaMAWl;mN%aaaPs%IPq1X6F9?kCkP9O6KHr{oLfd0j;D&+R${9RAJ8%!@0(U4_jC}s zCx~BYA4_^Z@?3%(@4sn&1pp`o8_$-4G-?q;;w_v+x_R z2usPze~)*C^V)K+H)jvdUjx-|T4eU~uHO~;aU#Zu+hxBw;x6`^7@L#XZ-}=62h6@D zrtf@R%Mv%iCMSgA(AE0T`7(Cc!J*$!OP@HVUsTJu=bYcv=33eZ&&YS0&Hw@SU5%mA zet?eX9}NG7LL~70*1}g<(FXkHzLf{PGKy6+l2}EXiB+_jnAwDq#GOImZB&(e6K7L( zfG}WfF(|JZ5r1Qxi&eL?N|AT!*&B%SP)@)|Go1?5^J+Y}p|*9A@&~jGEi2BleAGX~ z*tJ8*#S~v&RT_TTMAdPRp+#*VHENbPP;|xA9}i+5K14A{j)#@*=W#-CEPM+r0Q5Qv$s_&~z@jI9I^+~!V28>smY4j_Yv0+BKZ$bg zTVGQLz3sS!;eL)PVJAPdj^o-ha1ebI`H@#-X9q==^j$_yr)lQMt zzKh)E6?sNQ?(DnBBCp626}i5zBFWQe34h2ySkfbx-;#PS_*# z=i~Zwtp0phe}?Oir9Xr9r@#IL^yjT<{Mn;FuklCL9WSQ5-{1SczfF7T<@_FE-{A_X z*(sG6;MRd#ae|6v&#A!lS_%9y__3Wk14@N=*0f~Y9AURyA=wpI!gpehiUM6){`r9HLB zo@1>&JzCp(T6+=DDkfY4STBHzRI4Cb-J3yfDg@;6dwsilw*0Zj9k6xK=ybXp=9ztvs<`>j{oY{#~YnbL2bOG%kI6L4C>T6~q!>Dpr z=oX|>;p>{Vt$nQQJ)b`yI zcLTi7a^t?w{z5HW7Z$g&_yT2Xm%~l>Ayfusu?;zR2y*M0b?689 z0@1+UK3Ox5_j9%(8uw>>gf9>uE${j$=L?kmXj=D{lJ7a*kHQbkHUxjBp6Cd*USa5a zf_WH!>MjU~g1Rsq*^Qd&oS%eB_zS^(+i$ZAfMr_3R35TSzX!qVTBe4c@(Vgc!qZ@- zcGtm_HKSbV&Xv9xciKum-mZJFWPCRh*@1JP%? z0oZyEP4V1rZUCy1ttlvybpy~tf1h!)P0SgC|GV_(RZQIeA-#|4{fGR41fcHzK(@6V zYFAq+JToGDDp%fF(-#Q3FQx7=-l0< zhfD=OoSaAn0(AW+z^{L3U3Ak&3QAfR|0#^_zAn1?1=&cu`O6*b7c|UjdBWB$$ELQQ zQE4|@5%oT>gKy<3mBv68tT(FeO-9Mcwbs-P+7GVw#y)14qbGJCfed<2!JTI<;hU8d zrfXe!C$LNARFT`Q>O*{kBwa}z^#(Ekcv zYAO7W`3F4*(g%8h5bwcvwuGx`QzG4G#1Q@i`0upHb=-g4kiS`ECdU|k*1piqt|W{9 zpXwLa&2Q+_@c%v$;GEAxMK}C^FpK|m5SfsChyE`9AKj&iw~ggeMB(9r$f5tAI=j$6 zIsahvKk-j_=)XfSJaj*KCp)iymmdG`;QcD=;vsn7%`dJTdh(CkN&R=}@&A&Y6fDm; zMi0^t;|Fbs5p-cNc&~L3E{y+T6{rrUWguwaOPbwfPySi>uY>)k@I@y}0^6Pbce6+N zH2go<=O-HAzd8l|_S*hUtev5JV1+V4?*l^$vGLs;qq;T(ui?lZ2)1k|FpCPp0(hey z$$3N}s(;`6{l^h1Gq6QCuNce%u1i@JljqoovK*IJ2ObwM1Ea6gd3$~)pZ)fK#+?q&oQgY}F!82sR}UB-_y|0j}NWJ*H)u-l0Uuq;N(l%Ph5BAcbA zj=Q@X>drs4@y(i!-UZD>4etx0$I=tZl%~4**IF?scaYQF^HZ+t)3d8-L4BxCpWY`k zI@IeSK@Q@|6RmuOh4Q;}UCf<8g!wV+b0<~p(EV>$(zSaNw;M<3EW?@QEj z`W)lMQnOdY(tMPf&`BKGF~kuZLs*xW8XvZ*AET$)s>5pQsZl9|9@G59Q^xXh=vXHh zq;B63O^;d^O;6dz4A`TpU38G$B%0zG=LWCx8p&hqrGU}$p?%mQ;MEaUIu!!d08J$t zGQ|t*ha|fs@k{P0bnbGbKsl%R1xYm0 zR}DtiOa#WOsLjp?HYwFwSuUm_p--KA5urds_Wz<{YA)lLuG&(DE2;amo7?X9M60e+ z0mjXLzTGRXaaXo)8tk@v1CJ2zXTSke!n}CZp2RsgFa`Jl_={rcF$9yfe2iR3=6?8> z$&A5F;V;YxmCUIPl@ap?aw{%B8ri5nK zW|}$dC>%u4$JyI_&sg+;zxb4+Scy$qHa@_AcmI)M0lo{lc%N1UoV4!v-=q!W?}4=1 z`^nE#ZSa{iM>tY4ImQ6U2L(Z(6!hA8XwwrA!LfMHb5}GLdN5v$7vxjSEw= zO?AZ)%0>oSZUIHKl%Z{pQ`Gy*1j$|PT1jQohGo%obs0jYPIVxNLE`;*h&8^DM~E`{ zk1*)=6`G@GZjc?r`@|(w*0>uE7t-3hcjW0aA;gZ}2Vvo-%Ib z`MQ2^mC=wW--%df=SSYOGkE6hL*5*i@>$5NR5w$;-`MAYJSG*0T|-m8al$jTo}x&0 zV{IlFM1g6z{97_Y*lL02e*j;nY{|pdG6wQl1ks;iA_(;(T`b_GjNgi;?=zHmi+Joj z3PI;IUu(shw)b$Ff5tO+B|Fib&VICk{r3C! zYR%50_W@rvYq0xLeX91tPV{BNJBg@X5+zqU_Fs|JvGUi5drv#g+%NM{JoOXJJ&!8a z)VQmXi;FHz_3ty*?cawSH#nQyTfc&m(e!1JD^5{a@Wwi+ClWL_Ne{-6+F@W6IXvzgpkwcbrPudoK9+U=AOs95ZSSb6+sU%?xS1@28%4 zdM24Kx3-bJtxff^>k*&pac{&?3;>qRJ&6zwl&{z26u{aJl_&KvpRaXFh&4 zrebYhRwlm_0ntKH$?`ohMSCA&TR~kb3I0k8U@aBaBXqlO6MbsATrj(7U9Ia~lTGDp z`6e1_c2)N~u-|F9hNV$S2J+XU=_?;(giQ@@J-_>->H3H0^h5Niz&rEbgr0Rx(z+7T zjkPH&p7Yt_QHXWWP^@a#)DZ%N6jt*%R(t=(Awwnwyv|w#Sz_xyXbU0C-r>;*Y+8Gw zca#L&4fC7@19pE25Z! zblBaxRtRYjw941Q59d)yE|=@i3ci;5nhckOtG%SyIihF&yl7G^U(1W40!ogu){9;S z@BqL6OP+=GN!hRH{LAYe6=V>K-1H#+<^q-URq(t_3=ym!WG{|K2y|BeC}|`fe@b)f zO*qElUbiSyiV_tzE0|n7HS6ii9Cu`z39xfdBR4_t#4w2bnYYD3*!L_nmj#SWwmZ&M#iQK zPl{oD7lD9Ow7*9>2ilhMX%watCjs6oiyL~5Dx#eT8Mt1lX$5Nu5{Xv7oP6bEo_UtC zqg!iBY$h&ACq@DZ`1TH`rMLBwEK@4&?uo<+%U?x%usHlMU26#mFbRt7^ZJhfiHz`hK`c9KW&l;jrQJT+1iA?*8tWwCT^ zAz3iCIn4@J?ERLNPDMg>Kx?bhaDBA(bnR4ZF8iOy={L~_%%cF#5Vc3nDFh z9Sl4yVCP%(EwI<=lTEB7UIq(~Zxs15y*D|cda^Uu6NR`4dg9+sr(l+vsYQ6bRw&eK z4(fw()=pik-yvYq7XqyhC+#9f8*ejI*l$#U^3{BxXz#0=_~xtjjiF3-((PCpfxTjA ze*{w0!iKX0gl+X&#%lKKTm8jqB52#Cp6v1~-{Tuwm$R86d9(6+g_eh#oVl{MFep5! z-ao}y^lx@|vzbx!@-_7HP2T1796WC#wy*`vm61e!`A1!LGDCY;w+=Ns8BA$_V!AY< zmjQfOH$#DPkmt*wtR%tMcgtV~Bg^|{(7M*5GIec@tEu1-3(@#7_pnRSg{Na$FM22f z<(IL8#v>m1G^IMUc$uh5ves#{IcSrZYn4A-PtyZFcP1O-#aeCYb1(aaZH&`+F`hj{BCTendFNvzM;$`>d)uYpY(tp>h5d7>wgbkPtfZg z*4-uk@S8DT$oUgw_v3iF@o{a)*x`oZU!zf%5HqRSgY%5M6>Bx_8dWwj-2rhnz5NSJ zsxyB=Nj!b)LqzuR8t)TMnVtI`6SL;D<7()$TX(-+C_S**x_jRpXokxTft|Za%VhUf zKd;W+U2`Rvb3duiy`{TU;mn8JC0BnrUbQPRfc5dXG30wLX4nTYIODZ5G9y3hmgTK@HU;{#fj zf-ryLf9S0pe*|N;mcRl<=bnF#bptb*F>FnA19g@^fH&)CIf1e1JX*qU3>(Oz*l9yc zzu=?j42p#yd}vTO+)s=NF-|6D1AZ0? z-ke>g+U#gjn~^Z-UlR>8?cLh>5M%*!TC^8IW|3T|ID*TM!hIyhed&yraL;nr5o3|vIOSMKS+mieHI(MxHx03rO zI(N0x(wzP8!znm-y~o2j`<+vD{SMdehl`NS70lW9Qxe}eceUvCz6(b=T))8eA|!!4 znEj*sd2qA6Jh0*8Ud~+;xQ@>GR+OtK2LE>yWWx;Rve7+<~Rak^8=PDgEc< z1=^;Dl4s|(UJpLiw}4Qg%HpoupK>cF4w&EDdi{HNgMjz8UJr*i6}oveys6gBufv;h zy7^6bbE9s47v4%iV~4hZPe7tc9h z6LI%`YE3SysBS$|cAWuf3zJnjEplJM$zlU#;2z9>Et(z^P+eq8ZXa(~HK@QKFMYBv z633yXS$OI`2hYpHn-Z10GQ2T(ULD?4>&-RcjluK!@a9In`AT?W@SJ2fUGU7_XW^N> ze~4b|; zW_tbr&kZQRiUjil%Ek*NjvZR+{~Qvt2z)PaGnpsstj@(_3x(@^ST?UVPB9TBtVKT$0^YO)rvfT(@jILB8}uqu=B7WeJ(1c#KT;P8zBHHNr#T zi?_r(szCw@PTA>6c(+iZLMvtn?5MmP)93!_L9s1cz0(fYNYCvEZ%=1QDgDSe&bRS& zkS+p7&KvlLUhoE+bdYfmc++lEHFmf`czFpp*?02j82m5{B`!&CEbNab{ zyN@i<&%5RVx=qSu@<1PbL+mgyO~qCGz;sUztG-!PVc*R$YL|D7)w{Lc-RF(7%lEyg zs-}r*`(5v?8zIu&4Tz2RX|yw`QjRJ`nMY9VWajJ7FV*~la9_M4n&PnX$$@djO(QRi z<2#r*IW@XJQFh%c`r~nu=yMI3@@hqoaraq&4d;i!2R49L#++_*+DG@#tm|6M&{KBD zUhjYIu)r@5|0x)#c&B_ja67c8IeeKIRM>24sunJq zMqYmj0}SLfY)dxCBDvKxEBhx^RI7?(*y@YDk6Oa~Y?_!;t%aE-(R5u!*i$aVg$xMZ z43;ovARdTCi%O{~@a6Ki3HUqB;s_Q1Ho{vB*l^RjS__;v=Maa1e^ z{2O>@^C0fc`xhS3uSGYjE#IY?uJaqyNy-q2VTouE4J*0fq-zy*N zmtf6p@WdxZN&9$uSdWs1jSlofOk|)R+5%LXiXkq_do+@`;Qnk_r8))r@;8UM#hE|#!t=pDRz{iS&`zC2 zvSDS5Xz%P9b$+`z`qVkWzn=0OYgSaen2WNM&OcvY?vYa2Y3>C*j;041a?h2Ei)30Y zr&9E(GQcD08akgZa@6copDKjKjSg1cK^&$lVo*EIs!=2o$Tc>@ZN%N`B1G4ET0J=G z&S0w;S{loGK-b_{SIiMR<21`9nVj@-cTa{{Z{iL*GzCPM%x6q`O!v9o~Ha{FLh7b$l;oxs6la#6ghqp?lj)FXwjk$610mXXw$EdFE$SVzv#-{L3K zySB9tPkSUDtaDe6!bAG-{SBksgoA*ox;T>#@bAe^mI(i5N6A&{Cc;$SawRD8ZeXjB z>kyQPvB;&6tlrB>+E^BiwEM5Hn!46cdh|NW+_9k({;SWpsK)&-HqdoUU#2uS?pcg` z2IHAEI2d!NdPVzmjk91FNm&_h)L;@vf!p9-Kyk+WQsdID@!mzn!FY8b(s=*Ccu%Zr zJz@M_zN9@SN@sdHbhNiHtBI8}J!C2ryIbtp16%NeQ2-vDs6&f=-w zako#MyJBo=eDBV&?)W~`KZ^P{bjHh<*F<)+(z@#ZJ#2;UDv^xuNiHuMn>zlOOWos( zYpY(G@_{eeUY6eg_7P|9ez7n4%LaJ~8pi%j(e}4{`kV5~$J1lLwa%ic7u4)*L#gr? zW}r^u?m`M7ormSFZ5=n5m#9^?!9CQuZ6whf-+O<<7)gd- zQ`a5?$gVwtA&o1ExgW;RuGE*Wu8XXwFaL85LsW~-+@DD{CbuO$!egse8#7|?TDPqx z*``BvPk4Q~xE9q^wN3FtN8J_v&3ss!IuUHBbB`M(os7_7ub-sPwW;1buXX#3N+k~8 zt7WlQ%fg?kzN?cApq5;u7XkOZ8p2-xSoLFJ7m+dP643gALF;L~O^k3*&lTm0X--voHDeEXa z3-gZm5>pVg79vgfCYYMOgD>xZ7=2Tu3XVh0?8$x3w1vDX(jjQS_xgD(W|N(9oW=#0 zYyO8*+u}{2yGkd??srE~<_Fe3>%+~g?^@rMX3@H_E^iUAReC==TVDfw=oWe6MJ{7$ ztRAp$@LnYZM;s@>qRgA*g;xibc;Ek`e%E`)(xF`a7MdW8NdSdMqjP<}n|N($6mOBL zAw%H&oaXhSE2*O^#0FNq?lcb)Ax|A$oxL}Et<=%u?EdA%=Xp0NeAhD7h(1T&2e?=W z;V;PCEPjd&_L_L=Ch8ekOj*P#-Ud1dPf*L}Cugg^C1~p0plYY(Iny+cRKN7ef7&Nb z%O7}boPOr8fKDvbL7=9!j`|r(PU%N-VpW)2dUXI)n4M+{@`(PNA5Wb^cRm*toBO(| z9~<=OBzkm?o>sk_pv2K*?D}=5MRquuNt!=0Pkld_$2Hk{c8>}A*f*%;WIjAR_%Kn) z^-0-Eq~Qr21gk@>_-N`4#=(9mIH_MN!}^|NJ^@o5b-cwRo00kAv{FZJ3GNf;A#XT3 zl5OBeXp%>Adh2;l@hFYsRuU(m|W!&a`aR-9(USE~7sVM{GBsitq|p;rYS z&db8Ddf0j7PhE1*{e5}&n5p1z)@!;GZQnp{tfQa4h@MAQExDZY%u^^W;SxqxA8WGT z?X*0vd-><<4lQ3Cly6u0oqhHl)IQ(mv5?~T_Td!ct8eIgJ!GRJ48k|F*CMp4c+7jzCr{>m|e9s{S zT6e3@(fWgAqC2(9(THdhgcQ8z#nq-B$5W?e9s~$~I2?L*3QzOdGw9j)X!#DMh>t4R zgG&?OuU@E6$?Xn9(UC$FA7&jXdd-I8_z;)FOd9oO1+hwDI$W` zS{NpqW53k46oa8ByaVos^qf??=8f+;^w=g39SRlN0PlYu(E$;&AnD{Ib+B>b=b(bnEt&gmfQ%v6# z60)d+gJS|Q=rJsBlMx-G?M4e(6qJa$F9q}>KnnI8u%aCny-y@szFXmtqE)+{xhDYF zY=#$n#&^Uco8sxh9MAT{TwxyHDGZqja?~!IU=57btq_8gkOSJ04 z#6Z?3$lVjAtJQ7T9gX}YM)ri}KhS@Bp9kMRH*WLEbExM!ueB;|wvI?`G({0VLC zgZ(p>>;&qMQgAe8e|;CzR;iz0{MmDeK6l?jsov8YRw+V~n`EcuMB4Jdz@ILfXCVC| zES^6Fs|W0t&|*i{IBs7(y3hL7L}LXtO{Jy#{Ud>Hh@b9DsA~LLV-5%O9)M2oJxxsd z+~W>2m0#U=p|5As7%IOB{doOW@cI+3A-|{SwZm)wz_@%GoZ}}s$4j;$vKCGCjxN8* z1SFWc$P!1=u8pUQB%mn2qsW3;?Z)g$p2hlNDro<6g<01 z)neJZ5?_xfWc0has+U~UxxE-Vu&-pr)a>4 z9*OE%zZub!4WE5NSwX8ZjqgM!(q5d#T770NrmC;qn?uHsP?mX1jeov+syr4y4^`CsCBZvN_>MK52RzVjHU z)vhV$L)nQru|0ES?mhZZUcEG>B;YD}8=iH-39Yxl_`>7k^k+pS^ zb^iH=^3_^heaVQLj`!XV`I%Bf%}1f{&Jf+A3GnJWUaX!{7Ijxhkwv}uA;4+X4lllQ zW9{&95$7Jw140E1MpjQ<$KlWa(1??LkEx$YBr8`UJdQJkbWpo1l8Rz)(C2yqpFwes zYbCaONJLTWW2it7%5LA$0fG|MwqBe4`1O+9$7TAsgs$tQRq@X@yjr5N;NV%{@5rs^ z;2wAO?D{U>RugISYplnV$Et@h>d~1zl9i3T1>pC(&VO?@OOS6o^tV`{ca{#*Xi5$e z^^0&pFRL~uDnTL9J%nqA$a|Nc2H8k1DUq1)EgM7Jy%F&W5z3Swd>j&}aqu74ikpKv z5KfBgYK4J{Qa|=rw#g9r1jC>Ep$WVw=7%j)q~KYx!JxgVE{qgtd=n|7bAK8m299{F zm^(|$oaXQG9SicohqWM&ZqW}ULF@K5t|1BidpL_maNlc+-iZ{j>K_qism5q}NIWdp z)9Arw-ncCBUY}R-^pIotVezxlha$ik(nC+V?m)M(11AWr;nCtRGeB7d=X(2DO`_21iS}6WQAlB z#uNUh3hNp9ojUUqrGrMb4mH%PR+PBts17W=L>rvumxVz&`f&5CA9c}(j?9}{ui5rs z%)7UTfbk81CfDAr+4kf?`e|)uzROZ(e&QVCOJb>+MX~c|7DMS(3raiH6h)UH?5@_x zDxx@3XeD`Pe>~bI01y0weyqMY9T)xBKIOtXXA$hkj)Uk2EC}nI zO*OmDS>w+9!F5&Z?%e3yBmXVdIIvtj^{>#7+Q>_O4_jo-nuhLlB${oZI~{@F&DI~% z5odmJUDc{P-y%R@qz1w7J?&JNB`2%Zj+A$boL8MC2@;6Br8Tn=-;(CR^=~_ z#4RWVi+f14vtS0=Ls&j}C?D-wsD!^ME(@ zB#JyrMY;W}W`b-sV(x*Qm~GBx!OO_(^$QN$LR7g%qDC8h&~o4>R#H0x}Ff8E-H5-aeW392l39Re5h|hrY@u}buv8s z3Z<29J~nY#ylN7WpPFYHxjgzU%?NZ+von`#sGBbTg-auu(7&JCq%AjcIh_`$1NwJU zSRx>n4z$U|5UbZI!Q<0W8}!-}&U}T)W23;C9&(pe){Q)hPe7H++;Gkcr@q(pi=Fu# zZ6?;XfHK~J4aQ%HdJKbBohU+DA@WfaowHv?1kT;((>MC8m!hB+M3qR;fBZb$XVr&| zzwmb)v|h3}g=MM;Ye=Hl2@R#_f35+L>)x$dyzO+e5S6KH;El?*qYXe*Fu9P8aYO98=Rx?K zzf1o{&`uuxd#yI|qR+8|s)PP@!Q*TzDIFc45ERk_0dU3^Du0Kqad;CBayjnZ$V z-W*@n2li|C6w%Y5$4*FZLcZ)Dpr^7+%cG|+`rn62b@exJH8`}tuYd55_V-TuE4s-r z_rv9x7|HvjAJntIa3-XWoskZIP#%5kgwNuU^bf`#NuqAwdu{qOP@q8DyPiL)=QD!& zWREAG~x9!eU&nj?)BnO>rcmxYU?pmBTG@LLT!!43;k52K&MVKDdA&7Xz2 zB8k7PN$%_I+%u|H=g&JCKl2SUw>*gATy50wozLlIbE$|`j`%m84&gWQ=62>0{zHH` zA48Q)vv=YU$mKLz>Du4&_)!jzb2b+V>mZWD4x*5qG+Nna40wav2U*^TGZTeKVlGol zv1oc~gaafpMO*Exmso+9WW?&PKF#&lY5AU{lyjB_&8*AobM~Czz8XzWi72Tk_Tty6 z4&!1+lxd&FdH@#e8HlFo9|?9!V?~%riUySh>}n<3UfzH2*Om#OVjR2=SM=4hiw~TxJRJmsKPZ5aI^WtYC*7aCTTGVtnfZSyKGTzZt_? zK?jSW#?NyrWHV}f8#oBkm069!etdJ5S-paHMvb-B>oq=%anJbp$JA!_BpmOWW*+D@ zeJm2F12NHOY@jhMQ3OZLN*ux$hw)UV$x8vjDy-()kpA}6RM|X92K?qGO#B4G8nz|T z{dm>KjX(F-=GL3&X_1)JE^=Cwc|8w*c%|kpp}9-K<}~G>-rTonPAz5b&(gc_lfT&~ z^yFgL=}vmeWFK$6)xs^y@A4O@gBkWO2SA*sXrHF*!+O#OHLY(;^1t2UBc+j@2*f0y zw>3?BFLdtig%uMuQ2h8uBZ)hL&Lg-@%CwmCR;0ESMIem^=AyMcOq~;5y(QXnYO()V z0Icl(l6&5hcF=d^?!Oh@+bH>%Rd&2pa4avf{gF8fl0CION^N7(lbPFn-#I7XiuYvt z&CBjLFe_PpIFH|+H6y#%Y=}o}uNiA(GVi<|>3sIAle2rmtJ=$o z!uk=6LzMTxwC3n`K&Rj55v#LUt1`4kd#qGedE!0CdEYx`{{fx6%_<$Fxx8JaQiDItG5>Hc6{iHNV$b;#f5){`&;vo`U#QzMy6vhW^J*f>15X2ya^ ztS4JDqO-z-ZSe?#v91;K>-Y0kOuXuY#Cd@Tcv%E`_`3j|evSoD7dqXTMW?A#ah44+ zDYH~;aG`TgC)h(-km6D>jUj@77k>Kcsi0~9(LJJxIi#{6=2@JXdZgjY16}Vk&mw@^ zu)nC_sV|D~rq6wBCy{v5Ba3GsPHa0GPr$m`TdxObM^%`znxsW8Pku> z32lB|dmY&PdR*5$E$PF;e9PZktVm$_dn?yD%ipM#4@`gSifht|p$N$83Z6PcQ;!66 z9JnQ0&`0l)nQA?zse#$A?&Fc|IZIXD>&7fqe;wYKrRs0O8?#jXU3g=bs(%b`%u;nh zcw?5TPuWd#X%oFr>)CsmVddXH)a_ntBKJOP`P)PGzAu}-FZNEGPX5M@N#)zzE$*vC z`i-=uXGCPaiV9-{DvTp)KqtuU<{qtuM+9cp)7wJR>$??4C@G6yGap??TX~!G?OJnL zi{G4ha*4R}WJeE!C(Mmk0RE_lSEmn#r|$FNsrwu}uL*Aqp4W#r)vD$z;f=v_Qh0Nt z-h3^*F?il$H(l_|-e=*Nz0blkd!L1;-G}gOn0K(rqHN1edB>x`pROQ zuiPsO{69e378dbb&uX3)PU<;y?#H|dpcBbKXX8;UEU*kn_&=c1nx{d}0@MFv|NCgo z({LPt;Q_Zlu6dgES>TVRB5wv?X6aKd+Huc3PEDHPzslk}5wLaAhAnsIieZ%RLd!F}L8ee2*%eKl9bP@Hl0lq0&nN0}kge;{Wh&^?Y3?hF)mZ6#Q)m7vW`G{UwbZ@L}X zA`I=t+mQG)u8yWJmBYA`YzD>5P;Dm{*lo2t^M_ZrULarb7Mx@t`L}mw9;5zeH?TYM zZ*~;DWN;){#X2^A9>2-lxy;>Vd=V^N2~^o>o})pgaoR(LA%nZmh5L|f=PIzalcgP- z=Ed}RF}!wXq8^*NZP--N=V)i#mD{5F`|U__f6>$#)jK<|cDhlW-I-X5K&z;(wTOp3 z5(`|V{D@cVZ>V$moB2i1kMa-dBU@#?QJiP4=?$^2qwsWx@;|JV%nss_Z82jHlUeP3 zzWpUOXG`i`GGJ`S^s5LvDgMOMmtzYgBdJxjk&gQECCT?X>83OHR3K&NaUQU1)uCU; zGU}34;bGX7^{c_kGqfw)Z)jc(oQFr<3*47bMH9q7VbP?Lz$E6lKvIc$Hw zmwyfgQp53)zaWJnmV4*ndo|(yLeRf9RpjohbBk(I@ru0y>0TdA8^HsJ9nep)0}e;R zM%nLa&1JQjn0hX!4K(wdZe_{gF85!uMLDu!GF#or13?*Vl=cn4jJ0KF;{Y(-t1jq8 zJmn*VOn5P&{A_=(mv;vxGd}tuZ@b>WBY)>ek-4lrjvU(31D@EzmKtj4zO>c0)aGx| z&aL>`&dakvFnRy~b@m7MLSSH=QBwa;*&i$eX8#@ggBR@k&}x9y2E+J&Zh!DNmHa>Z zga3Q%5B3aWL1kAg^c=0j|Fb_xNgNm0A1oxoOH}uPk;#8yfAARQd;fp!5ANCw`3mh1 z{&ka)uVr6{eEp^`JxC9D&F`XacLc8=(d&D8?O(5UbNUf+B}U(3?yIt|`UpcdvqHe) z>pb>Hqz_fv&Iw4+EOX2_)>U|sMco%<+EV_iZC38K;K1V&aiXv^G^|KX6r|Uge~yu~Z8?*wy|4js_iwm4m+!-E!D*J=l4xJn zq>5G=VQWT|*H?X<_(FX-0c5twglRCgRI-c0SmI;v0_v72)L4zUf=MeB0kcjjwsLCPRZU(UNRQ90n4f5&2s7(aX8*5>`*%i zPLIiy(_-=^eB7gG4_d!#U-gVeJ}_GsAVHV_0Yk>T-E7ix^CNpHGx@S&m`i2lV8SyA z=w-mdo~?Ks>HdA9Qfh7!>xBJJdT1XR+rF6ir>^pJtEM@_0 zq$FFyBS%b*+^${_0?7_4*!Sfsi&GLq(J+z{tC+ct2^)zT(b_Ic!Gj1;vHvVwg7}v7 z?U8zSJLX{N+K~nI<-|7VNE~DGrGW+c)^|cNpbmrV5yY(VHnq?y#|}jdA=e0YP|?1q zRF8_eD*_1Cmv4wwJ)bzn_(GvxAs(25xeTeWx7_2eFy5(&O5n?x>4$W|p{vr8uRT40;}#F>6H;Q_#k zPa=(90BD7!t$i}5i{7zV&4krELd1&my{6x0#H|C#%|7~`e!@P@61nS?@U5eeNN35V zytm`5k_Bevbtgnuqo&_-wiuQMM6{;CsBd}K3BzcOeDa;50`GKc^jA_SpSuHZMD4sm zhLB(%#I+1yR&jyL^Wu+5t+x`b~)nqsU6my=vmte1}sJkzN+y}bdGWo4ElpO z69G_PqlY{M4f=rLUG~dl?%QrofzJFd*0?)rWOmoQ02o%U+EVSz-)ZK8B8pp^@yI%e>r@nQ?TSo-lK%|E)%_A*Yub&R zwAwx&-!CGv@_f*@Xip$kwRp-4hTj}IfHSWCZP!@*q@aw`{0d4gHM%jHnoyjlkBg-$ z5rz77Krr~ec}?T_u~dwSIJfvN6sSjq=QcqL8%0`5oaW500-`;zk-A{iu;Y6tHfCD0 z@QbBmkxZV2b)f3^6|4*!@M^`Y%G${d_I?ZgODifI48?xR=OSB21BQ%)Tl$G+agNu@ zS?v>JMqXue?_oSn^Wl1zz9SOFf+q5sGryn}FE*EYV_|dGTi)Iz}b2kYLiK&4$Why zaz=slA9wS-t1oO)I@XOM0ttnz!&G-wSAig{Yi=H@=vn|~1t1CYj7C!qGj?&husk|4 zP<*$ZB`D%GiZr74sQyF|CLLY-%QZ3P{)aFmi^qv>Y6rPxvU!&D;g zG->ppcZzVP2tL*Twj6y0Hg0?J?MUK84TFfVZzPJGMPnqBzO{1YHSP*!oekPQ5qg)v zNpp5F#ygljZA8i?Q_i?E=ADbvLr;xX?Z=cmeMKZ*zOnJfc=+oW+&gQC@UIhLw^PhS9P0JfIDhTI-K>iIYY*W8ZbUU-0@pwzvES&j>$;#iM z|Frc&<_By&@4nr&w{)(zt>^PMu($L-uyl(SwjnO`He)6k#+P8d*ymp{gBIoXkL$ zYLAG~ogGtI+dTm2W_Lx`dW$N-(F9iSmdpyHFFEoewy!6CaFN9MHA2-ZA{cdI6-olt z#ZyZvSITC9^$^ythuQk8UYLT{mi%Lv%nQPY6~|V4nWa`9%q?Q(>BmpQGI$c_56YIZ#!w9^ec9qD|QwD+WC^8+3(#JqF2$^^{KPcKo z?Xf2#?;eoD(ZA4cWm~mUtIpwFmTnuL<0Pxjp!G;cCbT<%_aQME&%}zSFaBxM?qjDN zmE2U)wCBRv%*!QlcLizQiWQ9} znzG`?h7E1SAX)uOvm-`bd!dbSi43q!i8r-BIjCWL^ljr(?dMBax|*Y>nrM(EpB}mK zUD%8JdeBqNukjNT=)G|T4fBi^!Vo=cophQDY=r-!ufay>)|o*!;XGo_{EOKS7Hbim zB@ZE-GF6%>H(o=zlIdCxy5=-*lF4Z5a{AVfuB}!fixg{x{O5Taz#(iu9JS_smA)ha z3ul(u)2BsKVPE2Xm>D|MI5KELM$^f)xmJeuW6nfJw1xBLX}wX;BJ3s@tpOX2DJ0WX z?NiUftP-d)98LCe>)=i~E~&6V57<2dYepcg2@#mHThwRhtxW?3fk<&Q=>?_);p}MD z=Peh}(=23h5)=GuCPYCBooV;873oY11mq85$2c?&h#j@sb9qsD^k;XQL))!#N3Mlt`-{$^(0SyBew|DH|jI8`h#pN6q^M0 znZxZaZ}q-?Nc&k0i^VF_&_ys^Q}OQITQs$-X6Mqv#<6uIGlYNW-P(iu9^xHTFm+63 zPL@8vih%#OgJA?~b$eW#sy(IiVz>4rMQ$Y?U2SAz`=*}m>JOt2XBMY=yFErx0599x zllEqQk1KlZDRM=xJ!yaDKfF16_F=!CwU3UbPd~=^fIOJj;=0ym(I?;35EV&ump0JC z*fXpc{kt%pKKI|Rfo;Tjwuv(E8&k73XxjA8(3s8YV_!hgr1!3A>O9kF7Sy=977W)_ zx_bSH>!!6q?p8cm$OE%TL5z^@bwBl+Ei~s`G}(m}6%_^EP;$Ddt;#jF%hfErR*lo* zpZ4ywCk5jnDPnSi_3D!M{jGg4zu4!rh*`DMOWvH$Qgz1bWuu^h zuI#tj`dIGMYQmhdSi`LMMpK)A1T_WgIKSMnRt^UHjxVDqr|ck={TsW=!L2s-XNi68 zDt6uX7=-sWLk#C91`}q1pR_g}rE7VU6qqQ9w4p(TyDDLilW(%gZGhKcii4he6d!Eb z2{on=t6U=!9!_=xGGC&(K_3)m zrw{dVS@&Wx5bis9p~;^jWoFz(43(UbZY)47i?Zeyhe2tme4IZK4!%( z&2$Gz&QM_QAulg?sbmtfVt2@0EQl z+LVtQjTu(<7!~MG0hC?-s8d-upI~v_ZGXJdnZME`x~RwGcfu&70Ymf{hT!QKU0mS( zNb(}>=7=)jG2CVTaO$)Dl%;2Ts0oE{JZQyTO<2(Ry+-v@a&)J8F(9?LQz94DiYbLm zXp%;bJa+xUGkI;K)qGqh0Z>6x^FY9Ea0IuDZnoN9fqDg|RdBWn!r+g5v+rRA-i(g~ z53C7cXMVUOijU*r0#CK!*&Rm6!NEA`wC#C-e-rIF>B#dI*jvJaHuMu#M38# zn>K79kbN7Ax0P?jI+=Dhm}c{|4!c}*7WH_ecB)rqr3!6h)NEyEQk4uK)_zmLxA4xy zsldV#-q!179yv!;7wh$F!S#t6MTH6t>nLPa3YH@DN+12Z1O50Iv+$9Zo>f$%!#@03TH*aINE6`jxORcxP$({&ikjA3ZWz_F7TG`7BFNj zu{AMQP=PUm1l`CC`LfwGz7Y@n2jrngs)@#bR%5Eu=z`nRu(d&noU5&PHDkD_IP;44 z69|NsM@y-e2m5ybEu1#HgNhKOBKwcoya+3_A+T5XG&G@aF7`O;S=LNA=;PDjTJM4v z?$XJn$n&%^y&=~A68~)4xAR8GZyBTOzM$<~Ybpv;sVwHTEG@*#=rsb0#N(^=n#Y5= zzL{(KJ@Di*pcZw1XyB_{Q(NUb>1Ra%7PM(?VwrO9&mb+)iS6|h(fGi&eH2fR=sh+) z^q6`KLZF0$>gBU6`3*Z-wf~5w#^A$w(7Agd#~5e+;`;Q6NWJ1rPvkzXklpLO=dmug z@2RJGO=2?jO#MdFo@b|ZkUstN0$i`z=qP~M$;J!YHx@-!SH0leGmD2+_{%%@9t*F) zNMzW7S5k7%B*+T+zn7N4(@Vni6FLl5 zTLKAF6iEuyk8>ljwaPu0a}25$nEJ2xNSqj}+TzSzdy;iaW4{b#4-h7Zc4SpUP_(!p zQ5s9v6k5>h6}V1Ntfq&`qVi!g3CnWRY%tF)j>fOS_-h8U1SuQGE3hktH31*lmM&z9 z5%?j8yf7>00-BoX5-+x%{fHiw_-7mPHZeBI_4r2R#j#|b^IqNpH;DWxOW%{5Cm)2u zH-qsKh!a$S*zk!V&@V{6k^Csc z(0!lH($N|<(^2o|Z;4^LQigm8JhTuZtC@+GUsGeiUdTKbe@fB1tKN~Uk3yQOU#d+H zF$ONG)`?c@gfoAQYR9LS3L=Z6ikq!}v!iK_)!^`4J58r+ODm(v-GiLFe+PSo6t-Kv zg3%Esl#KVXcNJ>0G214)d|_p{J8bn9VO|wtko;x>F%c&Y#-eKNQ^}tLf@z;Z6I%HS zIdEXtZRI5OH8GeyzKSnCbZ+Y@o4aw%h*8Ig5mazMwwG!)jCg5<-a$ZXOK*(2iXg)F z=Nxg^PL1Db{tgvzStXY-!tmrv$BCkBP!QDTDk)n;R4?VD)bpep%#4yrA`;#;J- zacLQ)yCqQcYG2U3jIm%F4O|6MfjAmj39@o+FdkoeBaA4vRe0m}T_HDyYQY=mUqN7D zric^^0pMHiwl>Ts4i^mB=rt$w$TG0p!j<>et@{oHQ`2%2_w%%amk8e#LXp1YN{>d);w3Ggb|AMNmHf}mEx&=t5DV9`Mo zZ$_7gjA`M9t3^9Do~kQ4Y2jar7D+VVodf+e^7vKjn9jLDiG()W_1?ti0SMtC8)|kU za7Q6SF#sgJPb_&8Pv!#vllcb)niaO;!y4zdIwYNgrMph15o#MkLhZ#?rWSQ z>b2ap^53MAu)!bG%h;Tm1qW!@xhth{L;G%I0&nB$o2BD41>>R%zx9<{Zz@ULcAIW* zj4r&bubYHbo(_C)Tlv;Id^I0x)V;ZQ<$85obEhKLEgV>eK=KB@cwE0M+{GKzO1*D=I>G?D1lbpDx*TdBLwlvI*G8J#D3O)q2u zf5DVQmHg{p#3bi?(j-qOC%1qpcu!U5MN*pNA%hURH}<2GmtFEugNwMKESTF#NrCY-Byqr7kij zPl7Hw$6X$shSQBm zUSCE;Kl~fiqx68mFF?maKaO{o8Xb#X1Rd*qM`TVbQVSG$1FNp=SRf~nLK&wBTdCgL z?^6sEEz^s<;(SYS;;d6tQG?Tn|aOF_jj;p1*8IPio=g*6kryU=dy^mK5Z4@Y@E^0It*w{2uO z{*sP%@eegu+8`u-ekE&JM5s$tr!p=|+`K9iPk$?daZx;yiI-=rlePlh^1gx%LNr~E zJ6D0JZ0b?fztK3hLm32lGBMOr+rnEX1+|^~wt6eyw9bO$W;=ulfbl0M#8cmb-^|cZ z=DsfeN(M*>tX}f^fnptngROGnNuxlY{zcLHF6DXVLG)EEZ+z!2*7iq>yY$^f?Y6eh zsb*~-zX8an2h_Fk`Yo-w^tnFQ2y+JN^}h81W*r-1&?((8DA120lu>xTE--yvU}^}! z^bVT$d@v0^>C?b8CJUx(4*?V4HF>C4@HStD23FbqA({eC4FR0q$^39$V4x-VYU1@yna)!S$QXN+z#a(iVq?E zp5?1k@(O7Kkm{uhLor6J#Te}h^x(`tyvAK2Qjdvf}Gaf2;C*KWvnT5W|fP$!1$DC&|sK-OD1{9!ll9Zd}^ z4NiQKRZ-HHCI3hXXa04TJ@`?s12HL5<-rOT%L(_Jr6sbNbM7{I8a8uI%S4a`bc<-S zl=6qtgp3``h6}?LJ0IyPhLna-S3%hb+K$9Sd7zqy>mh1E9#ll76Eu?NUPK^Qe2(5R}=ecp7>eFZ**Ebw?iDiFvm_{Oyum^f9(@H8H z3-LSOX3mU=viZPAatw*W2fBYreo{2`tmHd|PRkboCIXhjQOULzo6nG)Nn!8UkNC(R zKnyXwPfh*OH5g{u{@F z)$Kn_=`j6KRwIMCAZqkVSQ}uhGxuV69zVgKF8UfJGG_Zb_|L5OzRo--tT`3-FI8@w zHYAs%1#GJ)L)-NFa?D#VD<<+^<^<8hPxS-CXam2h?tWm;<@m>i%3f*ha=)QJV-iM~$j`~7-a{}dmnr}_90XQyBA(7W-CfS7%2 zNWezuH>WR0>i(eu<&b|*=~IxeVcLks zo+Oo6eXfleCGy;_e6NzrS;Bz&au~=Nydjzt#ckY(qSCofl1h zP*P8V;S@e@tl^?qKgv_Y8}cCNw>2V)W1NL)d43H-P# zFm9N$G7E%T>u6We}x|}&J z#1D<&hc<#AE-rbwaapWtv4Za(^a*<`p47x1B7kM$tU!KXM$EV&N=#3J4lYDOj?uQ1 zT&Bj!`%OwdqMhIeK&-Juz;hQVal*DYMF?4dtUFaqXnf)=V-$TzeH|)k^?hLV1;#H_ z1_@CP3-4hou=M6GO_d3Ts{!+$ofaLC4c?M$+Y<@U{2_u07Rso?2(B$PW#t=wPkZ=! z<40YC{}Z4jz!E_7h521CD&Gj6zQfaccbEStzuJx8I8J=7t;bM)Y|(?0n?FTANGMAP zx?0f5bSA&S)`-D_(=0KfgeWa1bI}2BWe^7MDv*EHv8y8LWF^=!Cy;iS;1f}&yuYaz zu}2B@m_`Xm!v^HE=cj@BY*shs*uI+UWltEGcF}s{UDD|&(RhpOheO^P>5Ft+PP5{R zukr#eYaJ1%x^Y>r4A#=@#*8{Gk`srV7RK7#9LzBW-EFyyImpp1=#0>&%;bOP@g_LW zN_+1828v;(w>kbIrZjQ8ypMNMPSTKgs+8;&(2IE0JBd*m-_#AMD?AAvzWs{o%D|)t zAqU|gFmuSyGjl1`^IhX}nE_dT4-EMdzvrDs8P=yJC+z*z!UBL@VsixH zutT<{quR{*c~z!ef1C{WRnX>)X=L$;8So|A%(f>DoIl+jG%*X%p*()mmpnCGhuEQh z6yVjeq3egXN8ZaZO;V{xS!?6^ty8Lk&_D zW!0(I1`C4Y*^#D8Xe7&!1rcd!Yy5J6mNhPWV=DM855EFk&mP4piF)F$Kk1w6B0fyyE1kplJHx6lr%8RUR1W>h*V^(ZRccX$Z=Dv)_r`FVRKnb$;(g(8g9qV;M+-#M z^!gLk(8MBA`UY)Qc)Mg-5B9SQB5+Y`yPMIE8jGxe-h4P%W}5B$;e)_rp)+IvU6R?Q z{ESxhbqTy;y}Mtjq&Y7e@7cbGF9zc4_066e2(xzSl}HYDZ``0Bvmb2nlJ9B^>{bf& zs$Dmh+`@jcY|4EBT~)T{9K@Oxzgi)pizOizF8t8I3xWKeK~ca{fP@$ej8)cbZ=Ley z(ua5mONBEUH%;8w$`u0BKz=`J5KcuR=rPCBsc69MWczPf~;iG z)E`SFA2vF2icbs zeHx2wu{SV>1c=}04~9}^=}Dex-bYu)+BaV)J{DGOFLI=Jp?n+Y&Oww<#(5YQ?s_BY zM8U03h%%iHP89?4|Tg2rsUq|5+w?T zjJb#4u7hun>47A{+1Nu7o+;>lh$t-5#-X<`qQEpYts{n}8xJHu z=t1=Rq1b?07RtxCuo=6%57U=iQc=@-yzN$+>b%_w7&9|VH}DjJMpn(UL?BO352Dh* zwiv`4UbF*YuSJN*1^FzTb)SQCdw5f#VJ;1C49?5Ln`*szF1#@~zYyNss5h&^8-w%9 zcGCst?0pu_+53m+zCO<0XW?x3d2o)rfrjsRz;^ucq*p7A`0t6AnP;O-jO>+l#pX9RM{x!S~AQnWb$wF*s_Im|kRDivL8nbcszrY8I z6T`ip`p0qat$jXAr&yvMkKNVDEfEbXUf1{2)@ybGM)Ep00oCD+O~B~z#wOsR@Wv(} z7T(wdsD4#o6L4vGV-s+>-E>Vr_C7lS+53m+u6mli&rX2dhZB(8GjZA&qr>iVc+P!& zjUp~7-cs#17Eh`zZ$qr$u6B1s+G>&X2($6*?BBn(wf~^>RR@w=2)Hz;W=^MJ_o8%7 zMRIrFX~mJ1M5b5S)-n3&uXHHga;?Jm%vmaMF7Xn`Cd_^^G_y|K1{pn(jSug~&)grM zh0tiM?-8%(lEL>h5h*+M4ICHFV$lc5_6Rw& z%4zN?9?~TRjI;^y@=fTho#uN)D%1UO`zLb#+YAVEC_>(YKnqK_tNZ{XyvTF)DR?4O zR7A*usfnjA=FHH~vg%FadqVJpN%cm-k=#xgoI{f8k%=QXyTu7fly0OL$vu!juE=~o zyT3$TQd(ZX_tYK6`bl;GpjC;PiuDsujYZniBbu7E4ZpX>)v@$w~mJ^~#aRK#h=9k(1@+21$}DPg+s|q^nDO$q}>V zlWlNoZzZP3%RiK_M>Mh|l%rJ;iz(_(roY5#rxa2R`nxVc>hvkw5M|QmQShk4usBzL zC+Ei}`j}pa@rnA?wmSLoiO$~NQ0vCe%f=^SL(lRVi9sYCpgFqTA930iZw9nL@dskA z6LW6>@VCKJ92AwFMTVddro!HN1QFP(#wl4ObQ8dRN~@$#1<`(x#Mvf+u!007rY zOZQ1~IfAp&<1Teek0lks7K`-UfWO<}7VKy@!Hy2k20OZ#`gW*3gpReuTqs|RP)^e{ zcLvmoYgE*A?vffp9c8Pmsp_1v+5eJgX0Tq8ZNw$Iiu+HAOY}mt{cpYe(Y(YT^Wgk; zn?YC0Z}%PO9y|&BRc-6##X)|%oAj((e!I(f#(6i)Z+AKA;||JiN8F~*%x`xLpW2}a zT|;L~Y(`-zBdc{6Yh;Mjh$&EbB#TDb?R;_1cndt|uZM4~P4y!TmFo~R>Fm9l=e_>Z z)K;51+@*(#rF4N}DGejH-PlflJ72i?AT5YrU{R}vkqMH=uk*Mo<=y4Qc`5Ji;8o6q zpI}SvBnVtVx;u_LFIcp4c+%ykz>_}x9Kt_mYw`4emWR6--ttF`g<~#YZla z6=By0l%GAgppobrm&%b=OL_%}TFtSeuS_bpHB^1OsBwp$2J;$EU0UQU=%`#1+qGT3 z=BfTg-}q-X2lV%UC%;wg3f7#g0&+(Gl6F`ygZ7nLjuO5g`#U7R)p(1?NDzV@Rty{G zqZdwr;HIi8pmL2)H+@{Sv*=@l`y%@XHduUy|DEwoTK<{ids{>Q%<*OY!K9_*h$!a} z8M-|vW>5!O2FhVwCmPwB-V{D&qnbRJKwnOCB~R*8v$)}_-rU4eH()DA);Vqb@zg}# zyqlP${E0mNATbMp6c^a_{m$Os!ut;r<(Q?=44QrK7HAm665pQUMP(H6V%C3NQLyo~ zc*AyAEK#mWM8fKj?!1WIwR_4e1&BX@Y(V>TD`Jc-6E(_2=On( zj6!ris6vXeRrdCc#5ou)`6u&Ma&W|H_PHs&)!$#K6z4(>D)A86&&-P^mbyM$(Jt@q zup&tPTjq{pQih-!8uY#vzV9ayNs*;sQi-r3m8i=vQS5(JbT)ZVK$m&J_;Q+8<0-1) zDWZfjtj;^)VM-|HF^MG8lbBz`zk>m@ojj!0K^_a6p}AmtB*)xLS;?J?+UPl;^^~3CyK%Hk9Z1*9q=x>7{?wBCg%rIVj}vf9ReGj$(=wN zzsQiPbLWm=Jb^zYRlo1eSsDNu`XaofgC+irYU0s$UT}cEr_cTa3_Cq!!8+t-5Jp63 z4{(VSzBX9ClZ}2*FZl!Js8o8$clCof_E&TW61Fy)#>5g~7IAK0=vT13*SC0Y@JWyS zX^X(rYqGvr-s`&T3%6H8@ML26#G3}$Rh?hdZ?0w0JL}(TujTspG?$;zzn`g8ddRQz zLtXt2>EAHx-#xq!`!}1=FZ6GozF6LCX7+{K>#pEQGJN8#6)36mNBTXqf4kP^`uA5Z zKcj!`DwQ7coPMb57RGuo{O*5V@cRw#!~UH`-bMQNxV~84>nGV4Zm&mzCqECLcwY?r zw{yv-_HU4i2lM;UtDo7wzwnCwZPE|@dyYB}?qBDh)xQ^cANKFrIo7{b`eJ#nXR9s+&)mafLbu*Gr}zrYQ^7$r6)4H*RUD zJ^w2wIse?2_a?-1idGUUM($JiX3wi!*^r!lNb&tr#$a znr58cvvGSvazo6y zr;g+FcAf}E>&2+QRyDrfP~&_H*Ng?171g9-g`5^wG&tX0Rn*YFxQL7GMb63^SI;x; z4K?m%MeQ4l`C=CAMp57A+;KgY2&x=LV2U1i$UM}aSPY+I>&voFDzm4v;A6v)1*l6d zq4X-mCll8YCDoam>WRb+{|slrt2iDI)j87P{Rtw{5IHRXphXd|`bPxyUzx4nSwJ}U zag1sL+_7u*5S=1Las#(_L$XiNq5kjcX{WQ`Lf{i!-dmU!2P{}<$C+#Los)9gN$OAv z_d9S{t^8ix-OhrYvG$FSJ;b`OShc{Cq1>sHk%mtW1BqCqc&v_elf8D`+DR%Li|KG{)0Y*hrpWGC``c88$)8mQE#5!%3acpnZNj6zM0L*{Qqj~=R!OqG zH+4`bEMW7>(W$CqYK$rhD-@iEBOZtb*!E~|8QJ@%#9a6s5RJQ-oV>`Bj~=vn8epWF z>=T;14Z*YBWb45Ood+)k4?G^^&X-!|3(gZ88pny&@XCpUQ`Z4ijexV<4gq6Y4~7pc z;#DiBf-Lj<_p42h>PgQ5UO{BH`;xtTaq7u>cXo1dA!BZ9aEl|m0Sy)xQ-_RZFgA?H z3X<2UgBJ$}ydV(p%9dv zg<%7f!#ygrLh@ovgcO<~xCfdUXX7kry_C4=k;nen2-Vq;gG1_UoM6R7BzN3z#SXJ# z-^ zvenF-Qp4Px)Rd~N*h@Qm!}uw2151E4i7M|u$r&K}Bv^%rnaMICbAAL9^1#CG1$a%k zBg5PqC_#9m8I;NL8=TLGq(CSD<2yzdHo&f50%nZv;Vd|ebffNbwN>qjD(Bw2_pq)M zrpf#j2_ZXir&yv3ods+?9aE$A6Wg>gW9}a--&VQP`~R4G8}O=%YyUq75(tRyL{U?v z8f~l zUIN;xp!Kb`f>dQ6qXn(7@l zx}A3E(1LZ8n`YFT+t|MbS%3hy#vz#%gt`_Oz}CaS?TbbB#S6Sho=MBdx~(Fw;C{P> z7yUzn)7Hjk0Patqr}%i(&Rx}5496$r<8h~l2(p!HXCmOgIx`~Z1Y`=pegK#efK&C$ z9&7bjL(0IL22%6>C=1hR0x~iBAe$OaDqG)}yo6ECnvX`gk(D8J{||pRpk6Admfia~ zw;xC+#EF;;qtKJ@)>>QSEE$(8GZB3CuVj7|459yx)txKz5#`>|K;4XN^Mu}FGUENc zdl>tXs^;C#+;pDIZTsObP}7QA9ivL(IrgC1TaS-nf71=-n$|bv3F`%OET;nNcxwt^ z`4@`kL@M8%d6de^QCzyX|7&t}|IxG>$UzqjfLq*{zf{8m7$nXfY<4!CUF>i=nT{w& zw}vFOhMtQ|-Plx;M6VFY4}zDA+@|Py|Lhb98F;I`u1NopCH^-o%%=+G=ay-J1oKx@ z1$2O-H?{F{lRejDUvet18i4}<{Ew#h>K{RHn;u|*OH&#cUGQs9p~+uC?(QF;K22VO zw+$8>OMiiV>{3R#Cm2E)0Lmacjza)L<5+AoiwutjvNSc2MRp*I_ZrA6xDaYkD&egF zw_nGm+Ozn1&v4uI{)s^sN@WvSkU%;47!v_QP3n;b7BpV`qmMG7TTY#Y!An!|*YormoRxPSasYg^Ld8%(>�IvJg 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 z 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%0DBu&GtP4{jY>c%& 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 z

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%0D&WeQ^fC8q#*5Fkv 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

c4KH%8>P~Kh8FS>6= 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 T@ilqGeSOva<0uy$|!=le8atAEph;3gBKq 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�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

0hS(StHZs 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

Alp-=(3uTp*j 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 pS9>%OCu@BO^OL>vs{%C9 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%0AjP!z~S;c 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�)n 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

>o8 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%0Db9$Us~`@ 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

DFP_Y7v@=%&c zMW|Xt^>5iAtz42j|AUCEDT`{%i3Uu}qD> zEh1_%VrN=JHz(M(#e}mdsudzu1Kt=BUA%6a7U;To1%)-KMKkP zGN6KK`u0CYs23_nR6*3ttq8_|eUO!mP^r_S>`>PSsWB0$ATmNd*e=9yM<87V z1NDbtdihsIO+}-sKjF6lt3>!f z!bQ+SgOUysAcCIh|6s`o5xN6D9`#JDpodz|6ZGuDEj5vR*AcD!? zO$0p!Rz;ZPYX@d0Vsmwgpr`qduD5}}hKe^4^jyKs2qog1hL72V8+$A0`6Y-Kx>0V{ z0sEA2(_B{2^Kj>|u|ELpkY{fNJzGwPOl@BV_MeAaK~L}fQG>?{V!;`~Ev*&w(6!|W zdh+8JpGdwY__&AICbw45bFM^G`H_gP8?fGlo7`GK&(3jfZM_8S6|omV&kEdK(ms}N zF)&Rjd4irXW$~s*G^lSgVU&s|=qZQSV{yKY5JvUs33{d`xOUe)J1giJ@V;A~SgP1r zLC>d;yMmtT9%cnSFSQSua<(GOEhJqe3kyZK@l zu!5fIZ@Su?~3wEO-) z)f4nQR|chg0*ro^WoC#X=;^2;>J2V82ya@F=E@X7PvOPbhov>7l_0Dok{N2Ppl2(V z6sW7{-N5!+CrSi8OYbxtPoD*LN$f??v&u17VM<}G3L==1S_D07&S6as?kfSRK`^H- zf}YJKX(XVd;z`i6eMyu_x+9of#hD0tc6e+EdX`6U0fD5)<6|o4)Kn{Z=q1wHj!yV8fhfSncmCW4;rmr|Id({8~{G=l4m7QIQ( zbGAvy;I)C(7hD8AUp<9BaX;d_5JoxG)V7|W=j^%^^$f5V1*dxT1U--KjHuUvEr`Q4 zlSI(7@wJd??TujVjANSBPZIQu3Y(Eh{|>?#AyF@JNf7j;tai(ry9hS;5KNwpdW4Qb zk3rD$-0P-u=!ziRAtcI^$(RUwwv0q)ZwtmlmgNb0s`N9XnH~Uan8kAldM?*6gP48` zg!x3G)^tg$T|v*5h%audwRuD4dN%4Z74l|>wIS3EOli~$Ev%7`VQy{z;Pl^}xd`u-5 zLC;(~=S_6I7$2*|ZU$XaBIx;yO{}2jgNNL9{|WSC@g^eZx!lDiY0P0#5KQs80oi%L z3VJHuO$QMU!Fa~#tX^t^TmZ;d9>AP`0gi94JuM)LzYbo0uB zp7C3A3VP_KO9c<(wx!OpbrB=zc?6Rx5%e^w8C5^R`4LKBF)Ku@pyxEyx)%_wi@T7f zZ#NP2>{=92#Q|3k@-kM1SV0fXpy%*I5oWhTWGAxvfDNpmht?BC&@;9Kp8No3 z6v8-D=%Hp7LC@fcSdxdUI^f+&T+Xlvdd@=FLN3}PJZ9nS zwF^N{kEO=N5a1&%#}o7%de69+322dpv)3*JJzNXfYL~KDukfo8Rc~(nu*w+!T?z|& zR$^$VI{98u(!0RM~{w$m;j1!~)ED9rzsK+)f-4^iXa|(8EOt z((g#ywOvE1?LT;&x!#gs0hKYXI_AO<^!x#1d#)G_7A)xDQ6sb6c`Uj?&~vJyC+MM( z#0q*Yz|;zQ>U|qk#csv=FM@v#jk#9PGX&azx`=IV5p##IfH+prW0r=9;R<@5t{zrT z;old;XbJIMLC@{?gw#YJZwb1bP%G$ZxGbcW0oo++Ig}t;2znmHE%|!*9t(V`<#3kFUS1XiJu&PZ5N9dywZh@r5kXG~k7g1_?*`## zAyJMzK~Jys_?1T4^+gb_6X{c!h@gk(I3noDbv(ozU7`%`1QARRu!0``sT4s^=f5M& z(XBvyfXM7w1U=_)6b>cW7tk}}O9Va7UQS{2iGW@cYb)rX8xBv2jtm)Rxo*=cAA%{Q2zs7-&$TZDtRmrDE`BQl33_rh zcgx)rSPKugf}WE*O~G_`V0}E?3VKo@gr+j+vA`yJxE1u=4|~QJ1AE`Yt)S;Zz#P7( zw*&h|a4YDc+Z`=}o+lTEn4>R%cumOsumTBsTEFMw106ZO4dw-bw#R2&iX%*CNEbOq>sAdCEnjGpNfggv4zlf}XTB5tH1{AeqXF$bvSJ5=`aX?<{+_F2ZEl~x!nc~;71}qLiXgWpr>@6s7dZN z5ULZ&yT}4o&{H8HYHGX%2<>xtvVxxVK6j|>55mwKo~)qf({2%SgFFp{c{w~;K~D&G zczlDr0fg=Gp5z{i=Y}+7#S40P62$YPdhNf(*8cSLysG@f>F^8}!N7LMN` zP6StWh|{sFK|DPTAM?l{nPB=RJH+`Z#_kYDJ?oxMl~M)N3bNjZk6*-^zR3=88XLGf z#N$5?D^5R&3W~r5)Aa3s><}-g5mL24X(|TngREqS`1tZLJJgRL_6Z_VL1c%x2Oi}n z{xF2mf^wU^hJRHsFY=r*s#{o<#yLGBt6&!Y?Q@8?v-mg-OA4MClUe-RwL|KAxHv*y zIbT#_nZ=jthVvgN1-LZudAcpKv-q~9AgKpbL}03IZx+7>vMP$H3H&bMJT(vwWfuR} zJ%;lz@NU8xOq`o(Sf~UlNF~qwjk+Fm6Gf_GLP514x{1fmMAdTm`;dGVp=?>*METlb zwF9wxEuu>hY;_aeBhYyv;w0cp@f53@cn=5O29aVx1omzEC^RglImW`Q&cAnKZId)C z(Q4T=EL6v$VM$sUQdQui6N0V)L_dXZo`!||1PQ#chGoL{DQx~uoVlidZ=zv2F(*ZR zD{M;Iq$nDe%flmz^6(cyRjFD;!*XFtm^132I0h083zbl1Zd!}q2eic!{MTYRv8;xr z&S>2KAff?+{~_{f+hW!XsCyCH#Ui>h!L}{x|BCwoL<|HxGM-}FqD!l&dK1t)7M8Zi ztbtr{?Pq>MS;Gib1yNSR@*HLW-@<4g8P?=Xxf+&7?~kfK5qrTRx*o&s2=(3e6qUO= z?gtUrFn)w;0IrNswQ({E@pK)0G$w;41k*Pep_)^S9iduz);*nhc-E>lSr5d=NU^4G zGD6+Y2JQ&;{`83A^xp+#JsD8JG=2LYBa~i+^)FEV6a)4_Rx(2E{vCH-Yo$ zA|q5MEMyT}3`l7~d4w{}K>cBu9+VzZSvaR>HYo8Lmah4-YgoGVj_^qP6nM{)JIat~ zSl&K{pCUv|1o9f8RB1-TVy-_*vQ4Msu7>5=MpnZzGZV>jXT70@CF6sL`W2>skk20E zQ#33OR)lmG(YfG(A>D^?(Xe#*F{*9>Rz~ptgo}pd`>MF}0M=CSfu4V8SZaJ4QXPRk zDLC2dY$Rw{O7xAW5g<$v5^GqPlug6368RJjOQ&4Wu*`*lXjls3xYr@%{A9|gY9=%+;}P{n4uaLNl&S(1%u;}B;|Zc+p(?tm zhUKnp(A80nPs92j>p|T_!&3BC{6vD}D_l#f;s~bfqG5TWCyqoRZ}ouPMYySMKC}jh z()b{hX8R7n9`)?4hUM)6IEsbr2Ll`7*;@_E_H|)nKNHwHp1swu{QV$qwN}Y3kdcI{~6e?gmeDnP#U_nJPpgbw?a(vCD+DI0D@aut6{lqepGEGZ)Jg1Cft

hdXB>-s%T>*_&p4WM^XmxJIVU>*YDCxf6?H~yv0b%9jg`5XkF zgUT~hlR>bmSD2d9Y4XXZBbC@P-+;pFRFXkZLoL;u#iR$puL1Z7B!ghRr!iiGWDpz- zrY}f-G6?GS}A$SoAbs5BwwIzo)`*j&09ivJbNQLdXP@0m{EMmhNq*Wqr}SK6Y^-dnx`7 z#)U(!GRl&?tf@y|o{vARAn4*(vs_Rtvx<)OdA#=g-~XUEe-g{6?hD!-#!r3lcvun7 zjPJTVz`|Gw8*5ir!JM(hZ()gc-_*J5^L(|~5ZSK@a@XgNbj6>1AzcfS_4zTdc&owJ zcdsC5H^^I&=bJ_I*^v4jfqF%rZ%jWz*!v*8BG0hjApgLy*or)LD?W!I52RP*iR%Qp zJ;P!v@(jBM@-R>uUx}WNT^;s>4MrQmiu~3nN|&!j9|vYL2wje$&VV^V;YY+YdLF$G zsE|6%v3W}kfm95NaA%peX?R>XR()KZ9}4?6H{#cQZ)L(syoI=_q=;OhKD z7@Po#tiliUR*jgcICTk3adrMU(|QU~)!q$x-mB#nT8f~b~ zF1m4kB_zz3#ajV-5R}e0xEf~)PFCmn3iklw_krZ4E==+jxQ5!Qm?p70f1W01A?j;D zKLuHQ*}d-tEINV;7Xg+|%}-)k$8J{y$ud2GHdPC^62-lM8im)&L~*_T8wA@Y;iPj{ zwFa01kcE40rnXnpSpp~jOe~?;!o4{)Rx>JX8(MWeuQK)_0WRB5s*DTx7EvdW-w#37 z#}F=n`HjL`5GwBpsZ3Bh-*IaTrlJLz1g=GJQ^a2ivX(%&3QR8weA7J>ObG}@$c+VB zKTdtY9AI^;ZZ>kz2T^wewUTNbA?yaTgF-V1N5Q;Fp&o>DV7>ySbC;zy=M!@>L4OUw z!M!0B2eO`pkPD_7g~uSY22(`geh7oW^aG`H)4Voiiz%6?H%5uhK>W2-r~~0HFsmqJ zLD&vv8-)}IN5LEb74ov0w?l~U#gO^~A?f^QOJA@414G>jyLAG=b%Ch^vW`F~0@IYj zD-imD=?y9*KAnH{(k9R?(gY^%R^r##TMN)cYFz;4Rxpbx@NZw6z-$Di^G|+S+Z1i7 zw;l+73h_@;p%sL;z#O8$zxsU%<_t*xBCNeh-eqX6N-Um_SbK6}HTgUAeg@gBNvXl4 zmqIE5BsEwCOca#I8q|ic1{^c4O?tIi1Z-1~&DxY&>ti)}l6IdYm@r z)#yTCZv@$_QK`wbknRRaO+E(ZK~Q^E;xdD^H#L^CO0kQT2QJp1&3dz0U&{>E(Z7JG zC7ZQmvvzFO$})r1@lPNt#Ab!qtO%PGkbhe&)y4hsAZ_$CXT$Ag&e0W;&YemtV;DoF zqfy8d;06RAK>qjhg06*d3d{)#+>i7vm~)^);?ucl`T@^G4uWI~kdAWx8=wo+av(%r z4yp1W>n|u&15*W*&i}G#ZBx~UwoC!|kCg_9uTOZnaY`GF_m}%@9VMLhKyr(E;c-` zix2ZGfELab@%Xq~yr0`^RHy^4Y$|ljrEtXVUg*hRjf_D?-F*;LHZybgxA;d0{0Bic zHS9TXROs#1H~0!o{%B#HdV=7=}1`NiO zmErr!hKr?eMPHTH0vec!&X=H%HOSpoG7I5n8UC{l=e80R`VRX_!qriOe1c7SWCy0v z8)9WiK*M90eWZMl#lVKUu-7H!gF^B~1YP0SC+|hTMWRH zT-?IPF(MNCR#~i{iInb-3UAsD@VCjLn$29y+>OZ^{NF(~)3Wb?qkc7* zi)jlxT>7wN`JD|`3b`w4*7sY~#oPxwTvV{Q>h0M(% zW)^5R)vuh3NIakMy}3`_l;6EgpG>>0)47~c-q1gX#oB+vCSs}3B2y9J$I4cE``?mC^9yQd0XJpyc+#Y`&n4ut=eS(i&psl$O>IQ|~@QOCD;LcUuzE z34fNN-h}@d$fhm(PC6UuJPt>N6mt3lIEybLOLH3f2#Ir-i%D_8rBMTtZzpG*FEk6 zi6(EEGMYrUx*5mdz~_4aStL=RW7q@8brAC{IHJcrfMxWEy&w1EC-A=jxvM6jS*^_y{fMtNnewVij8)wgfBkECl*U;G(s=hQ<7GNP8H z*5>exzppS5?kN3u;K@CpyF}ws#b;Dp23-MKUA!F8eh&c@PLm<_FcVPNqH)DocPTczN?mECt zMa;**dZaSqi)>Q(g(FL{J(xLTUr1+5`i>O}=t>(Ly1ja)GGh-vVF7xhys| zfu6v32f6#@hQu<3*BESu3w(JG637u~7(hb^OlO^p@qou&U`45f$pB0QNhRC>W)1~b z!ZI+of~2);ZBu<6Ywe?PA4|dC3(P%KV!=NJW(Nfp{5~)*Q($X<7tB$R6udTPdD)6x zX=%ZK2JELG6#UeG6+F?u8<{&&m9@a$f^QUXI==u*sK(kFEzrO4@Wlm%>`c_FSW1PN zD?gi;tQL%|hk>vgf?9!QPrPP|x+(bHdUP)kSAwqZdoV#Ql5-lZ*(p1gOW>MVad6q)(wV1Y&x{Ygi@*S)3f@fvE|SS1DT4=h;9R$9A}kj2^hrC=I>R0B@Xw34Y( zsq{nY+f?G6QVdLg!EtZD#>J@`F0N(+;2I)kAuzK+RxX77VD?a`2;oOCXF=)wlc6@? z69c{vj3nzf1XntUc#w4#LMt#$D4c+B4VY1&G-^NOU0W+8kG~oEzbHidv~VXdE2u;Z zkAvAtfff#ec@-pYlC%X(0%&2Qkt%!WK12K|DsT_o-(dcr!0i+nuj9QnDBpa?ZJq9l zNjG=#Q}zI+$6_#2#kizcBkepSO5!kL9!RH2uyPjehv7bxI1=LC~Ow$FNuG# zP`TBoD^Q)O#>b_>Uke`TO2n-;{j@^fqVpf(X+3)SfQwtU;Xvb+ATgC zJ_Ci_RBFJ7xG!V31^(W|k~kF}MI7G@9|qDG_d50{ zc=>b_VlN{vm{VZ590=FL#}s|#mRf=9u~uc=-4xl`g_r_>s(`E~A>09GJ_SCX1m3_~ z90(2glIl&b!Ec8F`?^YPn!o^e!gm3zEy&_d_=R9*Q{ayH=fUg**?fT|JK?nz^gFO3 z>$BVm{}n)=P>Va^a}I}81(58B?+2zk$d(=P+zGEum|{ZjgkK2EY%1{(gy+HRq`)2V zKZ7|3k{$6MdROr#()V`6=e&s|L9*|nADHeS*%5!zYdhzmz&G>HHNtiCA$>703yEX5 zrEz@s0~}tm-$ESQ@D^Y;fm9y%v1wqO$GH`UHjLN#@+$vnfOk>B-9@1DY^gMw#+&)i zX_`;ZuLE^}NO=pcfriqYXBuz8GcRR+p!5+Gj*AkP2{hE_ao#MkPKjjU<#3S*$ijL1hHhWT(7_T1s=?)kCR2m3Yrjhe8QR?)gPv z7K#Pl^WS*MY7Q$A^5YJfduV|-{asMFlNNZ>KL}>CSm50K56^<;yo_T5%n@4P=Gp|R%xi^abCuuRK78k*z3Lyg##ezbw2`gTr98;`P)lYb6&F8HPe9>*u>63;jAdJ zThvg?_)GP{;wvc+&t(eX+pu zTICILn)C92eH&&ISYUazg+gm8$!M#gma4&-_X`Jce zX2$+5m5TTjQ0(tg>HM3&hQ_JkuE}!NUkI)VSXDy#zyFJD`UDtQ7?&jf`;OUC1DU^? zUh!#87oR;dbt*53S#1Nmtw4GFXO{+=9;a3OI@>*g?asXL&*m7-8pl$(3dMteR=IC= zI9sn^beEwG;}Vxn^riXLR9qTn+T)ue2V8L(1#81VXU}a5Lc8U2g_v199xGH7=-j5{K@(F>&m!Uj^nRkoyNF4aAEk7wC4; zX8`z=AeGMldA9e;^aG+YjRb2Qf&)iUARvo>{7eTE0j2X)39VqNuc(l1BR5DA0=R=JKW+auqgfI)tGzuRsW7&bd(G;Toj71Qob{YPC$*TCi zr;_EPM9X4}8Bd`)_%qfX?tvAH-|+^rSYDbPKn|V;EjPIOP~3n^4He$S|2ROhic#E& z8a*Jk0_`^Z>0xymA@SBSELZa)bg zAsnBNbd5H63B7{mxkP(Sc`meeK}1VXj}?C>smT&_C&ZgU*Ynd$(=w8@bsE#be9EZl+AdBw`DjvfdaZn*q&FdiK3P>$LX?%;RtypR< z;_>33V!zffvkOu4fVlx=@zv&?U{- z=YRM4EB*x|_Iktt!gIz}#uCzy4gTb8)RX-fx3A^#V2ua8tdw%GOl|ZhSUhE8Jdzv> zl5;m07vT$U4L3c`Rm0oozm25NnF`-|=kfRkjkP?^!_G6(Z64=vQD)-)g)`1!mc-1= zLPlnk$&8fjcJCreIX4C5C96)GSjjGh-Yp<0*>zyn(hy5lrE%lMt1&ZvwVjRHFsmKx zhRbM%y0hESX-TIB9E)2jwnKXxsF3L9+%@q%qywPl{U99w0NWlxX*_I0n+~Y=*+8+8 zVq6E<;vpLDaT+{W!{Rv`=b`cq$l}Qx>Uc=~2_c=wlxZ9Bu8k3Pmc{ePa)8MK*)t&6 z^XbfiQ^pL;(q{HKLb zME^-&_!?`3A$pCi~lMdw2})&V%903Swuo=7|o%nj79hP-QiZ2soOaWm62UfdKq z6W~~b;H(6E8TETX*aqfNPy?RSuJ!%+=C`S^bWw%1&-2*bli7JjyT#Mm_d?@2P&&UT zptS;`mGDyFa``TRd?CQ%w*o!`@;FGo9$@i10(CyZ|BFCr{4Bty-fgi2sV2M;FyoM{ z#Sa8r0ZcnkD}E0^;|xU{P87HJQGjuX9t}$8Hvlxm6o@~`^jrKAz*5BDOboyCpfQ$< zxzzAm{My5#h<^ywVDo3C7{7WFN%?O{+0`C7;+HKB19A|AQL_v#PJQ6wEPl@7Tg0CQ zwc?jKbaFm{V8UbZ^BmADY0g)f`lmj*e4*AsTff z$B@f`yD`Q$WcDX zZUe#MF++zT9Rw8;+rAhfX*{}6+X$*FXk$~Lp4AZ=Ji_oxpg#kpv)k4<$Hfi98a8{! zgcBibaX>meA_>{zu%n@2ELFnf6M^atX_7-t6wpkhN`>*LpHM`{c=lK zDq^0bUyg7Ti^kN;a;^d6=|K74nGX(VJ)qSMr1EcyDYWeC_Ab|>kLl@KzH!bka< ztfm#Xir;yKH}DF1UT3Q#Zuf(AJ6_@bK*4ClTRgLKD69?!<+qPvcKq`S`+CZn^R94z zpvq<%;uTJXk!wL^3S6#mP)r?Lc0De3g$DxVKcqUZ@Fu7(0I7U`Yz^l>uQ0;HF|Ur5 zLD=KG96b^U)n&`%fth!}+)A3vV_SL1OTCnfW z=qezqD}*j!+Jfws5Nw{@>KYjXF2eicEw9OxafB_H7uU^wHcN+fbw`|>9kmO;yg~jUN^?tX||kUS_s^0P(wI z6<`88-7L5FN+e`rh&%@TyC9oKXXo+Qf30YHoToU+OtYQKux}Pg~HEN;#V>1@^cniDd2Hh3IABK_93ySbuK@E32PQ(2lnHBqYMS1!DR;nrRjX^5HLl3nQ zp0KnR9>zzm@95QGU}#(`AcK@3OQNTSDic{qX5mftg) z4e%^bggc`(KFQ-e`~)L0mvzjY(zgM>6eK&PJ%Kx=??vc6AeGl2Be^!0>~WsCi5STF z@t$n}KMJbLZ$N2$ipP2Q1ql{E3bhx|7YOHfuQa^8$7wj$fh>Lq>jjJGTI~8S&izoX*qsG}shy!Z^GI=W%FkOe}NAKX>wh zsST2U?z9Bc9AtA}y!>NFYhrJ)K4Xjj*y#sQUuy9mI}^ZMO)dUo2lp@k0k^`tYfCw1 zALo9?`%=BCTLQ4sS%?h00Z;iv0y8K*<)7ld6o z_>YPzzXi9{j6zU1(3RKW!&CWvXyi1+0}QJ2F@mmR(4fz-{10;1xo$v6yj4@V7bWXl zg|dRR5s6(uk~?GVulBL{TJI4N$5l{9=$z zq}`06(Fc%U9*O1cg_fQ8@n6bTXzNqgj1MbG;2+)0Ht^Pn)s$he6L9bKW`5(w&o@#q(pipw$fJcFYA3*d$m zKldXbodN1EL%z4UJ$#}e8Umh!jB5Acvgn{r1g1U6nh9YfnBgE<#MKGm%}z0<#6^Lu-;pg@#GMJubdW6KY8>{S5vLb%7bAWV z2u~qgJ6;mYHvXJ~I}e{6h*r4@*0^?j7f^Q+DHHxRF`!bKbFUXy+BQ&SGL<;t-vWhA zAer#*2J;jJPWTUjIS7iax!xPIr>(RL$1eA}{8ufn#^D_mSj{hp8d?3j|bud{V>Dt?aX-R=y z`_*8EgRm}WytfDcyFuVg-ww ztD4bY>b!wKD|nkz;d1)RoC5KeJDtV9-I*=^3g>R|S31v#zsh+}{5zZ<#J|%iUqt=Y zPA&28axNABZfB7AYn=JwuXWaoe~)uO{B_Rf;;(luh=0FRsRiw9a4r{rqtjpfP0n2L zA9NlN{}Jba_>Vg0#oy)xTT<@{Cr|t*ou1-vcdikChqGAxoz4T|KjrKZf0uJy{N2u$ zR@8smd0zZyoR7tS*7-~P=bTEd8UMV~LHrk-;o|RgmWcn7^O*QAJBP)8#rZ@0eNI*z z>b>d|iND|JBmQg7H1Q8OtHnR)>=OTV=a~41ob%$p;W%xn|Avz%{$Zy>%pWcOo6b!! zf0OucIj_Y0)8Zd-taj8t;?#s+KIj;cIi1ObjL7}MgpJ4>!eEaAucdsjl99l|E+5P` z5?IRRgH??L7H|1rO(Vfo&ovTU^*kei>Xy^ksnG>~Xr6NjXG2(_`Hq4Avs$6W&Trx` zb<(;~Ugp#nf4S3M{M(&k@mDxg#b4#D7k{<$ocMP;N5#L#`BwaOPN+NW-0Rd9|30U) z_#2%G;%|0t6#qfzHt`>F?i2rE=UMR|aZZZA)rsptJC8Y;;%{@Bi2q~c63Opxkw;i^ zq2D9DCH&9GWbrRV-V*<>$j##a9oY)MJP!MaoCVY2*7|tUwJjL#@Wv!CwiC`7F$3dx zv+%P%d}(16_&~xC=MD(=(?BE)3-7}nsJbvFVMNm40T^H6F#iCV+4vWiA<>na!)(H+ zQ04@svJh2WN2|)i`XFX>=*_F~1zUs`c`=b{7Gkarw@$~&3`nCdVg@m`I?SpJNpP}1 zcpd(!h|p=Co*Q$m|C{j`EfIRBjxlPLDwg<*v#=(IsGVN)2e_!1-I@N6%Hi+Wh~mx? z_d@DXJF`(`WNMNB|Iu|7;B6dfduAo=NLtC3WoC!Tu@lFM!-+!H>^%2sj1!XP2TQ zFqA#&$x=g!Ky5Bef|l%u(dLrQQ!Oz%mjdb-hpp}y)X<(B zeX|-YDmO8J&?AS$ncvkw(=dO*3?W!Nl7XV&yx%iKa(kKI4qc}8A9wpj;B$bUq#tsw zf!*!F0bm9u$k0iw_sRx##IRi>XCblmZ2;XEO)p$TL0UaPlVrVeLRg`GpJgHvp ziIJgzH3;L> zJ*ghYLYP=SO5qHWE|tfmx_+!7^>9f{mtjhqs>d@JSxQk?6&PiLw1A0TM!VFV(H^=oDWxM6fg|kH9U8%zDjcn4$ z&5-y|s>fQIfH&e2qQQAPac9A1S}+vsH74f7^lJ z$H}WO)>x+7AQROdq@)=_%j1Zgrs3@roS~j;g!%zAA`Y95k$GWr9G=)Gr$0t>ncD_M z;GeC=Rv6wYaJP^@8=53tB6A)VSN^^^iy4x+9E%ozRZavmeoT0-S^>fVQ15{`<_gm# zG8-=hzhBM@3g?ywaCYb#Rk~gX#{MZ7Ka$T}NxI}IjJqQ9hM{@F-?OkU+%kL9$z<6x|e(MZ`osi7Sy zzj2(AivX;RgEE(lY)#ms4nX;SK$p5OD?bLGt47Yk2mt8O(_mQ!ugQM&KJ_&wt|I7s z9f2oZo{lARDLQy`b+{2=nR#!CM?{x}*)wF|TQGC)$KMu2A5rhDGm=>tSPEdQ=1k(8 znG0r!=ZqWw{9(a+URlrW1E>kE+sWAdKMVL1AY%Et`@(J~Msr zDFz)1WOOb1+Q%r>UsTPe*faoSnTzT^8(kGHWtDi}LfWF}5zDbqA?H$<>*8Ef&Hbk? z6H&kXX{BL24D_kf8Qy!U9T82HDs_qB;CYY0mRc+?-kCXhBAP4J>-!A+Cm>%q4(mZD zy27*(FSm!H4Wzm+*Kk^Z*V^T#zQBw(ld4_=A^ISA7$G)!lh)MFF#<$eOEs?)GbOOa zb#PAR(Y8{}fyg<)4!Ss7u<&wXiguT38X6AE{bt}t$zh9>dQ4)liOqXXeZ)3Ms@+)G zHA3*4V1D7U6NsF7qobt~SaonZl1W(q!5Fm^6<*DmD%H(R45tzBjxNVlCKK4Rq`Jpr z*dxGP@;7Xq+E|ixEDNM+iuT2n?1s#RuAJ`sCM8Ry3Sn77&h5ZYxSZOQB(PUW)oHe2 zzX#?|f5VO?f(wc0QIxV}N;!gVR0LC79ErpeQfX{CZn|Ua=cMBF%HRWFUU?>4cypQ1m!w*PRR)OUT`<=-a-X9Mlp&v{2++ahT z2GSCjn2=CS{6eaCQLl`DH%NzEVnRYS@sw0sR~X{mAU)#}>n2pQzeo9FBGdT?^ZPT| z!aHUM68e)=yM`E|gPVw4m@}$g6MvWL)H#M&4pJ|dn2=CSv@G=|mIsV_5=cv2V%>yl zwzAY(%&-V?ExgUpoTDL2;Sq=?-VM?TmzYqZni#cIs%?n8Ejr~A6B4S48I~%D zH6}ZXti$|u)oXUHrMh8^VM5En>~$tvcspTz7HwduZ?_xbB#`F2#Ds)uVlzwKDh=@* zkS=tI2?^E2mX_*-(TY*u4$=viShqwqyUbFv_ZaqjV4gaYEt1||fP{9o)W=9Lhm|m= zU+On~sOZ~+z^kliUvy|uG-@q;eXVpx=XY1s-KR{&K^C}!5&`C{_2VGpU{dGzuC%8+ z4`7(~q|S6+)b=drq_$@}KWTf8lQf2SjnhcmXE~j;J=Yno?Rm~pZO?bk)AnNLc5N?l zUe)$8hevCAQkOd!n5I0bE1U{#uW|-!d$luD+v}ah+TP-9(e_s75^ZmD?$-8p=Sgkv zaNg7QZpVZ5iYIlildSFiP9xaeKAwoONxM~snxu9Ozb8&PCf#tZhZgXb0LX9n<(PAe5|lSawP^j260Jw6ZZ!yeAaFH|HHt+;idnfE&N1svsN0Ls%TDJ^VY=-< zF^SnHf|SD9b}ua#Vk%nb{c&n+4Xd*ussv&X?#pu9i z1SLR@sQ+LoaVY|BhOt&tAzh}xoZB;T6JlSP^a+9n(_>#_y;gwl+u?tm0=G~=>$9hz z?(FMA+Jggwafe|)mDUqU74~=Nr}ooPrqq9)WEn*YFGe4*UsV&3ifkz6!!Z-RF8RWj z76E=s{j?J`52&XL>+EJ|>G#!~8KyKQ0G>+97NkdH@V3DISbc^^W^OXQ>3DfS4s!KAL84 z5C+6aBK_%XKt)nDYK{6u@Z30Lnnn7@$-oCn)dchDMqmd{!zG7*k;!4hp4LD&sQ?*y zcj96Xl`7B-Z4wE22>!?7qA_@sR6n7iT?F`TKpzs;rIvRDlc+sWsu_(<#(n|xXRUOo z31BQ8+l|5~g(i`OJT!&T(mLIegMmoj!iw4=)gvHw0b%&*B+43Q-Z_GOVrVpy@|QszC!-712+MH%=({@DbupXEYq9hv9@?- z`&al^yMf;&?`VfyySPrQF7C37y}+NAy^AqwVWnyGYZosfv+%Y&Vb}EfjqTHrpO-f+ z!IM;%tX;eaeXDKH^%tV4#mKM7BUqEHcFFqog%@Fzy(yRU$1_nE*E!QU*K@Uvh37@c z0q5!mNYW|iMWpxZh?IXL)u09V4v*d3?gCf|C;$1pot>NpzqlVH8`7ffA3hB*jvV(9rdSV6R< z+7hZQ%fuv3wbVLv-$GE!UAo)e5}AiA<;PUo53G?c^C}j-iTFNCJ%%1o18lX6bMj17 z^01{I#(nfY5H5E~ERjUgW0rch1OB8AgvVVHV~UYpFG1C1deqbu-2Z~`ahzo4M=$rt z@V$z9e-O^YgBbqKSE&5NvJi&T!lPyZBc}*>3zwr?q~TO}R7-@D(+l#U zSBng14)CQeM;DLb?DeP*&=#m?5Acgz4vR>5k8|3*)}!(Uo4N7`@O#P8qnekyR`%^4 zH9KJX?Tdh3i>nX@zTcz9qVut9ehcV7u5^FyYT1u@%Jv)K5GK(mjBXpkpwD`K#B@X1 z=0I8z)iGz@IS&b&-^!0hBE8(WvS0P6E1Db5Xz(Vwn)D`@J+E!JmixX(RbZ$hXEV$W za!ro7%VmGzQR7w{RaXJJfiNc^;nnc>9<^w#kv<0K$y#Y{#o7P!r~|1c(H{W%v=-)G zobB_fdQ%Pj2Ouw6MJ#Uaq1nk^^&AEkCM_ROgIbuIXm++&)nM8r+!;`hT9~_Nb_1^} z>0-wF34o^7!rVr)n|oCN^~!#^2GGV@n5$O1l~>(j8Tb-FSGaKM^x-~Xck`zg^#kOq0x;dK}WLHOh}l1RO9H(JYRui_B-3$Q=qxbW7XmhEj`rMj8uv(Rn} zU`)xR-Zlcm|K(ogAo?~4?n=mw9{;pQ{6?=T8-o2`VB_MrNIkC&G~e!3yHL0b5WLKV zyxbkM@As-Dlgz}o7tncxO%vmmzCEkrIOiO_J!n7eRYx}(&I90`h;z-@tsfxRGt2I+ z6?ogL##bBSS0MjLf!btqKhgfT_an@Gj5dTa$b`|+87#2{xl@Ud}@FmMB(If`+n z7?V#kqG`@NpZYga%F(JL@ZK)Rj8^G$k)EwS^=yUVOa@-#a!h(O=R%*_Jk@YE1Hb4r zPVI~&yqbNDPlX#A_7O0TxomeriV^SdshJ%O@hy-(IgJ?OJnmCd_ZiObz{8k!YOB+9 zBopfkKJ{qC5F3Nk+9m3|rdG4&!nP{!iv3?;!(7~y7oQp0`L;^O%97=E7VzaR$CQQU z46xPsDTcET_$4mK%o3V2-B$0SH&D-=z@KtCdX97#GQz9b%WU=UWW)Xt%zwM=g!0nF zZMHg!L78d;DBv_0Qx>LKXwF5py3B7lErEA&IXc#ayxwCgyMrN)25G8GG;QNIY+u>m z+UoP6X0}-ae80=ltH%V5n%z~Ya;#Ul0=*H;`%h;ls2#7=D_C$bA1{G)(j{t*rmVHb zB}(~w7~-!WrJ>&>RDRvU)FQi-dL8Q<>TU^okJCjGN>sBiSL&^7!=3=<+%wt2tBLn1 zl~iqrTS2|*nnT*sjE)<7vTNu zN@?}H2t&;GtEO09v!GLOf0PGfiiPT9oYsDI0+TK|ZGrbbjUzQN^@l3N+S{+{V;mR{ zLUo)Zy!)Zwp5j-%V`aG-(7rfa+v8({mS(T;tJVWe@^1k1$-iOO3ddqO;8%x{Y}VKZ zkon~=C$~qUf(pU=rGeE-uq0H2ZPC`V@uD2)ctg{x8@G6{tmC_p8}h zcu{02=sR2yU4i;ynyF@g?N`Tp8}?OTKJ*vtx;d}{>J!vCBX||`FaJg)Rzz6=)eq|s zvaP15aG2T(*Oh5X)pT#2rV#<RoIiPR;3lW`-grc1r zP&cF-kwc*0^A{p)fs&V4URDOwm79#n3!s1T7b1Fe;Uy+=Fpyrg&4@_sCS<^v?7Kv% zN0+?IxXL{lP;+9nQ3_^1m+f|=gu+UHx+6qB4JZfm?PO5bxpeNQ7^Yi!+AH$*uycGB zPzz!;cp+qtxN^18xN;&diY{h<7f|2FddM@NzvYV567_RLTL#s|$UZfF50b(<-K=tS zmAMg!R6dooLqRokCRznpO~}-%9kvzW-He5`of%Ybp!gU`ci?^E+Jt^)YBvn3W!PCE zJO$9qI&iC?dK?Qr#=IWTR>F({Yb8k89fIn@)n-%ZGCa=poEgt@$U_)O~VYa zGe`qnBD+c~YCbEo4+T{lWr#CDTJ91PqSnNtLG|=lL)-__H7?POI#KNlLA5ZJqldwK z?o76MR%m}1RL#&WSht^o^rK5mNGP9`+1~|K!FWSVD#ofG#$-Jqp_-WHs5`J?qQ(l4 z2D-$$3DxWdjye=I?3rLLKa*{q7253`bt~4RRJ#wP%UxnZLiw!B?(3+lrWxXWAU)+0 z6B4S4^Bwgq8Xq-&2-1%(v2H>&`)o&T##(^vq?X7(%o$a$i3c5ZDQ*>X{z0m8i3thi zvoiZiM|JCLh}9r1a)}8E)x;+pH4qJ-8h3(pxl62@P|beTQK7AdeIJ-loyj)O3hmDw z^$AwjI{zU3+a)F>l+ViSpB%M&q9F!Ku;&ePM%8O#UPyfsYjtHHRk_5v3DxWtA+-Q& zPR3si=Atv%=2@ZLHKd+iVTe0Hy2K?WB$RJ9*h500Gx1O0X{GU8yUJp#5Uugckh;3euv>yT@Nd{U z5s4}BhgC^GBR3N=i(EMtSu72KI35obQ9 z>^^k{-a-kmy|En6mt`IdbnzDi-N%`=G||3fABOStmW~HE33>}Sz1+N!XTOHQGQEAY zJ{A$?kx_b^tiEtdo6kesi@`zZkuRlfoAo{Q?&x6%iV zSZu)m0Ql7fJ51>vdo7Pse(Oa(TpFXt)GV66L~L&B_})X}GX~XTnFVrC5T49I&N6fc z+81kkr1P-0$2f0jdy@05wkJEm8uF$%&0}^yZC5*UV)hPgPjzmL*-vYGn)5}>_Me4! zNx$rc+th>M#}W6W1qU!njr=Qz=(hlUK08N-+b=^Y_;b1j-mgIM_UMVXxq7CswadU; z(9v=02E36pWD9x+e4=AhRPyW^IO&xg&zp|--5&2@yjI8aF`(64k3~CCZ^wtRn{(E* zLB{LvIN%`eae9p~-blw!CJQldQ_G7PfWx4H`7ks$QSI3l+ZK8u2TH?BwjhvN|!)ZN3#9`ZHZi(UcfGZ&_;Ss5_r zM#~MK=Hp%n6c6&EBbN`d4H+%>_%51@QUg@%!deSCQfo296TS#;hq{9_>U5%J8)7l; zUUOdaZA5NsKw1_jnhk0F?s?9KzGFrB<^~Df1Nfpi#bi6zH!)e{{Nn42dlZ)}H6^0yo?imkL|OjXe-WH+a! zm3||9{-TYW;VZF{`vQs-<)Aa=lo~9nXih48t*qoLhd?ZSCZ?pEj+XBaONfgR|K%{& zeyU8b833rO4WrsD+r6oPn0FDdvY45d3}|lJ`MWGFp88P0}FC*8_#|0|=hB zG1aDVB#;JMzH1O!76=VolEG(C$xzEX6n(Hgu%2<;RHun#xaIp0@?(KbkK;NeBAw44 zazetd;2WQ_kSq$cR~2(bP{*%MS3~4q+0D~~WB@vGm{&h%0&U!2ODe}Jvgtac|F)F!4YQhF9 zcICCQ%Aa|i$F`%UeV6((AY_ab>p~H>Op0^^o?kS{tx+gse_}6)P%Xc z7h}MbkFUg7)fjhJ)$%#Cx1`$^LCJLKdvp#u4cdH|rD00(BV;FMmh@dY8pAJwD`1R5 z-MMRf_#s&{14HeXGDW@sPSFZfZO$Ju-82|o;a^H0Yw(|E}8-HJ{lZw7cIP7s&N1{j!glF^!Qv%%=(Qv`M0i2xJax*MuF@CsZa zz&?G2oHDvh?3`#xPwsH%4Wz)6JHq*=wnv&z^KvITUugeK$AeDq$(`dAXuHNKhwU7N zGMU#bs5;<{j>{iR7J04m1Kps%tUaC+UW69Y`XU=o2jIi5)S7qlMA=5vh4x$JQ97!rnpt;7A=KE`hcaY;O`z?089JRk&lAP zXapAhp2BHqJqOXAp4Oj5S~w$Zg!a!&8>j7AX;WbPcKwtu@~^FbK4e;RMdhoRga=VK z)W41aE76mD*^g$3{6meuFGWCUGE^0{aV8_Do}zN+EN!=SR%pAOvsv5ioguiv^AvS( zCTP2(Gh5r8oTb|C;(Rxbcvt5)ZFh5&4)5-yYP*N?khXg|=b$Bfih4UoHLs8JPiEMp3?Rx=XTol zIyyTS((dY9sO?_Po!aj0yrJ#B&i}OC&#AWvy!xG;O6I$M7iW;RyE-<8MNj?i&P0t@ zI&-w$!`Y(kp3ddk?&Un7?cUCd+V10grR^$5UoVEkudAxHz(6j7G zJOrVT9;xSTT9GEaU-|}M-LVT=^ye>~1_P!~U+|2{uX?UUGWgMOn^-f z;LBbCw{t(%`EM4t_WzEDNcKZ3!&r32VlLT$6==Hv+mPSBV-7qO+7q!`qG1%b*Pbl< zzA^B0(4Hc@C918sqxLklzrxz8xRds@vVXQpbX_ilx!pY|-X zU)c;#e}~V6SJ^XAJ;j5foGmumNB6-qIC%tWdb6$2Wr~ORH$vMMd*WP=C?1x40G=K8 zzmDXJ;&I`wP;kJ$s2a2hnU?~&*q)ID&&2F&;knYTw-KI6IypDm%h9@uCkNOHj@Z>0 z7K*0?*THkYoxC+i6j$rC9kXwk4P=`CCMY-|d`Dj?5G|Fil6sbU0LfBp+5xuY@DtEj zGDb>%yv`5SrEVJGQp8$vgD086eHqM)P-j6dct5bxSLA$z&}fGii;Pqj| z9)3J;AS&n~lKyK!F4q$}1)Iv#x}Q!6w_+A=G^uJ42gQQ$d<5TSg2Ufpv05@sN|y0B za#&{CC+QW6Z9Y5^wO>*xlgZjjmM)e$)bMyrfF)g|&d4FMcoAwQi}Wb^f9da9@e{5B z?V`?DT)MtWSeEyijRj!Ye0ZJfb#CqUB^T2l~1jKPh3 z`hLhS^n^mNnUdzGQN&&dL)?DI+Z*b!6cW75W##_ z(q>)LyIlPS`f@X%LmJ}w3AITV!7j{yXRYU09fch*5SF~E8yHVnNRSHuxC2nCS7Wkg zJRNTJN`~R9OI)v&%jS#rt(2c0`;a9>t3Yf#9*vtiJh@ z=W3On%x2w61h|L^zJ<({{G{{3(<5{~MQ|mgN^5k%@GObilGfEEf{i*sYMU-oo-t8d zIx#$y4Ee!YjAu{Ol@I@hakA7ly}TC*y5_Yjq5HA^f@x4y@}^GU3^H}2(={8uzZB59 zGI=AyX$-aN4VPH^j%y2#}O7rLtBdyy&RKxFP(xNm^6fx2U{$vZJ zPvp~L01p~Tj9bIUGigzp=Z_@D-MARiU*^-IG>;`oj9bH>XVRjy2h(pt+)1xuF;)_l z`LrqClsFw`2GQkdND-My5|s>cmDCpcbo4nU zq34{oSeJW3?>gq(kIx-*?#CC7Iq&03hv$8GLSH-P9FT7u9{X{foKdqvgx>O;i-C;_ zo?{xGf@*ycS^O%gbtA`lu`zjAG-G#&**C{*en!)*0GDVO6;n1fe`Fi; zq@W0b=H=Rj)20KN+4x%A;PHGg$*;`yMGRbrp|R$sgBU{*Ht@3TD41I?cWB?pNzl{~ zvf3AJiU)zq!!h4hFjrsdH9j9dz$t6nmY?JVHX#OmZ&KE-Ex+vX@$-nXind{ZK7Kw_ z*1j!2?a}v2Wu4j%K&pIvU9hZk+o5nfW%Zf!bxHq6MeB02MA`bv90=Ebgx|n@8ZvA} zSFEwyWO|((WMok*EQmR}r7qZvTZ2~KoZ~I<7`z|e{(-S7aN{Q?YN*_s4ULru9T-Ps zXTm*s&)3XbHWrrm!UAX+fLBg)3~w>GE6K0aRNm4x_m*)_!W*6g>QJv5j%G#5VVJ93 zs`sWDfJb@N2g~uu9l{R*dW^76lYu9B)oj45@V5bd8i&n*=RG_dDyDnYbpfN|58&SZ zt_ls$^(r1-Ko$9bn#SRn3Vx>DX0caY)7|8!68J!Jm>)@(=*fHGrr!45nJKcwE3O+Hg?_}(j7Mr*z5%4!qu1;DQ)r&g!eV&QDW8>pCxsOJITC+g_AnR@UN z>jhhlp7(%%QAf|vBClw(%c~~z#B(Gj0d=lmOno%?b!qH|c^dM^M?NCJk{C7|7u`m> zqMPY9!b#a}Bi-g<3kX_V?*f=Z$5Hlp&p^~gizwTlpi2yhGVdbvSiAE9m2 zk!RsK9MyV6*f$Gv&m}VL5d1V|-Z4v~i1$yNCy{irBPjoq8E?YoV6O*!Jw1_TiXKav zcXwk+GZSN1iL?qQ!u|nVnp%}{uIjoLFW1YWNaLGiq(Lf%Ijn$|e4Ql3%`!~&ezD{Y z_->KOOj9HxZj_BcYkar#{K|l(jnIqgN&lY>(2lsd<10k$Z5yTY&K}z%vLS*tcoEb% zQ^S{_oZ2?gE3JB#ulGK{6AKa4G>;ntzH&5}w$0MGAPH=vy8F>0+BVPNE{$(KO1o`w zHdk`KgLJpdwEEVJUF8OPxjcWoTw?E7Dfe-3bGH+xDqi z|6=5(ZHKfA8QxvO-7)oQx-VV=cc--5=$?U*r)}S;j<+Zm?tUiTq!8Q}oAk690rw@j zn)43UK5Y*h_q}L+ZLiGH;WLuqexjasUve4TFB;kP_-~cAFYCRkfPhU(wlfNjn_lhYOdsv>3*Sy~Dyn>M8JWSJ>7_`bD>EdO?I9*JRC^#Z1DuLs zzA$LM_mJ)ODz!i4efJ~V9fHx(a0j>r>#K)m(J{-^5r?gg*`{9Fp~5@nn7UYqI_;RN z%isBE1pb_@ljFaa3Fvk<)*O)#wF&#hZSbV0PlLyAcI2J}NAJifQE)FBbj97C>p5f1uAaK&$2k@}DSn#h5{!B`i{0cWX=*+_#)oJ=E*Od&d zO(<8J`sPeBf8tiX=BxP7lf=5`X>~edrYDDUHbT44lf*{ys;fQxI;y1NBTq7`o(J0L z*!4w(n?Qd>W3Rp?JZ~qXn~kdFEa%Y_vyPmVon4PD5B6HFzFhT~2szsb5qaGCOTN zs816_umh&>uKRV~d2FA#_tgWhz9k6m#4@4l5FHPf@wFQwBK#U_;4@DFI}(@n39IyQ z-dtd(qz>Y8-^3Q(jU{-+w;7vZvCHuWpl(8=7mo+$hr<1^II{ERpe`pkdn!0*>w9S4 zG}PiE_`*Iw8}wYmWqATrPg-FlE5P7-R%AD3w0ho1Kg6MUn4IEKf)QS(&>PWV-!O~^ zo<&M=QTn32XJMLCJlHD0bGITqYfSMHm`yLYi6Y!(ReUEYu$Eyw3oAme<43(#cWdM4 zF;w>FQ?TP^w!iT?eFu2V_P5{u00T|8u6nmAV*gSKPcQAsvfCBG(_4Fr?2oCSkM=aR z@27$)?P+DdLj`@cr@cKG>xORqw5Pj02rZ>sf9>gOFUf{yfS+j|YOkPYp!N*2N1!ab z4c4CF_Vp-~ZbP+agnjE`c!q1wNV{+YJR`Mdls$4HJQK8MwEe<-cqVGk7<&k{P0^mQ z_SMujReQ$SH&WYl?HO<9Qrk@JnP3m4wt3n!(SDZN=4;O+5v)pqZ;c)nc#fBDqPn)l z2!8w0ZC%Fy5UhCSSN*%Ocur~W@C2jgDIK%&Q58b*bNvWU`-;$|e&a=Z>2iEy0CW#V zCPK!3IvFEmNbmLwd-qOw!pVH-fobBdD)^E-<)Garw>QGhdyAxzy^(C3&W#J7gy?50 z-1XNZIRfXvJ@Wi&xGtb;Y7$&mz@>>iTSF65@$acfMCHgR(-2^|;Z zA)m!X1S>E#RNkk@J08JdLc=_tt#YvG@;s3v7Ce3if`^)59?%if(RnX|zt%cIoz(`~&)2rQef68J;{6Q~WB6q_Zg!9z9-_-sglDZn@G!Fr=NT7cCzQ7y$47{AupZOJ9sJ*PxL?*ihXX||Do<;KHO9ra$%{sxWfs1To5G!K7P}9kAN0yG z3*7U%!<}muwZ}2K^=^^%;9$s(z$nqXIQwO~yR?V9W%gHe_rQXTL5eMb$d< zQbg5y^YTR12J_NG)kgF3Le(bol0(%N^U_7tR`c>i)i(2zMb$ax<%p{7<|T)!9p+_- zsy*iAjHVtJ)^R zd`%)Nl!S$7G{64WDCd6J&UYAovhGGJ>7U~??|(Gqb^33`j4+^6vKTdg(L6D*Y0{Gz zggpa`)637os6VKFo2IZwO}L7yiOCOm@+4y9v+pSpq}dUWz^wm&IOEMczQ9zJi{9mpVD?&@lV?BRxIZ+d|)vb!k*#d ziqo|{tGEz00_sa6P%4c8{@?mOxine+`-4$Btc zJK@oNN|vCMM_2hvR?_b4*AZBwNB9S#Zw#LzMvn@#W~xQEJ6B@98#CJL=es*aZ)0{H zGsYXK)Zp!M<|!Xg?9>Ht1JUGUG5WSwuZEgD+!Ko)Z-mbwntXy(Hfxr+lW`sAwdm-OWtTx8ZZq@`;=Qi|x zId+nNBRm;iRN~m__Q&XFdV3dP!(puVQKBNF0~*}e8TS54gPsLsk&AX1sYP0>&=$_K zr*>b`kW4XlPP2n>J8h8~#`GIJE%_h9W2dBUS%|$2q|c4Ig=LgK1=8~{))$FU?Gkjv$;&TI^Va&$-k40v?5bxucj&h60MC~OCyGmQ1I8{OzG zMcL&B9SMYA^cu89&nfXdQn~M{eTb+sZ#mq~Eg=)p^YG|g$0Is#gHd$_fa_qaQ;88R zX=2bvfIRM^@raNkD%XvC^f2AX3%F}DW}!Em4N}yfyAIFl$2%*lk%aCCkc4rQ{7v8~ z*}Mk8l;Cm(R)3C`nTt?sG}?>w!3E7fL-UF(tR<#pQo{KsI*lAR(?1IyBR)I0oPl#L zb5IHhwPsSh7hDjpfVCpy95llmN(j%m1!+|28MiR48a&UqMQP-C#w|`;2!GbE%b+FI zsbAU$FYhELe}rk-sg6S7#DFes?y`$q}0@d7& z10q`~w(4}TH1jgCi00#_t-3hiMFB8>N5D-;YqZ5Gz#RgRVmrmPnE8jYoT zP2inH1{qk3yjcund*CjNKa`nOi=4k5$Zdh!!Uo}s@v(TmL_Vv}4@}!)kV|WkCdf$j zRe|VCgWO$<%)ww?{ZOC_GR$~haFLSUD4nVGBhJUjmw#$`B!YHRNYB)c;UQ%>6%c8t#p0SbPPd zAS!RbXpKKEduA8jF#ktjKIQ=7}g%>Zy4$%H(-!o{BO}o|>nlOo*rE znJ5!lat^Y+Fzip8Tj-5mih!&jy3wLQIP26>Z2G4=&F6K=V~knHkb)&S$<3EEOz(*d zG+!_wk1=LF*AO3lcS=sHZXz={I;B-Nl^N{MY1PeS277K=b#s})j+$28LT0dErd1cq z40gk`>XtHty)Lb~L}sv)rB#>84ECwC>Q*v?T_~-(waj3TNvkfC8SEgQsgGo^J9wr( zn(?}}k7lqBc%~l9$kO&>8Eny>smC+M)1Fq4ajmusGj4{RHr%t_AiVYl5zwdK7VnyG)X>+gyo3U&j+^y@)#-ur|M)YgY z8galiL-a51!symCG|{bTWTIQs+C;ae%tW`QjfrkexsJ}WrdC-BU|3aL<;3b7WC{ERtkVe$s4W$WUv|39#-HrbX?2Q@z?&p=dOJPcN{Ci; z`a7L~vo)RFJMn|AGCCujCZSump|dEfB_@OQ6CIJYdkfN)>-2l_E{sd7JUFL&-q{&q z;|xiQ8{hnx&g_8e+iHDNZa9-QhwE8>XlFJ%YB@nK*2EjH(OU%k054&SApEZ``GBOp zk>^KwW-tt|MHfTNI+)++nY{qBwKB3duU|uJtDBqIr#|@nr zmf_4UM3h^TQn?X-r{pch)`+iWgGv8}yX0W~#AgH6$lFLPOzjDx&ga&8zOhXVPqr{L z{KeY?+evGkdX`ITEVY^y2Id4AF1n53Z?tI zp*eF0VMg>~@wFq_S%BcX<(F0Pq&WA;6|KdN)F`TXS5c@t7H*zh^+H3nT|d-H+YLiI zwB0OpiME@E^w&eXT7+)a{+6M8wcRSj&p~}X0*=_7ryrg>AFaw4kv;eMze1e$-nJ=X z&jY@D;THDXC#2Z(VDLM5@D9RpSb8h+PdIdKg@x}(mw?z?5ao9~&Yu`Vyn74%jTb<+ z>)d>?w_Y;2h_CO!B(Zm0l%M@LZym%l+P&}j*Mc@7viCzZAC5LNM?~;n&p`&Zx$$YQ z*!z*Qo9<~Z!u_#x2yS8Dx84zZKM8cBM>OKcMC8P_MH^8&dD^c;BPQyWxF0?lAcj;@;jy?KDggESemEs_enmw-#5f~{i0wrDEo#=-$dBq zdwan%O-3olZ=NJS#L^d$^ejg9eQRaPW3Ulox!9Kmq1%|F%@E9lg{*L2oufcj{1n++{+; z|HX*6f1`PDP{v?=(M7BHEtulVVUZyi3>Xz2Q?BbQ$ml;P*(G2a3qpR{->Zj5m=cqCW!ptrmT;80aJEPmV!f zXpNWJAd(GZWLNhaERG(5AX715RyL@|GOxmbru|16XNYqj%Phw|0sX5h2aglSFU8bI zU+)!9WQud22dHDnv#qCPP?L5WpM8*BKtjY~IQ?b626GDs3 z$>gOzFD-d#&r45U2IKO8oZZ(Jd7jbgI40mWqx$2|gvVrX5NUJcNJn_aX0n@S{IVM( z`gs4(t^InXGGQsUK47fpAS9o{MP%?}e9sJj%VqeRr;%6z0p3}MvZ5va)w9Nb`;$h? zRe*1;LwWrR`~~!C|H)Y?TFVK*FV>+v&{zr2Kf>=HO%~@35#n>eyj|645rxc-=N`|d zZ2S}IGL#35^*R%1kVidBTL(lgLR-WU`5`kwRWZ(SkHC1@4S0W-^J%S$Cq2K-vIO4) zsd3@2G`#Lr{JZkA{=Sa}#X3NHUAQ)e!8(2a3eEa7EUp56hs)82FqjtqZ6)&Xf&bNx z0bK~sfb$}GENzi7u?qF_vH!t$ZH;~o7k@Mpg!d2Voz_mJ}f+wrT@MEg~S8|&myG7b)}`}T?2f&^j}bs zEY}QGzRiO95R;SZjVzHX4lo+g&03w=MPQD!n(3#rC%Xtg8q+ zsP3f!iYbN#7{B7GNO5LYTs8~~RokMW=S}=Q(;AF;^m*Qqo>xAyMRX;`1{iAvkQnr_ z^jwGkUTTTpE^$crXvvhuNMB0N$roh{{923_Mxu}tWmVf44{0lue1A&im zIb0kGukJ0wtl)%myt=t90=^>75#Hw5Me>ZcfjoR9Dzo2B;+pzmv8J%F5L`Ck~Rbn>0m zcmW1R7lZKX5oDp|&r34xtvR4pwXhzhms$Ra3ygF>KqKR@T+FuP)#LP5%ik{$(J{;i zzN!vKPZ~Qd|FAul<{SimxDJQsBzyK*{%dY96?PBshvFRJ^v&CdHhCxpu^=MTKh#iGhY`txC8Wug1t4an?a+}NR} z+X1SK!>0cgJyL{J9J39bd3NWP;(s_1)uuK!^K+yB}h6zAs$DIx4XntR0g1=`aPw}`+W(qF$n zEGtC5@XGv%y&emA922R>9s5~?%A#y$&9WzNO&7AB_IMB8YxkTR&;oOg@bUmI z3zuTFxL~`Tv==)E*k3c-PJI!*ctrMx!bjy%>_Ez7{sUw`5IiGr31tVf#5|OdNajCC zPG$Jq)54ER3&3iG9g2r@yR0q$_1=GRCO2K+UI2GveuyFZJe!8aKd9}dOqt4mwrSi4 z*${m!B>8CsgS-Ss0Tk(P_50im@-HsgW7X$-Dv(^n|I8`n$29OPpr@<;f1c!Y#G$Z9 zZe`%2Q_s|xfB0-jO=(4#27r~pq>z~s!9^tV@bd0(dHUm`1$QuA$$K)fnqxTsxh^4` z{}8f>;oIZk>%p(+TZZ~9l6ip)3SWt$xd6CzOPsV3sX-Q}3Uxz${m%ytDSsdxdx5Z@ zf=Qu3%H_C-K1VuX;R{#1P<}2nIJ@H>2^%!+UuJN>{2Sv1$ zNKf8QiDdqbNOMSf%H!fpxk%=}kMv;pz<9VR0sbY+c!n>Ehm)@>)&8T&ZDk zkyBcMI|lo$T*Kjiw_Humt#OXgzZ#i;5JA?v@$m7`U;5Ep$R5i)0aO>5eXPk8rn4c% zhi=3Q2=?zVDHKk5oR=4I5y@90BhGq6l#Yw8GLykp2yejfmZyjFZ*4j;y!YwhrmzD5mvsRyZW|O0N!j`wKAC`hD@+PW zBAI`@^B`QF6SyR_FdifRGQ?>X?t-W;Ax7Bn{gwt z%ubM4X2&F^7D5Rny2m9T^S5jG_4*?c9quecB?Qpgs`{G-^wM#$yiqUG4<66DCe8fD%RcpI1$vPJSakgJ5t8i0!{CmND+{v-GV z3idRZ6p}=86Kn-6g3Gf8m)a~pCff|d|9+13@4{%$HGo)vyOP7hw&N+mObo$eE9kuR ztB^Ps<~X)XmI*mNNao83cp7HSYZ#3uWITnw?m2kthP52}C+geIvyTCpsz0rcevOlD zVIG%DmrNIOx}K;!2ajwhW@{Pz0m>9VDKZd!b$He$Z06)3-wPlz55^ycXCoYE)5A7% z2#$+jsz$_QdD3sb9A&M*b);;SFNg6moJq=;V`aGz#cT}$H>y%ZH9q*p7DUBXaR-#$ z4%3AN7-wO_F2>jC!^O6&z)2)e7waH)kvPNSy5d}QO+(XXL{oO*IMFA1AZjWKqHFru zm5(9fM`1)4juvsEa$Rwa6nY3kdgSnP40#b!&%^jRs(c8?`!ItzNXNBc$E|K29xKrU zwx2`yci^9*3}>4-GvK=7F{>Nv>zT)|AoB43uD zgoFd*=a8HaM=ng$YY$+z!>x%q6p}K%075Ab0`mU@mtqi`!-%dN$m3Bcv5IUV9shO& zcLAXjjGv?VAUFn4LUduLiHk_r70(Qd@p?wat~7|lVw`Kat~giS-^7fQVjbtNIMM66 z;zX~N>gPN)5h)n2Q_+{Nr}v6w({f#LfyqsRTankPAk788hBBv#*k_1LY1AbyvIg{3 z6e;F7{Ipw`J5W5clLuor&;JF0y`b!b@xKGlKjCoYr}58aI&sqK5vW z#<2pq$SsgNk)fL8Dd)rr~!h^DD}5+WHLq zPhbYIpT%XQ>vCo8N%FIc{Rrw0FvwS&%(adgu6e^A%MiCh3NYUQ;M{cvxza1r56%lek5l0=JMP0Uta^_!-JRof;*@^F*ASPp%1 z2qXF)+K+>qV#++O3(EohE00uD*-aqb0Qz+lDV_`8Pj37V&$UFK=#!+a2JjFl_rY}S zjA-I4uOQ1a3*+o`1iu6P4H*9za^U!Zo&oTrejgIaFo@+8MzXB8Ofh@KTaX`|GHVxN zNkJ^V!6}9Dd*L|($K~|=29bt8;J>(Gnr?xoO-x>i%z23aGa341Cp26N=u&Xbf$<-N zrx1^n!Z2E>e@sY<0TjXx&XaMW-QaA3(L#^GaSzP+8=!&IRyVgQQ-j=|{q`4f&G>0$l!{3#?lz~~%&6qC0^ z-h7jT7vnkD0M0rX(S>RHCPu7vIV=YJknIrx?AF(&@gSu3Q&QLFPi_*6O%$Qe!PZUS zc95=t(Y1LBj*nrQvfNAGjhFjy3ZdMmFbZAvUD>dPxP)mWpp9saZGH}kCNNs#TsWq~ z==MRHZXeen-LD~00;5NXX>g2(FyFVhrMhd?}Wv(Ry|p=D9{9qsiPHZ4K?7PPphBxNRs6485zc|HW`FHWR|R z70aciXYT3Y+~8f!aCV9WJ~zZUuzJ3Thp&bH3ci?w&XUE=yNzQ z)m%Y^@U)_UXvm4B{PJ|s3IZHkQYfCni6n(ni|E6XFFD7#=UnP781I*9Jnj8^KuR8oC9nJ@LoJ_5|;^CU#khDX~BjN8pcMgq0(|9~zg*F*1D=7ET;#D|+M3DNrM`yP;WD^f#VX zz2FgB-reyX^~)sLw+n*qIGhKTG?!%2C;P-4tf4T*D2t z5|E0USi&bTOoya+Q&yJajfSR$2*>aFrSYW`{<0f?ulbf-x@?BXD3i|W)>6DJ_tr;S z^V9v%xTJKRZ<g?QQ)Jk6Gw>q8si3GPbH5t*C(SCvcG-TXeRg46WZHkn;R zUy{WGk}@k>P6jJy>)Qd5*)!$F0=$R<><*awV63wMiX476K) zxkyk+n<-OPXa~}?5pbIR;s&vefsWH++rgN7rW`vi#cv=M0&fIkEliAU&_16=y8!9w zqG!g2)%v$k66Ci&nWF-9FWQGa;LIbz@S+zM!(lt&#mi7WnV&nsqQ|4ytk3+y3H}J3 zE!N=TS+^n?;FoxDbs7&wK-L-EVI;=-83ioXQ6}>%$LDW=v#}8HMjV$cVw?$4fm+P` z+6f*>!9Qi44hruU1gy`E*y1uM%Ni0XMNM~XcM#N$_kM<2>sYS_?Ym>NAs*FseDX(+ z@OHd&5x#O3K?-G!QNKdL=zn3G)9=q3B}3bSSiH)WpJHV?N#b?F~raUQ}hfw8V<4ticqXogg`4p!ne z1V0dmVkMwOXX3x74?E%oU~k27c?;z?umG}V$&6bZk2r#m?}7jRSDe{0qve|c&B^ef z{li%IK)~pU>UhqQDIfeE7VUsl5@!-6Ga*9PU4bmkld4TqzhKCC;ML?j$YdCJp;Rlb zur<6I&<4UsHLO#)RI0aoIvTzh&^3e;V$hs5QeAhuM{^zq{uDVnl_nKDIV)?ERIfg3 zQt=`1uU$R5&4e^(n^do$o+#zTte*^H^cW7$$I99XPRoGiGzH#<9G#v74*vDK(MYK| z1A&jJqesVeP^y+V;GA(S0=^=yN0_AG|G+OnYa_fL&;@Z7BBWDsiBt_sOe$^zba$<^ zhA)$9!YGq~=K;M^E6ww`vaXVIyUJ>*>hMsjaq|+0^ zoRbNYm@mzFLaJ5`OqyE(??g^Qo9nkQAhMp3>d;#OJ;;s(KAs%Y@-_UDR8^yW8eR%$ zHDTTIqgS>`!+oq&1M$MgJ_KJ*$SqmPAxRk0r|4XlCyTp4c$_3R35FE{U>A@Fi?>ZB^9i4jZv zexo4{0%;P7byIe1A4(|GQvE*i=ptAF(g9cF2_}yT*73&@p+#^)^ZxxIEpij+kGs16 zUZmJkpC0yVk#|A=zrTq^gmeVumI{3z)a;-i(;bXS{OJ*h(ABfib~{_@g-1*!wg+=K z*}60Ip}x&O)RlAjl+MkFHP1tcn-{y ze-nWS-Gy(FvsPPb?6;<;{|aUh`#5LRswS?tRGWR4uKorfwIQ)?t=`f)D6+O#3a|EQ z;y{ol{*^{e++nE?XPb_;9Hec3rEz86|I_x}@l_Pv`!icI_ujpmW&$Az5J;$@TuKPN zNC)XfrS}ff1VmA)AVr$eRRjeoiXeyu3t&Mhuc9bmqo{~jv5V#RoHKX#CW!Cn`^WFi z=QEkT^E~Iwnc3+(JBz+lvl!g1TM4puUwa zsGH;q>Q4EBx_7>yu|OuN6HPad#guotsdn!&#ZS*D#s3{y!Q*O`cT zGT<1Bjxbnsrm5DVy^R2?=i%}g$@2)K*eo+)wTu(*AO!m)Mc-?2W}68&Sei2h_$=a_ zq{`2Fk~yBc&7`|v;woSpeI0ZqQqB5tqS!REB<0mdvVCb-z0fRvTlcUSOiCmVKy^mm zkJPP@^gm_zLynN?HNw9^M{vN;@toDcnKv3@Ddl;}m8CB5jbs5lkKsNgvP(M?xb@k#S;=lM(aLkWW(*7+0VDHC z{6lOzvr8asXy^=uJ)^^>Rx5(Aks&NdicBKoVbKQ|TxV8yQ#;niHp)DiSsa7a5FG(f zv~zGe2sz^_qES|joVD>-<(`Kh>L&GbErjK}Sa^doUT%TpX{eW4SOidK1o!qJ`6lCY zNpz4pQU>^VVADKYm#_pn_ENP-zkv8<3G?P=}IJwst1Lw z(%+?!gj7* z(uy6AI%$%w!eVAI-q&>PxT^5)<(wD4tzv9aOWP z(FmPDL`sQBA4>2!mC;PY3xF*3QNH=#BSVCh3Zru-)2#^1bSmMVZf>dj0vsyX;(0K%Z<3aK=;q7QB9oU|{t_ntk2#AByBsiAVl<|u&r+!9F zz}?RB5Pi3VwI141Rvr%s8CN6JF%dt$Z-%^&YZN~MRG#C;T_4zfA6CC;23mwKx{VdD zZA08Cr`$y5t|-85cQne~dxS2)eKQ?7m{N5EMbao9(lg^cL(+7Ag z-zeS_dhM-f1Pl2BLUX9Xi#qfrzoJXsk~Q!cYEFlcu)Bp?uEw#NcJEMD|2lCZVCTuu zenekpY|Wss^JNiEMKWP_9ci~Ni&-h)jc^7-TP0)lqGVCpv z1L6v}rNF2LXCxw%C0)se_$N~Th{NfVww6k*yaH*6(?5juHRQ&PcspL$DMl!(R7WKe z?KC5_8;eoN^vljP?53AZF%635k?vH|{Ug<~@bNXst1QFbd#@=d>J|J#G@N5r~6gAGE?EW4W7p^x-{Mf-1-4J4w`444BGb7BIQ>JHUTiDID9RXqW zK%%m&)u>K(nhbvq9sZpb<%?jfL2Exa*7=Xb=-toSIXwh&Um5{}aO*`&)qXq?M|oiW4`)30I^DQ>xZn1xR&u8% zmUsyvw*k6~;8z$%aTWG!R(S1RL%e~IRe&D!rEBzUKU&bFTleu4S^4^l^cWdsn#|4m zdsG7KxnhNa~ zs^6zr@+pe&;)K0Jn8Vn0wkrCw5(egLqM?ULN()9MM;&3iHg^t&$(65&t)3ZeYbKo) zHjYFnD!GS5G^w1emi-yfqy-?X^+}{xo{TYT+UkdvQRW`7UiO(E#YnYnRjjAf>Q003 znNQN1HYX+tyS}XsD?E^(^7S_e30MQwhEb|?9Wt5O*j71xbR9A(fK|t5Qk(^uZEf}Z zlq9XQ3s?hvCPl27&ggfMNu6!AyeSraX=5Xurm17@-V!W|UO0EBp?Y<<)!(aZVLSxJ zj>4>-pbD+4r>#1F85G8=V4Uz-{jSp0*H%-pbYols<4R%HVAl2Aag^FYwtB8aKp06V zJ(+NP=jFNA=~mr*9jf#&TP?(UAaq}hS|HRX5*MA|&lp0|I4yXlXHe`oj3HpHfgv#n ztzhuw&90!*7aWd$gWAR5yVK%DCsf?>wXf*q0`&0vQ53uHJQy#Q1ndzqypwFmsD|9g zq~>~_uh*}WDD*Qy>RvR(7V}ue?qH!G)`@LN4JcomFB7Af}k~QiBqNSRa!$CA`r&^M7>Sx z&<{Kjr!JI58&MBn6FB1vWrV}nlX2?wKC}@xB7CTaaT_5i?}T~(5wu8q;?#Syb&`x3 zU@ax4ID}}ZX^^@?55oI3_R%YY!mNswDEnfZx_@R8-*KZ12)RTe8%64}_t22u z6PHFsK9wF-*z@Dkso1B|5ZPWBSAyD>|5ht%EHed_h5u4Lg4hNwo~4p(O~rl8dU`T- zH{ToKS1~Z0F56x~|81D=mX{NR{x6N^kdle7mTz(GFsrrwVMnYhi45LhdDGg8LxnxOXKcXlkwAM zO0+=m4Wwr{>G7Kkk&VSygbW5WlHdspdrijkzZqf>LS_S+?@QnKGX@d!FQ6|(5DwnZ zO7+y^s^)|YDcGD82Rm!c2)qnp&rsnL$ zRO*o&9L=AJg>E>8>a%^{zvd*o}{EJk=i2>xA1=D zJ_>f~qkYgiCAh&*|XKx_G>va57*#QWf$D=eA(a$i)LACb+iu*bUQ-Gtl)p>3bHxMC#b-Fn*Qk zo<*GDD`(JJJz%OmuLhVChQ6Y3%#|;aKrwFKZa3Z9)R0(&rj~pHVoObzqSrbeHPx=~ z@!kjmI>PmX(>mx%D@vV!M$Ep?biYPWGRJ(-RIPDX&P)U>@+B_AuxmA)|DPHQQS&HD zWz7%nH$>LL92y5SvBK+1Vwy)6qhSVL;$Jk`Z7i2ksZ-O|aw&oT!=}xj z!-%Y`jd)eSUTlSjWg**nmbk`JFO}1?#MhC8qj1JSx@*Y{KWwSrFnT?Q;I9cf1V~RZ zlb`54Cr&=G|uJsf0rU*QD$eErNT&zP~jq_keHk%XfP6$opne*>bMWq zJVX{9C5w+!ic-0ln~ICMMd1I=#)2KnXv9==;4LUJ2fv9ES?@eXb1d`&Pr~k8TKSCi z1MNq|i}nca3TO17XYqbN(B&yx3_{3gKobZa&al@H+>R|>V-T_s&@zHq+HdRioR15_mCwR^`E(i8dP;Aae0{)!u@xzvQ1Ms(SKfxIj$O3=PmxpKLhEp1gU~tA1 z!u&a3pGJwoD2MRs9wsR*|2F6A-q+U59-t2<5sFIIq>T&yoUeMHI8C|>gvCCI^vao} zTr)A}+m(@|nOnfx?K9`bNSO0o8Wz%|V<4RJNm`RP=Ucbh((|()KrpjC!zfh+XL6YH zRV$-3vp86leI~_Okcl~8{c4Gt*%GW9eI`YG)ts*pmOPBnU`+E_Jm;h6V{^WtwJ@$; z4#vj9tip4?JIY}G_$(N2_$;3D70`t_UyCE?pFRQO+rq5Eb3PkSwhSAkClQYCyj;k6 z>&^Lg_K4@QYg7awLL@FaT>a<)0ME_%f`)OuXog2~J}Q0xea^S16vk?KeJzp5^S4K# zI`b8O&KL0Y`tvu;`6hwXea#w-+YOp0o{GuD=6qy}FM~dFD@a)#9>Vhns<^|k1fLs} zm>v0xHMgI@dOLz$IAbX#-mkbPzY2)82q_Dw62a>k_A2ggm=`~akmi8e`qF;I)pI_I ztYF3cnCzMGJ}p3E&Nmawv6++=BA0;JobURsQqRG*K(XY1h39;9xBWTaQ5?v}bH4Y9 zeT_Na(pMb*7AAM#I^1J5=o&+6UA1b zkLz9$FT|q`V!qU>JPM|rS_x9l`0_Agfl**O#5dQMJmYdtb9D7dN2vWcaWaHNsnLM+O`UbpAd3CptS@Cj}q)vw^?{b_&ea;fS&WEdA>CG zk`jjz^qv=d&G`};Qm`tv13PO(yaih^Upj#&Ot};kn=h5zmLN)3Kz6|yX=IE)U)q8* zUm75|l?TbvF&y)yHY;4w8`v-(FGsjPUm{y90{!{Y-rk9#5;)5dxZ0D7&6kRQWQ%Hm zcL92a;98{5pDzVw1jJDUpY$XpUB%{0^}zP$OS=%cKVSM3O9={TPln?}YDs^-RP30A zGuP4o7sgY)`BG!j?9G>&(~oP;m)d`TwKJ#~4>!$M)e1HWf4;QIj1$X%ZSZlDxN5%S zT2jxK`dC5nGVsG5yTE*jvR7EY(GC8rMRdNDR;j>zsTj1x=1cj#lxPFfjl^6$3WhT} z;8$$Ev^rVF=1V&^E9TS(ucgP8T}i;7FLBdh5$eyED0+Xs^wf8b=mB&(+!9|0U1>%B ze5qz-fgl{y%0RqgXC1gXGos1ua_>JplYVlb8H)5Ci|ue@|V6J zYVVe69=4QBg4{Z|4J3aTiKfy+a(lCMeXXc5v36mN^Q)^eW^DnNA&%^&*%$GcQQBw|F9pUPR!xq#_*4%u_Na z3BPn^UXm)ipJYxdl9K_axjMJLm8#(pLlgnOCZM_mbFwu2vsBd%8-hw}7eIYH`2Uod zB$ZV$jpkOVR(M5KnuX)y0hDsS80uYQ<0A7ks(Z9%mbP4~th!d^TI!p8?D0j^@4=lV z6K+POlzq4=^GZfZ%Z=5^EX$=TsHJOIDl#D~zJXK<49J1g(sUJ7!D|?$ESIY3|FCcN zX8lrRT^NQZ_%!S96M>=Ltbf8di=Pd@0MibVp#v#}{;a=olYlsh;PV6xqa5I;r~a&e zKt(Bj1!h90#<>;#-=#=cbWgL!=9)+hX8mCd^Zi+W5l24;nh$I4CyPdt#pC&&d9!|M ztStincQzIn5m^HfQ_W{;I-=$|JbvyzezQdnnVQM)OE7%G*3npjY$bC)Z-&}0!r#4# zW~r@I&#p@pv+($$GdMTF8MCQUYq$fd@#n5s33wc!$pqia@YsV`l~^LDC)Ptix+^h2;Nu7&_ozo6_fcofEvZ5Jwq?|N)R;HzX?zuU)pa> zg+)`mtYACZt8pimRcoLsbGtVk4LgR8WnN9kW1pEanb^B3DzsnxL@l^qzr17 zC=%nJ4_h_S0tN9;B-Oc;CgS%y+#w{@$69Lq0e&MUQ0dNrB}M$JNvdN&^g{wi!Wp$& zqEt7)KcV5*k}k~;h`RvI_u=aa&UgWjW8;shn{jO3gMha9a7%*2v~?-|eM8+-Gf_~; z0pLe{4vsPQIA;wt`@H6S4*YwcGm<#inN*ECGh9@UZoj0BAUR#{$K%NOja42&A}ih7 z5|M4TKf*d;Mf{Gy89AJYMT9(N*SuSaW(e)zA$km^1-IDOf2YJiKw~^uRv_sCoQSQ- ztIj2eDhRk6@Y2E*Y=ZLa>*m=<`JS?&8H#Pu$ze*Vew}D)fb!M5rcCs%Yd#vgu2bMT z10~esWEHsn`jeQ>N0Vcm(*dtnhFaxgZT)WNX{5lr zK0vAYuqk@I5*0)1kebIO{VGu@ZPHp-+>Zd`2Ffgv6HZ0LiM?-AYhi|Ruo4QAxA$$r zG2E3O!KM z6nZpA$Gsw5>ejUQcT(+o8ZVFm{i~3;q@N;H-hx5ki_)c?j`eA8W1MNI zpU2pu63o$&k*tm}jrKLh)iqSr(Nd5NEs0cyGWQAD4BNgwLVDRs4ihP_zJp19iM&wl z+Ne@aYfF^KPw0Hy7SkX%3(gop_gN#g6ZSr9iY}| znh+fc2k*^Of)@%bx?iefUFSbg`J|*TM{LV;R90hWVJj(A)*>g3{l!ib)DM-l#JP$6 zrOrh5mpS*bzub9}{rj9F?BDNv!Tt)zYD;n}oigmNa_Y0c+G)f78fPr~Yn>JBuXA>> z|A6x$`wu$5vcKL*xPkO+a3bt)bULyBh%=h~P0lj*w>W#*-|l?K{u7RDM{-X(ne6X! z>a+ip(~JGx&SduYILp|7+IgJ)z0M)_pK;E!|E%*Q4)s)7&pEHL|Ge`#`}>@@4ix@^ zQqzpiJ2lupG)%T3_OZTN>rMWulCmZfO(utnfb zIe46yD0g7Vk2>q$iBD9`-zi5;6jS7C^nHY;VMba2P5WpJv`v?4^gui|uO>wU!k;8* z{>LNdw0FmXv>cB)TXV$-UXGD1}$U4i?p<*RMt5jKMoyn{LviuY3~OB`G^ZS`y{ZQK^1_xfG(1 zrSdsMCsH58=JQg0WGPCjMd4|6dV%~7-tM|X6KfKgb2@ES4?yorRkDcAyRHP09E*cV6)^#Q%&PcT%Gd>EK;Yr}k?0YaqsSX=d={)BpC{d+rId)g_^PMdC zIqwce@0LBn`L=m~&sIHWBmU!1c@oa34jIv&p?OJHsQ7%1;9osR z<`b?(7pf)DE!_r4FC2?X+D{+Fm#MBpfL8|Apb##fggV`&X75#(FvP46t=+)s=kqw8 z1e!Z$-{v*}EE8xhnmy5_Vs)oQm#VagQTJbS=n#!m_Z`@fXc-R z2`PRWZl90FCp3ZX*VPy-_z@~k;NJ%^c*)IxkEjE8MByI+{qDmF+eZPu-IXmM8Q(Ag zKi*acpo%CmtDz8O;j|s`YgQBy+3%@^Q=)JqK+R)t1Cstg9q`~jfCk0jwkU7eXH+|k z;8^)IK(k_S8)RSh1$7UynzB`{1GFIqQzgs(N)^XW1csjnv_A$@r=0!0%IX`1PXjs= zgXv(|?BCSz8M>&--vIsX!~9A__7t}*-5!&6Qf1@Ck6XuSjx5^;Jixw!mu~c;0Dc^#IAao%Tl~T!XesDPb6XxA`LY3W4 zss&T=K$C9hXi%s5^a4z3WV5?V?A+6htXv7!2A@g7!eml^skUN_NzIeo2g2Jv$yX-} z(1%F1$Bfc1ff_^*y*ehYN23p?GlgFv@@>Z%vSh*$sVbo8aBx*n8~u|m%nV}UCExL-qRgAY z8tyX-7|YD}q?(F~!#ZbywcKYGFqWC8rJ7ta%6uHG13vR=W10T3RAb9W=^ujn)j#RN z{AnqSJulUf_E9E%c%ulM&V>TTGV=?mK15r{#zw$u>@y1(%gnE(nmsAX>;cv-KJ#j0 znT~grFLsU6?*Vo7Kk34}aUP8QMXLE7qRgkjI_NVC7|Tq&+x+$2QRYWreeE*~7|Tq< zP$%zxlez*uG`8|u2a zD04noYkXz_W0_gRP$j&gwHvHAeCE|T%k&IGH7Xrdd>+&v{z=E#J{TKiXX9<-xlyKz zfkkn+e-r~|Rxs3d8D-{!)zW7cFqWB>4OI^<85fxTU`_IwR~yUp>V_J+FiKwn>iU1u zMcQd_-a&ALYu5xBOPq07Vnb@6vFLIW#zr=Z*{iV)9_Ln)Q*R#*M^Z<jnjes2b_`YKj_S5{~>2H`wu&Z*nh;i$o^*MPxiMs4nAe=9N>&!AP#??v9{@IQ+D!2X{_I^Rs; ze-#O_|96op@Jr}<_J=tG*dOlP#{LLr zG5aH(P3(`tx64U>v~z*|agK>MQ&gGpPI>k**Jl4#X9W9`oCWMpaW=4joAWIDcRH`J zKg&7E{%q$P_UAakUZiiXlfnKxr#kx!oSWERrHq^_BJUC^rONdwr!RCIKYgr;xa$pZ~JH(!LW8GWFRc zt7G)nR|by6st5?1iL?$Di8NYXiECr1mmy2G9PlB21{SwV@~AqM-ieKSM!Hl1QWsCd zk9TB%Qh?9jVJE#P(oHrQFbG4OgBbm0xi>m>@gwE)tr}&lM(EHMQFdmoIPZC(%*>NeI-OvI7RAhXzh<0d%H)~3u}Vk z1a^l;y4OMscvNW7I|lBX;jQ4+ZH*jGz|l^L?oo9V0nIZeKsNK%fz`*57K?(;$ObnS5$@O$J-gt82?&sXNB_$0!Bot>L+$J#1R0ms2H=~NKvor6 zwFGdFw1=Q7^fhpIQFUrA%Dr&|u2-wIJ&}hHX+vUkAtt_G1;~@?M-ycM0b}5d|Bynu z(m9s01GAw-cYXY02%1Pg+>OSG64(of-)l%f_J#oKOX`ce=RO+dA0nyVVElSLg+2x? zlD=(-ABU33(!g0snUt8Z3gcw=UDXp-d<0EjkT#BX&U(`%Mj%h-Nf`R4usFE&yk6QHUQF;P|`1Wxb6WL@}2wg-78_8B=Ja#YOzf^k+ULFRty)Yc^jo)q@=I^uhWad@; zK1>`|9$rQHnIcsxGLFpr6wr?Za}4MGdz*Y_Du`)P6-U_&;(jK;>9iyt!Ys?p!r4C6 zaDNe8)q`}gNIstc{06DYVXV;%Sl2?hq#jWu(8{bkAe)PnMU3#SG>CPSDp&z`28P^) zz&W016z+ye6|DXm@PmLJAy_AjzI5gGl4?*{ov;@G9gInb%K^q9yB3Bil#d?*`pT1L zyY-wtc~%(2SyH_KqHKr80FI;3B$Cz4@ZC+oT!h1=AVI-Z!EE$Twg~rJ2;%)xmB`h% zp)vDKTU1#8N^rgPw=9J zJ2G&kw$H{w(32RkHTBs%>7##mA&??Ji8%o3)gYh1>EjIGF^r25`bs2&#xS#q#MX2A zlUrkG;(mn#lEw(J8rUOny3k&x3YL5W3bBi&e0K<5jRN+LkNZmazD3Ju!i}K+gyI6( zFF^hEpLF4HYb6Y|b_{HZ#~3>WPFI44jJbxoA00*o1lRN+-HK`1VupG+1lcwKyTu4( zuqIT*AwDxf7zuECA%adjpGcso^$c|YWn8WRZQC`doK2eA4$-0+lKVmX;9sZ(&FpWe zX{gKcdvN1Adim-XzJk=XI8rAC)J)LI`P5%xDcWnO{iqPK0l;=Xfx6RzYW5jwUp9gU zf-%8o(VZ;F+Ha^g>wt9+7^{62MHXezUJkdYsrn~@wF8XjJeKY=O?sB-W|`_^6!1St z?p+W*@ko-3jwa=rY6$8elYRri>QpcvgeK*is&ertsRRfWd=ghNO=@kbceA3TrXbKz zMwe91CQVvos!vcdIJ#jVOz=sRRl+=g2E~2ERGBE3)Vs+=AS@>mH+Lqj3A#H>H8dEl z%#Qq2*pSG&>!US9cT`@V82MvU<)axRjvS1CBZ;ij zMT>~;7pA)Twy3f>z!nhB%1p*Dn`$g3F)aTmux&AUTJCiJFx8UlqUnAW*x?vX>z%G` zsZ#x;_-DW_#c*1sbQ3If1mh{zZ=)hPa8dhcnbIw0so|KLGhPN*ZVab&N;lh5RT}6{ zK{f~0HipwerCZTb!AKMz3~Xc!ruQvcc=H?vVVusej^iSoaX#a+1^~k!F=c91k!PTe6Bu-nZ zM?X!JXTZKh5;5Cp<<|YqQs>ZJQOqVr0r7BbfmX_tIJ^;$o|@t-3%D9lVp@1{*DY!* zg%*W4vMmUmJQBV+iN#+x+g7jK6*Yb&uyKUzT0o1xZdF^2SsayL0BmVYp7DCNibqpH zX3A~AcE;rCGm{LA z5|ZI!_f}Uht?rnuUQCQKD}j~oGdaahKe~%vdVzdn=A1Z1yW5zVib+croX!$mNSL%TPCXEalInuc#wT&a1yYPx{Nw6GnS;Q( z#b@f0LOYt>Z*YP%;yRtb&3zM09m5N8h#m1}#>xsh5tMlVcrRGkE=EosWPx^Gaiq65t6-D`*T!J#xFsYoo z!GOX;ULDKdASU!Elw^uUXlC(%DvzN$-=7L#)%2MZL6lT2pk6^o&7}4q^eIG=%yfQe ziHMsARB2REIT4Jh9!r>u5rx|~pqhJmdLOVY9v*87qD>mpCk0fs8=`4A2G_Yu7nnk5+qMQ&8waMJ5`>!GQV6ZfPK=Wu62SEMs8uS9ikY$XZ`V_aH&H5R9rW`rr$Fm6h&DW6O zq!h4iWKeBRjmqo?|ATAD#OAy@p2VzMl@$cE78Wz1PH-b6NXLCNq{&6#ze5fu&J_{-bUGv?bKI+qH%|;ho z{~q#B5nf1D<;$QN6TOiyLgu6|7mLA{6X9gkIQQG2x*V-8--9mka3a>WYu)^C*Oei) zDm^+R%m6DwOd7A~wF*B5;n2fkHylzO2SZ;A&^q}_>0SzR=5>g;Xh^+}9AtY&f-uh0 zC-`}`n-fwK)1vqSU`wyUBO!GV26Lg=25cwcGzi1^3UY3pkXmt@UVV~>fxR7*r)QUL zn~?gcW;8vQfC+T4Iz4_CMU&6;n?ovXSd^X)YDJ&!cLe&OsC#=zeT+7NGo%?w8dTzklR{euC?s38@OGC9F6DtX!X2z}TOb!q{&^szi?{vpHDZd}aY- znVI6Kou#A9Tfmy_Gp{z5>Di82n;fM-2yL4MQ z>fr%V=4E2__cEY>vCJIpsBaoYnVDc!^O;v0%k(=OH521f&abwh_WUPZKf!gEI%*9j z9L&5GtT{fjfU)%K(p~SUM)jl2hrrt5GYc5Y%vT+STCH`y0oKPp^J-(6{;s3Kv!nE1 zK@A{FuBr_B39fs=QJ;dq#+C-Fy3Z_NEIqq)e{s|Tw5H6w0jyp=vw*S8%nYkfy+Sw% ztOY*vYGaw68&+emdc=w!1$ECq>G}z-+c2ySO^P!A1J)-#vw*R*7sc%mRtM2){Mrgt z;5V>>m_q3c;ArTd-e%$s46B5hdXZ9QgH^?6QnI3?SHfx?Y7=k&Xaz!VpX95Hj#+3+ ziF+}uHels|>61ZS@h^0)xzXy&f&o`mfoUxGB!ru5sE#^kyxYig8q0)#JpQp}hF z^vA`3K5s)Y%Yya@PPPeR1g8cx~fs)UPE_((bcqvGKV z2MYCeyt1v80E?BE160|Ec{^U&cB;!b4L1kU)<>`F+gxvCv}kNlWvq>VWh>+Kz`?jb zRj#r^u zkqrr0Sx<%I7^Bcc_4Q~#6%m~0LGox!bh7H31-uQgZa%&-jJu&#->yDN0zLxRtv-I7 zMYM;Y#XwE|QTGc3L7w{K+4(mzW*A9A?tI8D-&v9TMd3f}F z1sbfBTcJjd1%4UWpB^qLTJe;$FiI-7;htQ*D3ywvk^!eP=)9bXkwdw?YCqPsJ|r`% z`IxY7K}M=_-4cf&Y`5fyKDWQZn1oep{UBVQPQ*R(+u=~vDL~b28YCoziq-P3-2w3~ zet#-6M<Gspt*nM`{-LF}HD{PYTaQUZ7e^N#u)VNrl8 z_d|Mf_&F0%a02BU22)US60UEG?fgxXxJj|T0o-BsT?iSH(P0)A3GiEr4&_l_%MZ;M zUM(6TJ1ifFkYO1IuaAZp9qt3Q{P2uTn7Xl))nOkpsr-nH0k|U^66nx&DMChOH0u%# zN$l_`^0WM?j2ZFKkgU&T|52kv`Oz6EsH!a1D3RMj{;JT8DY14M?uE*P`yyzIa&?guKF}%Ih%;D_>38KcO2uOQoh02wK4f zX`|IBpD*p?8BtTekb@^8sCiAgYfXNM=$y!@j-^<^mwp^+`NtA=`u| zwKwdIZBdOt=;4zzK8O=IsUEKHsFv?+*k{@bu^8AI4`)k6GBuLryBYRf zD6cz!Jy#eHKaV<7{w5sdTv6YtcYvSrI3jryRoa1u{YVQu0YLCy9we(!Lb=o>=Tmzy z#IV0du3v{+lMSbHgGo7@n>Eoklpk)`DfvRw2BB49QXG?RoD0$@!=_1WZxBZNB*JA$ zCf#F!bcbPg$ie;x5SIBQ!lRl0XdXy+8llgS{>>oJ11W7&4N|gIGT|;GwB{ZmUhzTd z;kd8V6`8BNum<7Im$|1gG}eIo;(Tzy6sYgLaxP|FE8{RvBpYP!sUKvD>eI2T#J`Q+ea8z?V>yiE z-&XG%8lho+3IF(ap!Z1B)x28MqrVe-cfgmYYTbygfbp!}U!gkYUnm#--MIHR7;n{X zk)?lI;jWAC#3HtqyApcfENU2n~uZ!K95s zB>MCGCV1|F<@4zM*aKX-?{Fw03Y!j85pRK@?ZDo4^R;6_W2KvP!uVFMp+^&GB|Vv zNYdb}L=hR0QWDo9R5wnE$k0*>@7^ZOz{hPOBNMv=2qe971V2XckHn<4_?TQ|H2+8| z_tpf6jJ0nY=?bE5gp+h3LN!U*uySE2)2zw%F`U3fj5mly7oyyk7(hktwBN=zmPqV8 zAuK;fGBn5TyDOm8vVgECK`DzHI_Og#3#~wb7|whLU#{J6e?2cGCIY(4hcgJCM5pFQ zj@b*746)dQFlf6_5$BfSW$bDw^xn(ZlPkMoFE}p{FN>rrMPJ4~J1S1RjnEH0ME5Y> z%h|XfFUquAa+bSjCShuF|%h+@iaZz2+g|H~2Qr0{h;@9G7 zCt@ar_^-t?$$KrHe)zA&cQ|5-$;d$$4>u&(e=WWqPNJufQ@}s#=TdQyJUD*>4*=0tR3Z+)7Ozv<)k|qD z(7cznkJXG_pT@PSHXtRx9x70^fhkR)QdJw2(vp7NT8T4XCVM(@AAN&nd-zEvGX3 zwVh+^*Ktm>U)TAZ{d&%2_8T~3*l*}eWxtVgH~Wp9W$a(?w7|$tRd4E4VZXUkhr?Sq zZP;(=bZ5VnGl2az&R^`ebwbR)!NHe4A>Ym^&3*^xLB=~eTiNgAJk5S*=K%X%ozBeb z=F}y>MqQ`DCh{9PZP;(-3}L^yvw;0p&Xer7c21CAv%d3fSMnP;SJ-dp#M4W(H5)rQ zo5^qDRAc{o=LYthIz!oS=FDWjxwDG>7S2=bw{+fMzk?I*M)Dn3cyQoqq=eMaHfv0g*RBb(rpmHxY0G&e#Yw@-h6=UpCF_SBgH#ViCq?OXN*f&*I~- zzvH)!bu-O>ocXjnFmG_BUHFksyN~kj#8Y~lC=6N!xT+pqgy?m~ydf3#`pjAC?cXIc zx`1^vG53+qyCrQyns@yr9HETBv2c?JBrBufqW;gCEV&54aspX0L<7FO;d%3s>U7$G zl($T+ULDVjyRZ&BVlwI(Bu_52OQ#sE*7 zqtS=ejdl{t76+0|DBF{s&;+q;Qk(I;K+1`FK$^r*+I5t-O?~vMPRq?e`o>V&bCma_ z${1#_=E*>&#ZcODl($FyI9f4!KajOP8lqF>^M>Z3(GcmhZk6}E>V6k!BI1Z%E}0s!8Qc)8A5q592fJpml}oOLWRM$@IJF2>DZ1U7Uje;8wWl zM2P8Q!ujT75?I3ufDaQPrXij7)8u`pp2EjwNyoErFA;?cl16`3&7aT;-Usp#p?v4U zw3jB&kg9ESoHBvnpW*%>n1wYQk}4m^rBDJ=QI0a;qB%p=KCgc^)rv5^g_(!F)mL5! zF{LqREr`mRLiE}}-hh0n7Mfa2s^#z7Oc@EFVjV7WUzrEv(i+^FB!bwxo7_*I;P4yl zkUwz_YZ*Lks0#<6YbzLg zJXV3luv*9M`Ij6qj4VC|{FKL$oL9URH+aQR{qgMsCj9`yUp|TROOujJHE6l5NoknV zWy9(0Ae)3kTcCnvOf`Kej$*F^u(eO%f!>I!f9yV3dSR6f$ zVEH@#iMxFJs0$9BFx8LGxEfCfmKDRP;|+dfs*PDLHvqCOu*NZ*y58VwuZfA^3G85qrn5~p!s@^njGUV&r29|E|wFoE{w23O*&$LE6_?*YI^i4wDvDO)YI zEI*0k`3&%Pg|(P8oCrQ`sV*-iYV$)gu+R+0di3_)-~sF;US?}sD*}rUt}~N{6v1P( zN!!x$ZGd%*$uo|f$X}0)rga3cu`ziXNCYohs_a)m!Mlp*16vZ4XZ#yW{rQF?cmvK> zU{Ct;yzw;nm!-N+#*pSUgum^{MoS9qObsU3>h@1?{OtvRmwm!`YAbk8UJxH(n^X&g z02Y4Z;dJWbX**)AIrhPTqZ_4ifbu<9Qq!Sh;eCt2F}8XS19NKVWGArt7iMyFnmOH8 z<33K*%-g|QP?*ULq-L(c7tkWMWn6b!`U{v&3)P3mf?ZNBg)GxJ>Z;b)A@Cd@G zvLYmc_{3J@f>?K!tzKwF8A5=Ri^eUx~08yq8e1X_-hrsKO&PQ8y3 zpLq`b$pr*o_8|E_<8v!wjcJg2U<;aig+=dVI2P4|EAOMk+&Fn3C4S=}#XMOX zA#_Q)@;^$viJ~K@auWW{@TKX>|0pqU8;Xy9lz90ImTnw3gR++d zC~1w*+t0jSR3Y?3+1Sf*T{Erfk!a1X?$3Qj);5a4zM~R2ju^7$*Qr1WPdm^l@ z$jzMF=~m!i#{FRAQiy*rog896OU|Cs&3nGPwX{&Fr zCQkM#o5aLD2z=fbXnNZPh;Q|$OTrf5U!Qz_;JK@iCPJwBM3cxQsY=8U2$?(wFEI1 z*zG>f8LW-CNvdAUf?^4<^*&DW1ueyKR;fo(_d$5oCs9hIj%fGU zPL6IQ%G}c!8970w%tr|j;c7ToH8@$SpJxOF)r>Hz4XrB`%z!&_7HaS=sg|rZL?vML zeVin8E;(=hiQ07!-Z~$E<77L7(c5RClJY~9vApXtNV^8PNL$oErTmbO<%yyT!mGg7 z=jASR2@dj#I4(qJZDzbEy4aZshDEe0ySK%Qoc7hjB9K4Nsk9gk??(KSJ!{m)5Or-5 z&8qRRoTjq*DQAa6c}*q3m|61p8789J!SzZEb3LTGSN6p?f#61J>M7y0Xp^Xy!! zIil`)7IXPrz_onx{iKVV?EK@!9&2KXH3(=A_~yct_>NhY$p2NPHpaLBkQ|SHQ;72r zY2eov^B<|ch|*xv7ZCDss9c%3_(A}YAHu&!V`N%@%YQgBgURkNkW;ay*C&BF@(75> zeX_X)d7WQgs+PZp**N(Xu*-yVK4=`ZYUyub!886ao-7oFV_YBHZ>}2(B~9?keOp&6 zsRly6M-m#x8E?0@cD0gDzsh&Z5=J0i18FjknLK++)8T4OO>%bs`e-dCy5kOYZ{bGcSu$Dk*KE2ApCii zCYsCUqX5e^sq?)ktSAjvKvVE{JgMW-Wl?Tb8NJyNDZzbM3c{nJVc=ftQ4#gL-lHOZ zEh42<7YxTT9u8BX)e>9tK5YONKU~_Dr|6m=E^W^{g|ZxrHswuhn3EZImHrr_!5ufn zi!bmt*22RJj~N%zu)-TN9_o+vZ}8+O{F_VyPtZN2 zD}T(mf&{!VYvj zmotTK1;&i@vO_L~_+!R9oT=Y>HaP=#LpwoCHBO93bd*$_jtX zc%fAy8~TwC`NPB_c&Z{&{w|Hujb0~yd92r=6mYLY7k;nvD^yrS%L%{g^5*p&I^`y<@}@8tQF?NOj^M(`jHlD`q|71miV8saYm+yQuQ zVTyP1{E60R>ed0>@WL(K2O#?`UB%OQ z01BS$j(`10;0(cZ<+pU7QHa;leHoJ;sb0^t#Tb&l5C0zWrRmCV>Aq!wXiGPKh7uhA ztDu}90ZN*rtN+r{HM;=#7jP7ENK3F167yTS5h{)~$}Et|5|L8kw{)8iBr@C(NHZVh zmaYqa3X6)$u==(oY6l`G!_Oluv;J5Bo#^8!kqZ?<&9EUTE1kZb68Td7RVTzv_9F0> zlR7d;X!IMkR|W-DiETi35=yy-wY$0a?guxk6lF?}nYhQbXN51~NASt-T*iV=dlv(K z)(<{K)~)v;k7_TM;mAr@^)l!pT&E}Y0Irnk!Cw-1WxNQWvT%k;HI%y-`loki=twD^ zlyztD`Gv^6;kUp|%5ZV_m!uLPGG5M>BC<>^IOmFi0Ed&Z0M$;7tWwX;OBB-(I?qF- zOK>F?d{Di1Z=zTSXtNI|$E4S*a@nSM9?)w(T$JG8kZww_0ahN6woe_wKDNj<>Fn5q zzEIAcXyNAyBWS$43TfxoFq4QPQ;b6^kR0E^6p;rEtHwDz)dwXD&d4Oq8hXUA1|a4< z1UL2|S&HzcEV{$69(yGux&iCw<7EjS%J^=>Dvd81-3n~FkLSkpKVw)eMkk8b<#^);1p46knUh-!)WgC#>a{0b3Q5Z-7Z^@N&uzG`SvV=!9~Tc@^s2-?0i)SX?G_=95W2W*J1&1C!sL+z}TsI8q2>~3Ga z@~h1d+b@RNJSi-w#W6MjlVpyleB>x{!ZlTehp|LYx?d!WVu@mSe*NO*cx~5d!sw=n z%8w<(rc_fsjddfI`#C1ZSTR#|yAvyC2sV<}`EqPaaZ}B>F<#qJC5G`P-BPB?T^!cw zY(to~g)uxP|KMVrPUDc69PhxbV5-wECuq5uF*(L6o9fPH0WJ5SFK14_j8arTU{|_F z3EGY+p8<9dj_;CeP4#kyT=pJvDBVb-7Ft>ao0C3AMd%fG8iTzoT)2b%XPCJeYHdO*Mv#HkVWG zWkq=Q@5q|xl|B5p$-38rx#wSXGyAZzGoHjZnqkQ?Fwg&+?s`Q+7;Rt+!t}ea0RJ0k ze|w6B!`P$PUN8j{t<;CG=M7G03U@7CC}%Wli>bDE!N#0=V6^aAoOPP8(^NCjk;+~G zhx&v98upmVXoeZ|G=PhI0%?%U(w6SS$!!T3%x(nZ37>US%#at+7WAR-KLLEV5J9U+ z=0qJdRil-LxCp{ug-O(>M)&tH^N^|LOu!b@^+J?~)2XNUxMP)A%J8z_EmN)9ipNF` zL2Lg{s&G;%t52CK8($2PgTT1OW9i{DZ@7tEjIZy zo&5@PR}8D<6Cms+l5TBji)!REY_(a39gVpC@))ppJtczo))gyu<@UGmZALq(1fPLfR#b~!$B+Jmd)lAyk5(!!=xnqz? zvd9Ju3E`sJXm3lzwN%D9SL3yS)%S5e3nY>rumI2#P2$xLa=lqc^mfDmRz1#c1dc6=+Kj)9^vDE$| z=VvGfrjk+VVjL}RqKq-7kiJ3L%Bdi)xw9(Il@Y+?R$<#FeY$@x$Xmn>lxI`qr8{AKtO#0nYE8I98o&5;r zzi>J_O`1y$G4_|lFVdZftO!CLkqT&Hl3}Ysak_@c4j}ZnN>lGPXbV14cC}(k9H!Dg z5rn&ZO*(Z<`cv7LZCC8s3esv29`QA4(nhQWMuH(b`2+nid-);=uXrSVerM#(IJ4`6XM`cu{xB@+9cz3yYW^Bw#G`j;&G} z>gG=V34)7}jLse|d92)AauyBmMO&@=8au_P)RqG)|60uN&p_v&wz@nCpMQfo*$J#( zg_y!*lEUVj{;noX0%3+v;sVECcBO%vKd}$C94^JtiU`@a&E)o#Q9BwdMAo&a@~ zHRy#ft*4Jv7w%3JB{yU01IK#s1P{vid)|@uvMi0|ECRzNu!SNr05Lbh90&p3;Chl& zm<4DxKhjpFQz7Q>GDq+n?;R{t6K4k8+!&XZU-5;ybXxG>?=nY5NOj<-%bdr-dn(2a z9LMawi>yq8QT_^Z1YfOb*b1-OA=*>meL`H$0S(`ZPoCiI6H@UjoQVYJgwZ(wB23SE zBGaVmhr2*3GJ%)&I8hkiVx6;9tEdO4g$L^=J!R^y!3x9uGKsUbz{)q7m^J+XJ|!N( z_;(*#f#e-OqR6^Z{ZU?tyP;+wsj7XPZWlvIQWe82>0tzK_aI4E(c2Z0mFcxU{)BkM zlqvKGLFX=>iCuarPCN_lCvcyUbOTb%i`x-PrqJTH&Ry)!&wM(-90yh$!}a%Ioi#dlD@m30fL1XT_;imG&D|PO z-GLb-saOs7hzA$U-DWb0bD==)l8IG5#{tPzdhAXVDPNSf`K7!k(KKY%&PBq#Z`Be} zcrWGA5C5gSyRexp41Q5K;{;MD>6@qiOL@<&4Pk=|o`3rACj@)ns_j-%iZ+0{`S7O% z`!D6~e$^HfG6wii?>%hxCeAY85BQu5B2(nJL*(xeDB5U?Q9R1`!&!~zOP7ZgMg1VvGb!1tarJ9D%A z_4nm@?q=@1?>STN+?ly^W-?pJ$oEb0UOoqvmq_gw)O^-_kg(P`ziAS>ES}YP|KVax zbx@TsKI&h78uRa^09MijxtBCNKt|e`u!3HWH6I7y(;RsFSk6GPO({)nZlvF*VUhK8BpKN(7Rtx5L&C~^uZKia+_%Q%dYIz)J_Bp( zVO2#>cn;P8&vDAfh{A^hWQ|QylW4?H+J2aYnbUc=ec1>NCcZ+??b#g^>ws)A=rBSr zaDZ7??Ax@s>HxrB41qpmNFx?O+9`Z|? ze2%g_IE?IuS2P48$FL|qF|44p%bj+KN5L3nSR5(Nh?=EJ#)~YR0@pHtPYpA{Sfp91 zDsoNBLd&t|5x*D>?dyPV(HzOSqc|0%edV;9IfsCsG91n$9&=@3F-(n-N{_q=g70me zeu|O^--TK1tS6IrxWxmotY)aI|6sZvL|FkpRY_tz<$8F-yMB>1CQ5Gdew@g{Qh>=G z%n%bf7e5agGS87_wZnnkM-#Y4$R~kKFgSlz%bHt-yCFPu%jzQS4>Pes5*)b_Kkpba z58bkQ;l#}CLB@9h`r5#}d3o0SEFK#1&@2n9VtlhCbL15eZx}KUrn2yEocL^l!VA2E zrVW=$r8`_7rtVk+^G}1Yic3{sH65Hx53;68d+Gw0!rKGu>fmI0kTpx%eal-){}aGQ zJ2;shWG%!ROzh=DX^?Y)Epl)g%w;XZBBiG>U6g^^wI0}q1`pFPwYnPARB-r69axNaT_n0G~{eH7{COXtjD4ChSkW7A=79Ks*yG#sLJG+0bQgu`#jo4;c2l zI(4f0Q@1+nr8w@&a=$gJ1?3$F%Fr*nOKWJ() zYm~|l0>jkh&srMC{d<);om}>#$K%BypmIKbUNJi6IGNK8pCz{0Dswi2@TDPf<|rm@ z^P2@5tlzLOh990YVErD$RDW2)j#rii~s<1iUJP6L(?y@^=^(##k zL8xa)942Q24}!B!xNP|hURxc&$ki--9l_8w>!QnEk7WcL)G%OA5l+pBR6!*d0V&yS zd$Hn-BfSWO3} zSL54}AWXVL6O*R8?N1)E6zL@pR>o>FukNOLRK)AU)ud;X_#T2y_isPGT#!$H;3Ev@-uDq3)BT&d-Orp^z!w`%72!C@%D59Hs+(Hv*K8~5V|96VU&j89~K?=MQ8neVwgFI!?4w0(`s^(tvB`WGSV zTo+o!iyz_pt436h;#XFexxw{3PTzJxV;nA)ly8tY?+B8)F@Mvme(@GO?g3memZHLb z-?jIw51-|*@s)wO|5=oK$6H)YfAfo8fCdauc^&X-O%X*NLi3h+Fs@GlKlfNa1@gH;8-0tnW#-9y-$ard)tWCw<`4IB zzm_|knT_H`BR^$4Eh)}yYX9Q$3d&OH+lZMUT&|520kt7uX6s9PEPmsb0#eSP@$^E@ zY+Iyk&!`<;BS0+-oN#Cf#uhn|ha0=_{SV#`5ww}~CLAQFgT1C)NVrDBdy0ls!6?yO zJKuJc%OYUQH7-9PdEWgkv$riD3y7WYaBTs;JC>t#jI!s9v(VcIcFEw*_#oi}Du4;t zN&_}A7IGwvi{mIsuP8d^#h}PsVE-`;^Iw3{4b1Tz|IRBr=wCc|-GhC4BJJFS>J9vTciYFXzUJAh!KPwxQ2TgYa9+chX^ zR*#zvfs4GQR?RJzyd-Nb^xVA+emJM_WHXN_+0mW28n?g6!?>$i$CD@;7EAYvni+A4 zzx{=8NVQJ{4gr5l(p~KnDWAdk^BZ`$c7Kediqvfot5Ii>KkGv@{jEm_M4e>?D|GM`s|3Cq0{QA#aYu`;>v=4-)jd=OD&etn?p( zkS!|F3FlfO%v+d$Mt&56cQFHPl%h;orbuZqDDgWm4njs@0U;fb}wXkTdul z8JP7ZYRyRak26@|oMG{z&RUtDckgp^cE2Z+z8wdJa4{q$&0m_$K&I_Q%q>FA zW*{|xM{^60Rz`$eQMs7SKr8~(ju%+dRc;F&s$uYXE>_Ts0He}+M-bY!Nm|5H(%2E? zau{Cg;IqX@2PvjzN00&A@LB!|iMKm?@$JA$0Lh4B9Z=-sN*N*ZJVVwoL5ez=6~ zZ9u4KNTh}1cgKz(Ph9egMqqXM7bX{#3K^r(hvM;S9|YR?SSp9CSlAJyb#si&=Yg@@ zuqv011})5vAl-K0Iou4!XPTv+L+&79N01Gj{GtfO_$2W2nj<-{%#I*yD@GK_^9i1C zT&n0fzs!yxckPI3Dg#1QL!vkdvm?l;izxaQ0J|Cj*9I!oC<{A+)GUm(C4<3u(y&;K z*%3rwRjjikNWuIOX3Ez6l(g9qBrT0%RtG&a+7V<~(Re1wI$$;=HY+nbf}}fa>g!D*(Ab_AIOvp>ck12)9qW=D|yUn6g)!v6)rDD9Hy&W<4CBY1FD0(?J) zAXV+sJAypA1=GiSz&M~;!t4k#K0X@7OTexWuCh??2-0VKbY?NU9gQF^h3g$bE6@;dKcj4Sc2XWBwRVn;qC`~f+$W*^^PE$n`3_;Kz|dwBPJNLBS?0E zcoqF*5K@Sw>Lc$Mf*nBuN8?poYXQ4YD-mwJBgml=ekGp^>_JCf?+9`b#+eic`6RFj zj=bIxqyRcS*Ow#pi-Eo3$m<z$EY_z869YLD5 z!7JbzKx?PYq*QLG{%C>%#Eu{XhQS!B2*Bc+AoPwP*_h;~=1XP*YNlaH&65g+=Q3$W zkpAxk6|)yukH<1OIK{+{AX{Is6mvRQOJbSaKq@A71bJ*_STQ$(^<^y6X>iSsAVb>0 z$b@2c2GrkU=xY9xb_8kJF&cXCGmLw2scOS1q912Rkm0A0>6O5!Wmxo%adrebHv=8p zY=E6K!Pya{P$8_u9svKb8spj>EgHQe$oE50#pi&rG=}Bu2;w`PAYAJK?l6R=h+|ZZ z-VvnnG4%6}g7KSSaXvVCWOfAEf+x@A-G#v+t~^hS*%9P5zgleLDhom-O%iUsBgkn? zd-4md1+cCfS2aSFv)&P8YGw68b3Fmp1OIFaQRRKZ4VkSjSGKDd%znTRVff&GW*(kNv>|uO zaNc2>Rqa8_>usp-E3B6>R7sU<&^Lo^)v7PhUt$BQPWJrznD}T6oh@;>Mt%mewjxcz z9@VlZydTq$9LsprwrV`g#^qDMrfFPt;`GiV6G1k%Rj2!Sm?zhQ{1FLECzxEuwrV!{ zXxpm!j&wi!^1~6a8&vrler_0Pav9sI#VioDt=jNfP;mGqkk(4LIBAkx|HHQGUhEJk z?+2%skzgexW^Ak8DjQ*q@=5qkAR?v2*j7DM$!2&VkYxttGIwSnTN;ec2Tk79sJ$5OO`;$Q0#Zf#&qHLfB$qSu3# zW1tAkPX>y+i=g0ywGlz4&iVu+G{m^%*NAbk<9T9Sb_Zr4W1@9%PmIgWL+9>I zcyH8@>`u6jar(?S(HkCn03V5^=olxALyRv0yRPx*(?-Kh-{c|`M>(Qhh7I=cdRznee*x9v1^x4jC2}*_S?AYPh*`@44FQdj2GPD59a*6+%SIE-OsGm+xZt-SpeP zIDV5qFN%PYbF1Sw&?3PvtRLgh@`-zD-t7|BL|Je@MTFNsTcc!LBhqqDde|qdNizRM zV7|b384}jXxMY(03ieahWSJP)gW7XXw-NziO;Nn0dv;C4zKBoDg0PYh#RE&0L+XdP zFi8bgU{+&>OsWT|iuoR$fxFq#?v9b4Wmw@+S53ft0LBjD{{U5zlchMXN&D;)^=0CF;HNc53}12|RJZg#PuxbEm zpkYZFC-U9h6B+Wcv>#t=i%!5EF*r%&C4DCCt=K|f3HzxAz7_-%@=BAoMh(jUa+c@cnR zVhAcxby&?j%d_%kK-2}HvmsFt-I)hU>D?|n?n$(61Hm0-_>|;ms4&OeS^%NW1h_1Q zkT=wFE_=zz1hF23t%k%|t%9lPvfF-#gntL{iXmJ^7IN)VakD-*ex$Ks^RC6eI1KaE1^nur!;j*9a<>Lob{sQbb2dCK? z>jjs6wTM*u0|(F&;8Lk~yRlEJwZLWHg8e7e3|R(PMF+1$?~J7`d(_)5CEpxaTLIq2<4#A&US+D}||`-SmL8UTD`EJsz8 zoi2Ox5x-LO0theNLE_r-mCN?l2`JJg5I((w^xZhJPwyoJ&L(Y^P%l_IjSh`U`pvWgQTj z84?$VB2D#rHa3V>>|P)YAQEScBGHN{>l3f%2DZZB(w_>#3wMxcIgoYB>)Es@LAXyM zxVJ#qL?n)r(!`{~Fvgtc51D@{o>FeyT=+n$M$n z565jNh?o(kgs>p%YsxEb zFbO!(Rh;RzM~=Woo#2cIK9@MA)<{a1Wc8tvo$(GV2eZUqRFB|oFhBh-cD|2Kpf%rR zdm1hEi9=wWC8nw5s!Nscw_H?`bGB#tJuYz*gnWnp4@o_Ip)Y15`=!s*E@V5 zBQXs}i&&F=o}D`_7Fh%O4kJRnM9wOexTNXL&?t^^+nZLo1O<5#OwLcCpr^1ic&&g) z0(65Qa)=Pw`&#Awo)N2qT+oR}Q1x-CyrVvo(xHeQ{GJL2R5hv%QY%BG4oF^N#P50L zVU^H_KpJg`T;VB4Rjhfs&bsOId|e^>Sj`1>nW0k#s_8mwpWEIzEu@~k4?x&qNc1>H zNeA8b_6G6lu{r_5FNUO^7+M`^EkttN5v9pGig67tm0m6{4wKh3TA%wp2fx6uz6=-@ zHA@8V?v1K>*zYMZ30PzJx6_y^IkxGt#>u#Rs1efr${M`re{tJMYr@QwBSD{JM2b;C zuuYdWR>l=#kz;8nOju<;vp=lj`6lR_jR?n+PyOQ zwN}-tXxUTFhnXmEgB3WIH|bGQCTvTKL=-6%gbId4qcoB4nJK9AcEDpT_lSnTatzL; zt2)|DsvPh%nq-N-AdHM9sg8CsW#n&u&r7LZ@jM7G#gbAeX9`q$(H53Z#udwlvLi;A zMy=MbMQIX1@|s8)&U;{Y_i6qLvgbHvKtqv4zii}Iujpco?H#`1`?=6FuBac zSAFu)6JL!T>3;T(*#Yq>sPY_s{xs6$G812ISs*&`wGjJDa`;7%)-t#_X_8$3W8!OU z4}6bp2~Mt&U?n7GCcb{&;%ANW3HXjCBBjJkd<{lIiT?tw7Y&-QqA8AM+Uhzt3NPi2 z@ZN?C%d-Y?IjhLgOqQB6;E5KCW>t#M{~KS;Xj`)b=xLk9p%g2#IP~{kL2&}=LSV=d zlnZykN^p$*K^|;?VS3K|yhNkw{}G zcg(hCFEp?@qU#K_L{i?QxvWRyoE%Z<;2be4>#$1CtX#X50lTTqXbsXcYxxahI2akD zr&=Q8SOc%fH~=W)k=}74J!6Gmq)zD^5;a2ogEM}C9vc3I2HrOZ?#R|{VG$aXFYP2! z+`8X1j|k1dRwAeh9pTdrm+M}7eA_bglAZdBUkrxta~hH4l9j-b)##@tvDuy>G_?XZ zB;o$uV3;~S-JawWgDE- zt7ItBVS7;)=D{8YVYnet7lEt(_I13({XM7Ssv2j)*ZauS#`8~75#;o{)2bSO>QHGd8=M{WdRn<4R7 zn(d21m0*%3eS#{1JO;v#L~282>ZTE62-^gIRZXpJlK&8P%HTBO4AqwQca>dSLuE3s z6bGjfW9U9a;)9^VYXQ5@;B3DXnv~8110IQoT1q>R5M++*3*tZ`^Ao}LE1}6%_$98$ z?J=QrGoCqe9*B#LW*#DiI!pV3LSBV$0JhoSJj@Eg{&>t#KL>UI&{2XpECu(Ib}g@) z#s36!-AKD>Y!w;^>*aUCN_*mIG|ISCzJcIxCV*VnS;$|JKaM99bX4mPDqo zB&AUGAVQm@ee&s`B0U7cU_;8G;t12QH8iX|4Opc`Ae+R5o{yuBl;lsop^soXHy}<- z1S(hIXT8zUnTwRnc|zNyJ^BD_Y7w;D1HuVIqS(kh%ygGs0^d!3r55xWSk_NE-Vbn; zs810ZUSSRT7t$h7#UjIHcfn^y7OM!~nntXb6AR4r{M5}-v1kuMA4B3;Z~#hOSC{=b zR*rLg$AL8?mdQHVP$@LZWlwF7hT(NE))KUe4nNVl9{YYh7P}48B0^8}}WJDC|=eECnz^xK|64-gdxq7O!Flm_EE{M%;IN}~m zJSX7dK%^qk2t70n`?*YxQ@K(GgsOLtXz(3c=eEDc#wTuyP8$%q5GhY^Oxo(U?IYN; znn*)I7#FK)k!*1TuhJ0}-!6=5Ng%JL2_13UD-OBDBgh=N8onDyERSwlaufRAZM(Z* zT?>)+f^gK3`ctOT+LzFIx1IPY)}6rP55Tt!g;UFvOPC*6mLP_JQt+%0C2-}<5Ss7` z{q45zMq1T-288;WB-}LN75c|*AD^9|@UFmmIyg;ug|H<}dF(CB@}q%G(Kz=61W$N{ z;w^jg(I{yd2&)Z=Bg@lUp(#~(GE23cNtWF?9Au*W7VP6B!P!J1i7-uFg`Uo&87(zQ z8Y*eojnUc?QCjCf!KG5m5~|6)*RrQ!_ZKFmfshePQVnZm%Wl!q#bLJs-ibI)(29dY zmx_4YtY|RsCu8-f7P!7;pT+5g9N0V%UcQ4wvsGf< z#mq44xeDJ~M5L6MA=s2**x>@c1(C_gxD?7IHhC*})-vQ+>O3k6e8JubMp^PP-`roB zi{9q_@a{~)6G^rH=00p8daDEAJyJt*I^p^Y_MswfF&iGU056WEM0cZ5?~zQ8*bVOAxa52w(hsgP)FV9>f&V_#`?ave;x!@U zh)cTtkD*?{@gdRIuqkL2q8aL~+<=2eK$t|N#gr9hs8=I5!Vz6+pz&-_?OiM5s2qG| zLu-n*Nc{N;q!j0#O#U4=`rMPj7coGKo_jJ3ZgcJl-I#Mv=*FCTQnYQHh`^%|F4t;` zl0NsOCBBlBg>N;D$TbW{&pl}dqk!gs+8cO1!TQ{j8871u5CeTckgz^S;`F&EbMMP@ z?n&EAsC=BTWa5}}PxdX8;vHyNPnx!H@X>Qm%D~F#bNKGpi2U4v=esI@Zi%yi{xI;@ z4!qd)$ETLC5oSJItXJ-H;Fn!ZKEvj5fU3p7l2uHQWpE~ouYXW9)M&I~>O)a>B4rk( zD5MWX8Ssr;96|u2;5nY8j#Fp~t|0A;Cu~8ne-Y49f`2C19E!sAl>E)1C?|gRGjTUO z_Zk6nD9UfA!r~`*pC^ceGKZpMpB(dju;Z9M5>VVp(wL4sc{K}>zbsB${dO^0oB7f6y?b8mY|2D1fHpKxKswI z4A6(79Let%^?|iBI7vt*nL|;YNyjp~hrt+PSWGajD$iANeYdFnN^FpTsAGHjx4_qj zq7cm6(=)Hd14rnfBb*1k93#>?di;yGJw3p6)JEi*B;K%9JYFz}gw~fEl?FK$RX^f|DZdzK&R?p?)C=J{y-+&pbBXY z2L9+duP6xb5*m`8FM%6dASwZA5o&CKPJQAR&EV15h>$BP7h?;g%v@jw)MYwiFb1sI zu`&UKr39biCZA3QrY2unL{#Fi1G+X1izzn4=QAT7rdS#~p!cxgQ62|))({ejpftb^ zD7PcJ3%3Bq{~65!Ng8BfVi`N2fA;xANf2rn5^3QG-eCvy>jF!(0_(wlVRA94kYNYZ zX)d~EBS4!POXZLi3*XI`<8!2Z35>T5>i{ad${S+`RIMFivmJ~*nx!6UZ3lGpxp;9G z#rQ1nKQxC^s@8hY$-o;%_!TMc3MwBit`U;+i>IFa*jf3lhr^0g8HCz~L~(NLfQDmd zad|($UWULmflAe}1G+H}J@AoWOfoE1W9)#=;HBZ%0p+`h6HvgEZ{laI7IEx=&O2<_ z0o8xZ%_MmQ%#*|}NrCe?giZ#2EhWU-t^vAjlqnedQ*?blz~V`N32_%LC2j10j!+R8 zJD}GO1ehcngV~bU{3sbapc4)oc0d)^SWJ>b!5n3D8#|zhUYF7~2iQWR&Da6`deE=r z*8%&$k=J%W>(1LM<@riWC!#>j!WS~fsHb_u><ni#m3X`kf^l54gs}rU@Uurn;cs9!3FpeeQ=@b;aPjxC z>oTpJD0EebVz?Bp?SL|Tn6{}5@7e@8F*J5SFLPDYc0m2`b%L0(4}J#SA)@Vo-f~1> z2lU$h05jzR&|f7HieNM!v>i}A9MSB0AK>;_g0=(t0o$ljxW{n)OcW=k+79UZ@*WQ7 zHsHXum|%<@(3z7i75!8Y$`FZbx58lu^jIXK;@S{cbFD-eJD^7RP{PUY4eU`zUfTf; z{nMx9Cjoobk=J%W9bdx9!Bh)g1GdVM*LFa+(L(Y-b33rzM&8%~`Rk*ZISK#sS~gl! zv>i~}$@ruuucOn0OJ!1NZm6^!&^0QX6o92Q!Po(f`3R@Sp!tyX0kzYxq~=M5qHK0x z2XuT&Kr#D)H9D5b!6_!}fPBR)#heS)>#L5>24h7G%drEx^(uDv_z2)vhCsc_s2Xht zG%3}CFC1W8H7rh|lSjr5=;Tls7RCRAjt;IoPmHkxdZDsfv+b$^LZ&7;c0hMw`vg+% zx*u3CjjI}=%30e1Ep4mH*);~N>Ho&mc0fnNs>yV%0Ba*LO>=OE9Z>J3A=Ujl1eVHC z?zR~_pyigW2!9fxJeQZY1NyxUayx*RRRLTo?bMGnc0eW0`Bl==foB>HrPkO1MFvNc zpAG!M7>;D3u>(3>F)W6I@U$UupGqy6;Nyc~2Q&~Hr!NNK%~%rmq|C^H=gZW{fd>oG zvl8cH2w-i8VEWuj*b_ACh!p96V2GT$1-k>&9NMF|^+Z`GyUP%)JoVl}BY?|Qnes)? zq3wSb)wl$_%V|hfXFNKG_HYLJnDv3R)VS(=Y5Sd8Ae%X~>n8%tlS4orLjv^)CYPB* ztFRG1dJe5tb0gi)-g`YHo&{B|!Ow?Anp|cMErX=>$-$kl=O>5%11P_f03}V5>wnCl z6>JYf*ZjzxlDL!vDDHhsG#+QQ=i z;FGZwZ3S{}7Q(#(3?VA*s?0{z#3nrYV676s*ly+ey+pJIf}i^JKJ-2i^2bc{QqTPRlmTdVPC zEsNT%P#pia-3lcq@pa5#k==?PF=x9KDh#$;VTWV4G8k)s*lwjQn8_z0>)5S~gdsHb zkE#J`jLX#?ahF{2=tr$VQKd}br0$|T!vklzW%Q})WZ(P*BD}RXDfpOki z=1BLm&&;>P4NzqXmlWl2DQR+<2ks0DL?^9(!yeTfel{o%k^m)5lIwpwa6>*r>oWAN69%OQguT`EA*{LOC3s)Q#p{Ns zd{pG<*;Zx772Tp*T|8+Zo+UJ)-S4&M-zA2D(!lYjZ%=7?S} z&=N^`gVlv?;+-5(>EIkOtAg-JQlu{T1laa!PCh*M1Mb1YR`zLn8T*mh5P#T_pZF^N`hB{888W{D7 z{}dHIC(GDgU1_Zh61o8Ip*hC(Ds#3KV|zteW^AvXlWy@GG|q+CA`<188r!QsCd3O0 zYaO618kUqHj_p;40SRJ1u+s)7iM%A(UUjYN6W2hvtx1mURh!Y+ejMIOUMWiAQYqvx zjP2FHGZu4d0l!ak9NViU-+Dwxct1=Kr9jT4AE$pqwpT^}g4r|((_%^7zcIE~{%s-g zG6*X)$+5lqy(h8$2Lj4s z3bt2+y4qqT5tqRC4Wo+lNs(ZC)d?ruF=-nJUl|f7OOdc5XIgepk$wi@vLR8V9NVi- zPou&2`SEtZ#c5Y>RbzW~8hc*IG=LeJASq;Hdv%c-LSuV%?NB@uWmm9!Y6)X|l}hcU zBE$A-N`U}#I`|dt4Wj+Wm8Z2cwpX1#4=GYv5ULr{+gt;pwpY}pkQRa3_9{}z z6fx3lSEpF8z3Q2*6v+$_>fS-p zwpX9vR1aQ#(iw#An&jACUCWMFwpSy8jWf8hy&6y*xilC4%LwCKinYC(G7^iFQI+Kf zAnY(CE)HXR^%u4^rRPGP0O1!RamFZ;w!L~96@qKG6^C-em6xP#ua+;weg$|9$TSc# zh{SPHnzZfJ#-A-QpGd7i=p3ub*j{zI;pX6m03TyG?|p^GUE5x*O2uG{Fk^eQCNYkM zR={(u5h9mkd$kgMGGlv{wjA$8yb2D1a*70;=o;IrO$FkZ^AGSyyiPY~1*J=}dSiRl z=m-`Cphr*!%)0-@Hnvy$axIYqR&QdOO0K$8#`daoYnK=a!t?)^ql|>?$FyKi5FYkKOe0M3U0YF^xt-+g_E$ zwv1He%7I?rh)|wzR;k1p+pAXn-GYM51ygd^#`fyI04#X`4JU{kj_uX#jjENI322!K zgZfNLhq1jH@}nZY57Os`NF9*8MA%*>98vF~A3^%t5V@48f~Z&<+bhp~3F@(m;OlcT zE|o8ofkKgBdo`(mtw_~CsBcJ=H&GI7uLfrY)MM2Zgog}?b3$o??bRobMPHKRL6~Vs zTwWZevArtv6ebszgYl+jIks2-)JK0~8~nf0m?}AAd-XCsl*aaIXjVKkisKAgI>dka6DPg*j^Ry9M3x2fz;Cwc}|wH+p)bmv@^s+IU1}f zhN*IzPRg=idsX-YTalK5u-cG#lEK(sJ%s)3w*uR1a4ucd(bl$CuC-qA69`vgNvfl* zZLdn#35fv4cSUgJc_6k?&cxbY5kuQv@mr7A^^wa@wpZ-v*&9pU(d}m2tK0-Q$o7gS zUTDeRwIF={Keks^ewueGjEvJeE(fY&X~Y*Z!o0Qpv*^Gjw@#;0jBah8R1O0AWFwlQ zF?-&8+%R68L9BnLv^}#A72?_XqL36-21XxL88OQ-82jBfEP?mmon|6;Mrr8$+Rp zr(-xvHM5T(t5|sspe_dP(Puz!QL2^QcV>X$AwWhLG=KL-Txowpamv0lai`Fw> zUrPTsHDlQwaF*l|bhrnYDE*0WQ z3PR!U+kti%h0O-G#Na;>t|GkE?ge|JcL8lSFvl=~)APAK?IMcq8(=>eoYbpiDAGQA zY%b#P7YN>hIt~;@Ueam%{?i~81tH6jsCfQ0f0W`2_QTbY(QUx*Ze%z+^F;ACJMtD3 z4+Y_wSQ6(sGlQHMx3oW=jIRqzL0f02P8{-3VY#$66|>B{K|B2~R7W+N8o6<#%amG%Y0CQwx5ZW0MMN_ajlDn+5 zSG*e*R0(815C#+J5|t@`b9YykcH#l`T}?g*Y?g!5L+7rJRdziRxQ5Erz}|Im8brBk zNqfNjc!hrf>>Gn~qv0N#&V6MbZ@QaEyA!^96GvXf&n+VJ6T#+4?r~N4y{5=5Kpv+! z@}4A2{oztE=K+fw=1N(w1X)=_K+OqeT?&S^((BkWor35EsIQTBhwCHWFjg8|ES_OG z5!f>hPJ>f74n1t28K>}9fvt3KviWhpDea#g^$Th$<)^^DCY*woe^Tc18_GSTLOH@M z0{PRi8-_~*@kN5guEW<;Sc_fbGGX1H!xn9pTV>PTAXG3UN{tFYsryRWYii@EChulo zb&h4SPPXK6|19mdXJTS!AQ+^F@B#Xxl> z+*eSw`gs*;CkWp-B+ddFnz{##LqL(n zg7AzXkzABi+GT%R2*zXd+`J0H+lF+D3yOowa@ngYM>XvN;gCb365+h!exw^GJ{>KE zZz~tU_*1jg2Yq)tm;K&wd?N@HMf!26^i%Vo%#qw9U3Q0YUO|n$tN=n)BB^JXCMw+6 z~>;vQdxXHQhiRMc(%4Kpz!$}RZWO%j|yQlgA~+)riF zoQIldbKi|kOr|TM{2lCnNPJUk-BE zS-=|+#|c_-s<`b7M`11iMGpY)8>@$>Q{2_v_7R-#!+}i%;rTmAG@atc5mx(0Mz^wg z1BACVNg4aN8@cU#?NOmK5aV6IzBV`;`?yHdI;Y`(i7<|-W9;MZQCn;>~3Q>nz7)b}4|BVhK;n=h4Bc^-EYZ0MJ^4YUgpGNH5*-sLREa8Lr^zWJ{v9~>eVY$)fe|E?q8Di>NS59 zTlf^J?n~(W02&VYq8$*0YWOl<0bEa%Zm}v}jKoO9S2|r%`$70p%AGprlE1{g3akKV@TzJA~Xx#-$`!35l8Sut!HIjj}38HHkVTrYemj-{nf!{ckfhhr&v8Nu>Jm@Bvl?3%`-WfomVz=thxU*9*S2#=?D z8H?|^BAgMzdIWOCzd4S_rO<#t=wU>^09DXJg933yXpH+|Pm44DBl+%CuedC`w;3et z;R)goS^rv`7{%M@ip1SR@v8Cm4J|H-HeS9x2I{<{{O)B?$7}t)PX=Tvo@x2w>IBiQ zk|jQtv==70L+0b*@V?-8e{HyP0$#ZDcduVrka~Zu5iU`zGV&$45(ZGpy2krNTp=h_ z->zYh{^%z`u^&<*1zG?6H~1l!2+%Th??-X(08(5Wm%V$vpShJ{xRP!~K%)QYeJgGv z1Zq8nGyA*`<1E}uI9kV$DHx?)eW#uy?I#*VIOLH;dI6zFzf&)R**(s~p;XKv0(4_{D$#GPx{RakMy))?kifysw417dl+Eldab+?76Y9v!# z6oJxM095yj)Z=)Y7zt6}_jeLRp(g{u43woFomWJ4PyF@|>>~x6vuhZC8=JGApibMI z(YY|j=8SHP%^BSoo3o4(*xm*n&*5^tLUGqNXD>hH5li8_N+a@3hNCuTWoL!O$ACUJ z@Vf+So3rDmY;o8?8we6sZFp##vv(Tgu{oo2Xp;F6O(u@9Ih&Le5+#A9;c|V*!AEV* zs(*vk!SHRW5xK*G=ewT15)iq79yai92Zqhrj{z|n&=dpjap0F-?_UUsg@9JYz>-xc zo3lk9=M$SWs#-FkZO%?2WfrB#*qrrzQi}Zu;37QfXdu^N3eDJ@HTyMQQ0(JMp@QRb zog&!SoKe15kRMi1aVNt=B!P#fEWtzaT=0mDJ)}i z*0Yc;<^Wr2aB7Pko3n8lwpa&jdkn6W7@M;m1H$4k2&WC{S0@nIoW(yH7T17TsJk3L z$+>TA&Z@PwMPXoR1}FKvF@?=pV$q=a92Gm;obhuJh%PP-f?*LYwOZdeo}x@mbEYV{ z@1mzD>w@*~QE9wTD@uFB#fKv?50@0@!$}V9s0QW<2x!O^z^eKiZYkguW zd|%LrswDap!*6EAixq&@YFKt4X?=>}no?fT6&||*ABd&!DTZp-bev+Sc1`EVHmwdL z-zmX|sgn?OKMr^Cxp<*+2fT9`-2tEKqYijO+`lA!KGOm3gAkn#cuBxMrvpCKbijS0 zxaTZhuhgl3%jk5uNaq69>2evJFU05^4%p@BbQzs4k@z}}|HT^3&{yF2CtzB7=V~}; z4JSFUi99y#kTs@Qp(n70n=0paTb?D_=3O7e+vo`)UGgI=)+ zK6e36GaT|!Z)gt1qR><4qQ6Z=y$>{9)XVROnGNo{lju&UH${Ef4vWX(J60pHMcwur z4BP=N(Xjl2q;*l(NcM`o@K_IcYb=F}y4M>NKNK}NgjE9+UAzS`f1uqda3|t$DehC; zS1$TWM4#etW2aAXtd-2Fb$7gRX|KMRdC zxy&f96$?aH+jiM!2@ZcND0@kOk|xRZKSp`)K7l!~%fvvD$aqSpNfHJJYpd3pCGA+NT+T9KU*0V zWF|dFBe74#@Jm9x0q8vq%YG!SpNbOo{bCS2z5x7PEQOy6^?A)4<4T_m^^=gE=c&lb z<8GYColQ?m_YYB5P+14#qn+-7SKsAS*3gW2Q5IM`TyhD;u2-}NPCF9%xI;~RuC2UD zVdATJ*^tWZc~sIWW8JBLSp>ycV6TzNSMsW)#mY)0@mVFWUrsMRs1Q1S;4hPvv6*6@ zjDL4sk%OxHME$Dn$8KRSb=mkU?BmnYJ#;4?jfx119&3?%uDx3XW_unk9~2eft9lMw z0n;-qk{0eOAPRJno=Zgv@YrG~IObFtK9Yt<950NG<3XL|7dZcrKM$V7z3)s(6!-P^ z9DX66sE0S#%cLV7(QwG@I*Cz^$ld#sO9VD}n*Qk)JBUcf-kA18#i~~KvtHp{=Ju4D z7Zg`DDK;V;e4aSGOL3UvdGA1k<50X(o^&{|7PWc~iU{u-w#o| zC`C1}H68AZd@IR)PdB)$=HEp_BK;IHzi|>L-pZ^3Wu;2Pqp(W#2guOIMN~>( zfKcP2Ds|hCdritFRiwc0M~*cqSGXy;Ya^GMlrP+a-1i}8nxq#VLGF8z!%Zp`u0`&p z$kis5i{y~|apYu^Dn%Y6_d?`elZ+yh$i1N~+*t*wk_5g&BAV37&$;vxa<55k3YxCVVm{Ag}3A%1g}^Jj_QLb(?$fxDxUeYp$VU6lVrD77Yi3e2Q9q@dKA zJXCNo+>NCx4$>Aa%`HhJ%N!b83C&u8 zJP~B?75sQ=y5O1|zz?}R&%))QTMrf&2yb`tn@g^*gZLqrXCGXiAEEQAoG0nOClhJ% zP)0Pitm>FDZtSzHEa!Mfc!D7MOb8esD+iPM8b!HzPx8m(c&YaYyC-xIWp-w4*r z##^ztC4;%_@W|j(aM-C|22bVC|6{>}o#_A1!9V!_*BWNi-W<{}=?g8KuWo?ea`%6fK6;!8@^fAuIS-4Vv2E1Z3Uw?t-QkmR$nx zbYjXn_-RNY0cO+o&DG0Tl~b7=_XyZ+Ejzm|njd06hMysZ?Oxd%czeq}0d^SjavHGN zgmc^!-p#Tf22RB<-vqW%<7$G_z4&1$!I_({V<`(O`38i8nj{q7&$6%hqDp=T_K(J+ zO2}Zp`e4g`6)hB}s~|G51TIdOB$p_B5R-@1OItOPIB|BTlU;ZQB9jb`1B4< zZHrr?I!1V18{h$_0FHxjN|S{D`s3IS05!t@AkujiHAz^MuPw6SOO|@FPAArWn8XAD0k}4eT~u1!8=<+vM}MM?mWmDrt8iKWFs-rMw| z>$+1KQ6`dn13zyYwy8S>`wLN$lDZ4n*MxK2Ox>x{SBM+P0eKeK9~!@-?)*A4sw6H8 zofKSAC0w^qcM^w3m6QioL*sYUooDfSVJYs(85W@Oam$I~1$2E1!j-F5a@uEBU&Bon@Cne6wB{i|Uf~+8`M43adK&ugh_^ z5Y4NW&UqAjgOFNxV(afPG({6Wp_Xdei%(Te`VVMQscFxS-an52$vfd`n)ZkAF02ZV zEl?!StV0gxMw|A?+@Lr@zUSe~KhdUr)&{jzQ#Eedi@7Y-d~?$tzNpMNs&UhP^-r}P zsTw!!zqD6O-L$VnWUS(dv2NP;BOba5zm7n46Mh@+#8RJNJ_$|u2oi`k;TxcVn{a*t zc_Nb1B3d+_j&ta!34gy%p2u(xUIpecTo{7B_n_>3T&^eABju(EkH&$7w>jYiQl(IH*AD3$iv-M-xhS~Zt{CGl$NwNZ%RSnxbhL7Mhuje2y+W>1% zILFOAhQr=S5LC=^Ah1yyzvD5SS1h8G%mHDcCOJ*`ndFF4vJTi5joY_;+$!)&Ak-p~qt`r!e~gK0>HtE| zJ2dIX@R{$Tnnr^#n37F2w483@ZYNj2eABe)5lGZNLtqI_*}W*a6TsqS3C zc*4B?4})py&N3Ii_g{jlE2M72$9e0Hs}aVQb@4?P7en$x!cE=j{eIrM(`!pSGi7bi z8<5CWX6w4siP^gDESQ(TB-szl!G>+>&dO;R&_Z552W%GM95+*UicWQlkLv(m4QzwP z@2ERRuSAvX1>rkQa_UYFa8~jgup1h`qwbu)-=)%30GU`E7pF^-%c(mpIdQt~T<#Q7 zk#7pp{Ukz>S0bkFJo~z>0`CvP2qIB_MM=5|-?25SX*LK;?$D&`&g}2-&5!b8BM95> z(4_0m-0$NA6`wo?!jGDy>JHV2Javb3C6=e7^3dKMsIS`LoY|`VEfD=bCHj8_{wH5Y z7umGKZb-$v%z9|-}V8KK6yh(Bo?iQk4VT8(NJYg zC`J80Swj7<9lfXJ49T?G!(`2HG&uB0tTsNgsx=HcYvPyU;7ju5brtjzE%ooacvWU_ z*7z4k->{rDm)}t5Ypb{KvHl^&iI=$xS?7CL7ZAUvHjOW;nt zctX8>|002C&Mboll{4tHsGQ-?d+BZF+ai5II4mAn7Vj2Gz7`ciKOk$`t?C~TEoxLd z`5t}YDfiRLIME`@o>R#$vVhjZejJT zFOtDY!R2~_Q^-gkyI;4ks0QEq8p)f&N9@*ElS?V=47j_dL{o^xlHXxpHl%PkkTHag zb5c0ePPi+;hfdE0vdEF;6ppYbceVu`YW*IN_l+#4kd8dUk))KuRu$rf%Y_uaj`2$} zeaAB?d>A(_lfu{HZE*`~Ebv^f=1pPT22=p}mefdW3XkEF4yCXr;QE?kQdo2vc2!3T zI|J!X=v#SHIIo4;mS;GSF^+6Bg>8O`7i8oz7sw(b%PFMEOJVIod`0Fu3+U6&ho%dxvvgZ73<}+PXv)d+4E;Qo z0F=ICcv?mP&{>7_adG5wEi`RnRUF@PC&+w}FISqZ@GZ6FM zrk_us*?Sg0o?Lu<_13@)#a-;;A5tG^3%{1Lc-k`1aY3?Z`CTEJYPDt{0ykvwgqAC1 zLdpEt>k{{mpGU-7u99&ySL73q!@yXyTrI<{s`&PmAjZpkKy0~Ax|e~R@Q<9^8k6>| zL{d|%w2^09szD2!Z$_QgbFzK_2g)Ohe9y_BFlk241kAnSJ7DWXo*JDdeQn}pkCNET z4{9b#t4+k+9QZy-U0+$)5v4ev#7?+X!(#K&4TFp;Gd|%|^-*k#BqML>V zcXyVeN8}Y8mYdx;aSv`DiL^!DWH;ql4~k63lty+lz8MkV+ zm5-|a_{f&$anm|XGrAKZwvC%MzWvZPF_PQQEwbB%Pvd54Wbc}yBD-_kIw+VKncoAn zu7xfFSrF-s8j_t`_$qFeMM{jvO*f9t8<8hQ;pPE975JJ+kAb-99-un6DH5JkL}d5i zxNVKBco@iozMD|6T?Dr5yGz_}bCGx!AW~^Npe3iHlvKq!p=?y=GOYqa%30wKllMUK zrXS&1g4>i$z}oMV|KMqyLl8MwOp(&c*MaPMCA)?Q^q@vDfmyYjFWe!jTVE0;5#uOU z&JFBU}vVBF;UoOZMb%%b%e`4Qr2O+H@CFTtkp;{Ug zpUAlW@PAwRr(G=Y6cZ^6 z?uYW3oJ|$Umt)6zqj?p{fLw|@)ZNK*JBr5F{>1TNp%MyrC(p)JT+q>BCys5Yg#7VFt{hr&#>ZaMq8TAhlO zO1pxYmz?|-WB%4U9;Q$w`3cWz{N9v9`->VKY#-f3V0|e%_@j+%hZeXA@QoE2^(bzF zeB+C}FaS3pz6nL1?1Gy(zDbB2&BaYT-y}xLBJLg3J0U5Ojr!dofsy3MrVwr-d{aC! zc?@n6L-f_EbfhmHsSX9gRGBLZD;|+bIeZ@y^EanuC+@j8MapnUweQOrbB26PPIKXi zlzY(J=S=22^|pyhshU99AW}l;6SQy5VxWCaK$d)wA7_2wc?c%Ja}s`K2U6 zRn8%f;A1gCiL^}>0L_-+8)(j^8jM`RLm{S3!YpLYd>K!+8Y^Q7DQMtD&gBU4J}1bD zA}dJxst@o#Wn?@4Q|?`ik>~m?l18IDkn^`JG6etW1)LwRB$W>wAFAXcWeDbdbCz-n zsu1pk#F>@0HWPR^$ts%@fu3-YHVRKePEpln^)q_;aZ{Q6Hk!WnNv!U^N`ca3E*1bzM;&rz>)DHhCfwvs&-o^EReNc@4 zQACTi)7e34g@QK~BA7Cv7Qvhw3Ksaw`MwzaBk8V2n(hP|AHc^7(LWLzWuz5+dLrQM z#poY-ylAAAa)!4RqJJd4$w(`>R5?hWD@OlF`k;|k${GH-5d92- z(SPzOnw>Y{>Y-7j1X+kkq=Y_!I>}e0G|xlO^rB3p4k&#Zb!wAH`T>2yoPT7&L-;g?H07Hbk=7${(~NKGMOvlfra9jZw|&yHs9n#?jDDm9KLBE$wB+su`Aznhir^qX$ ztta1fj=VwIdhtz{NKw+(hi|$@+LE@%_$D{9o3!=kn{Fbd3C24eN5xa4Rva10C8O2@ zO_w)QfQ>0w9{!#!C>zhK$an9hM))C@XH;$c@GZG8R_IjA{bDsVFH|BQVj$3|wx8RT zM~C$3FFMuX8w<-8!0A-i(-yR8GNDsL_tgACylsRU#Zx0Dlu%>7@rl4Q;B;!@nH&{r z?e2xLr0?e{q&E4fnni`$@(qM~gVU*<=L66J$MLjww)1a=?!YFLX_r90FX6Us08IQ5 z6QK!RgT9RRP+0d#A-X1n2o;e%lW|j^z){@zFv0ShN7TqInMkIiWikSU<^lAcHKIqQ1Tl!t&EdgJNrnu5!u^y>%#A35f}z` zx2|r|!h^Y1kYx3?D6j!7e5ZBpa2NP_y5r|ISEZqF@$y8qMltRDD$u@H{q*MuqaUp0 z!0&ih()S~Qo^s`*|5S0_GK`e@4+!xe~f(xbW}zA{>*J#vn|P{2M7cb2q82ng7n@$ zDWO9sp@Z})ozQz#P&!KQM5Q-r3Mf?s1q4A*KScri|9NM2?*=}9=lu7aJ3BMa^S)E= z%-p$ir;JxE#A^5jct3xZbc-rn)@gY z8u{xq*wXtLLdj~VmW2mTgu#-^p`K^$69u_}>6?nxY%Hs>yo*^O?>1fG-BfyyFujv1 z&4TwMp<|BeoBBDPnOU#O0=YiqU9&B`OGzC^gWjBMOs9w@WhLcfU5<$o@Gaq@sEFz+ zVw^g53=~+ni(G2k;9U`QHmMK7?DDB7Qz-OjK_a(X16Bdw&S|?nmLydRO?`@JURTO(D=bUmBn=HIBSR zl6x=3+gDa2UMlD#GL@xvNAD-Ane69hzJQ6i$htWT;n5|qOBZ75_ET1 zYDu&=SyyDjmXLSoei^hB*C;{;%_lRO!O-=37?s@wVj_*+io$yaE>X&{4mG+yGLj}2 zX!NC6uZUu&(RV-N6UZ6O@vt{KlR-ct@eDHbek7I!KfQT3491Sbl+bPkBL6}R?bU4# z);(TKppCdQJb`(-?Xxy*kNP>Qte18BK#zx=d3&G0DR&>*Tfl)?A1U|~QR@bah*}u4 zZ?9})*@?cEm?j$W&jdHqvh!JI0{6bwJAq{va1$3{*KO!x*<*b5iFSP+`Xbpkt#<%T zUg5z~^dAtSOKJaQ=lvL-KT4LPU8qM1ek=>2iu^zs;`G{{IKry=|DZOw}}+d4@NQ!ooss7UNAJ+G@~OaL&w-4r=E|TF0wgbGrsBrn=r}~U;|*U zgP?jAmQ!Gh;zg}jMr;cLpCGWLIrBOL1ld8 zSWl3w%|%Gp+g_61Z~E%=oplwKsxa33Z|;DVS^5ld*pO|OK0_V-#Q!kIr{aIOgUW%W z&j`mm;(w&$Z}C6c5h?!1I7W*9HyvMy|FI4#Czd|r92>>|c!wRKS^7+L6cFx7jw#}Q zvg5w^pW>j~W$BaS*em|0I{bn^(@|WwXF2AJ|Jjb8#s3^fmiV9RI4b_D~CB%{vbn&IT5AcmZY(ELgkQ8r&NT zb{A^{i)Bzg-ktsjM{|<042k9g$vrfIkEH)$K0a_QXBGN&#_6sRjwuwvu*fv>vkXg4 z8zufrrA-$9Rnq2&|AuMH#DD9wHR8W}+7|pnAc;$X5?l&Y;!>aEr5nUQ-uxlwLxZGPqLpiIBhI8a^ z+_ktnrepAaIB0rQ?K%VT#2Hn`T4xyj*R_ghDWhJu4uW{Ej%-v5+aXFT%fE9NV^v4D z)U0!XB!7XP@90*V=ez(XE8V`=fnxq^r7oCWcRLMeN6kYisK37k9Gx@|Epn*;4etNw z&YFiRcK!V5FpbXAJoM!Eq* zabG`~ke)IY_1o)k^wJ`~LX_&qCBxBM^H!til$i=gA1#v7#L_Py>X9r3UaxB&dWW%3 z!wdJA?9?{kMr?f*V=H6YTX(?`tD$!=ri*bGb(L!ESolrGr8M6JMX?poy&2Qhm{U!n zD}byq(eUO%r1Vhnhg(6~?XD(KY)p^T|if6=u z_SlYY)Q8q;2v)3+9`%v?5?+IlHKJBUWZuE{C1Z+N2L%aZio1{Q;;eKH5h)N$vgM0O zpcEs2mcR6eXxB%d(5!19A~q8l{jpYp9Hkp}>&NIVDcY=VSR%}Q78hn_j6R@Qz5!_( zuNY>q(TBBsj}TEva%Ma!d6FtPwi|pj&<+9(Znv?I?r1;~# zy=*@P_sv>Jtbq-a1A3!_?{4F0n~i%`buNmEyS)`#lSpZIM@W;eyOZ-Gdayq$18XA{E`N^-LAnP(i-#9?lgG#wr6)o|B3~u%Q@5;qMstPr>6m zmZX@)-7kXlTHO63o`7g^4~QU=#r;NvvJOq~?}L$9;f~k(B9;X)lIb2|t+RVD{)bun zq@dT6qPa&|iub`n)Hx8temN}_=3b~TDvw3}hv9P)my&r1K}qN>{rC_8I+C%!??+m6)0%75cB%xN4&gk#XL2Ta#VYf-j z4yE?8-WAg-l+(a2nRp+<#UY^XXAx(fDeMi3+V{Ypn;fA-a{i83Vz)_-w#i8l| z$C?BggwW82+ux}T4T}J-GzsFSNDW=Mz5YRH*bDH8Nf4PO34OW!tGOUt1$f6KhN_r(1+q*G#nF%MIWg<0OsMa)R+)Pq zk8X{*VMOG$VKgL(p_K3LeNznPo*lC)M4r#1r(r8^;_yK*Mi5yPS#|MbD$U%U^*nHx zzye^)2p7s6_wf{WFXi@6F*!)t2LBI(va%>i!n@plV7Qwp7XaQc2{LDP#3Q=DD)!zN zQBHmW_@_ybc`FFd6#GaEimb0UzW?Bosh1kg;?>*zyJA0G82+UJRtOT9JNaG8)+kY1 z)HWYsFAS!}7R6FD!RZ8IcOuK2IZhR2YSimg8YP*lv0rz>>m_k!!B{{RnKKh`q^?_4 zqvvDpoVXubfbAk&C{qQlsnJzGa>?BP1lZ@Myl)=eCWmTo^#RU5hxZRAlzj6L?vP8h zQ;lR@ik`vE9h<)tniy?Rxe{*XcB{TW!PYeQe;Of0GiBArvyLNyOk0A+qK|I@wno;* z#aPOt;hLhX#_^_bCdBoEnp*U18J91r3=(>r&s}I|;|i3H$8%I;%{t&6aa@w6Duu?x zK4;^KcuTy?#k4U#58g{~DK)7mNjSw@zlbI#B=PNl_7YrA!2dy0I4;ArSy31jO@1EG z<&d<1%eo#X8jK1f{{hf1rgW!)-MX`JRa_aE^+>nRiFEjI$)F`#)z$8N7^C}D6i5c4 zB4jfwDAQPl5*VQz?{-fgfJa6rA08PK3VAw%Y&-j94C@OE6YnV#!^6w=1La`DMCO^4 z6mbMde0_rB$ZJxn_aORF3*oUAmy+@x;yk<`)cxE6oVMrFac1zVMaTz(SAW)lt5O2J z%UV^Ie|0==%;ZZv;!lYB$Tj&Y_dd(Q3P5=LNct*~J~0S&g7@v%7^i{>$4TCN9?AaB zBYb3={1^BBPzZDE5Y-~Mlxi=@MaX846-juVu_A zsTkIz6k~70y&jiRoU&h*fb}Q_ISpgzo->uz@gt5oEjWODgsTRlNBw z0;KN*QzPw}U{;*i7_qCk0k23XKc}ZNHf@WoFJ8Z>v=0P9mb%HjAJRJQpzT|HsiZP1 zy;;qX@Sfh*kvV;GB-N)1mr)dFB)Rv&ZkZV!Pj9!DnKALl@Xs=5y(vlgN7>ozFvpTN z(1#j=x2QS!tr7dXAO>@itlvU1{wxf1DECK@U#j&F^7~x+9etDhGOTV0#}gU6dsOS@ zl(QBjKO)0#cXRT4&03E9h>X77+`_JpVXH}_5OZod8sx_)5}#LHvGs%R`<$HfaJI`~ zl&Ng^D7FnGR`VoE#r$-4=KKngM6@hO@d!1=Mx**SbZ0JX6*&d|%rfV=k790_bHYcl zwahu`qZnG|eC(rGS>~MbQA{jzPWvdTb*3Qgi^8l0=H=6Tb>LCcj{3CN7FOZ=L5wYl zbj%nC(v|COwj{}3sP_}RvMecVn+(tR#}r;;@>)_f>iAf6AmibkgiDE}NH^|9P%+C- zGZhpDcvlZXvNc%Fg=|U72j}si&IH&cNZ_%gAV(>e4{<0J@o7_o<%5qh;za_}exW#I z&aWI#nNssGGHGe7J9BBF$OT|#E^Hf5nNsr{3dFKk-36u;;eKjP3rtDjerkIPOiAT_ zYGn#cDa!rSs1%q|jQgn#DKI6C`>Dw&Fr_&6QwvdGN;>ybgHT{f3GS!*UtmfG_fvH* zFr_5-Q|&G=r4;v5WwzuT@Ke>b|5}^{?^l);RpQ#vXoTgR`hGD$*58F~BMUlC z^20^2)M2HUTO(<`SBvXvKTLMFWJfNA*3*b%*kMpv?P0Fe(Yrf#raQ8 z!Co#a3-iQ^z{G1R_9pYu9Pfi1FM;7r2M-j>YRk01**me-B%{}v6cbsgLX zj*_;qoXz1`Jz2ei;}H~DyR!OevnYY93dsbnN|p&+RZ=E!RVkUkRi$MDSCtV7w5)n1 zfR~f_>Z%FVk#NiEY6PwZBrI` zMEqIA(HmG>vt~H20;U*0fxSpQO^ly#@zM{EB`=BApd5=BgWan6nh|^=L?ga^hK<4C z=uRP0Ucyde1#;j3j@AIsgD`^^V1%tER;aBR$v+P17|A!14q6ru;BH9ANWS7F9RiFP zc8QWOn#T_{<1w25Ksso@P5>zsU75Ji{M0q892}B~8_jROq%>9}F8%?fXAG|mrII;@ zS9mEKXtaX$VJmDHVemG${P8Bj?~kr~w0DLhdKhLS^PHzvHY)*Ea$Ld_c{Vw!aPJnp zMtJA=$z}EK>5Rh#=lV;);fW&!-uVT$VE={p5%xA*%Ees>NFs|1_8;qI$KZP{h;R{r zFi1s!_*TJ{L*48#NY6~-71A?Rv`OC8#h$w@>;`rU)1~ku8>TZ=rx6zGH0AC>8VvGYwkzKP zJkHBwFvxo~9EF=%Ykh$(zxP@=DH2_A@AXJA$}?TL^0Pu>UpkcB;b`@#2(q|%Y=!0h zD&_J|R_29o6fQ;IO$gDw_Y0Ok>So2@Thc^g)3N)%_s3G@KXx!XsP%v}A=FKBvG*S% zu0NM7>vD-KuFDM4KJ&?PlIT zT-zy~=(SSfW9h--Z5h4wGaD-ieV4)hnj})-;H4-+aV2XYds=D#osKsEK>xf5dj#Ay ze`;ln@SeMIoSAo1|=k&*Av}Gi}m`H%VSHOKE>nK@&8kFr!aaCD@PYr*+lE010DE3N|ky!tXOQ}X_ zRRzp>#x`AJ4G8ZKYzX0WXV?s7BL$%Gxc2Qmfe=(`CU6#C@-L<3igg7IAA3Kfv+i2N zGLonM6|IWGqZ|Wv+SKWIG*xHbc%FRsE4=N01^;^{rjEzX%-$p(Hlv^{c*;M(^ije1 zsH2`jwir)Io~ntWr{n{cY~qexN0Ho8Jb5u5XUePauV!NEJ4c+%Tb?`LZf!`}w!k`v z@Ev;*?>gLhu${rEX;MZ3TNK3kQ>c`US5ssSZz1yUuj+_zbM6|}17i{-vkm+YNrv)Q zmK6tWzU*zoZ7mLC;O7FsuT7;CPJl(jDBeyy`FI`l?4E*QjD{LfK?JJ}1?ZrG4vc`= zCSoGA5)Ve&i!4$6B`VwBh~t&L zi+ReaQ!bg&-vIkAgm3>1k$ab?>^_(n41qb?w8(9-reG_*G{X2Q`xz~|9o#5Y_Ff*r_+GHfKZ%B@)n#ege*SCi#F(ElQF0RtWgNp zK1UXx=S6L`91_n4*4M-xLjPwxdE`^v{)zCPO<0~7iU7Xg$yZ->Fl8;kZ7&f-2zPn1 zvyFu*Cjee}iEtqcnfwE{ohe{t%6))8nFM-7Fxx_GO(&jy8g*-G&aBF?)uaPm)&YG7 zvgM6RrU$#Mjq`L_n}{weJH`LOr@^w+{bg(TqUsDM!joND!yk3UPBp^8*KoZqW95Yd zA{X#Esg7{GQKAp}_u1U4^+h1_`0dxwb>fLbsR>~D{nZ%b%Lj1lyKu)71CP1sg1B%x zHn`@=1Yj?Llu^(!5?Xc%unFGu#`1*y65Lb*;3R+-1b7Ya!qa%%bpZ~jhNvu`!5#LJ zu&gU4Hhj~l1?qYn;}pe}anRp&s}axA$*Oeqz0Oz(vT9vVWiXaOR%_Seu$Cli)vlv3 zUQvpyp04fjmRy>w`6F+pBbZV=UuU>Z^BmbXd`0PpM`b)^x;zWq`-ak9^sF3L!S_yA zG+rCewYMO&4VTi9nmV%ap=9)=yH{r56NANwM{ge`b37DsZ8uPM43H9$PVVBpb>^Z#E@j>lEr<8q9(FXK@Yz)9cCZQh%DhY=aEw?P*h$;fCWfBI3 z2yy-((40A~VPc z#Os-&JspkF`_Djo{C`mMs@7C3x-q6n{pmlhG8qk$b)r!$U4ub(sdV!EvO{%JuqxZ14z}RTAL~6x{R+)XJRIT1W z$iBm1T>f8HUWKo!+N`Tc!XwcBc#%pKClI-ssdC~cCo zQ1zXvVU?uKAnY?qqQptkF4b4=AG;)71mR1QBxVgsQm*Pda|O#vDY&N~@JYc$ifomn zD)xP$zz4y11c^|^4&e9ILM;>BEQjy~z?Km%Rp#3o&%A?`%nk73F*JhV?W?pG zFJ9t2An&iLXW;TMA;QmtbeUv@?wCQC_Tn9)WZo6Bv;m#BpVGeSThJtB|5p90FsYqH zxMMQ<6}V)$;w&GpMe~fhXcxMR0?Hs*sFtut^N+U_m&(M<|i1c?s=bBw7hW;3yeDVgI!>_S@NyjC7T;_JZNWa?JmTI^@ubS?VlSzf8_ z1hBKFHi?(l5+7`~O8I-h9);xH)eu@W&3|-am`u5j9+d-^Ou0Cr$Xj3YcgEvTepkyuxZwHk~Qc+AR^ZrNo_K#46qFsOwzNkk~vh=8J<=i4IR{-CBQHx4j z7J1*$eLoH`Wc&692*$MFotJH{AdS_14>tyy)BGS5GfA>J6{N|!&sQqYFxLX1sY#N} zsUXeJeG_LnWN^Je7-EuSa~g@+VBUqguf$lVB+UWgEt4eUBuMLY-+*!f(ryq=zd({b zBheX91%03HJ7I)Lop(WfV$wqoc*#7Z`%c|ZBr^Q3ms{vNj^l>(u< zNeVrerMgSHZ|ExlW;?L5O{Pe(qZ5^?FLm37>KJGl18}NIkoiUvA-q56zQ0CVWO%DV z*kY1omI%^6x-aWk;92!C2%niG`Dhd*yWtz&CUBb`gTQA5lSi8J=9{3$8ovML58SXg zP>Y%LJozS=NrtcK%|Ph2z-syelc|D~V)$;jyfPiVKp1I~^5mOfrW@h+-VOx35UjN( zQv@vUg`fpp5q6>I&Cs#nW8frye;Y-Dd-J)9% zHWMH0aOG(WU(O{VGY`pH8qi)1{FX1uQUt{>b!Iw%A!~jso{V$z~qb9w(4WF}8 zp!B>2*0vX!c`{8XK5c|GxTVV{|7lRKn{@Hmk_AdIFB@T*Wn7Z^1T5>UU@8UkWyL)$ zse@B3lAZ)=sTb+8C_kx#k~-L8%S}ZGy)GDygDiQ7rFV+OceJ1?)7=Bu@F1SI*!eKm z%)7`Ec4&8?3o{?A6(*CS7f|=UCG2J&*)`((K=}9t5*JKy+@<$`#g_Uvo^3b5xEo|K zbzs}-vtui z4MJo8MKDi65i-TC>4&eoWMIp{-}-;Z1d>wG>T7y6&`O*F_0GT0^W0exL_=$O$;$zm zKf%X9Q=qtuf*=f8I|RLzHT~kr!1JOQsI~ru{&Fg^tm(ZTVY)T7FCD=j{C~&c7ay)?ju)94vdq>Kcuwu+##oF&BxZ?uT3+ zCH%>dC!%`qT5aD&;msu;v?4^M2R^6tFm(b347|^+5e={DOeDM-2z7$`m?}PGa9hNN z!eJ8c3@rO4+-h@Oovw?IZhSnj9KvOfqsR`o zdHH_yZ0K#MF<2c;rrCBfRWN7Uypym)oL~+IYnI70L(i*toz45#jKE#n0P4Q~r3Vym zws}Xq9wrrE1naiR%oEvPF|)^e49U9Skjy{8a?B5AK%U47<~5slZfYR(WUwll%$Fl8 z=#OpQ{&uTW+#J-d|4V18VE$_JZdX*vd=sqMCNocDTVe8um)X7d*9Usd?}3$TGV?@M zFeB~W$^!$Te+JgKCiCUU3VJcSH>Psn=JEw-1aQgvVA7c?n5FFATNpbKx2zagubRv} zkxj*H9Pev(Z?9#6WVHaRo5{=*S;1^>_Z|ofM0PA#3r(gOdY~8xdbZtLrMy>0VJoNy z|Ci2G!R%-E9_}9~-Pgc+U^4SW_Emh2_D-^U&*Q`rkt}5)9s;;z2IPsXU@o(J4^<2l zgEX+Jnar0XE9hJ8-gk<6q~f-q_WoZwQw4L6-P;{|tcfU025XVY%oEuu*mJ=9i9O<% ze>{u^5&1T-4w+0LOa@Lp?g!@Ac87*$ktVhA>tKCjGAUUB(w}z6+lo_?{stj@Q84YM zy1)R8&{@FYSl0;ChDm2}P#gXqbaBf9_e}`aa5!$`OPUbu4xu+pLCU#6WSTe}_?9V2 zGeB5pl0uO&GddvC(SdPWP0Abs|I+^DD~x}7>>LJ4~IGZh+kXByqi{6D7Be24G2m4@NP#F90Sc>*~Ciz*KA z=gYt@G^i+s)_lD!o0njKc{&`vN!sr5_~w2P+~c^E++B#Ogr;dvtK#8x9p2vrAubkN zh`HXr+2P*vI{O#`{4d~E=oI3TBR=f=`j-^zhQ*n>zPFu|aZV2LcsdN4_#g$yCg%qD z29?A}Kc?o>w>aNA+lFrtgSLQsn`9v`BwRE;;oIT*)Z!4z_#}{~6Y(6SLVWo5^(!f= zfjBM7H=v{_1A$y&8f8(<;%WHy(9Qw5Q3hKx(<-(EUGrJkw}bH#N5@31Db7n|4RSCV zDih=DBF$uz=P#`JDJ*qp;PBQprFq(dl`4x{ic|`o7+@1*sjNINk$(tQc|p9YNfK(w z8JJ%3(DM&C;w?vI{{c-*qs|UPwbB z5G!U@2O&;@vgjh!AUc+(^{V6*_|Xtf`Br?H%f{B^@DlV6O%m$&M4-7-GDV@tO6qi8 zVgb$#7S!lvVA1rd|Dpc&lasAk#7j!Y8z9RBvhd! zzs*ao#}XO3bLyyuzVPg7|n7Z_pho&)wKDn_9GbS>&KF)DzIVM%yT_45@ z9YY1OZb-2#fscnqPdAi_+l5zgz8dj+50`R~+VG|VDqrZG!XCCCz8?n>xj^ClxiM3O5u-;tHq`@W`|-=m-iG>3}K(;eZMn=-RNL zc!9Ytsp3Dt+nXE_ZI?nRUtE09ZvoCw;NxH9c(-Fm{tfFb;^7!xZ?MRErctm zz%8+gLpI-Amj0&`4Gv}PdvB)`Ulh3amZ#r^-S)>ICS}=xle>^*!&S#=KJB`VVHwpd z_1Bdc)S=}I+)?+q&fIHM{pvlqtSdNk;ZjB&LOx4ugQ{ydQj!;fe~BO_7g9;WCRIPZ z2L-Jbz@{dFY%E4BqIy@YLMu!HVd3d8HbNl{X1*`%1?uF{Y940{HjPM)AW(Ki0O}D{BE))Q(7g#uIbTE z3^04%!SrujA|Lp4B6OhHRqh6w`=9PsHU~asfLAd&LW$(G(%cUY*###Pco&l+^oTD^ z?kSpkW+%)5g&sZzgsCP;u2MSi8P-}o((G+C#O57<@0$dYVKHL8%~G`rEwAB4v%3vu z?x$Mp@7E>s0@znbVxb_5^)^e?Dzv;NKz^phw!;JrBK?I+eK&a1)ip6*tn$%fTmEbj zq4ES^DTI?UP7z^}^oJJv(|1w_uMR>ZB2mfVq?W~q)l%=MRm9>bmFm5l>Cp`@s)EUf zfIf;uWF*CMsTFD!u{uh!xgNd1DoK0|nC}x?6wUdZnjDKBTXwWt#PTShQ>HQrTlLtK zMyg2TZ9w0e(lKH=&)aI_XpAKBGeVb5=kqLr6NbtWjw=`vE%)^3u{~L>2|2tDs`tpP4t58A-;+OO zpZxx6F5bC`HYlBMQn5*2pV5AX6~OdIQ=1E|LjI6Nv~qGU6UpfyIJ8*2E^)*rF`|<% zHy_mSaqRsyVrP{ugo`JLXw*_KR89cI#r7v72_rFyFiv4~i&gq}TBUZlQFE%n&yGvcHh^2Yy6}WIsgldhA=ogFpo#}C308(*4HEokeMk^*H_`ChE_anE z@TyoQKPWnqw26i6gJS$ds8hNvW1ADKv~L0%>W|3AP2gKx;TwU?R;cQ2@#sCr$`p*9 zqcj$8d}Fbyc`_06g1Nw-_jS9&&8YrzVbxV*DZk zzKTn6P??lae)X4WfF8s9SrFpSIsk9`)weNhdy<`WGGxRyz&aW86wi)ETy23kREDBt z+Q4x~V=gyioUhOpjysx2rh7Ja5Cuu

u~ zAWi1JFYr&Ae*YJePP6lMs@^&^4tkw8Fr&p|X@y}1oz^26lLx{e+brI=G-EsKdVXw< zg;8zsRNvV|?1|S9?FOfvBZYze>QF;>zV0TUEP}|u7DA07wVyOJ6wnxg$UuQ3g&z>K zTRa_>5+t@`PWp&^bA|6#@+E`m7CbhS3ZR(ooE%QtPn%GZhAF%|rwQM$OyAU}cwFur zCpYW*gS>?ynql1uWjdXNXFR5AN+&29r3$yJ^t5~NInTwOcPzgufjm0ERe&;Xjp9y)zWBm{Q z_z@U4$W3ALiFIIz$F^{ijg4x3&(6N(8JL$%jke;k2*KYWR1h+G1W7M91@qWWd=5Qj z-hIu%M$O#kVi)<^&GKLt#bXF%b)cx7sVt=8j1WA2#wrCr=5sy@3hE@NjDyhJ7X{Cg z%&3Sztn3UwUs%4SD;`bIw}E=xq<@Jj%!w|yXlQZjUnApnD-uzT7`C0xVIPfv%N>6%3#eLxzF-yja##$Z{g`j&bC8O zM6tamoFa}Y(-ipW!XR`3r(jOm)X|;r{)pcKz8D^-ZR$wVV?8|1*wo>s$6k1xwW&h` z9_46OaJh*%Ww&jb-|B%*{1!lR-B9G8yF5Cy#(1Is3Hj=Ev$DPh-p4 zT{u=i`FXa&=6Vj;_=e4ROpwcSPJfIqEBrb1s_<0a2a#`u!CW+d$n%N6=WRRtg?dx* zz>|oxOTaYY$MdOwO=G8oUjkm&w2a2cjReKybYjE1XBpiMU%cf7wm&QvKI0Y zfX15A-jjF*@qCs@31i+O*i^>zc_hVZoVOBM1n1LANW816rJ^$S05-_Pg?v*X z-`#n`9>#J2%{O7neRhruJp29zH(L+rk_n6FB{kjh-9(HCtfPboV$U6j2lrBKEWDO)wnsCI|~m(gzf)5YshgpN)C?yDQFg zNR^wx+!t@*e+THlA^6MnPUact?u)%2 zgtToN3IQ&WZst0N1$3T4?w`h3C7c2%-Gn`>@MXs{*xK(3Qd$GvjR~UCCA(D;A7U*X zhpN^E*dP-ZH&5)U>*-NkWuBqdHw&PMP6c6sNfLcCmx2|3o?-EeFdRuo9rDet|&!QzZx9^Mg>JWLgfO&6?&ovq+ViHv!*EoIIg-#CA!Z z>5f+2b;&so{Bn@PTr1n6(V1cW3(HJIE%^b^FCqAGQ>1UEHMXrhTaSnB!1xEQKn6Fj z59wK+Z-3Op_69r+P^l0+pb3iSZ2Mu%grdfYHvrTu1d9f5jgSG(dAq*s}oLKF>UB*f&tT7Ty~PlKHmk7;5!=>!3@>w?ptg6NCcyyj?gn zFR;)0*e&CA7x)jv5&0%YDO@yY>sjJ#9OsbDn`I|H0^^cpST=z}i=&3Dx6a0zIgxqA zfWJbVJo*1_OXT1-_t?jQ9Bcx-%}bmH+0e7y+O%I_w(lU|Z@$ENHWYPvUwDPZ8lzU9 zF9E(H$YHL+gHTgGvL^JBohQB*(EbqoBR$xzM2y_wV)T6AmjT@{;b!7-a@|P}3M-3C zKa47I!#ZQ1%Kic;1Hs8u|9>>AqR|y?YrE@}Q1ZTXU%`ijrW9k*cnK9Ehl>;`hk9|- z|JO)GG$6f*BdT?~W-AeaTkgx3t!#SGSH1%Y$+f)T*H(53C;u%CMlINNqbjUZ3XKnt z7M&jII(<>n=<}yRUq=mc>SWVt;j%$1uMM(^&cuH~6EDP3O!s$(CoL=1(U=HNKQ{9w zH?2+9X>qXT2Beb;ofZ-sv}8voL!*^i1}*V6YK_1?fwb&ZC#Ocs!whm7w9?F=<#EP4 zq<}v7YV_&ZI0~CVOMnu|&mco5r$MU)jOH+ON~cDJ-5{GmeVIg&cFKC48c&`4G%AP& zwca{?CNSvJkwG?{Z2CsLg&7$+K!s5jHsc5x!p5h<<|2bmGd9v-=ojHkB*Pei57!3S z^yy@)gO|)ivL(I>n?Z(toX`O?;aox}IgQRE;YV$?;m6u6BZrK2h(@CDTT5iJ>B4UW zq5VjLj<7W@wL=W(=wpMN`c@*R&4EESooxCoa(0~un=t5%PlM*v7{XR|K5W&=h+P26 zsfDmLUJM(Z3aXRM5VnuVMuzSu$}uv?re`dHQ5J?lHsb<}L~`nP$$4ohoMcP94x2%S zewl##WZSkLwm+A__-r{0;j92>qM(qGxP2XX?#)2oB;&*`_z5Q&IysHD+u_$3hS7Tm zY!(>CkGo;~2}6Hp5B$h5giXYGXfA+x1dw5np&!}^CmDt?T5N)!or3I2wtSR1UP^Bc zWR0W`V31AUO-U%X0k#hB!M2NRXDC+N5O|`nk&!qN4_|{0Wiyt-_>gB~%}ac4OUtbf zF+Z?HeVygD^83)=sr6oS2g}WjqP>Y@shgGC#`?UZd>RbfhfjaFlm`&vcVVzt>Sg72 zwH6;N+tRlHuX~9?O>%Be>$a0p%K^ZrUZPxips?H#*4y3XxcS$BAH78RpsW7{JPWBfss7PjVIu)eHsL=7Jm!+ha?e=n9>kIxK<}GyD1^ZxeixkG?}f1g zz&|lLqUR_Y=hz>rAq`(yFIALZukV5LhaH z%Oj+}0CX=1%aJuF^{8{}bNi~Uvd{Q8a1D7PlkRM=-otX6aC<3T_IeWl6*OUAo##k< zD{hT>7AQu0aqL4cYNnDi0_^~05l3XZuQ+D@Jq@OOoHfis0Ca2S#Cka z`s2nxZ|*k`wEakv*f&qKK$4WISev2=5M91R5K>K&$ZScfrC9qtksm>L4G`4e0rK+3axKkY?mxvJ$ z!y899E|Dip6|G1w#rkRUz>r39V5LL2Xh-@h)_7N-58nvb>mgjU)`JymJDmF~va>I+ z;X$0!mV-T@r1>DMc!?yQ9@7+SGwi)3H0=Z7=u0Ge;mDn>Sl4U_+`TVB zxDzBX)ruA^ccJ2VvlQMpargP3gdq}vI6wl6*X}K(!5-iG3^YjPY{>YG5J7##N@Ezp=yYYzcJLCdqifo zZ-ocwQAO-hpPy+I5rb-^PBxuv#!NhR5A!pt@qDHO+>Kl9fc#n&Hgf8_@I=?I(PO>h zM=;2yS0UT}{V>R;A0gZKWGp`bgPitOGw}VYhQ)UX^@78&|2a`-5!GT=f$<5iJ;Bb> zXlUsZ{v6vX6ep|bQ`0t;qWfGBXAks6@M0HD+9T4CG0uiQ+RrmlB!#x|O{DoJ1{pdz zb@~de(bs9?*OfrYX^^3lbE$GtO<;$Ws=T13|Hn8zwm&v;9%tok?c)xkUy<)SvPTDjH+y>kT8d60Fs;0ISn*iK zJG-bM?&PIWRGuXqS>A_DFhJi$IJ$cOK8>NSu1*T6hxb`5))wa%Y_YlMNN?xbp!E=rQ4@GS#QxQaE;bmER}Nl-A-+Li_ieSWnU(25%;N;%ekQ%WN0R|&E8EWFiCUxgH-4 z(%~>x6SUDpjkthXLjiCq%l~SK+AC0DBZGNpi4sq-&ie_uI}eIJHI)e_&9D(8dSV1k zjE+br-7cO;feK}!4f}m1G5wHCInkH zVSZvM=UY9U5^ehOMIkHgT#7G7LU|uR14HnP`6!%aoQ=YD3C{pDF9a|63vgLy z*^&+kZv?bG1aHL|G5i(hk43x^J`L!62;Ny3xmL~@onw>m13*87;31g3#LGK3?+irE zavYn$;0mPsSP?t|DmbIs1>nMf(g>y!&Rh#`AX6(kCl^ws@>+nJ24UI8yFSDole}`I zaSyvY1NO>`xa*zk5Nz(;@|l~7s@ep2Pm{BC7ZN3^fmun} zr#$|ileG-L{k~0z%mQ1E{)ig6zatX$Dc}2d7;EL8yInp+cMwOY5X!_nxY%Bsk?=RI z53mTC;(8jKXB0A}o0lU)C=696;S5!5F>fz+76xJYSZDEFhKP;(B%Ud_q!vmNi_0vA z#E-KU{ma490o5f~v~(lT)bjdhLS>s#iOPmIr3VyFh}-fLeaKP22RJeRrU*<5Z#Jqk z9!8TrKcB|~b6m5hZ{fa9k*>pii>@|U4k3*9ot5BaQw59nO>Jdm)5t!K_x%;$T&I)$ zFz@@(9UGe=_)6b_GhA$@;47^MpsO`o99}+7X}$g=S}W15n5wjHG}d5qg=41D`YLut zm?s=_mDZ(dTG@QzSg5ov_DdLBARJ4T*5fK$*+Su1uC!iT%*hs6DgRa~truYzw8g@) zN@;!VZ;dSxj@3%*q9|}ng=3AfmY={w;*pZTy5MmvGA;NdS%yYeABV?@Ug!*ZAREu3 zSF#O;HW5snoCZ1do#$X9L*GZXuAjglo4)i@*w)fe813O>yyJx5ezJ8S+ZaELBjnrx zn{kf}a_Zlajb!y9QLr^5+ep~-w`1TWo3Rx(eI+@cz(~ALwgcpM0?Xa>gqw(D$|-bF z&fS9Z4Ed4G5Vq(zptT7lo8A-A)mo6VAVrs)dIC{;!cRXAo8kNlMhp!7GyxNcyeP-Ek#h~jdidY`^Y#= z#+>iKBh(;6C#Uh|H}H#vVR-Msrok}Aehb?hDEpe>o z&Oe5D*jor>9WI3sUKO?gzMebh{a0fj!smpE*9zeqxihz;#=d~h*Fl`A6&Bc;V=FJ< z%eJshr15u>fJNwMYGuNA@x;#mwXp4k$HK@T!arZ`W|+uS{A@Tr^;5;K2&`%dze@N4 zUbIHKhczR-4X{ooo?HWaWIB%VNa}yHa~$U)JIm+rR!Da*Y?(hB{AEEISyeDs zlQNX))K}9eFVa83!50k%V{MbiQG#3QAh6eB+ava+xbrxs*nSSqT~g9OG=dQ05AfQ+ zRGK*Jc!e7SumVyvTYrJ2LR@J|O_!K?>!`?$dppChZ#BdcfE6_HarTtqt#cURA}AES@Yz7(neo(ZVK=sLJ zmyOLtAwOf}&p@fI*8U*b5>Mc_ii|^lfkJ?B0XBndy6~G%Xby>eLqM;8V57lMUD*1= ziEYE6ifnpQPH8Iu^=;0oNh0DVFc_>og@0YE!QWK9L|I{=+*hOpI5fy9@Dl1(pw_-T*Gd4pm~PQ4LP z{voBmz-H7W*=D5bHv*#3)i5p>MV64$=#dIz2n?P4^m}BhLbir5j0a@)xDgG%Phl9hVqhByqeA_G zjD1+j!B8Xm>>uW3RjVrbY~SOl>#4B=XSEd4A2-2cyxgal{fbK=UH~er4=3n9@NOT3 zIN6wcdO=VNxM`1I?x{|CQuTMSwwaFwJUvL36@EDv0j23rx1jsH65ysFf!irGv9Luc z?%Z!!ML_&G@be}|yiZC_hEuTwI1hmT5acki?nNo>tkWj|TaZ8>E|H!<50)0cD6cr5 z206ummke^4_=KudaF)o#naEJg>jP>Lgaa|9buUUKXLz?jF#Uj!c!~2Y1v?m4aW*a# z&@&(SQsTHp)~+la!IbLuwFl9i-U9DjQ(R=NYt$JW7*k8XUBV%waS`}cQ@mM?&oQ&E zevA3I-BoE>rP!ufi$H|CENqB?8zqswD$YQ}pGJ4npqs4=gE}c1b@hxe*o+j|%FM&o zjyiP=bsCK@s0(AzySqLI4+ecal`U!mb!wLNn+R5GK?=I$hm#DgD>=oSOB%<)LmPg> z$*({G803uTH3hHr5nLwQv>@sXoPtxVu390GBcrFb?7V3L_v99{U&Y zvX6<2W)Z&hnXreqU=#|AE59s~MHI9~oD0X!&bZCE0$6xUw&@_s4zG@pLZOa}8KUIL z;;P~t+lUlv=|?&%4w>>Hxe%4LqKGXl5W(sJZjMW03t+>E>%gj<4`Bdv}Yt+@DSRhWn|<#gBFVbqj(AcvgyKa2BD)! ztP}vfP%4Zr@4>nMeE?n0FIlDqA3(5Xf)B2 zok&f2*^ArbU@s!jaYiJy9j$(n)sJJo~FT--H}E1 z<@Dyu5;Bfp^d9eHPcC6%>E%GcF{o%|2jZ=f7fzs;>#|Mop2!QAq86@fal8!j!u5px zI$jxh;da7a25*eK@Ni)-eGbh};l;wf9}b@L}P<1aFJH@Ok0?1zr|; z;UCG)mMb&yZn#1@)SWTzk4Hl{7x7Zx3P!FcBFFsw6)b=y|1&}VW9X-p=-6=pvn-AJ zMB4koUN{R(wvHD>7SjFy68!r?nfFjpn7`aD#(p7P{wskDD2_LxpssS#E_4+I6S}IQ z&XKMZ@Jj_{Mv|^|oQ`QCtS0;$2eHO@7BD|G#slD`E`afGt*yB0lhE$qu16G%q-M9o zP}t(B?R`gyD45LruOdTMk&;b8gAKw{^ zRIt>mK~PnaT<8{oIe;0eQX&d49R0}gT1z-s#&lF6H5L-ckAbYpto*B~g7_~YS4+ZI ztpg*xV~YWd`nw_lp&N17T?sdW`8y)-TM)S;48f5Z|8@$_{~`ZjL4OUgVg8%N@fDo> zHw67FAkg3qiIaA5LoR^H{0^9VKvhoV<%fMW0e1_xf+diiF-XXD{C|ZjirCD5Aq}hG zU{jvK5b>gLSOQVBg)`>*gmR26QSv&g*RC>v(xeTBkdW?mw=ETbG{ zUMolhGjD~+yk%hagReRXhR8g65QqqbO5R~Nje4*a6VIV{_mOiUs2gwz)>I&Ql1FO3 zDS~bg{^|2U6p@)uJrIrDExI2@321A-2KysiLdP+(gtF)qoEyGY*q``Uu0scrnSTt5 zx(7}*7KV@$<=o#pjcBBSgXw-OvVA&li{@}NZ@l|OC**gy!D}rt%vI)ldv5&V-E~1#BzM8 zuygSGEXZQDJfCW8T)8N!p|xTfIbbg&zF%M9QHNEyGK93B`a`ZSkc=c4fvPG}AFQ1z z;Z!?W#uch|y@}MZ`2f+kn$D}C<5UY?BSn`<78Waynhl+@uvmEklD^2Tyf_ym=0B1T zyp4h(6G%tvPrNJ^STe3CVn(U3F@JG9 z$Sc97G=O32JH*21{Zb^M6^c9mmD+#=l3IePrQPs9ATKeBWTR@qVE&)+()cE9d^HTA zAps47s8srQmRi>Uw|V~+^tHdYIH`?i8IP$!y8yP?2FYwlRboReTdGo3Hbi&OJGuq3 z`XH!(AGO;4kx=}U{Mnaz!etqr4EW`TpS-)MMP-wRd6<2ExcK7M!hxqJKFno+Q6nhX z_AFF{>J>>>h_bNe_-}(Nipb3W;UmU+z@|=zAyV24a=|8!w98w+wD1-%S%#w=+MfO3 z%H*N#$&b8+LpI#Aa1TT_QNw)>4(1Poc?JT?&0q+0H}b@cv>hIc4LtDw3$7?)Gk;6S zIc`EO7KXT;G>93xogJy3Cy+qac!iY#sY+gA6v;+Kz`(Nu?W@`n)?o8jLNtFzF<{vh zzI-YSp*Tmjqx~=xYpL}fVDm21)0buJrj~av*k)sC-sMmejJqsaOn(L3<>Mf$p9b|$ z6L+~j6n{zn_k;cvF7uag;rUPg{#$|goWKJscrR#;ZSY=T4iETr9AY6*)$|}=Jl`|i z1>x5Ve&P`t5Ck|GjZV5sCR1qhB)uHf0VBK_4UAzs}eJC24|ag^1qdK?GZg|4q1}NFZtg z3_PeXw)6pP{22@(PfbVp3C%Fz=(47k0$jcvP9xFXRv-1oWeM|Hoz$IZW8dV$N=Iw_ zYS5TJLB}KMYa}=xhR`)7s7qVPi#63Kz+AK$MS=5bK~ku#x?`zEZ58uJqKDIjG_?+r zZi{BC3Du0r@Uva0f=^zk?q$=LGiG0zAnZ#Qlf9g1WHRc0kDIj*TzN-P^_PGThphT% z9_Ok0HgK8$!FP7%DX`d8$5Xb3Sphhxq>yR}`_Czfl5Xf5FCIy&Xt5RS+`| z(JlY~$-{x5G5@ObjMal0wNp^n{h%(&!%LqMX)0=DKj3_FkQ8bOkcZR~F#kO?KMP3H ziXf?hXcXx5ZS@2AVFV`zFE;2jzZqXaoRRIXy#%}9kj%G1nFG6sfm7Lh>*8tKsS^EQ zD<<}y%COPh_#4b%JN1y-i;UhVCu+u>ycypvPsV>=Cr`$wQJM08-W$X25K!yF5Cy0G zA<{I8YWGn1nYCNq%N*_tRihjpPqmq4l)zJme+9N}8p^>S6n#-j2(&H0d_ihi%2RQP z%;d!gE>GnJjvB)8V4A`rTk~k*m#2aaM>+-5=0=>2MYfd)HqQ2sMxXI}imrAy5Zzm{ zkJ69XhVfWR63f_j3b~L9f~eoN0hWS|FybNN565d^nS(NAMT?I zSZ8LNlYBz7Eu?IAr$}}L|L1T;kwDZM7_0>iRblw-OE@0k5_gAsb6j+n5{UlH?Pq`D z-|`Klh!}Mb2J?THhzStzQ}V$Og48!-3B;RMJ)C9W{}o(OL}LCdj@Lifl*TXwonDDp z0#WX}J**@CyWxr=67wHIYcmKobqNeXA8oca2W4v`S}yG%uiQ%`2_IUibs+O|L5Wb) z^NXcAH9hNjn?EoBp+C2{MN7o|1r5%=0AKwkC`64K%UDIX&T}tN$U;rg-h82^Xm174 z6#3JB!l)6bYIPVQs&|4-5#6<+KLlz79D%#G9IaDRkd-b$iK#C(MWiWT4Lci*|B<+& zh|T;pE-*F~Hgz)$5z?1t^MOpE=EKaCA4FSn2aUytAoJTniBMaDOrf?UPo{{bh50ui zm>(&a--1HaN-=-8o7iUHKB659Lj+GRW_emr;zukrSTW!waYYfE`RTB?DzK^bUvbkwDUFVpEYkX~sbeY+~19u%oGp4h7ViK3J)*WjD7gx;vpw98MV#CH^8 z2c;j>=|_=Xza5tH0$DQsP<}=Z&qWZx7(k8aZzBp+db&T5WawUOC8z85BXo%?XGTxel)O#Sl6J*_p$YC)1DMG&RTQFaM#uL7ThG(~H z3uDN_0vWUlkQ#$cP(F~AjYtD9^(c~zNCz-&KqWLE)XH)Wl%qzVg3uwIEp{kqXDG|6Qp}qiuelQIZ%i|B4sU{_MhO4*t0I2 zoOVPug#BkKKJ5j0B~XaaBBhSNWrC>DNb6l>XHO7?h1HG-yMaOk5-Df=*Z=^|9F0FN z6*+s6vOEF1pphi!mr1XcRS4`ZqwzUD8v~g8NWxSM;t2Q|2h>VtaDfe0fh)Hde((KoWl&H6oR<)`wo<;BtmE6 z5zrP0+krv^7AYg)W_y7%2jY+Q$eW9l9gzsAppV44nBk{x~1U&E7E+PXSZ<`N;J5<;bCvL}I+;&yA+gCmJsi$p5{o zOuks8(03+-NHTIG(<7>j@D{#gQV(GhP>9eXWedFZHQ>yi_~XJj-g-E^^$ zi zlJT2Pr;Z@P9^r3E#2V9iB!fbP#^THxyaEGJqcWw_y^^`m6Jdh9i+60)Mc5b=B9KUV ze76uCz#0AV$8hrD5!n!S!uCWl9^n*Fh|nVCV{`&{fiqsgpXa+h15PKf+ej_#1a=#> zDB^gd*Nsdbl7`9TI)7Mvgz#LXsSsHY-AjLu(BD@4iIn4T7k`2?VlTMGC3g`~T(WV> zUrvM}uLKGaTBJM-R3V~9Bdte+N)aZ==LzLRM}*x#Ap(h%d*Chxf-@%Lj}MC6MMO4) z-GK*)7b3h96e2XPMBV~t9Kj#MS0Wn` zCdgVD7GEIz78D|oNNJFb^)GOS_`!t_U^qdJ!-*v#IYdMtkuv%)Rsj(;>T9^aY+Vs{ z+O9${xth|nmNg}YqDO~fCUikx4>!4tM}ExZO3;ccK0qf@s2BE)@&8k_LPdUz2; zq#j{Myc;84MEDvgL}-yR?E^feK-_8ku^zddi2Mk<_?%Dti12q%h|v>n!3@?vPsLgn z(c(d@N~6gLRf2!kIZot5UIYpeSWLJR>*D^GeX%VO>jh#}S{jc~CAi%tUW`CE4iqA= zNa?r$?=}QyEX5z|4Tb-S&?D^6cm?3Y2p};0Bknv!esndTDXU57mUm#!D&!#|2B##(W2+aUMt!Y!zN|+g?0RgQ zY>%)rC`4#%5nYXz8my2&3;lOvP$Jjd8fSEF0o%=_^}K0p`_1UwWNEGoBoLv z3qgbWpdD6Bq1_kewB=Iqg(3@rY4yqakMfi;v6FEzo>^=E9uz$D~1Y7qo^O z{cF-7x)EBCL{Ceb(=JaMR5USN)J&o$Tg+*5Cl8{hL23o*F=}(#?#YAbagf^lG>AFv z^yC(FNniRL6^UO!GaSQTux9RUKjBE}GB2bth6coGMkABUW%8J#kfx7X7_S+PvNq&6 z(@E4KxiT$JybcG7%)CZgV{q7a&)O8AmTtxXmqBHB+Y@5 z=siZ@tDj+oMram|)%pV08&pE`XpIdrwwa9Pd9+0{>M_8K0=1w?v&JQBMjt`+@|4|V zp61Xz?Y+GqxDd`7A=@|2D}rgP%U%qYNTH? zS_QRh(Vd<_fDa%Qs%88#-@_HF!Adh)D;fn1od%+iI!-OMG^1g3wz(t4EA?o}OUq+k zrW1imO8*T9NsCl7koAoq>o-Jpg4qfh{{~s$$^4dl<9v-&G$zm84tMDcleQ&6=rd<{+^JwTi*6s?>~I zaB^I?(v{^k3=J?eqmiWzqs1+i4RN2gs2Pn57N)%ji`Ei=rlanrf&{B<)+(CuREpBR z*DALHzK~Sf(=hgRtrA4t2Ww~4`-84f2vz~I0#rh)A{u273NOpfwPoAErCd!X!MiA$5scQ%`T)|4VKmb#aA9(Y1ACreH0K))$Vh?}(i)qFnVLy*O90Cjt+>qwbSB7J zfXGrXiz#vwB5T2{24&K{g$BA*no-(Le_7G`6o@T=ZYJIL5P2EQi=YtQeCXcPRrc0V zTF{*5Yu(5+gCQgTa7rGyjH97>(0&+s8&pI~Z5n83##Io}Cyn$M=q%D|+NXe@0Er@6 zuG3JTW;~rwjd=eh=(Gpw0`T91tj367N2~aUA~g|7L?j+0GHK~c8&R6kWsW|D-Ndx= zRT0=MP!n4DI#uYUcctt=ob zdi84pFylyxR=;iovxp+J`gK2;m7pfH`lXfS3MkX+*PnFEv;wvnkWHjRD`0!T?4}5< zfPDbw2uO67WzSqDtxf4PsTr?ECrV|}V%1mB{Ss72K2W0!&3N!daTfW%-+}y<(9}U{ zkf|AsrVg7r$Y>Q13dFzm)Q%>*-dAqG5u)w%`WpvGZKncYX&`Pp8f9ok8>Y7NGo2P{ zJ2e2WPS&~YXsAy!o(|eh31vfVry1}~K-_k^g6T{VYCD6$3Tv=A@mc z10er{ZwHEvpxLJoahy<3w^$-}GCQGUDi%4Rmw|f`B-)b`8lp>|?!X!mjGWLRKn@U$ zosfo^nn`dgQahnjfSv@g6Z#R%4-_FMBrIHuh_DkHuS=yFzqX^DP(0uP5Idm^FzF!2 z3F&j_IicZqx!2XGqnL;O>vY|>paU=M;&Wv;**I7Bk+pJVUz$dV;kpy0hdt{$O1^2| zPKqKmQtpP{pEbmA-9Hj^fNTF|wqF+5O?M9TxTiCIzzBn;T0*Qhnz#pzxhDUfhoxh3 zn5dh17cQReEnIO=97OlFZiM#QiVenFF0_8eazI7%<5hzJ0bE&f0BC$WD z{Xk8g!86C&PT(*Qz9d79!Ags@3zD&bj0TA&6C!Z&pSieogu4}zn}L}HvTjBMZ@?4F zNU120P-@)Jxw!Sk8I6=MPywj*z^?-pHI7g*|EuEP8l~!yN(Z2}0sb^7lU9K=(x(}n zi$Bqi4giSVfbIgJ$Dmavjf>KZr+_>xT6TID;6skWhKOpk{;NP0W^DuFGk`w@WzwRT zMn!AJv%gj;i&nwT1A30&v=pyVF`Dtx=c{Mx7N(hbu0^!AUljCT z0jL4s^+1KRJf?wCGg`wOXq&%r~Hp_agEK znBPE|v4gw%4NOxp3T^?jPrhN65%C`23J ztyl4v3w#b)+lEM8Fm*uP*11(do*!;nHg{{H+a6bt=*;Y7E%+b0NAirmiv)k98SwUfG;O~KO&ESc^D)zY17wFI(N-PyB2(VWi{(vAa($|jgPO{os;cR;(6F1gvkUzkVK3~4vJ0ML0LcC%WS z-Ruga-c5$c&1!w0X0)NQZuT+YH;^@Qvpc|S2X&*b`_bt} z@r5~dxruR@@PpXpW`W57IWG5@TVSCX?OHsSTL;)$q)aZiBbW{pA(z_^OkWVY+;L#W zfJ$AiwkS2D%SJBuFqMs5?riAH1hLCq3T82gU9MI$G^6#k%UuuTI*{vfHO!|OeJJE| zC)0T#m%9@R&w<$Gz6a(oMaboz0&^0?E?3*|YepOMT<))c{z$syas%-JVT0J^rh_RD z>VDd-+z6MelcZ+!L3u8>7BmY$>~b~A(2Ry_m)i=+79jqy%hgDqX0(dua{B<^3&bv0 zqx_oDaL?tA26QCB$>nNPlx94*cDb_woeARKa6LDpCm%P!)nYEF=ayznLKRF3{jqbq z(jcZA%}Dzg7AB{CA&L{jQ{3SI>7I0S4W4ZNKQ;AOmtL-PDN>WxvG0}9?h;S}rjRr_ zy_pirxrtSrL@uT1KEzF}fbrD5@>}A1UVtXVlYDL`a=W~6P~W-+;FG9eldtO!pI<^U<9v)Pv)#e zNb|)If$^A2RUv3{XuOO+PfvsiG90&z4vU5Tr8hM%P71v+EFnM9Qz(*#82~=z%|m z-^_4=><4@p!ZDx_fke-qZ($LzlA49cQV=W9bGW7D`alx=8|>bA7U4R#&5d_DAKXi) zfr~}@D{)~h2DPAV7#b%vqpw9|_7lJsZOwQa=r`$dETdvxMWu40t8xPHkFQYiUqz*l zR{0+Avsb97tEk+iRsI3|@)au4S5eueRT2_#!y8ogSnR8){HRqb0-kk+O5iFgIZ5u} z*8#lf3YGY)sPxthM3m@(hI~xOpQt+lpbPEgLD#z zhnN}>Oap?3n6Km2fIP&!2au%%qamh-CFc_iL(B_QEE-~N0c11Cnbkk-HY=%_47a_I z&QoNXhMTVe|1yY&o5#T%13AOZovwj0v--0Te+}Z{rbgg()6SAyzkVK4C&$K4S-$`;^C&&<>BUdq>d#+G~CqsKFw%DWrv%$0Dm)Cqv7TARbmO1T&u^G^|_!=57!V zE42;3X0$PHSh*3<$4HlkmCu8Djv_RZe*?^3Q1>LaawCS7I!S6qACxz&JPyrcARbm~ zl%W|7*Tc&5K%N8fkB5~S>C=o>@rIQW-(mR|Iy|h@D8FVj+#6OV(PvvgJgn5HD9w0q zJ*=z*Xf}v{187&EhFW9MFyUq`+8NjokRl@5SgjG!n$cG223c|{P95!`9s&3;vRp(P zw9D(3tC<6?QZ#Om;f>5)RMVrWL|#_Y4Ln*i7c>eI(yQYz>Ok@qIA2AZZ4u2|X-1Mw{ING4*eca)}{X1IYa#YdRu3 z!8}Jg^c1z$FxE|6zpcb?ZwZ3k2 zn!&T3{KMNRriM{u+L}5I=qaEg+90oiQZrg3kZK0YkqYgZzYXw3q(b}eHPXkves zyiDql4i(y#e?Q!ioCcSP#w=$n*_$&h8rxE`+AQr>Qon)5Y zL$Mmn1E7vG5!nJ}Gboc@{G;{#n(++Lh`$JkmjQhdWK~Aw0GM|ul8VR)Fdu_5>1|V5 zKT0#&5RdrjUmFtaH_ zuO(Ol<}OgjEJz*#vj#M~1|mhjU<9HqO3gSe0%sjd$!QgFDD+m6r=asB$fEa@>;m%& zh{ya|&Crb2*JJ+ofqW0-j`=mrrx|@HH0Iw$`O%pFTPU0X@t9wvVNy#G8uP~^5&-d- zU)%6&MjPWXKaK1w0h$fsTX_w@6jOvI0A0a!26g|~t=xz)zfO{x(Ff&?`3FMt1`v<= zHOkP8hU+o^6d)&o_?Jl!!DysUGg^hm{Pa}J?ZDp(%A^NhG|I0T4d*dGJqhywpsNT@ z5BX_Slx93Qjrr-Rzs-Pd0!92v=mEy>bZbsWGv#fH^c3UkK)whnp(oxo#3&*NJ)m0$ zspld73S?D5q+xlC5I`0^_C6fU4WRLaFIj{pc|kYl)?|UUC_aJI<-puYN^1}~0Ol=< zEJNgLFkgU5=v6>kS&}lJXL=)$tbkiLgufY)3`9~v){Tht1=ACBRQmDBBl@{rGO;}i zGw{^PNSl_B-UaajBCXMuE+B?!g>b~<0dX234bwve787Rg$9@(JwP|1;gN}?pfK8Q*Cx=reT8S~t8SZnA>Ux-9MN}cXYT5>le5#=R~D7;qS z0Ky}n5P?NX{s`Q{0cTvmA6xwUQB-*jl0}$sG1w>kFNN4=6(VHlTl|TX?}lUj8)-%r z{ITK%Qv4jrSOiC!xE^mLK-dx#B4j9=QfqZD#A%_;UHsfGz2cK!S<&*lak90iOI8*r3jjUhlP-bMS&mEW)BBae_A<_uZCNaEEB|!+< zR%X17KQ=%w-4tQM)xBtn;|NcILIe_z8vLrtt=VdW^Fm6Kw)*qCDpAIX;^nO+^qw?v zpFFl357L3|lfRb4i*um+WKX>Pp6EU~6E`M{3(y8HbhHFsPi&pd#^ZFdqz)dDZ<2|0 z{NDZy8M?nQBcntQOSPOOL|X6r(?!-tq3RF?>F*DD-?c)dW(wSH!IO&L;#pbZz;1C_ z-&$FM^|CvVXswlB*$$f^diYd3SPT;UPiZ|Q36Yl77==g~amKchh}7dqLPm`qh}7puYQ_t_5oy4Ytc)6s z5NXJfyo|F!L>h6VR>ogd5oyek`Wc(ZKogEM&-kN0BF#C{E@L8Yf>kczNSBO#6A@{_ zkvzp9@8N}~ zmHP&U!NBs2RRaO*7m|PAnb?e>afn=>W+SpLBYQ3){kb@sGN#T%7;!E?vk85 zWvHlHB<*iM5+bQebDK_OQk5n4J+PfrWtp44-2Rv4ciR+Opi zZm^S%lm4T20f&#<-8p>1zKO#v_F4|N+Iu*B#y-j6v-aN{ZnvwT;U!gh&Thfs4!b{x z&)YX~_=3HH!=3h44qvoqeM0z`?7KO9+1|$CEA|l%U$uYaaF?C_DdAqT>v8zHJ%Gc# z_IwWa+3Puc!~TH7H|;+-e9NZKQY2M*+pfvsJ9ZZi_uCUWJYX;9@Syz+hllL9IXrBC z<%Yh`NdH~Ck{h<*@I8Bw8_wnMi2bk|?&9!$`=lEhr|{K@Dz;2HbAgyxnWE5on^p

_$n>fX;%{Ln)zk9UJ1AoKaE@N1?|6Z_+m^%xz>WKRFw+{&aR=+S^!O?ZMj`2BM16mgS$ptd7@v8*)xNcmHPM0$F8h}KGl7w!wv$iV9;N>!aAq|bf8#%uAVD(Q_k zXam%eK*W?HMf%c80lddms=XlxH1cX7u9(-Qdc2PVTH=AITqacq?*CB@9g^y26qiyq z5okBE6ZsF_ABS%O$!t2*Af=}_xE|mSq*^`O0e(neuIcmz*Fkhls>~Fp?tayF9AlT| zunEIO)TdGf>N~pWJ?2B>v{bLxa1tuwWIEu~73huVl!?FPl8R^^7PZG``^M#WfpXPi znf?|WN7^0e@$SQ+wdkiDYiPUEe%vYI8VHsxuQA#2x01z96hpLz~X;>%LvJSlum zr;9jIZ7e*8)vo+Gq{wPhv2tUzEl(Y!t35_d1K=+}WfqEF9pq>eC#vO6fI|E77fHKz zooK(XW~!QVFjl4fy8<$Z6zI@Q;>8Rk!n$A8xDAm7z~Ey& zt_B%lHBoys<@2ms1Jh(jZo%KP1f(MoO-7LT3ss?&Bi;|md!Cd%3!klE4;)9E>D6FB z&9}#*m3N>N6yoO=KA|=!b1otl(&IqtSF-JhHmbYfEo3Dm7if|BFUjv>f1tJ`ttr5e z@*=Kx$h(!rtd~oc<9&KK-2=72Ib9-n3dKySR%}N@GpSl#yYr6}*0V<=92Aa^7uEa6 zQn1Zx1F^4FPz<71dC-JyaiUK*l z=E*|V*c6+GQ#>pyBP?ociQW zOz#gxSoOXoWK8Xt0Wk58Tz50(d@;@9xKoR1VOcmQT=k>jmCDn*#rLLCiSk$cog%8% zm*EpX;ba^ghHtDCjJ99G?1S4y!Oa1uU2H=qQ?O9=!vIvSMh=gF)M@C54U%QICtkV+ zvKNrPN6XBw2vC*fi`8-%m&YLc!jn_ecIEe|9>XF3on%;eVB03i%^65?Pi(;p>Rb`} zOqk6AsJaK_jH*qBe=C>~_yJ;Bjr!e!DFJF~GFTtT+B**!qTp5a$<2AAWa1Yp z=6!P5_@Sa;PxTB(JP(rFJZbIt64-uAjj!q|uY(BFepk8n^1cusRD0m+s8kYPY!+{L z;%ZyQLOd(*8tPTnZi+@wa768aDT2sz`1{er)_!m$UZ?SqT6~i$j)}ub0XfC2-GsD1 zQG2wwDn#_QT~~Y!JafTm)d?3L8*c~EwWVTu2S~v;>JHR3)vFu<(YR7Ebw>r?t8kht zz7?XyrDD493w~5t16=WA5aDH*I&bnul2k8La4_;#02h1U?86fvuPRk`B@}o) z(w`z3T?S5RvcEw;R!}I_*qQ+Bh4Aoy0I$9uD+-FG8rchgGZ6mZ0jO1r1nR2`noBhp zEs4(%K1wSxK+Zw47p8Rg@Ncb%3_D46*GwVC(h02(Xgd!cfu!L`K`)8VQ=%h9A1wz1 zHO@nlvPfXiAgMN2aY45Mu*L&<=FABAaH)2fF8p~wKl~qXF0or|&S$(-c@tg5AE5M? zr^tT6Da>T4VjH@kWQ_5uf=bW7V>1GNlT?jHxbT*M_WvJnw;VLaDtHaG4M)SZjSo?Y z+dLgQ%1Gosscx(9A|C;2n};Mf6N!9Vs_*nQb^xf;9@6t^k?@03RYlX`BK!p?Etxq- z>A^)p1uERc*uytGV&v-X5zwOo7Vz$gNKYLEF(`yH66ofM&1O}5)bL+ z?iQBepGh?_&xLOU^o1+oBH`D&QP?k~I(V&%JOb3`9x|e^jQm!rPn)>NOF-FJUU4cQ zqOgoSFV(_nF0wLE4L#(43(N4Ia3ZiE!^hSG(4kktMMCe}QP|(5y0f#3oCDNS4;fKd zM*c0;`CDD&CZKkD$cVx+(lFG=7$tG;?*sLXhx~708LkX9tEUT>$=I(4x}q6WMf)zm z2gmR&XUA}Lpc;9|h{7@wPkIKUTx3t6hIz<{!ZI?&P#L;u-2&9T9`e71Wq1WcHG}uz zW7`Vot}Edpp%KQb1(ghS;WiifF;IBjxO-R;g=J(_Lv4X?Vw(m!OU(VQYzB<1VW>v% zWQ@!Qs>DP7x3CN^GSrC0F1#P0W3GgY^b_PF8yo6N6q;P*T>x>zcUph53)H6D8c8%H z63u$fLad!pj`Fj-Nl2FggHRX+K#&fu|K4^uikb`Tyq_stXy3r$o%W(%D89trz~ORx z7l(J-M>)L5KF8q-+xV4m_u2Uz-fy?(@IiYZhimQG96n^<&*8)NP7WWjk8}8_eTl=3 zcKmN-=LtK^;byxQhfmsFINV}S;qWQ@eh#0upXTrx`&|xyNx7HH{b$OuQ)K6_l(U?E zIVI|MivOK5jKhCY!W{maQi8B)O?+)=E+y0&Y||QSQmr9&)*loOv+Hs=+-}d|2zvmB zBkgG%jg({wLphYW;IVD?M%ub9uJ>NO2xq!8AjLFQH{nP zoknjl4GlG942IB19!8+;D3M5SbtF#2bTHIz=u%ncdZK(9N5?!Xc_5unQ_`57GC*xU z|5z79UYCJJn6>3E!>Bsu18LFWh=1jDTme;k%97c|m{#l^i}AYI+y1N$<|*$_#pPn| zi0hVy>x9vHlw`hQbcgEi$XG$5_E1d`#+leTnBB(5weY|IQmdE69HgVj_%{yleKDjZ zo|i{pbr7!DHX7>A@_1Hmj;J;MG|t@%66MAhuVNdXRB@3VJZs2 z=OFWQIy^R&cK>p)*QM@-skHO$!7nKy&r$uIj^H0qtNUS@04l-qh!P_nmB$LeKcjxZ zuqzMA^+D=uvPhg$VL4CZG$xqq;wB^MQAsg#gYh9IH`gIy7)YgFLK<7l7=T(ZAB*LP z$Y_L_n)z1pdpH*&V7;W*X@bwK%N^RdO>S*xp~qqau=Wpn+v3R6~Kc4d|nnrx(>3&ttDWWNQH0O zvB|%Hj0w91a!m3WtI=;UfcHt2QQbKul>jR6faH=y+mE4a;=cPo7}0fx%p_mztRt|I zwz*WPSTNmPj5Y780nXk9z;>y&)fM7y55VQ+8gHAj1OSZhTjyid%L6b+f1+CE)^uTx zYW3x5oDv6(71JjsVG`h>nWI0!ix%b>EBi|ijV04(Fv5t#wdxd~kAeP#WA0;S46YT0}M>Oy!;8Gv)_yg2AU8yRX3+PEA9*tDxa zxtbhkCu9pZBo_nr`2T=L7IToHZpO7NUjg=rhv$>Sl^0Qp)p-9(GN9i8_LB#Vqf_AI z{eq$JWgV=4W?@ATR1YAAdML`wMSWBN zHe{+ni9pQ+Vv$BUeP#mPWihi%^;su$M9`BD1F%_xOl~?3sJf|!;~HepJ^Vc@LM8Y0; zIrC9drC;mxqOuPFHxP*3T>`BMnopZ*M6`1;%bOsZqm2khzSC56S4bdE1d{Zg-GgH;WQ4&Vh!e3niJI6(fh~~GZ>N~?V)&;U&B&RM=B(VG^ zQ%#)Z>Q97hTB$xQcbbq<+UKI zTPmlqu35{co-|x}7sz^f^6Vkq{K9PJQ=j2D{O2W6L%wa_jm1>;usp|$hK=~xl&y$8% zeS%hQ&5J(u1^PL8t_dQHDhM)l2B9DZd{{9*JLr~fd zesvZ}?1xr@d4%L#NXP9lsE1#@kKqY}UIySz59GK#2HoIS_Khy+Gyvy3kmL3kG}f;! zqPT3yk3m=h$jQ#}XywMBObh*Le?1pe4S-?~E`982}p6l@{FT7`eAg zVE6{V3ZRY|J_pdH9^C7}goE7XSHl{*$W1_PFN1VJd;MzAQWtaxfRi4G`$Ff4Ipf2A zwF`rE&iHqr42&@&jyQWDoy9B3ex30}_lq!dGw$cPlI}hYk34^YQ zQr8V|L4yGp=YgC)g+W82)Tg*a*wSqPtnol(DYD)eJ|#+BjCbMB1Nx>1kEl0BE{an0 zy>T{t8mMz+kRpLWtD@9e%LV!KuuBT$)J8*(gifZ5@YXa5KLpm+x5>^P!3sLHu zE^gn}1AtK;h{vE2HW}VjsX7&0_yRyzl!ZqazD}tRl$-lgK)vcA*``zJY;zJ`9@oM} z9s}yfE0K|v$~t!{^%2HLTvc{ejQT(kwGdIW41Y+e<7qCuA)ph0>DFYW&XsLbZs2P-o;Xzf9QyW|gMrQxq78$p;R7E%l*$jx* z8YL2zAq#VWrCRGc9RS%BEibKocO=K~X_hMN=pMsTK%e>_@KS9zpXHWXgQ9a4zXhew zuc8=n0y(qImTG>dt8)qXgzEYTy$W-ti_W3!wbWOrbk3q0pslU~k2sZ_#YdJJfm&uA z+G0A{)A1@X^6<}DYENqyz68*XSAqZcD2!-z2B)91cpdnU{)diRQK`|YJ;pB#zX)hd zzCP&E68-lmx<@NNMu4o71ANn~=#ADV_5=`Am;i>*l#SyMaG(6&?0E^ylVtcXYY7i(H*wfRC=B>%c>r>~(6a9g8;n zd9)hoo|TF~Hulh^&7`!(a^I$o;j3t6FBYOJpc6eft=TvY*E@$C6*U&$1eCKkaOMB`4?0Z{EdBprsEdj%@&>KIiUy%yUX0@P#=8Ie09UyD(1qxu-R1gP~M(#t*4@ZlIW zK_AvDfF8UO?%csOPsgaLxJuaY*FgQ|AtMS)_b$yJVpPU;E;0d*A`9eHKty2~nQW_V z6iH6C+LF2Y1W=UxeS?%KlnX%p=^^PHID1jdeX(i{2JF0HC5Sn19>_U%&z#$7v(4{f)q0p= zcnd%W{SP>oBeF17Kozui6=y-|R!@;?&Mi#!fXbTbg4O}B!vmETCIa3qpyuP4xiIen z`rZG4JLTXFYv!PQ+Ey!rgsnz5*vz5z?m0~I-Yw<1ymmW&OfB&UW045799d)=#g|$<8 zr(_0g5-4mC+yIG{*9M-kuyNuU^l?X!@Ht3@(Yj6IOu{%f01As8yH#1Cd1BoOs8tiW zMuS*G)TSk|!qzGy051$hSrMW<5?7?lg?Bd=wpRiuGA>IXYU_!e-HnBvy5H!C2S75+ zla?RQ+Sx%Jq@h;-iGKX$Vpx(?)X*Lb>p9Piw}q^YFJD7tzCp3t^(!}0p(ws(>LAS4Q zGnkBvj5Dvti`reU*-a5~NKPC#NjzF?_Zo%^uTGPI*#I|mM}W8L46;ww2mU1-QJo=y zI|%-$BvGAV2?OCTThzmiKagrnrdKbwjw8(5z zsybZ_$b$R_$o}%=w1?L$6~RE=uLXF6o_wcJ_!uS&zvIxE$fiIA^?Y`vD7lr28Y z<-_>5&iXs5JIjqPLA;wFTtN$r`8PoNf_fePt0xunBTpuRK^$^Yot_CcPU`{58GY^l zeg@hEnRe_0(4ss67t0?;!Bkf(1MZ_DG)zhrGyi$c64MZUSEi3k6wPi;+IBXEpVu%F zOoCkl>Izbny;x|Z9*Gyt79>5tGRk?5#z-&-CMS3p5u}8qIzN{`i^8^vV{H;sM_ z4y0O(mRN3UnaEx}xE!!~a^WpP4DY-E%fpBwo(H!vVpO3Mm-FO`A$XE+Zwn`G%#-(G z2r}yNWGC*MCtpF;j2?`$K>F4^dClF}pwz0n6Hk~Y&!7g!&Wm&6S&NK8W5{5lP4!_XM|6c;M&>v6=rrX1M{Ybn^#(j9sX5lDe@D@E_!mdLm-pw zI63a~C(HuU-w3T9#D~J=b^aV=egz!#hyJ;A&^3W-sF6;)<+fjZ+P^ysa~jx}-66k0 zW1OR}?Y}-=6#waOhh<0V9^`b$ZzjyGRP2O5??M))^#5GqE~T%6Y`vB{HWDs%04N~+ zt8t;yV?y#30NyGK8nCV$K!wu(>i|55NhggqnK=e-HT-Z9#r32=X`WluBXZajc=zID zBXMF=^z+AU0P>CGF;uE%=W)cvHH>nPB4#z4J0GzEBc8gSgl6T@)fCrsWU0+Y1`(@e z#9#B95LvmykY#a0!~c(gW`N=EaFDu-Oy-Wd2BM~he`*u>KP1m96;VlwI~xAHR15%- z{J0jG+o5XmX1H7ibu#=dP!}%)aKHoc$RYxCt>NE*%uWMv&I38}p_Ee>!`Edw8Waj* zgSdRo33W2*X82D-KMS(zTFxaAx#SRwdm8>*&{~^Ac1>A%jhAu36!$Uwzrxeei5d#| zXpIrMkK-~e9%A?(Z6m}jNM5Ez=1w|LZgjcz=<*+K_ zZXBc8yId#z-K*l^V5n~(6Xab?mcK7s--rQ&+&i5<7@yl4jY}TvjKSAd^cclMq<wmFK|4?!=-;+FEj%r3tW6xy~=MlMh%7Y{Z1yz`+#XS4d=G_A6d?6F?_~- zhJO;WD}uNQnR$>(_Anj!9i&_wW%w&#P~8o({$=HlOOnSL{w=s_CP8+SmWvN$C3xxL zc(kVS&ZButNyev61gW_Fo8c@69|R|YbVa9~gpss@c3;rKB7Uk*pwMAs#LcG0KltWC&sWU%G7e#Y1ZsNExb-*MH5>}v)9QRG_h%(iA4SyWB zrj8-MRd=o%Png>IfFAukTvHgWeq|ZUJYo zL*a3#K)f$@H1f;;utEx6LhQ>tFp8dq!gIB0RnS;=%JJ|!W8fFA#^t~DUa|;O@Y&sA zVc6}hLL#oKKmPX=u?ulF!cz#Ie&HyEGc~E6QZG%!)$=#sSApNT@O2q5Yw%QK*ySg& z;is$rf$iApg#xodHdAVlqGE|0{REKp{I%XeM}>q^B*UGFOU`;6yUd#&`!Z}f&o$4q zT9(t#IM1}&Metp7OVfKr@Y@SY(|1Pjui;FtZ@(*~{ za?G-V2+{%NENg0uyx2`KTj?0i){Pdin^Q?3GL9G8BKAq%MVysKu-K>kZ>;i(Zb0?{ zsaO<9IFjf5Bkqb9W05*tOUx7&r+*MDVqf>4zdc6W1<^`RT!F-o$+Qgt5qsFbI1wLI z)iMl~zo{0DwTcY|9a`gJT-p|{YNLO84SYxgm=6h;Md}TgkYtnp^RZEaF4JGM#OdfA z#V7pH6{GM{Ss+2IXjUfer96uaZce&BCr(sDNLv-8|cOr2O>bru+@E8Lg5T%r#AphIL zY()87%;$#sqMXH;6r^T@oKkEjOzt1p#u$9si2WLmk+wrh9}pk@6CK>cuLc=)MRk-fUhVVlH3gjl9~)np2+cG$UQT?%- zcVk5#T1x-v7~rI(?Me|1R_A_M2UEV9@fdwUa;HID)35z4{BU^1NDpR}PSYpy34V(Ex|_k}QCoU%niIjtPl3gKj4w*>T$B%aU^X z!asjB#z0!cD@Hhrq?6RVw*Ah}6xOjn0D}6BKW5cMOrd#O}*s3wsKOE$w9-wz4;K z*xKIBVH^7s4%^y4a@g6<{e|pwu~jO(Ik_iU{r%YP?a@eR$+Y@M)#;IhGPFP7l_LoWT}poQz%MX?z}`@kMoNIF81b)#+h+(Prv5m_Oo$0XAkH`h@`x zbch#nBTPI6QoGX8jPwfwPQL^%NLvpNX_2{?&-kZ)&kLiQiS)yfWvqkS2jR;Gtxf9HO}u6 z*r@t-LeJj=$pf^=e4pgr3j?++j26d`auehW%3_=s28@e}7I$lbbGk$@0SV3fzY-<* zA)pnwQ{+7aM2GJ^1T?n*FBSv#B*^>}*_c0oD}4xv>;y@8^@o6J9`mz$HZmwxH!1o* z9s;_&5Z|Ns(3G{4qxTTdakzad!)OA1PF3MO1oV41#RXmDiM*$K=PzVtAn}&cpK6&R(qSVXq-qzUCW$i%<1MALUA>f^-xRN5xE7cmTEkmP@7Ev&?^i(uX*Fs4s@6DiRJSi=uJFWFCSkCz{7#3F2E3q$M zD@0z4U2uE55`W$k7N?-_6)9b$s&^!>C(dXZ7Jnku2Q*8}zewDW7561JS`Zeg5LNQT z|CWm1Nc^;WSk!~4g(vpmwMMS-gX+4%u;>NRa8JAlb47DI{zUc5*CmRivnsuBSWuR8 zfia^=+mW1Czpis650Zql%{V&WFOq%;a1q=2THB&JEXmY2+eo${g1c}i&Bs@x8u(7e zp6ZMXmXd^-&e{Da)myzBs~5>?9OdVTevxX&xNtq&6KhIv3O8Il_ENjz;fG40FS)HIkwZg!gh1Y)oCjUQtgj%MDC4|M(NPbO=_<6o6A6h|9?hFJIQJ8y0j(zd*Ukm{HEVUYq^wkN-Vis3Z852Z@SBNawH2wQjnt|hPGiPDCrTi@3>Pknc{ zrn-O6XAkd=TBjr-m&siVQGrqZ@Hex=yja?2(OL|;TKf}=aS1(yES{ijhM)-MI4XxD zZ|hHd>aMWZ1=%~Ed=km|d5xsjQEENh)O4iCF9EpVfyN+n7t|$6b<1@@7LtP?C#UHI z;(bv`d!tn623XapiljQF0Lm)6+t=wLDc^5Yd<1~*5Do#2NyxSMNE}ntfSq%+5pPl( zjB@CC3my&d_#43I^m_!aae@<{+e2T3yAodr`^2NLx|y=RKO4E~%kx-=1hEUL?`VlR zj|!!o_|a2w;v_`hdgAq@tuN0t?G166M97Qnnj1@vA5;_YU_}Lps(a!qFVAbDq6B5x z8W?j6Y3s{#`G@#)BP0Vz!rAJ}lZ)uJ6vv5kT5tgh)BMs-%*4rwKiU&bgpwkhcqcoK zt?nSJ+bBQJi631V&7${6^gM|?C*IVDR{|sX97w%PBF~A>PL82_g~A50$f-fkiT9on z5Lu8__vCEab>i>+<`Yzk7Lax-i}0NIho_>%V93UK@;9gio)dp!yD5wX5H9rqd|;(D zsE6Ay8%%Vq8gs~c&YJ&>a~%vq6DI@p7_dEQuPyyPt6!$%+E+$w~~AD zawj^lMI_;Duii==C+@V8CvX_eYxpe3iC63cCr*_jI*=g3iP!9(z_vdp+h0ZMF@&J(f zowD$pc+014F$KvBwTRD0WW$3K-`vI!4*>9}2V(oK6YqIvjG#k$8PYe)B0ML4>LGjw z53;X4xvYp{cust&KS~&vNr)=sB09C?H9XgeQ>};H*7qbTrtkJQ;~ghny)SB=k|Le> zo^R3L{h*yRocP*G31SGc7*E+mp$KLImBVx5<1m9=0NGMcUXJ9R6W<%>6XlU2HvzES z1Jy$2rB1xn2^Vw-fR8;;V*+_jJpXy@54iy0pB{h=mpbv&cn(sgLMIPY>cqLwR0GaA zA}3x27PJ!|9pS{Mfp2rM2l@i6OrC)iy)t>EW>}0ud;&<-$J)2IGI{RBuvmc9rCL&U zW%3?ueO?dIQ(9~`A#HDE($_vLS|H_3$d8o8@X{R35O`(MnJTmcBxiIo#sFBEOznq@ zhf=(iNe1baNs46YmC0`~Y^ru0ZsUMdTV!a`YQDEJ*>`+cw1=pNC#D5{Z)I|CW>}1b zXtF2nM`CYfGHxga%Sc%a`6>?+M)^utCO=;2V4i{eWe-!8FwPQV&`5keKP{}2o zG14*c5+gBOZZTi}8;ln7U&TNUC_nT$-Kln7btEj9B6oWA9coCQ?CT;{9fyO@u{zuA zi;J$;9(PybkGYW$!Y=#LSHAUf%Zuk^)Zx+Dn7@^@g&8KkX!ag*0=mL%dp@XB*Y zv@hl&dTzn#u{kYR3@gnKDZI#$dhA~P;SVS&qQ`!Ii(_>JS)D^xy&gNGR~%@WU_7SAI2RV{LA(Ce|MpNbXlLw3@WvuU@-UO3Drs1(0I z`fpi;*JF1)hR>|xP%=TBxp@zj!0WNkVHww;SK&7I0DNGjHRSZzTt%1>Ae)?u7pRV2 ziS2VkX)Brjp(SR+#C$Tdin7o>_Ev$98zJ=(Eip$^529O1tJD~=1ESrY_z}|9J$AG5 zesL6{Q=a(oQsW2J;m%6@43UYVaJJ@^t>muZN>G+zV9X~;Tep%|TbnGYM-tA~Yb8`f zuMV6Zn~NRnhuoUKc)N0X?4twVbf{892NFc|*wt6~*!Bvt{S4*m_1M!7Mzd%uiFT04 z>#@mHkkY*#`$#ZGyadcArFL|WecfeCyav&4o*l2pZulHNP>8Z6g490B!t1encTNzw zNUp0zd_E!@9(wGvh0)>~0D5^KE~ndL_YNoGeg9I7gY>4d2(QN;KFbzMAiLj_AEsh> zJ@%PxF~Zmi;fo%CYpJx--G)bJ&TW1DaiD!CZH#hy?2`jg>y#APW6x{t>`wEhT?ZPQ zq8yM}AoT%?V4kFMcs;gVE?N{r*4&eSL2|FhR?AKC4N~NF01PVyfh+B?2L+-W&@D*5 z(*s=~kk?~hpw;VjNP5x(km1rEd%+i2AKVY&2~cT|&4s4M=bR(zv5%w9v=hf_lE>qv z)FLOpD&4fdCbq*MTt?d;#cp!$f&^0@o01kI@ z$L-(1;n>SG1Ah|9&udNRh-(kW5H@fue(jTP=I=uOp~eW_QW`j|+Af9qStS3eMJ64s z$QZLXUIf0auxkWr&pU(V2efieMzAxgE9Zqu&`#OL%Ppspe$vavRk-PSp2S^SrREqc4{Y=E z6{rT#$lY)AW>%$d7b>&Wmx}1@_dl$K_ah{ z-*`hgGfz33c?)Z&sX<}iSV6m zB6<0Fmj!|f(LmUw)_rxEZ>JGu3HGg4z{r!QP61>R$!1%#|V=Itc-=z%B;X3 zzyEQcI1C?Imx8lMhv5ng@;@x}llsG(K3Y^Ey-Or(kpG=l%*}$=5{p2J{eyg}T{AGQ z$UOk};R+1$6lw7chIZ<^&7pl%{eXK4-05rf(PZx*%3bR zHw6jA_!i3aUr6J8jo#2i{q9MC9sN3dWEu#Wp`;m-l+1nr?>_)EFhM+9lK(t(E}h`l z$Mjc2)qRGS{M%^9vV29Gb1k@;d@e|)E$S}>Yq3TCiZw*)8Rk4hAu)6kM-BpElttq2 zPF$-}k<-WVj@|7O&mbyt0SL>86h~3Xp>-8esWOTtGSU@==tp7y;&jZ5h$Ii;=cvW* zI0#F_qwsoSG2U?z{u!<>EI23iGn`mt z&JRD1oi(>&_K-$+Ca@}mbNm))^gT+{chc1o-8?lf*%BV@ErN?DCqGLg`3ZlNi-0{! zIAyp<lEK>E^p}9XD;4g}6VB861rCqAw6j7C=^9agRrl8h5fUC`KJMBCvRnZ;7q}o!u zJrxEd;LZQVQPH-lWza;5mcXVb$M{5fSe|wjp*7NSUd!@Sf@avJ<%zN~-LyPas^=41 z5zro7*zO$lbS$OITod=hvpzxFetuxV6A3og#A%pidJ#J>hRDR? zQX#Y(j;JZlCC#Xg9*Q^>fLF6Py@*qG_ETz2T*7gm=mBgPE;hVPfoYKqZN~*a8@_d9(`~=^dCK76B+&mcL9~33vVnMwxNn3`-S4;WCAoyfcV4)mN zuZkcR^HIcwn+n(Ll-Jn$Dr*2Te#HL%6lFM%ZITF?>z|r;l`5TyZk!Bo5<%aVP-~jMsqOF>#d(i?y<^ z12L9HNblrik1&>{@H&&CF^2#A3OB7tX>_+eVvglmu1Cx@SY3=YPdkKcgjBS^W#n*_ z`KXs3M)z`tkbU4i%!KqhjQf{o#r}psrvqDH;wn1k@~i@ot>sxI&_szRU&PO05@-on zCzrK6t1}6h%d>g}q=y=RycsD@ko2$kxot_4%UYf_kOlnbxl9z{g2PW6iPitOIB7b$ z{>SpHG`w4p?ZN41Nstm2vzBL_UKzt0`eCJ;WVz55D;Z-W+w0DBM&r&&cP_*+std>?C;A<7LmE$Q?zI!ufqh%2n7%YX5p7TsVI)o<1JIi`iO% z*8!J7sTKV*2wE#N49F-#sc3}fvBx9)Hf9Pj{pT$(cX%Ij?!b-b`Cp?L^XxYr zegBA7jVpijLwJ+nT`rx!fmv@lenb`-C%mhrG3189tWV+lJuYJ^Wj}8=z+by_0y&S| z6i)i$_fcTZMb4$8(Elb!X~MZAo&Zt)Xla~7z0A1&w@su2tbogyOYv678e{Iqx~K!+ zrY52!bC2GZsGd_`VVNf zE=Qw9Ctw3DoaFT&(h<$J;NfU75rp{`i84=-X2>X{q8bLvCxAX{GF0CXltEjOh|EEk zvG9JkEZgZj)Y+H8b@d^iGMZ6ht1e!FQu#G}uaK6b6iZUW_0d?9gv

&3fS2Iz7IQ(I=|73Z$FGsrEv||pM-P#a<)@x?3Wd&Ptsh>zN{IdYy^|E zQe)9{aQQ*0U{hJUAbrTbVTp>-bYSE>Bh^~{4w1~7=_};VsXgr41c^15k~nTdOsV7IK}J6_Ntmn z;U@t(#=N>w`&C_~=UPCH;nr{5~i(RF&0%0mHjFr)i!)Rz+ zB8>ua{3%Tac9g9jq2&4oy8emW1;(XOF za?4!y2{I^2^HBednIBNs*zeF1dW732^@&z;AHnxrsGRHWI(&MxCEUJRvnkRI5bWbk z<>c~*Kqp%{tLRlfM{g@#r$<8W&v5&BoL0k;$^x_Y{p4t&t+TRTb?!{aWv%uio=qd{ zotC?p-X9_pEHTPN&PmnUv!-Kvd1to>`>t$_*~`G(63VVcbs+17nkeU?5%%XUM>Fvi zklwP0iZj17J{Ov)8xKtl=eqC(@E z*i18zJC`YA6l=R~tg453sTYiNi^Vyo2ruY{@iFGXH2^lW2tgY5=|;BTlkiC>E){wXZ5i#%(X0J5i+X}OF}S;duo5DeB&&m2o7id)p>yY))%0q= z1=xS-h7Si!6G;xh&ro8kl+mWp&O5r1c-N-1%>p)`a5ac9E^S8kKPnKp4cN|rJZ(Je z#HP@h)9pOjm2Uz&Y2i6^z=^YzmPFrfOBd~D&YP?#Y--<5IC@OQka@-2QM)w2Ex_*C32ys#DpDvTf&Jx^ghW-e!(nvfGd7u(pOU@fNo;qPov!WHsl}*vltIsq}me!p|0odo88ujLj%ssQMupJ_VC+TqEXGymG{;TEt-x-XRi~1`m=hCf%|bmvf~G?kf_ zsnjv)j$uEK!(DF^X)FlSElrB_)W?WZM5KLJAGNEDTo1yNCP|sqohQQV1vngsJC#>} zy+t^up1aPn{5kCcyRo8;U7Q2M;9_(l%_yhAM+gDPa)a@Uee=y5Q%7t&6E<_1jDi4B~zkLavckD*34<$!YJ_y!BAxz<7 zk`ZQHnQ2#~_8|1KNL)?w&n(13F{eX|ehWZZx^qTp+Kyp9F&!QYh~1j(gWRJGBa^)| zL38q*{;B*=6`yd%X*R8sk7qT9!1v7Ptg(r}s7D{$vYkV?DcrQrYJ=WJ(@ylp+oWIN zBQTv~6A9h;O(a}tXu_jJUAOQG-Pupm?!aVE-dYBPa!f(G2^Qqwvid#-nIyxg00TDV zWN)x0;IiW88Qnn-%8T<99RHBKzOb`I<-48)C8NUaA58FxW5-ZMHbBEO!CF+gaFCuq zmii4NruD?rcnDq^zJ)+v-Kq0H>Y;7l`13ILDm?$?k3mlm?rb8RGiM_2r(pH0v$Hgo z4DyLP2t|JkdB1_a$9kBd?l>sNi|?P{UD||na*0fSjO-w*()aO7PcNJR6Xg>P0k^Tp zPm{7to)Wi`Wob(6CNL`%>sg$ArSTSC=#a-mT+>NvCkxQ0qt50siF$)9dN<<4iI-Op zOX56(>$w1zUX3_gNdB@di{6YlAI6EBc#lDx)3`nhaKlgGqy6?Wi{|uM+mSU+y#5)4 zZ!w-nuy?_;BZevm6g&pU?%*W~sYnHsVZv&+x~vU&;pUu-vl(GbBNg?5H!(Rv!84_? z1@FU2MIS)JOjxO?TVtI~I9JM8&ekB46h$%r#uE`JE?A|$M^9OH&vi5fyg9Ci>bVPQ zUL;l9Y1@Z~8H$xg9`h{aBvo9O5>NBO2szdJ57#1i>pdw17K3|2CffHI5>+N$XL#b zpe&|%_PnyxA$p!}8!g7hM1+a4#*hdx_T3RubbY&$6K8Zcm5x@A!!}>E6xk@d^t%`- z3R=q8Iz>K_jSjgQE@K4M*)DwvY9)=X3$W+{-W^RyO@x(bYiV>y@rj3ljWKb3G|8)% zi3RO&3etlF z*$U7&c*w;I!n+e@SBCKANC{rCV zl(tLfuIb`)+&D}P`=i$8(rbNpfHE<%@T6cf)4M@?l}6r|F0K;t zbzpB>IDhi&Sy`1PF_KRe@^q8NPrpPkNB#`rb&Jf;fS!KRD0|z*c+@;pU0nW%(KDcD zbq#)m<3~WxFlqE`9>E-01H^ob%qRVLFm%+Y9;5JXzzPF+Og$)@Dvd~=UB#ss*t7sn zC;fQlNaJa2g+b|&>ws+z;B?ZDXQ?#$TyiM=hkzXo;B?ZDXPq>*mGp=IIj}DSI6X9a zHY5H69qOU+7BDg2N-RAzde&z1!v{YzdbUZUc(#o>vK)w67MY(JJv*c^;iqtgHwMg|sh1&fp5x zM9GjcQtQ}5Bl zq&~Xw)W_jU(^?R=-lK`0qdlHb+TC`Wl3vLp51rcN_De zfp>sb4-M@xG^W3n?BM;IDq=cNum1|vQFH$$nxuxTRk8MOI)+(J8#LzbxQu;ND71%} zwN_>EW}g@VsMvyOTQh5|%5cmV7Xeyp!S51mtyOVi1qb=O2>h_cv9CmIthFjt_bJXN zz%N;xSmKmjiwP|4-&B7ER)--~9$dV3<1i+va8wb^u{cG=o4j(6z@htvqWn*k^*#b)@~$oYhZ;OLK%unuZ^hdli>>NMnY31H-Y!xjpX&YN_QnYwyOFfURFdN2MsgI?n3fzwme92Q z1AU?eysZ@j{48AyKI)NJr7f`B;IO3i1{vC|DOg2GOZ;i(8X#e2c&rx6pdjDT9u?~| zdGi7+iv=%4y|xUGOBKGu!i$R$<;k<)CG8SQZ7V|Bfy-!2F)sfHA$zsqh4}s*zVDid zn(8dmSaQD>KEx+30=r`3dJ7U)OL_`kc8^2s+QLUes8P6ByW*(84{D`nVdWd3Obh0T zad}!JS@4>+4i8@WfSOxyCypR(NLFw{YXI{@Z$J-QFa;-S)3a^C$I*{sWf!g2nE`l? zNfEVa(Oki&Q4O&&i|WT_AWvIp|5F&n3%)Ej2WjeGYqb;wm&);kn`goW4WqgsLuFMu zPo$uU@nu(^pgfh|;^#+F(w!opHj*xAwGGSiXt|QU9PhtzDYPn06bjlTJyzGhsP6$l z=St8=@2_?8f+`I;axybA?eNdl%P&VZW^F2@a|_qs$`UC590)umTKdHJ!azi z0FvjAF$(${bFseeVR&d8fIkz;Q96o^ts9`@RbcN~c;LY$gZ2n1m|^tJ1?dt9KUpNw zE6Pt^>ktKNaE^=*Z=dk!i;I(>;!&RV+$(s>xV8!Ve*h|D!eSDA>rt?)ECnUBR4#yT zDi@Rgt|Mb)Bg8TZg01z>+nA4#`}yX5Z=)vk=033S}Wh&s?&W z_^?lGg6|F!QQ2tj+V==b_XwbOO;}$>($cGOUwP!H&!asR@v z50>CHTrsd&Ca#iZF8rF1hDX|}RgrVygN)~I>dccnLEcXS7obZgm$mTgd-zCm;n#?O z^iX5-Ff3sMRbIi*bxWFD*1|9PR?6C!OV{m!!%tcT1};vTPOks4@N4=@u-LQ!r-vm$ zN?6QV__ceHgEh)AAWbA9rNmnJ+BjLQvR`8cS(GACKcOq6mh zT%nM^`5)vBf<5oK|zZuRCaI$25ZveCh-1)_2_Rj7Vi-vuG8&*8LZkJTO+l*=t-<B&c>Sr6avM*IiR)#cO*EI*3tRO$^^<6H~DALw8WPq zjmfK%nK%iaGc17~6TU~LXsY6Zo;1v{YRM;DQbE86nd80z+ zbuD+%i>9(&I(BZyMzZ8MglMpX;>r$6COfE-vBPaT`oYnR!V+3a?J=>!cUl^wyC?Jf z^-YAT-s~#qyfoJSk;KrK1TBVXLM)bD&mq&kl*Zm+UdH(Q8sBl5K{+5(D&h-x-xX=x zxr!m^P9`?7jQnp3I6f(xnneiT4QX`# zB!RngGAq*vJ#*I;4aRT0FOh_M3IIm^(eIS#l z45XV-B?2?o=dHcs4m_eZ`L*ff^2?Di(D$BHD@fb~q;XJKwff8JNjU!yKFvb~CsW?2 zP-!Ug9g~SP6iGMnlyoP}=rI}-kfc6v24M4%Lh<$rLfyF-rbcSG-=2cw2ld{r*9TXO=;_@xhjVZ5tnI!Lksc$ir z<k{=4} zk$^nC5b(XM8x?vatCY_Nwlsj#3jyEjx^eq`KfV*#3jv&72>4FwM&ZmvrT-+b{{(P) zA>ccs8!ydER``#=ehc8VF3fj9H;(j8!N6**=IAj70~{Yh&{gePH6KkP!)E0C1~rSo zSYfh+Ye*WRP}OD}I-abeup8K3!c`HFslr#=W+Z>3x^(#gu#YV~V|V)$ky2n^j~tR$ z;C-E-Kn!!}rMT}+S*0FV+|L@|t{)c4%}rpYOxcQMBe;S^%2KYpC9Ag#h>W!vd;55q zDO-cyjYKGd{(MON93LxBvl%xr@!;UR@;o{x_CL<<$yO5B@k1l?64X0 z7pZXe1AaYJi)&vY=EwVO#^236D*ER@xMb>q{haV)HskO|9u?Qyz~nZ6T!m{u5?b*G zHshf?NlHE$SQ_En)D-@?%}9MJNy*m)Rxcn=hv53I*o?ydiRuBmJFq?hdB%UX8L$17 zAovk|BCzR}JRd*r!EXiNj6#lfC$<#fmQ1~s1Z@Arf8+{^mbn*ePs)RB* zIK`Z1H_pD9sF*Fl>JiH14pK4K*$wB*{?NyQH9wRY=y3UciSM@E==i?B2i*qh^C5Kg z=Eav7X8gJ+Nrip_gwI1rIweaj2JmHv8AYei%l`_-ZHq<2hv2s^zWQOtaU8HNW1kTs z5tl0Uv>?#v z+Mhm!HZU6COp8EMOMeO1TC9tdSk3-5s(`i*j6D{MiXu3~R!_xRo|a>jc9%cEh6xJBhH3%j@(8L};F2y!;r_{yO~Mqae7qpb4v}8q*o`(S7#* zAFKMKeGB|oi$huI=Nz|p=%A{P7J(Uo7njn*+08^=2(gAcVW@e3;T%)yTt z{+-X8BEjzGA>PPXg*R5%`TQk}-saBd+|QUhpML<>{dYdU48+>`eC;(U5}>0jE@KBW zTql=K9Bb!u)@$y3zU@m`Gn;_Z%9OBnKF_FZ2ojWo02L9uhf2^qM6_2UI|n0Y16p9g z=FaDD)Q@3!E07%)N;{t`V;glYJzvUB6g~HSn;;rJyBpSJ7-?_pGA*%Pj6x^;zJcry zB)^veH;uGSU_X|3;T^ft59vo3_Zw+%ECpT?SOpVTb5zqvn~HC;EhDWLA6^qrw!u$# z5;#sdM=r}q`#yXuBkh9$>7mBarr02nq!;05ttCw^%Sh{G0sq&zulDc>4*xY!J|qE3 znoh3&VWfR#JW})k@vB@W3uJs)N zR2u#nxQtVj5$5;k#dvul>%hCI3F+qvx6HK%TKU8!`1A!{6v|QN+A(;~GtmV6Mkx0! zBq0A&N+6kQ%kF_8$u!qeSy|@V=@YO+5QN{xrGJND^v~c5m}^Ooo51^`jN82dbc{e99C!o8eu_}xt7YoGS^b1 z8&g#xb8V}&SPu+=&}#G|d{i}3spbmI)u=I5BQn?KJ?#_U2MY$6FxOHYDxsC=>3=nA z)lV0)I;iFZWb{DI5$Umb!%T+TUtbI|+@6Q1X}G-vw`I7c8_RG@HiSK2#@Kw zj9Zjhrr~x(MeJV$-_0hX+wd}8l=mBM4G8W9^qK`n5NsK4mzVd6k1Q;jFyXEW57Tfv z=Z7G}?JLh?3QM^z>Ji5>+?I1Adw`X~Ww<$fzu|Tc_RYzGZ(S47eF1p2cDRpEv+nL@J+x1AdM@OUMK?F9@1xQv~~7HhYGcPD~4D9dpB;2x|lfcIDv(i>7(mf^MzMCSurW#RW2ZXfiCoxolR!Icur za2xvy${vJs7O7bv5EyQEqc{5%*li2v+_wz3@A|MoKPq-9TpWL$pj)KzP<7krs~LJ%-yp ztFgNpSf}p83^m-IMXQjPLHje5${|~ZTOG^7Wb}RvUbwiF^w&}2RnAz3+m&9ha=@r- zvQ*194Yw)a~6r>6foSr zUk1@R4)C-^u*x)Gxc#XDSXaQfZn0R6Ww`weBS*k+TP71*zkw-JUdBr>T&m7mhTFue z78{1!Nf={@B%9%<4Y4OtiCTu+-=`~WLja8+m>Ym)xP250c}RQ?u0;g1bii`_J_;Nqz(755#8Omf`kQjHRs2b^zlaE~U*f+@4tM zmrn;)fp8^n8g4%t=}&nBV9f%!X}A^G-HLOjKd^@bxM{e(jY$S2Le2y>FMykd+kY?< zVtgyG9Rb`l+!inQaVH?(0CpmPn}*w?SnNl&L4E`52Mf0hx2tKhGjR~>pKx*7xkCsT zZnt3}mrMg#IfS57k0H`b!|nSm!DEA04@&IVi|5{ z;aQ!dzXF7Hrk;S|wtW?UT=xPyWGV?5ZnIPT@*e~HJRr}8T^MeUruyZt1G^QFHx0Kh zwevqzmv{wF9k~4M!8F{Sz|@-`+jD@`Ae;-+GTiQKfYNFM|L&%&zowXm+cN0)R<`Px(8g7XZC(!aB7t6^doJeHV3(yRUO#{TRyR z;4H&!T)dxYe--DE;!*|2I=O?i47W39`kC2aH3($}I$X%)3y zj^|?_EDs@ZvI2(N0eGm8+rijtv1p757;b+3t50&>j`2S&Ifni^y znTFe=(KP1^{3yTu_d%W#`g*Uvcy{8R`>XQE}e?baXm01$3kB%V`+8g9#> zk8@&fk%CLbh)HTD)fP>P47axD5bs7{bjQW^Cb|i-8YoFF@_^N#>P<}CQ$`pS*ZKRW zIS^W7YM`5cX$S~g#wxb|sz(=oTJhU|HRPN7dFW_VH5pHDWdFq^z_kBzcV*ds!TK-u zUm%wK_sQ3B{u^|Z#bqp^F^63GWtOIw*OjX!v0l^u8#e~6uL(G(Y(8|JhE3O?DO7>rxpyMoUXzuy+A)GTf6N>Wp zltnz^+8fU5ucI7?#_1xilVMauU7{iOS18~UJKBKSjQ`7xs9hKz9WPx^cVOnPdPdr4x_Tu}4;*A3f&c zNX-hxIZ!%Xhyx|Z{R2I`8XMzKplQc~Qd;4)7*_f@DWyXj)X5E2pf1D4_^nW!1Em8J zI8bujH_%3ZMIw8#c>6HIG#76-kHz^zxNm~XSVu)`F5X@Z>s=4{4l)t-oM0~AKJz^6 zUw~$tu)c|;t;O2~P4L+Rd^Q2!5z0X{D+~IJ84mM{6v~J6m+@>uN3LHy4s#aySfA_= z`~IKotU}Y&!H>peyo~_$|8Oe!ME1904{pH}7EqQ2e?qXiy=>k*pQs0@g$17@*!pDW z&mx~7p8>!}TAZ)p3VgCt*i>=m!gqzm`Gq)T$JJM#?Cg5MCtiWiNnHONT(AaWP=&b7f6CE+6`t#(TUj=OF1#4SZJhT3N#GZGF*BJy%z9x%L6hi z>K1asb7nYtNzgr&+F*!_H#(hXGa8mh)3}Wl;P5?(%V>x?qmz%Hv&d$Y#seztrtuB% zUn~yqw!^XDP}~%Hx;s`?&o*xds^>W^P(9Dr!eb(^%DD7?!PQfus&e%tI#*Bf5&5TK z50Y^M4dQKQii!zkLJs^1jSb8qz=W*F%u6uvPO=jh&lG}3~rXL1JiU86v2yb~1Y z>rXnlCj3rH?;VX0=%FoYU~oey2wcDLU9iC{-aTFpy_QJQT6=E`8C8<^}Nb^yIa*${=0fMea2rsXZc4s z5EV!Ng1u{Q>CJoD1wluMNDfgveNc+9pP(4Z^KNl^Nrs!zi(p*AWfW8o#E`frqrKn6 zioZ-qpAJh1reN}u3=ht<)}JqvEK;CO#e9K069ez2`t8OZQ8mbW7Sh_NK%aCJ_Maf{ zM(@MBg+3Y$t51;kN0>x4YNu;85nt2$F)13~#N%D+gEo7U!!Yau;3A+I9#2TvY`=U; zl%Tn<&aeCUhhD9U#;HXfmfbc9i;hiMS{=Z$-l63Xih;gFE4w;42U`OBL;X|;N9k7`%OF=T?Wh< zd8-gfr<0fXN2GYsug76;!U=emq4QSCycbmc182IF+jcQplmw>wc6B04%DMRvz8YqK z6t9m-XP02%z_CG-N!WiDP(!ba!>jfR4sk=q&i}Uvc`FeQ;G1AyeVRXO4S!5)Ct|c{ab_%Vpbx26njeKDwNn*oBa(KE2uzoQEUIdi+}#! zL{<_u!o#I9(Nw}EN_B`G|GQ}anvWfoYGOrjwCeoVLy2CdIf{&agm>3v1BWa-+MzwU z2}|kT4ynbO;0eV(v8n~$Z^F~+!bCYb_x%fa1&z(>d>2#GZ|L$;4#z;roiKYxOvV2L zB^5phQX*MNI=q6F@X0Ky2B8u>gEtU#gwUX1!Fy^@AJRZo&^+#^d=|WJ9|m|KSTJzlAlKVZSp&*csN(`tertn6#u4g5 zx6Wt(CVcp>w7THMC*7*!Zv78zKQxQsP?NW*1E$*t3#w45DsreTO$~ThrskNk4)2#K z)W4rrm2yF_uuAJ}lA)TZPD=MrR%<7!+Wf3X3BDUFs6r(f4)wUH0WWG16H#&hGuY6o zzkSuyLOj?MW-s8LXjC1VKI?&>gANo*#R9wq1i2Ds!-XK1{>V?J$qaY?>W9e#ZdUe* zto`;25BWr6BAQ)fpjQ?H%4H=HC+?XfG1TN(JrsAr{_2aGH*^lnDcz;m3gSK0cO$(1 zUGo}j3gZm@X&CldLKa{6x8SEF_^-;-;$k=p?o9BP|9}1!q6=RCF8{GG!ch?>&QK-M z`rm?0N$}nxtayM*VTHZNMpX*qK;q6NPypl-6&pU!yiYKaQUPo-d7%X$8aIQPBl3CO zJ`4}6r-)=`zBO6~N&)#B9RW2l7;=0UxdnnMQCiicSvl!*@JDnf7I+JcZ7)w zB+{opRuM;{F4%tc|A>@2cq)y`ve}=4`FKt}m|#F;m2~_eTg5uV$43j+gwDSM>P+W> zX&PR)PdC{WsZ(ep5exbe1D=5K8-v#*-IY}eB!i8qF}9~ zW^_6jhkry$x3g%xj~MoE_p14C@@ZJ@X1)?F{-*d*yH#zy+|t}DW8Kc zAYP5K=T}SMCzJM|dMakA8~ydg2ym4bi3zxD^c<3MwNWgGpVd-5{;fB|pG08=Dk+D* zB-Af>%G_!ry1t>|_BW!NP4J~e}iNOphSJsf1%tYmFm#T6pae4N3?x`baI>{ zKSrFF&s7i4p5A@%KxG7%FK@_5l};$p@1yL$A=&hZ)bRfh<*Le0RVg3cjTCXu8uk(I zt8>5?LX>lSI2=K_%PF1_>KB~j6+f_Zilb*6f}TKLCq0zn{Uq}VqRBrZ=PhuS!&BEK7daA&2ubxJse!+Ue zupWa-?eQmlf*##wkseAzG0A*z-v1+XiW>ijl!0jF`ju#V{kAIXqoDq;Qlnf~+w7+J z=3qZEDee35WYG}~>Iy`;RdPEcADw>u#oH>{zH&CcAVBe^fAYV>;Ns=YH&xB39&K-h z=`@M<{y#*yQU!@RqU{DI`y{&V{}APraeb^feQXI4f5qN>eJsxyjzN+WR*b^o+ODen zLizIINFw(ALE{{_U+P8Po5gr+=q%+jRQ0=1rS?nA%bo`BXY?5IPWTkw^dsW2KZ(db z0IbPrSra~V>HHH0#81kHX9t@-p)uxXH<5dJ4t>fdGn77 ztuYB_>L8ran6S;1Q?bn60W(CC1CnHqSr93}b5zP7Xcmo=b>~(56XTnE8F`f`k^>924W5#$O$cRJmQ_>$0_*JC1B^<)hBcO({P%01M) zZY{y8Ejca2h($jlz9KYazt#e2xx>M%vJ|i@C@fN#_aJ5Geigl!i5irh=Su>6Rbd~P zn8;q!9?F++M*V6jXT4@_#pXcp0o@snf6A@6&!Cvg!q3Rlhko=X|tcs6%vX^y-rZ-vB1q)a5@rxlpLU%gxPcgX@if7Ll4bh*tECLf0&Sh2P zw~!n+A=#ZefLX|Gp+4?abSWkx+egJTgUh-nL00@k_LUic)-yEz9;h~@zZNT8eviV3 zIz#GXu421GrSfjf0pzwZ_OT@v$Tsp5@ng^7&9XMSNaQs&!s#Y;J?c}_2xY5D?bIAM zk$huIEq)j`4!#Lbr6b6iI{C(#I;k6OqWH#@daegMicj*~w6Cm-#L;DoCZQzVy6BoZkpMXRwIis_5 zeDgELjB>a6zfL)ubQr$~QKy_;I;z6a{4YCfqGcR$+3z`4{0?UJdB+cb(Es<2u$%OM z+2P~=D~@{n|D$67|NrEehW`~>{~=@1Gw93E(UF2Z6q!tD<{y#%Aw~ijkrny%mr#cP zn~CcGfd3zMT=vJuu%g}*@DvrJ@Eg&`*P*I&6t-K)<#sT zHVu(+_e2Q%1~4MG+D=3XFMtqw^=bNI ztz?U+RqZg`=~W(}Y?vJV87ZZs8zZLFdj&@^iSBHhczdE7_8cp{I}um(YFSGRk|7(*FdM+TmI>)ug!6K|)350w2v_dW)TWe8B;yTY_X4~sqzu(j8zOM2;$h=G)d^2uq>~<1gq!lUYr7`? z+SBdZpxQ&@xCqpqy2Fs{4p7#O6xM?JK<%mD2x7Jn#|gB ztpQ$UQHIt7p|MF)uYRab1l1nO*MoBVJbdHrbH_9`Iu|O*U3n1dUc+U4NlT8b zAu4HxS9}cbFHA`PfpDvnDfI@mEZTyVhN!FGd6_AV%R)rqGJavU*~ye(wmC!{EXGbK zAjxX@scEsTPNpw5Py7q=vLmqWgmc`iP9_mJ6|@`!Y?_JR)5*NL+plCD2%Ak(pp%*R zjYlat1nf-{zo(ON)JRt8`T~R>h(zhq$rb2i!Z~r~5cL-}8sNysA?JO#IPyxw>SW%W zoTvh?4nln*1@u~-Obwq`Y3c#OpnEi#olM$hzozLREVxIL*~#>eO%_yq@@WuunIzT8 z@O#C+`7pvgfke3}Uwcl*%a`;FyrrQgMIW_LlltyC_5Y0j-?LlY)5pB^7QoYLQh8Xd zNpIN`AgMlPHk;H(SczGgeCf@CdcB}}i--<>BPlnj{k!~k+@v;j_TO=DQK5nVj+@j1 z7+IESuSO{!f;lNyeN z0K}Bt@KZ=4QOq`*RHKk4mFDs>NzMUtk;S%})bp`EkqCMDEU?{#bKI;ZH3Dx6`Rk>3 zfSoq+dzzG<<5zMOgx^h4ph?xlYZ+D&^%DjzTpY-~O$rNcI9*jhs7)kFmrkxgld2KY zq~6W*Cfw`qYjY%{1`J%?@b;TZ5Hb0S5l7TMQOgVX`wE%I{H zs90-!yFE&@sA1fE$0eErZHvpOOh|b~Y8!jbMu`FN9cdzZZzr_Z{`3w6^NnUz!^B+N z&jGy1r1;SWMn2AYcoWU!X&}1@tx2kD(>Ba4nixM_u=Au0aY^R!MuljMa z=z{cnR-8{_N1ONFOH>Z?UDkP7`Cy`W7b<;Z?hyKEtR4w^b$yL)84-E*ftahUl_dmJ z(iN~Ci4HE?-L4Ki^wj|6Z<%lw|Ma-ckKAN3(8&m;6v4=Jem>GQUlzR62%H6Axj`6fTL<%76s z#y3q;v9qIS**u)$+$MD_-L&AFwyEurMJ-$LO}o^mb=GmJzUh!!aw={* z@J+|m4n1(woo_m&eo%y)9(>a|l}@f`*_&^=q;4T?efXwp>a(P+AK!FKO(tyv_@;Ym z8`3t6Z+fJjAZTPZG-cew$VjdXTr0(DdFKIOlM}|lKR)7D3}Gcvn_88L zpN)d>PPM^ZHj!$BcWraH%Ox!&caM^AmrwZ+&lcVsJVUk0C_%N_y$f2r2g<;sLIOQs zc#HDk&h(N6)Vq}2S;-a2|0r^`RZiR_;+KKtrd2if9CEjfg*(^1g4|Ekgu8l)&E&3` z2X~&*|A-szhe{kK|9phns)qYra<3T$cg+%K$lZT1+)d&*+)~MKH&x+Aqq}RhM#ZOU zd$`voGv}NS?hVSlA9bPC<|OuytPmkuZ7Ip_;|1_Pra1j$;C?fW{nuj7)9OQ|bIRvV z(dtwprM=T$%xg3A9G_pq$L5(eJny4Yiwm+0w8RfXG!hQMfRjM3_=ZvV;ahTTlHsju z>1%V*ZU2s1|4KC>TGx)?USqo)HK0heuETdW;avw(>$>)T5X2_wYTZCbrzUz?QVpXi zg2FG=i0{IMcP>b+8{2chBdJz;ziegKQ(?7sQ$J%$wc$HR^#`eSTl>S1^1g{gv>E1J ziEzCakacYh_ao#!fUIj588;bj_W>fNp)$4isB&J93e?`K$~G63rhSqs&k^}>CvzF5 ze_cLGxH^P~r(H+N>rO&{6YV5zBK7BvhUgFzI~O#qYrGoSC1JAzxa{(xyY95S#a@&MQYcgydQUfc2T|i z+&~!pi1;V*yIM=RI05L_S{(gT*&MML*{ge@^u3baKzvNTY?jIUE*b)tlI&UOsL=c^?ojmDYeOWmmYsRA!H66=&Ev4)Mat-sWxskSsFE=5Om_<2dw zpxv%>(=W8N=Y4`QYyFiTLsexGc~j{8Bl61C0#??>?{e0dBL4RXUv|L2GKOEx9UzDe z(v&=f=e%;p7d?4i~N0tM}!5OoGUMs1dSdF=xw%!$0+% z7?=s1j;?5DB6U8>vujk08?_JJ#Y>HG7p;@{I_+@`31uoqk8RikC2|&CSfz}o@>>wQ zi92qX@ca<&u`3GU`kP#R&@|%1{`3<|!NEkg@P>DWQL{rF#lcPf@mRnqmdN7>rdtcW zDSY(G_z~IF(bT)W%yqf9<(t5SNq2--jYazUUWF1dgzImrH z`gg0Ts^p=7cZ2TmuA+2&VtVW367dw%?7k0_6y1+Ysv@@u=eoizmSdbZ6*an>A*1Oo z@h`JjxC_a~X4#_q2VBo;5p+)jQVOnOxa$_J6!Z*HpzI%+a=R_}&YbwC2rEF?? zalVSYf#c!bR=pV=5rT0;QQa1f?#Th|bGp|A+ivm> z6j=f+U?SmL`sw*4eum&D9{aiq_c0JF(L9!G`X$_P1&$F3mylKQ^yK6I4!-dh5x)CZ zxDsgXUP8$f{AAJ(0hNfCKtJ($N%)ym4L`$kF}k+N6Qa~oo~f+YO1VmHm#)(2;`-jk zBd7ckt!IafqAnsFx1Zv6r;MQ|4VO!7(8_>VYOmC*g6xW)1$FU9@sr-Z4L)4#nH2sM z{8MXJ#rLc!4ytD&)rTDeditEyrJ;RK!%WAO7Jm>;-&;SzA$q0obTIv^@sM}D9R4-Q zFRT_TTnFuY;Ko6tZ^Hh2DDpCHU|)U(f1E9U!ok@RC0>@)ox48JpZ*)>Xx|)s37Fdq z8_a6C6S0lIEw{|rB>c9APk3(D(_Z1qO&RPJrE=F|@6G(&6+IHgv{6-`Pk_B+)K^22 z5zMGd+wf-_{6!b?2;#blVraz}%vP~U!LN?JFJLH$OLp0ALFk(l@1a8 zJxX^9gUEbui0)Jx?ag~#Y}76;L}6S_rQp-u*zwj?cr$zpZc^tI7^3hmeyS<~2-aNp)@@`=q>QFm+UlM~))YEqJS8l=?#ix^b1Dpn_d3o(FQ^R51b;t z8=T(n>Y>9d6-C{7{9|AwY^#f({rHI|SNtC}@v{;x_Y%GC(jCxp-?L&eL>&>JfdcoSp-lGaChOU7WBOhm&jg@>1_Y% zy!b#FVD8#^uo=f!D+&&iWOz&Uhu8rIqnB|S-4j!=@_@Fm~+~s=0UDvTx-Jc+SGnJW_iQingpX>&AH{~9P$Nqr>;_Fek43-68$8bO9{-PbP^*d?Ji)Pn?~5IO^Zz8r8Rk!R zjOY6)j<0wX`>0e`RA3i!Rya+d` z3kG<_=n@fRH$X*cgOPo7Y&2$HXc_}ha|a16ou*CAdo;r;qRx&ZvQZN}j{GH~A3>-7 zr5uhk0>(A!GYS=NT;uRQ_yRWgi=68*rD3 zL7!!F(e%408SegAF$&E^-O+yyw7Ftnx0AX|M4SiUaFF!)6mIS2-D3W!V!o3 zC5S_D&+zASQ9xq@Qd_3I>G# zj2oq35EPK_;3phHd?2Dsa;qe*i8&3L=|5yhmi+Z;bKl7uo zcv9=Ilw@zo5@pFX?T(E7IUQyoL^T$d@#sBrB{WtdD*D=Ev*yeQ8*+gXSqJ2x_*Seq z9`HjE_NEH%LNKSKV$K*KjUrmNQOKwO(gXe8^!5>hx+-Kr09k-?nO+!i1^osE_H+Pg ziaE~oqKG|6Ga*L<$d9Ns(~Bd{ja10z0pu)d(DcV6UaF;#>j7lN<3M&t?2b}MbfgvQ zD@f<`6%qfBu z9Jgw2FsU`5_2+g)rv7Gh-iE6F>LRQz-jR4cTxN402!PWDmlzYUvGWclp1n~iHd?1x zb()Ui`PU{-m_I+r1FFwEXp0L9(l>z5ydyi8XU@z!%I5ZDhcV&KnGPs&Ym!=+nmi{3 zhx!zB@QWh83I~S6gGB|tlhADWBog#m2Ldds>iddi2c5F#XR@r=cY$RD19xTu%NqF7 zV6Y{@D0{p&%bNKLSVk~vbxCijnw1!i$8GqFEPUp1Ir{G^$17>%kY zN)l>iQLWQaG>auyq)%AVC`e%D-BmKgO!XP~DqZLF2}}D1Z$!DuT=ZflJ_3sF%(f7A*8r=PSTOmK?0ael-sq0kd!WP|RT7~5 zpVEs7OPb~~ES(M`Oe@NzPgqeQcsr02mR_67uyi_(Cb6<{db8P;jSzd(X0xjpA$C8_ zW>+;r>}Z?@2A`-En*i;NJvfM&Cc zjS!FcX0vMJQw28n>puTXoUP93h|K5oO3v|S^kfNc>HC~c|PT}P`%?~xff3ta}5#r&|Y@TI=co=kAGYE@2ijq4GKu@qL9Pab64|jB0C%=-0 zM$h(iUz_Boz-O+mnzI%s`^?qVa(w7{GgmjsnJfQIbI!|uvz)#>E3Iyx^8^oy%=^kkSj(yL!P-uZ57u#Ne6X(6nE7CRSKh#puW1o}h==K#mf=U`zg2jL{I>}Y zho_wux4>nd8p&{G;`KMF`?}Oxpq=R&<4iYkMty1gi}7JSz9kVD37i(-%0(D$8x<)q)Ow@JtuQkkW>OHw?M62oShI|92pLMZ6+t==(rO}o zAAQe4Bd4xNR~jwh&V6?o$z^MSSzBFhO8a|4IL~+yr-qt?h?{5ZjL%h9kT>Vy-By@^ zlegy?uN3170(l?s;A@d@G0(Ua=ZV_nGv*ls(L2>4AL&#RC%1J2l2xa>aH@JZCwZlD zbRULK)2!r2%rQ5pCkxW0zgpiLxa#9)gw%!+2LE_-&sPRLvE1cD({k^pIha9$S%~=5 zAcl-|+0Mo5B0C+AC~cGrPQ@@|5@6=y*F!b@fE&r)D z&C_@47kLjyPW{!MzR2ZzHK)aL!Rueu=k?Z@QROG^!bhSQvxWqh*7j~{Bbf+ z3uO&J36*0MaU7+f>~&}AUcRwRWp2n0(wa;*ZYUcfU}znjvmOomIH6THg({53PBAv6 z`PV}BsL2`Dri{2Tvz#rMwaM%%_qk_bf-s-JeE&-T%9d^_AJ?z4gEMM5FgU&+=U!t| zE&q2OtWMmPRu0T`VWz6k2uHiIskPsaAUf9C#w8DQV3rHBR0Vr6VORUF^k9ACnoM>I=swuGs!ax61Y1w_$e#IQ-tO`rE;#y#WBQ1mzdubttx|a7_IKP&>rGlK} z2RXO#a|+dYFSsD5HhxZsI{(6KFElDY-=r1H#K|a_g~Xo{#PvRMAtu3{H;*= z$ovBTyejwps<6KOP`j~cUj6r1z)5>`H2wC z_tW}Mo~Xz!i_(Qsn!pKN|{C-fP5_#hvU^7EOQ5CuU_27??&203^Pa>N+q{3ytoP@f&x!`mw-`*RF6{kftH zRZtECH?!h>@hZXQOl!wuMw0P1jMaZ@4F-+%3vacQQ9q>*hTZjN_p`w-D~bdE=G{rS zE!DmY(^UnjDqbxxPQ%tu#uxv@t0gdCX87je&-evNYFV^<)@fD#3%f%G0g@#L&HiVS z)LEmrzw-`5Gb2GXYeEaFjAAuu*zz=ExOVjr|EcSmCBxd{r_$70#v|L)N&Q^!a>~{h> zu43qI82Q>WR4T4J%s$wH9fleA+>uOWP{A;;Ju2Y=FPzHHVijal+-VNQykW;KGiMq$ zzrvv+M0e+2-vy{tVP@y!srTXn4ju(pJwXZoBC&XjLNyInf%wVP^O*XuU@RmP39;oW z;@x?W?hn0>o|e)(A-Ov$J%Qos&gX(hafOff#Wq2*-IJa%uIj1|?M6A>SY?dDk-YP8 z)_R-}oPynzLTcxcth$(NvEYo+vTJ|!`~#Jp?2M`SVC&A8Qp8J3`6~eul!V|N1}l0c z(V8(N1zUjw(0B#~uO?d4y@J4*2(7>KZ8uUQY21$@*{@&Cj7aRtue>inV z^@1+5AtuGLvYT%;+J*Oer(bENcktm=@c@2hTsPt-72%qJuZ&?+MyYBX9;+H1AqTGh z0$_q%*71Qcx$Adnht1> z9dp|E%ty{iW)URIqSC*v^eOXeU)L+02tEeM&ZzXKS&&}Hn2pB)_z2-qNRE5bn(RGH zpOG}WTN%Zn+!=_@Ma9FvNK&TXNV<3`Rm670P)Q)iubOk(L7Zn~C#`YBg%DMZivPX} zr{0D}(qsEf(QXA%hp4#T6lk|FlFWZHL_8Ft@mlQ68EfA56t1{+G?Lbjz;zM$Hy`r5 zG)C3zv?)WG-HfE#aXt}00?}4aT&evZ*!I4LFOZz74x#uMMQj_+iK=FByRFRrM#?P( zY0|ZxhWwkTdQH3!)*NK`KK?sJT|{vrG#z#65G&2_Mz6$XO4KndlEyyxI-Ct`k z4W32|4sta|kV{2^bJ11!S3?lGy*IiFWh1x)qs%mKMP1Px!@L*`HxX!Qy*wB z80Nd6|5h?7f@W&ZzCmt2r9Tl2>kK({*1YQ@ZknDn3jOSX!b+l_=9AneHD zzcR|R(A;HMna^T6(Gh~HK?#$QIMa#4#ylWKKa#D6Yk@m~@aLl-$iz>0|CAx|s)G5x zkr1e4;G1d4ng21Yx4(#2#s{5hQK&1=o9J~#^b-a(@yWZk3k;y-a1 z4KcG?+@Ijc$3iwSDwktvq?!ChD?^SYV-aM_qH^gw$C|!3dM7wrx)rkBQMvS1XurC$bQpu=e?8}a+;cF`mRcJo&`73E20sAoE;-Cugs8> z=0elg1NQk!V>X7Vi!5*+#ckUgU1PD{-AnJ2}E%;byT#W^uM2*8UPq%x%c*^F&o<2zLrj~@BW4O4MQ(F{UyK``hZo32l%J2%hIm8<$@zHzt~Hnj zS?Fiu4R%035&Dt|x!^ZQ{OutKWnYU9gxL_2U_E60LnxSyBOp|J0HiDnNzwq>P@jRo zk@MdPTrs)ewJ7u7N40(!M;9|2l4KyVp;LpA>?HRrk|4|cFH)CW@B>KwZ&UZgR62kXsH+^&?`E2XMY#h}a-9}gU5g;kIEGhfn}3_>ix*-^C1l1N zBuh$xs^kD%qfSvN}BY62a)muW=o^rM*=d+(?mYq_!oFg9s5!%MfVzfAX?jkNXZ8kYy&dqO&*;bfJsE&mmji9K z0}BSYp!)&X;(_GN#_{k~mCwYm)!bwI?s^oS9RlJQQF1&>eGcHP?Hij9z-JJi^8ijT z5B-38m%<3<-W4S=~GNc<|lq7G{M*Y*wa!}0qeTt|SktMbpC#P}dS z&iC0hkUfF&!&+vsTTwM@ZbFpP;sSYC^3N!L0Qon>czePbL^RK4lV};2EnRT)o3YN` zY!xS;_VG3U0oVJ@)^Vxa&J1^vUf)jc=hl+ZTZZJMS#CH^nl*5840Rleb86NIoLyNK zk|Y<|P~(v}xsvnu2CkS~um#He!>JZeQ%y%fjb$PB!y(~Xp)9n2G?EqM9!3&mng0P= zAs6JwS^QgQ{0Zf`f33`ZE#A(5GWjcAg2#f((S8yCuW{LWtQQIX^=k;z1pHi%AmNU2rnE;2zvp z2z8l&gj|qEzkfWz+mV&dAjGmDdniA?9wWx*ND4q%pCa4Z7hAIEGy41|~s{zS+u>i$k{A*Cz}Ex!r% zu`KuqIR6F;_Tr3J%xv*f;6hA-t0+B8>5I(1GY8od%ziYPVZRv(%R*Vm784v|QoQ7L zfP38m@ZSVK4=$9n6atoom;{*(J&Y@7#Ve46b}t6k8At!!LF?GF>)iI5mNUeAs76R8?&Ys{2MqI*?IFI z_<&qGT=PFcL3LDK%xs8BFbrM)8x*v=4_PMukD2ADKgf4Y`M+cKeQ+UWL)oj5RAj<8 zTZM{|1gGB*T%b0N3UZ;s2au2p)&=LU2|+0BLDb7^u?a53BzQg5Izbw2@DRAGi5o;5 z1)-v~fDEQ!0tKg$4fS7#WZM=%CtdWqy84xR~FZ5Bp{L>%+Hrsg(wK}T{nKdohMYtxe#BKMLKKAV zdC`6Hh;O!$+v@q~+=*d9kgvt@HzvmqwfXraw&0-I;JSe;W{WG9nPjb(mD+92!B9EF zJQ0_`Piy7jrc1|Qd-N&BS%Z=jn0u{++B#4|A@3p8M1p&96n;M>toA@~z!TP{usmhv z$vA609ziosLin)$&^3xpRvfUGjvW6p+&hWA5y9VA93%u4P0aurL1 zO#Jkzm|TdycOKgkcRD6BnTaICyMrO#)C(hxg($$o|hDDdeXXuSvzT(8wg!cPl-EjQeC$9lU{U!x~xL#Lte!tZoW%oy0yf zi1X0ywy8}il#@%*)I%s~B`UpG%0vYzD_T4ZuWri9c=#8rv!#fGIA=jsZETz@adKu5 z)qlJS$eau+5WV~VMvupAC#!76S+p0TKe!B9#*4WhVj`aYnGtvO(|k@)sXvKiv#`ji zAa9Zc`Dr#kKjT(d5nS#+>8fl4WI(b@EHJ8&-+KGt{RCAPxz@2FCvd@oG(th)%i!*9 znW+XLbDc(Z0HX@|IkwOzWz;RmEsYg5{%8zdApBZYX|cJl^@7)*8gXN*I$rMr)bW~} z3i5VNQR5^W4_8XqPf;$hl~oc85nGkpp(l*IW`w%rgcUEs{OTFGKza3|E@jl-ndRo+ znJn+1N^1xk{HnEj+}v;guOs--Ol{xz8Q5rQ#;cr0OcdZUW2QpsxHOmVa+b;L(cQH`8*gHn6%h)-LB^?zcM zo=Z!5(hM)fLnyk?3CFTVcq|D;b3tCr)Klhwwpc5xp-v~kXGc}xorvMvHtupm_+qS* zbI^QIUJjbCjh5)v7`69lq&gVYrz1vr>9vzLHO76+Ne#g_kFT1A)jrLYx=564VD835 z#P=aHel@Od@fAyz0muA@Y`J#Mi@o?#50zUT&o>kJ2A*5ypuD>SBwG^rV|M^gn(?1v zl1Vc&q86Rwc*81P`*GvMeh2(Qd&erOrp3}gtSmY?0*6P%)GoMjU3C1dRJCuE?3K4+ zJ*FARMm=qAuNPMP%|oMbb`8v#sMPmF{eeV+-V@!k3N*v8D6a|1nJP51y!e`^)em@N&bqKWq)csSsxFUxfu=G_ydP;dx)ousAGNo2A;fG49l6 zc*Dyv)88@kFudGOGp}nidgSkuH7s=TjIMrt41Qss>s5f5Oju0$v9L(i4%vM!GnjYq=1?G6=H$RL}pqs z7?YBMxEAXM!$3^0fs!>sSN{s|D)J$Q*VcAz-wV(J+Lr)%_EoHXM#-`7Mrijz1xEO@f(A0JLG{l80BNMtUhHC6V1`O9c9>i!|*l9@;71X ztRl}3NAZ1L@ohP6rTD+sqIjoQe7^h*2)2r}?TzA>Vv08)Mk;c9R}_B~Q~Yl(i{*2p zRhu&|y(h}m3~vX^=Rr9&$lp9am7fx=S_Kv4Pp_8AOiRfmZA(*mMRvyL+=+n*zztx_ zYKcU)+1a^#pQ_a#WlqqpG%KBxoz731TAOs`+|8GMo7Ag(E;hrfTr#?H`DSV0R_yu5 zS@}U-xwGf_eq`(2*vjL?+1F;{ji1B^TewFfb1{d}OE`@3d*2+dQo5V@O(vrufVskQ zkE4z#D1@d}6Nzjq@hZT#O*UqETU{>uJ&<*CacU0qu?%Sfwj=%TD83LpN!m&QvUTw zly^Y6(~iH*!6P;>Ga7fTtRWu!SEE2aY8nX-Lix=e{CxTK(vY8ELtYvSmk*jo#^G+f zwJ8REsywa#$Oe8e7A_w%jcn?U@^@n3wb0H~UR8l~2GBobB$O@yDywR*S01)u-@ zz1#dN*5J(0#x7*{mcJSe51Gc2`Ff$L^4i*2l92}5)~?B;quzgV@YUSzb~Ys{!Y}Gt zQ&^3DqiFt-N?4KI#K;vuVAD1{N(Z^M9f|noo@At-J^|_F`su*A-RS?Q_M%p6fvKyC zbT|lw-%%!qVEC4Vs&}Eh-hi}3^xp~TkHzEJnsVEcRrq!%qaxSR!-1{cK(M2|^n1Ks zASm_%AsHPA$>>1vNc93iiHh)xzt&7v!$1gH2SNY=1L0i^x%C7R350u^lt5I2^s<4d zjjJjzQ0;ZCc8&BoOCN*6zbNwp@hJDs{|-bz&B5TN4J@@rBIjG?N_7-RjFjPKc0IzR zgQ)ixW)3MM&2)AgD!}is_n`1PB(f15(c{B~X{zkqc9@@ZQ-R($Vp%Lfw`=$q6XZnPZ9K8 zS??dZ-VV~0y^0+Y-xlQ=NW^KUi|c~JI}b%>6(wmySi^n0nH^%QgTN!|Qnx($i z?BLJG*K@kJf$R>e0PmEi8o3L&K@ooP+3I(x9q%K~UcFAgw}SoNM9&Vo)h8-3U;}Vs zpNV2~B@zkPNR(sCuTz;vs?wS&q}sNxedYw+v9y1+VjKd zP(Npf`Umh%IsA~1^hVx(8Re<%*#HXMLl|;TjS|^8K*v zxc9jcamUrpIP(LDu`iy+Lo@Vs4-#>4Haq*kF_a%-`Ku+$BVQ!L=vkC`pU91V8CL~9 z+NRWR)XKWbwHDpr)p9~ZbY+CXvyTeAi>~(yK&>`Nyn&mz5uL~!PItO_enQ+@3!p@b zW&i7Jf=J0(Ku1b4I#QC+k&7U$ykSpI!%Ig}^jC2eM&bE>`zpuY+7caCw-0gX2c9MA-e9?L^+wbr2bFtEm6 z$0dN(S$tSiw}7EQs=$A6%IE>8d9B8;lXD=|zr}6o@%X<9WD}$U?+jDwc5oIyVJ{(i z8SutfrK3_m3%^Cx&}PIsvYi3vC+fZ4)cKI^3n+^DNI1O53C~KXuuoLaQ1vIOrgVu> zHRKz-7cZy!Pkf$y;XYFB4QREC)p9<%?ww^DLKb_L#aYuiJ9c;ln%6=a^Zn+?XqsCd zYtC_EF0F87gY%(#&;O4rVbdcIQ|q-@EyoEe$f^E0Q76{X#Hrpnwayuc>(mgMKOm97 zt^o@B$~m<{Ulr2u%Jbm5V(A0Orh@$i5*2s|Q<$rfQ)v1u<<*K=GDSxl|7v06^3I3kcxeW2B&p>jqP$(Shq2BDeU z-Hk#GSk!I98Bx%1vpr#z3rJ;WF#du~2T3#PU((%jshdnlHen&s;{-S{wOYB8e9Pgm(?eO&Bp0$>MIG2n7WBCe>z1WH>K_1!mxq<4lyA zOSFA1NY%$-WgN<6 zY8?K}$l10Jg9UCoGBqT_!3;7@B*Vc>_;(}NO-62$aKHQ(n&k&Y#B6<(i>Kk6jdF6| zAjDhHk^dsGjsxXgK*%1}0`DkbZT&ETz?Vy!(?~u~8aWN(8p`Qa`i2u$NmghmuakBNOtDVzZE$q{1T;ins^s`JTWQjZMfr1&In|BJ#DMX?D=+ zmNUN{qjKun)qLCyg)}`J2TyyD;7*VwAQdTm6Y=>Rs@_;v8e`2T^SJ{XbBEM?QikCw!tXv={@!|zV}c#s zPjw71GG_Gs3C~{#$`;f^hZuepE0KtZW%Cbi$s~ zwxXA_(Y82r#PIGLw10rDJCTU-U+d7yL@e>JUPhVMwtjvnrfo?^w=K!&wl$_U%|3&J z`W>46PMhtHa%UHNZHtQ^BK*>gRpn~8ZP6)dTU>VHwJjR)+7>e^aMgM|gbXdK1rqUl zl2qIVmt4BCe3mZf;M=JfZ7X%%|7u$~kf^|+vv^AqG|fk}`Wb`+>Q38|kGK`m^ss|D z>IwWG2HDiGS0Pb>f3dH>0%s-kiP;0vwpc9V49DN-yk&nGZnkshgu@C%r9E3z9hmTD zF1ke#s#}!o!U#XkXN?5b+0STE(fy1Tbq;eD*?zVtXNFSkUR+>?f_WPf2_BtMg*5Um zUOad={#Sx*f>fY*F5Vpi&fJeg;OhaGYlta>jG|4VOMF+{)I5g&cR)5Z>}^O?VDCI! z{{&}VKq3Y>hk#RiEbi=!wHqLt8uoWcRAA)`*xM*GuR$Uc1g^3H zQ(N)QtC&2lO>&;`ypwU}8GJFUDx}R1vH0LN{4cqz8Jktu&6#vYg4I&9QFq-rxT%V) zk<<^nLrXO67!9XV^a;#0MW9nXFP$&Fr61r7EOP_l?2g zZv1xw+0?MhBT<3PIK%b_XH7&R2BOyi7ui{UIHLkHZ^rQtx$&w7x!W>Mr8Mm*ToVR;66!%V;`{hM%5-`44OVTpK<`j|1DG z_XEr0`@3Gb6(U|YJNG_RWX@DH={x|Opr%@7S)GbJ!}9uGdC)2+<$+o^;Dr$=HoI!0 zyl<8T8O@N$B<6CR z2^y|JoXg!|aLZCZNP2N7w`CPTHxjfW7KC9DFmIG2rrXftL6!Pu##@4K1pIp9w`u%m z^f>T&F5ZH~@^5uHhi3WwGKRIpD988t=Qo}und;2ctJxBnrADf}w=~cXX8)kNd9Axa z^i_o(#9T2lj{RR#2)yyQGuJFa(Is1^5VeA)U!8eKjqtZu^p zZ6KQpc5fsqvV{|v4PX&g%waKs;T%w6%n6J$A$)|cy$?_+*N&m+e@-I3a-6iD-sp?^hMNr5v)`1z=X1#LpiY>m{8T3P=($CsP4c^HmMSd{^v9-@Bl8`wgSQ& zg~T~H!!h1+GUR#d%#2vYCwN}#X8hj)vZ-!&V$u(ZiWKF+k^NxvLn+`sF><9j=Qx=f z%%CS6flJ>;wy!RZs%Ome82g@s1~zFT-dS#hIg803v;yjH8`UH;+{rX#Mn$@DW3vX~ zq{6#@EOVwXD@9Yz@o_8bIoOfxv5J6|VNg;>v$b;t`6(QOO;K!3Kq8wi$DlYp*C-!# zdahB688|mdS#yon99OHrj%rvDL-l90`Z@0qUgj$+>SAk|uUb@nnXehu^CcR~eVLS~ zz=%q?|4Uon#oBTz+!&Wj4P+)LYh#>r2P*I>f_wpBv&>-EdDaflP}~YI3;xA9Q5DkK z%QZu)0GOH}n;NzSPDRqVmj;7{4r2a(Y|P&`ip5EZ`TIs2+2F{{jQL&AkeIVf$6R=s zHmQuhODZA9Y5Rt3^9G2MeA^JQIr0iL3l8LARCyIxaeSr99r@P8U)Q^9@) z3GQ(7NVou2&qQ-^UdNF68N3Q_2&&6O;jxK;*iBR0B@Fa*rBWoP6y;$!1W4R&`93`-+jyY2~NkRP_O~q8N_>}9QBGQ%m+2d2`8!C*BsxKB{qfTc2f}}Sxok10;;|oGO6S*0nB;M-KHVrig^6=<{ ztog8M^A3kf`sHQ3k6^bGZbRKez}SSE`&g;}6^tHX~oMEkKq=kado1# zU^u!7=a+OZTq$r(*=hs*KW5aq$hrr zg3>s<)i_gd;n7xx!RhT;$WMc0!V8nUKA@rT>NrilX4LqVCg(tu6hXZpgI5BsET5`s zgDRc}Y$i4T3kDYh5^RcXDpX|AOx}kQ*>t14eHSwJOe8b8$biL3Ul_SIR}|Q*nJh+< z(qoSkCa!)(n9LbojOL;pU**OK@x;-Wd&zCp4w*EN!7BiL!1M&w zp4}u~_3%6^4^zHpZR1gtPJ?(n$X<<%u@uRZ$ZZ8BeQccZI`jdV<>{0+2G1W{Tc9`*+r zm5}KQrWGhDZ)d!E#SOlphENH&(cpTK&ocOd$a8SrCi&z`z1+@feuHphiug zK$x#7n2RX+9pvkXOr;8`DgyHLL8d*Jmdp%CW-^!wphgpsSwQ6*!90zU-5~zb7?+1V zKi1KYuZ$|uID87=$1d39wXmgLC^T13ETO~t%qWN(jj#*^>=)?#1TwlKV^&0MAfq)h zWx%8}Qy-ZKm^@G%@5X9_rpIa1;R{ANV-z4oz}BR4e`K10X~IlrWV(Rq#7uK!27tK+ z6vxFs+N|Yq+HBqoyS&i|2g*2L$56QjGSk6KVoNy}83;<_vR3VYDcW-IHEe>nPC!1M3YC#r1ZDv%)=n} zC;Rr4w-uVJs`u>~qhQ5#?!MgvwOt^a`&RbpVdM^iWS^b@^EycOsWxON&1sX~KK%sP zk3cr}sqD-1$ejbpzWf`^1(57ZZN$99oVPENE2pYNkj;H5`>-5x*&x}6Rl!sSHQ_$& z$$j^MyVVukZROsxx%X`DHJf{@CwI^#IP4;uyU6CQvAIina#xhbac9`v88&x<&ETi} zU{-+AxQak)8={?L zn^^|e4?F_-1}Y?7h1b@B*~835NL~Z;Dk!ClTQ674^Spyg2=WVbe+t*XapJIe{)rB_ zB4>Gp_8pX!yfn;nOw1rlhN=I@8symP!|OQeEQ6?c*N43ouyT1dX}2X;isjNhGIFWd zlEoQ;m4@6lHP;@NIi@h6AvKr)#WqBF< zc-2((3dkGFvhZsZe8ECJmZf@fHFN_YZ!Ak>V-}F~SeAtYP|y>U#7ot=?q=dcE$`z% z!dQ0AcytZCWW5@gyFtbXWZnRCl$pNBR?4w#Ul_R>x`WlVbCOYUV!`B1I3->DlS_Vp!tLd&)Q*bht<>mA}knaG= z1$LO^{RnL`ULB-KjAakgLZ7Nh`(M+xs z5*f#`PatDIhGZt!iLzM6vRo8uuV->El9V<7IAPLb+1s2p3m0di(T?-No%R7-#8|e~ z1h{wzqU@TfDgZKeAX5)aEoL4@rZ1RYpfui5&=$~j!h)PZ6)uENhI}FwegI}Um?g~c zzQR5*yFl=OH*&PTt?JPO42IN1c(5O$lRzD(+ID1q2J<~L>ySyl0w*hwaSt-NV6s7J zTyUk$#fdpNSuR6yBgpGeVJ3n35A^D@62R z$RD6WJ!B4pIlxR6WIh1%9y2+}{0QbNP(^N*uNz9r7p1B!P#Tx~KkNn`U%r4`Mn0=i z+zIllK*n9j3;@%QnVHB;1#=UqBJpV>aMsi&aQ>tTj(i?P@iKrGQ)>k>TfuB%hEI$< z59Tl^jSucLD1H#m-_Nb7h0Ik$KoyBk<4wE{t_iF;Ly-)9`l9$vfZm{1 zM`X@|Im1j-WPS(pD=3Z20<|_CTZXm_eYhYnt`?dO$f%1<08Az`RgkF;rYb0WSWB#FJON59vI)@RR3Xg`dmir~f{Ff@HDj|1JDEu~5*4@w!@P;$jEzXV z+nD06djk&lC@1^Eyhm9txl^J_neHp#3-r6z^Wo{dlv%!vL9=;a1m2&53xP0VJ&VLM zpaS3GzTc~?;fL6A*^HFC63X)KVOQt&;qnCMQ3Vwke}hv00B&YXac%L&UCb_`ttQ#{ zfGy;eK{nAUkb%cZ>mh44*Lru$4L?G*ugg~5@!tnz6NI~*6Y!o!aOMOg;_^g+6LLBd zR4{^mgc`E8HK;qS# z-=Q{)M4Vd?>VAXI%Vz9!E~f2>BK>V)2&LW*?>{}C%iN8`5QF_ z25$rzzXG=&%tN58XI+Kw@5V(3Kso8U4QcO0tNR7_Dp#*JT@ZzwYMKpR!z~%FD$V(1 z>+rZRs@;4us%;C{e$?_5$UKG2SDsFkbCj%XE9)NWoB`|=;E#e5(~n1WqMTa|mIS34 zVIbZE^c@f`M{2W^?{PN8^HvKi&xcrVub$?5`xVT52@-F=_q>gAQEyvNhu;1M{4XH! zRwE6ixzgU+wP79vZ#6`F%aN(XRtqf8O02imEv~nIm?=YZjP389w^1(Y?f2T-0^lPc z@m3>awOt)IwzU8)0>N7i*52}(uz0HlmghsPw|lg=Enub@NW8u1c^l=T-makzW7`e* zE+Fw%BQam_v`czB2+#o_c&j1WTV6>>V!Lhb-Jn?R9wNP_yYajps^dW7VS5i3<)R)o zqYgcs0sM53c&L%M;O1$U^zbe~7lPoShG-AjR>eatu+)0j!{4-r4?uM_NIdN3)e+^Q z9)6}h+yeY&ka(z(2(71G(!-|#eG&u@HAH*J_9-4}fu;7i9^QAW8^f2O`VvSy?CaGL z<)R+Wp$=pCF7T&7;-N-jmgQ-e^zaOzr$O*gL$rr%lj5NkSn7!DVWSzYhrdGgXOMU} z*sDWxey1|U9;pI#=%G~y9VbXU)JR-7bG1Dk_o&GPGy?<=HAH*pwZny8&2Q1eJ!ag0 zw1?%Pnhz2WmwPzP;lv|9dU#ZOSPc9XAn{NmG4XV@JssD>=72T@!9xwv9&$vTb*FoT zJ-j1cT|gbq#WWhct8zFQQ9OgE4SV^WGvig3J`a`0Rg1Q++&!&a z9Oc|_<8@2yuB=a7Q$qnA<3eZA6izk7AYfTOcPscFi`yNH(L!Z~++w~iX059_RaCJJ zS&ZDFkGdAjOx@T!pK^%V`nssNChAe#!d4Ne8(uEQlKaArp&GG5?XBI{{UBsc?O z#B1?C3S<*$w?U!;14m>056+y6L=^dmi1mml65RSay#ERR>p(V<_H9U1q#DOFuY;BG zJm1+T6NDou3CnAmC#BZ3vz^yEt3bW$l{ycRS!R|y)a63klFRmPbXGArLtVbO0VAl` zWqYjb6uhYm6KyVQ#%2}v?@TNJFsMYeBfyyxkjUD0z9(7MwtK4uS*th_M~sR* zO1;mt9$P}W!EGi=Sg;4DsnnWQgp1N-ccxxpm33CAO+p~Qhn5vL+ubU685a6 z84I5RwE^-&ZiO`{i$M7oh zA5}z=c}SOYte^jH2W(zrvkD*na+b6;Hf2oj4Dg$n864nut@nOTIlQyQ%;4A`&49*l z-yBkJ;{PX*P1E+BOzvf}0m-xGE~HI%Bf&P^ovYNpV6DPAZa|`|=%zWV=ujml7}JcJ zQc0jZqEHK9tG(9vo2$&X)K5^U1G8lB>@p5l!6xBt+5LeTuW@|eXUyD+`u=WM5sUx1 zAe&$n_!*H}4$gWIi8MTE;(>C*l-k1beY#v4WT0TYQpZqaevahQV*}n}-!^skZ6TG< z_rPl(@E<=nM!}{H`)wpRTG}{AOBMi?K;F?}y@-uhg;d;<8CDJO-wI?CXh)D>jpz~V zxzS)z@&8)H7uYrg%U*#oHz4trT1qwVb6wuCfAEl1jX3|<^2nTUG8LS4c{IKAg>-cQ z|HossZ5p)iV6qYkW@>zW(T|%;&(v1kg=58evyl6)q7pN;J~)MT201e|zNOunsgb+t z!W*WV4E@W_)D}PHRE3TPuR7wCY2!Q$HaJsT2!r!MGE;j3%pOqIgRTN+YWD!jQ`aRk zwcRd=LT~PK(5p&wvE%a|^WAaL>!{^5kc>KxdOA@KI}<;SI+{?2FXNmS-i_+Z_ws*j9#_iXid!U9Y|<7xi{Ebr{?F zz}E$dw;GATvZr0r+qQtV2Ekhm(cXG9H7&3_E3w{Qdxz_7ZWgwwZ`)Ca z-VO(TC`i23NL(fGv`cz>6QC18@K!^#x84Xje~Ugu!tNpRkM?jjRA+(2!^$2m%0)f= zT6?$*_`5;kp+;g%?i^k!;WV5z3Ahbd?b)f&UsL9%>{$?&@im^zctW{|kbL8lpY)W@=hssV=UEr?rQ^diW+GNIY!r z)uB0W)`esI4eenT@IjDxsF9fUyV{-SKHHZJ?sT&4-h=m5bdGN)UI=nFwWFA zq7G+D!}*gB6SXO>loPcVTxsk?O`nE1QTyJN|Bs2ihJ7;<75VWnLU9zVvx%2o#~-NM3!irZ#x$0c-o)#|F`Fn$ z^Ytb=OY>>^9KJq~1I_BO+BOZ^UorUwi3*&mtyCi*ta(Ue6J_KqBlqDcg&euplS}6# zQ!+PVuwL)^rD0`_ax+}kY>jp@xGQm!vc{yu$HT4)+<+nZJv6*V8$mM|&5|ISY&;dWVP&N`jv+6s+p6m1mCIBdG50ctPg27B}lCsYg$ZM8% z8+XH~{k=VSJJz2-Iyn~VX9dxDK;9;-?6!Z*6wN|<5dS0sfd7X;Hfyr4M53NISmUqz zmDUvf}iqSWF@)7w>;{NR~^zgZqx z>XtK*Xjz!=>~WqMz`nr^mB-^`7vgDbEZMsPV5?`WhBHH3n~=@$I_hf^-04yV>KHXf2UrbGrH%JC%T!AMdQGwM0NlZkWqlxxKkuiL^+eSHQyrhk?u(8`l$^Y** z+6Q)=HhT7`Qjfv(^Pq$sNP-KISWh7d9YEq|R=3fEX#ejZe-0$IC&JF<+vtKlh#S2H zc~Czq_+M?59^8s%SRWcKK{ji$KS6>v${P1Qf`&-}?MBVGfIP<@c&U>d>Beqv6Pz;qh|%%8Gr@zfsdd`!$Qu^7~a z$5l>c^_049h8+Vpm#kzY;*YeXKmw#?QDipOlDEI5lNdvC+>&@&vE!}7%?%TJ@-K7b$Dk62&*sf|24=aS_Rtf zRqA(eX5va$kIOn^^oV@~&x4kOJOZ+bR)Onxp#MYGY^n9Qx-v$O*lO2@RZsl)1KC8Y zKs=U_jsj;+L?V7>qdrwAkb_}08^w2kY=Tr^_M>S3;H>RP1kME_=#ZwV@I|}uHe^&_ z%c;kNBeRu{MWD{xs7l{gdeH{*el$rIB$VTw$x%C4Q zRY>py8^fwS{(FLKBJE-%Do_QNGlzh)Za^Z6(Ha8@aOXA(7i(eEYG5li^#KYGY9adz zXROgJMUORb*65Z}(>Wz1pswQpo8M~<*5&QcuJz<1?LCH%*VA!5nua$l3ac`!(RI&v zE=^pE(=mU>nsNsbWSSd=x!MrW3&tnNT>)^DPr;~0%uaY7OCgzk35fY1lhx8Y!`T z57K98m9f=`c#m_9O8YGPpc~sZjc{QD>jKoVOGwJuePjqMcRCxIlkTF3TuM(T=&o8N43V>=J@o08`~AYF9%6%wT?zgY{Q)#ZMTUE)}sw-2~MQBNEHPpIPDK@t0&`AYJY_*Q<>0m4?KeXE} zj1${!9^knkiLF+N^HkDY6~?yHS~s>efv*md*lHb(l-Ra_vmfI`{ebTSa$>vGgGM=539*f*D~#~(u99Jb{M3CXq5+_M&P+& zFJRHwcBNIub~^CWKu&Crc+e;pjqO}2vF+Ujg@sg-*lMV$G)pfpMX@C>9+gCqbNVR{ywEpZOMZX4VHybAowASVDPyZ}VG zXaMF>i2-;Y3hz=$0-&L$(%j_(a26V8K&hun20*2J?iO73;KM@IQewG-P~zCs2;4<* zv3fY+h3|LN{3}SpR~jYZE7Jr|Nq{7L8ew`CW5ahhhcawG?SO9sa>Dmtw{oSTTr_+y zP>JEY8VbFrB;nIg(^I#h(D)l9vDHxPQl;3~rZ&X} zgCw?E$M$q$`n~5FC-!@}fR_VFY_&?9rxJU}AKv7~wmR@tK@wZ7qmdHZW{_S3v)-y7t_HpzoVxoB)}r4rliXef-NlEhX+@tl#Xu6Iz$LB}*` zOa-N;yRg`PPnQ`=b9&Rf1NRQ-&Id^VN~0tIs~}wok^pD~Zk2jl6%9ap?g|FrQQ$X% zoB(8d&?pxTzzixe0FOgqFO?(!8fq%dT|NLWK;sA~HC!?PDy5oRaM^xO1|1rK3w18` zl0nBwn0^x^@hOdx_?&_CQ;@_*BTUbtv!Tv;Vf15ee9UIpOp?s@>v-{ra?$v#p%UX$ z1`6p^lK5z-sWf-_gD(P&JdhlG8fsmt6npR$0bdg&2cOolJ)M|?uet8nngQMfBnO{X ziStxq+g;PG*dTUnU4ZWdlGth;jg;69fph?^^5D~mc#n&X?F(Dn*iHj}D#(d#6EC(= zE*jfEsKnSVgu)$ElGtjfsWf-_w)X%uR)bPoy0yd}e7X#GMqH`hH1FWs0^Q9Z2|#I- z1mI~%p9Dz&G{W>O#s=U;hLs23%fP<`astrN3qX{M2H;OBF#zvE;S`l502*p4&0RhK zXP|K!l-jLi0948Vx8Sk|A8!Ab5|}>! zyvfd$>P_=bIR~M803-n@jgkPo4(V$k34lhJp2gSzG~lja06qf#Ly!}I?Op()Tr>dV zsl))BgTgmdk^pEZ-aO)}Up@dApz#MNbx+9vsFZ_l!DUZ5GTze&+-`BPmyGukTVWY7 zNa9l(CGp9HGz60PXoTrmjEzs5IO0p9@R#OGzVa;2hNG(L-|#Q1c8LOUu+d^FVb zlrDep^@YaOAUXK7l69$4?7=q*_z@sE__U7g>BJm-MY>~~0{A459DG_O&QpnPcQqf! z2JzsV2mBn6#8&HQq{Q|D?%U_ab{FtFKu&Dm^kN(3qOtv&N{sDc zC>*4c#8yL1rMb(uy|i3oiA#+4fwYJzUrvCDoDat8YSUt2Wdl)gij+(&th!& zeql>y_-+OM7LXIZ_&fBLN4aSDsyyk2ZxIykq>{8B4Kr$oI zWAicKH-Y5X)H=4OGt%8A3_4!W1G=XGe*z@OrdEmbRP<1Sac%nyHi*aOQQ%($No=)_ zMoMfyhx8p<<*}&|@g5f&+ip*}u`SaEj)R=oW_YoUa?#k%qY|5D0Td!slGtjfsWf-_ zeyBRJVl^G`vI(h)!4J5JEDsi4l>>*!qzZ=^j zzz+gRY_*O?{y);*1I&t|+y3tEb0#u@JftBbm`IAKAVH!55HTQ0MGzy1ii!b5#e@kJ z10v@1novxbbHvwxC}6~lSuw}&x2kK`IWyzE|NA`O;n~BkuC;dU-d$B)-Cf<~VtW+1 zGh|hJ^J%3t#))9o;B zMaoI=Y+WU)JD1Zv>>-J;^JcnzG)kFIv1ans;Y`lZ}7d4G(I~9Xim$;Cw|Ds zXDEchBDwe&G>J_6_r|v;j4_C7dQE>Ee}exVNdvG?2tZED1z?g$3P8P~R1qW%fI*YUw0{pk z3mDCi@<}xV5S1P3H~eeki^`6xm0e@d5tYram0jZ|Q*>6mq((lk+@z1I+m2bqB-v?9 ze{%1jY>VPP$(1fz=-xruwdOWvEb{&<@1W!su{g4*Q@V)76*6{-jGZ;PGMX>q)OLES zg?YEpQ4J3*Zj{lhuNn8sYt;5cP50Bsfc$%_|JUh$ZC_D2m5(vG`=YaW>jmS@_T4{< z1{R@&FCu9PvCM>u-fnpuEg_bfSkY9o(xbMeZ;%@Gf8l>tUM)&GoBs3it=ugAwnM~U z0^bGgaFp6F?#!#XEe+bu`7iF=;$Pfpd#;SVBx4HNgCgofO74#jnqJe%xOa8cK2#d({Z1$!{fi9jNXqEFfCE8J!&?2K$Lrhpyk@^ z0P)i0u-0X_Q-U}9+p$Ohtjs9>xU$lz&2!j3QQN20*xvRD?aDoDb8(rElDE8ut4x>I z+?K}Wo}w*st9IO5)G1xHqhvM4;wQYZ*J~1;u}^DmOO0Jow0X|hlA?~OvC%TtUB(pT zHYnBqeTN|Hj}Nk56w0`_h4}aypX%xdD6=Pj!j7kNG@sAs~DC zAd@dv7e$3n@(~FnD-dgm0dGMv>A@ejZ@GE9&C^d4L>+{m^AI2S;{OpyR*Y;1{zQ#u zZXHGA(USA{6ATc2UavVeX|LKvVt*xiX$t?yUV0@YGsiw>Fii#*Gwb>;{{QYZ;Qa1( ze>Fc<%Ou3IzZKnNXC$6NVkXK|C1#Si4dr^|sdx^l%u~!7I0&|Jn$CgRwGfV-Z%K!d&SH&58NQ2-Z%IZ(8oxu zHxPb8*{FnjCt(<89i&9dbeM%CXxBs>n{SbcJDIWjeaexyQQ z=raQa&Ol~eTt9w-&F_%^rU>_t_ygr9C2k_oVkd^RNYe4n!f1=IZ>I60iTh=)jjNVD zgD-u6^#Z>Y5_csr7-dH!Eq}LQ;b3+kb5&gA%HI>fXfag&;V1_yq4MXW%tI=K_0ut+G zsfH-^wV_mpf7?*%RobsOuKrdm9shQK+6Y*n17N^R(A@k*ii6Z7tKhq!cZbnctf*4& zc=ZeRP4f=2QgG2Y?V(=&8Vq4ak=pAmty!KEMRzI^>&wph&)pB|$6kC1pQs@Tv?v3F;W|N6Ua-2|FF-G#MzH;Y+-vrR(V2$MyH1ZSfhZxVtmc z_Hmt6^s;pLa*ykjo5XSBJ!ALc$>fMcMag?`vQ$drm2I{R5V^8oeOBv=43t}wS5#1GVj#z;D@83_ipCA+4}|QoeE)T zQN8I=#SX5dQCe`kqF>X~urjLkW$67=eT23TXzAk9_~-Uf^aZvvKk_GxRiehPwc&c^ zMH*9c{)E$X`o8HENe6e_I*4=h;k*C^rWcYGBU_I@d}!uV++Ma#hSGW6mo56mOB%l9 zBdK8QsCAZoBrm0EUWDwJ7t#Ak-=%Fnvf_L|dJXbueuVX5&|~wWT(k>!5s;leJvWKg z;?J=@;0i`_GMXUK-SN8KsecXGtX~%IQs_aIf^G+_x1i-^+onjpj~_K&*pXTbHlr^s z=Az@48C;ij>$0)NziIt+#qe9H7Kzx_U{6OXnr&d(9nW>G_+Y=rR7+2Q#y>l|5a5F4CW?`NP+Yw#5uz z7S)#;ennh4dX+NIKd}dKiBz(ZSyM<>;HdHLjEeL<(xf|o98YVF9 zg^n6;ERCW)(UN`n6L?VvK`wrTF9GxaF-TURsBPtrIJgScbwN7xeSEcd`v0$L-((GT z-;33Len88-&B!ma3o`;TYDQ5LElzQHd@k2L`%O%*#22wyzj(vaOGNe1!D9$YV*1?MrXO{2j6Ef5xWwk?7b4d>^?*-!gesZ&wCD z$c6EYOPfY5`c_#%1s~@dTzMQ=u zlz!NtgUX%xUbARA{~wKHWt~^1Rlt<1n?|Q-n@rM+4f%(?8C)s1IzBR{MHIIfTJb(v zPsdkGBv8Y%_y5`4Ex!9C8#9VT=6s#E&rS1p$xa{N!sVxV!`(Ua*gwv!7q!^Ek^16R z1g#m;US8Ru=Ue&oB9z;OBOlAXo)H?C>d+%)$re>RXa?qNwU^k1614 z=9LtbU3l|cK3Zvov?6CieopyMo}=%KM2%Z<#aZwwfvn_@JJ#;{{ffBwmg?xhr0IP} zSG(obKcULTOHO)+x6Tee`oJhYFxh2ZL{rAs!;s!zu-tomP|{3Gv)|2zn~}+{Hmzpd zl{D(sodWP{r*`io(Qj+w=%9lS+@BL}(o8vD0sR!|)SKMNt$M&YCTXZowr3VDo4eD3 zcavz^8{FQlzZE%ild_B2@ip`jT(cmP|K#P%_~fK=_FvS4g*VMDZTc?Z@0_;hY_uFQ z*00il+pi?FCfyX2afn-!&P=iXf`a4Mq`QXf^M%)%bbq4! zpoG?@8$6nInvg_m(;2xSXg-7y%dNG%_;q$s>(tE$e<~7{YF)M+LnxZO=hkH#^CZCB z+H9ADT;$MNO>SgBcTUk|x2?jg)~I_3&O-q4nzaLfKsj ztygy(%F&2hukKipwO-wgY`GrM&#hPYWvF0hrF)vUUfsO_mwRxf7V9hyduW>9!Kl>< zO$O1pVy#E@0+i>Ff({&Z15$q2_2bv^CGK)tZNHVu$Ae$npH7YxC83tk%56nDS^d#I@#r zDBB~Q1aqxWV}TJuhhIyOcs{%eJkT%TmZ{|159|8V=q>D!yx+vubh)nMa-G&2;9vI~*W}iQo+ziK z9GcvH+IKa%kD#naT$3{(YYzo-N(oKw2e98E*5o#L;Q!L(5{+g5>Xf#jC{IgG$44Za z58#v>yHUVC90sI7_fd?K(^3W}+GeFy?tV%`u=NoR@>z=uqn_b-?XG6RS^QvGzLcyE zpxOvoIxY`b8XYX)aY@w|0-i|LAVB?*cqWO7DC3nlh{SZ1Ly(>~+?*?ln_E~&R@RGO zX6t!mpDp|oByL8zQHgs=tU$RJ;VQ4tds(`T#+#)Y(>&?J!|ghaa~Q|`xE6mFko6X% z)kwu{dAP*ks_Q33@q=vsl>Co{(ML_pRwl)4%S}0b+T?E z%;)nI1+ICb%Q=t4=O%G;_9)iJVtN4VhLq})For9P?f_T)eo}PV+u-zZm;qq=A<3pV zw9(s(g2ol0`&CbmE4L9x3pkDfKLT+JI39qqzY^i`%lo4z zu>1<%CRVmBr&Xsr9918|!T$=#CvZPPO7xK&!!u9ITMPL46|ugW^CQq75PpePZ?xDa zLGuMf)$b;)URF%qN{!=j7l{hAh@_FSK?|gJlFGOqb{hh&FVf%O+o7~k;(HQ3P`V*p zW4z_t#tt->p6m-}c8%qusujNP*^G>x(+quGzWldM)5z*BN>!6n((0wFjTw2M7Jhqr zt7XhRQKZI}EaH#53eiW8q7G`C9r*_Rjr_0nmlY^#+=mZ$sof<{^T)y6(v%$pd5*8$ ztmc0mnXEwE2DyfNcGdGMbR_;k97A6r%3ZE@5Pa)1tE2i15OfKV6*zh#8F>}g7rQ6* zb$t=fAfwIF2P?H@Yb9D9Hg&oZgRkQjXD@dRG&ZRx?8pQ4Et+^-QrVLrj_lR;53Xd# zC*{iH*JM8bUlH%LS#{JSX?e!t>S*69@swq@;w7JcWEWXIk}>mWm^*PG`XlK@)>cWi zu=Ck)0+L>2^|Fhs%jWL%G*%{mU>8~2rx#g|0bPM~dP}+PB5R;sWL-Vib;=KPOpjYO z`a*sTN~&hOMhRkQDoN!X=2ez*(#hsL{^|m>jED#>E z*MG~hPD-Od?IL8UzCiV{2l4@K0e4E8j3J8gQnC&QG!=>UX{swx79ok&F#92RZkmlG zt1|_yUw$70T7L04@XyGAmS21mc`(b6U!v`DoCur7^pM z?TYxNG0W!rVzjbq81(ZoZ#sfGJ~sYDt9re4I2cP+$EeE_*W<{KWDUeNP5f zPhqcPeVObEfR`hs`u>>V3Zs7DbfS%g)0fEp1LkHVX@Nseczg6xUdunxUiBdyEf=@~ z{QZbqE^sBvi%N7M=WUd=NP$)gd^T7!%}$SD)xa;nelD_B4g3q`4<)o}VA&*mM+&rR zpz(8>Sqdu%wglT8aVrRJhSEg|tsuAqN*|>BCGU@&Xa{rjZCg&OPUD-NX!iuNE8Lxt z5`B@)@T@WBtpz+MT79BzJkWg*en~<|EcQvzd;#u6yN!;6RtP)<%0Z$PJWC5QQZ{IT zq!aC*KxP9z7Ky(laVE;?N_D$>O{LH4`joD^hCRODYul!P5$POI}f_`7dxnJj=i@`t^g5(goUp-It|Oic=T*3~jTnliin40795XuU~&G9g1aVXunz#ry#WHrab&Fy#@ z{7d3!ZijJ7f@U1%c4RfT!_DbMw6V!=B55YTZ(x3MIL!nxTsHbM#qIGqIL!oUy+02N5H}NKHMbJ!;Gf+-dLNh_GLb(Dd`^J}R>)2{e>1emc6z;n@AoD_X*c#i+0oja3=jMRi zkAZt-QFB0^M|l=;b3lxfM5fs(L~}r1)UnYVkaghK$bja6e2KCFN#}r^9!edmJ&NP% zjbiD@{{`p|0o@!B1M*EUPe}tw1FbO!r1AhxN(fJLGzaADVBfU#c+tE3S~N*}s5u}V zAhZ+7%>h~KV--bX6^Zrb7YV01Aicr#LfjmXp(ukza&th8#1n2$x3fHRK;Do6%>fw; zelHo&9FT)irpZ9rYo6lgfMgf`I)?{xd#GXMrhz1SG;5tlPP6?{KRN0P_0zyg^nqK$ z@>;%+f?*l_q+h&^O7&S&3r!|Eh#i(8)_kUuBx^qY&6dOZ-swjuuOOWS>w6PhO0~AE z(X-Kfwl}MnG{5#Y=(EY%a|)0Bkys1ME=Rcv=_FX+)7esb#Mm6YAi9?AWhWH3>i-?| zGstQ;mGK7>&ml1ZWp|{LV8s`+Whto(km74dyo<6{i91OAf%3f)50U6`AlD^GqJ?eE z*}|aNT%EE3#ci+ol9IJ_?FjI@AO$aAz&J%g3!G1q=J8uVCV`!R(8m|!N})CbIZQh=gg(#c{vPp=FKZr9dWOYyy&9NTT>w{v1x~P(;6^H3z!< zTRZ-y*$g)7!)Bjqce?;P5zg`AC94^&ZxTp3&6$kKb}Fvlub>+fNn#wszt8$JWlFSq(ZgFm~kX#s4=gR|B6_uF%_yQ z2231KwIi$A;cCT4AlD_v zX`ReG)gY^CkURV%vAwH2)30n*tNKER(;$=vi1cy9;whFHyrbuh5M9i zc^%?8wtT_^cn%V`4YrzO45m!Iu`-H*|Gk+>O&=TV+TqS6cZ&hhwqk6byqxW!?=!TOM_ z_W-REYc+}FU_SDx#PcNDlW2{^50U7LvaJ$#lNgJ#2hvH_ioa#c98yOj#eb5xALU-8 zbQgB_yl`ChP|=->s<-}yq7NnORWMH@*~ug-{uz`5^X+Sa8zpVCtpH% zDXX{_TaF<$9Vu-xAV*DD8wKjrq6=nT$`I$6-tE6+>fz4OLzYNJXB~kHm z-yAUOfTbVCt+H>kIr|-d;*a^W8u-gd*=2s$e(aszuqhs(V^Z;Ee?EO44%r-eb70aW zuE3MxL+M?S_)jp~pmasD8%b0=y+e+bM2@v*(l#!@tx15!inS5UIVh)z^(l#p)A7g3 z$~cz0z4a`c9|m-vSof0n0_8)oZX?lC6A_J-bu2xx)I`JHLN- zimqUfGE0(@KZvip5IP#nkw}zi%>n}!1Wi%V57N-?8zE^0gZU6n6{%E<9vG=4y473% zT0kv&a4DcgNUUWLZb7+82`!B90Lp!cyFN4vrNLHOD8)X})x87o0?_Bg)jI%hqpTHI z*NMih7c}GAI{;q+{X$&51MoM>p9sHFEedgaIM@%#`K3wKi9h0ejEj|rGuTBEJq9#f z60|TFFOJK17RODk2HysW3Krn#-NCqN=3AyXZW~_?WGlcuL`aKyC@@S5j2n{jyR4WY zFb0X0Xj-*FGeNWSVFuDhku<*E8^WH58($xYGR0ZY9P7tIv8LG=EOTShpw~}W&;a{b z2(x5C1MIU<&Ttm=TF>*rf@#6=+md>R$bw$=Sq$MaN75{JgJyyj9EWt9NV>wg4Z?pA zcZKr^%0teAF85c4VoeLh-kwyhmj%7F@?QumMJiRi44R2v(lG~E^)o=l=mS9SAudKg zpnT_8n#TWGDC%vo?ns)f5KHs;v(u?1h`WYsjM5M()#Uo`0_jVUxR^Q~Qf^ZHCICAk zoCouYNJ3%ZFmT1^VzDjYZ4eiW;V47JjuIV%3%*aom(xNpu1T7HBX4yK#=#gXmb>aT z5)W$S;nhi%d;j4$0EZy%s`qh}dz8>sZ*~SPh=l#zXet}dmpLs3lxHHmh#P}%kFu>28iVhOvNPgFQDz~DWFd^ACXzp1 z1dXDmqZ}rJMpN7_@lLmc5XRaklRrlUjkPaCxd7?Z14wREbrYMeL2{$2r%64DxB<6W z&Xr-;ry60+`js8i2x}Gi*AO?t`V8e0BpqQ@gm9SF)cdLt)}L6&jj;ZJ^_w%p;iz|n zIzrB99lZq`X}K|0m$}ix&*v1*jXIoczgQdcl3R4)Ss$bO3Ju7&3?Uk*5ZNHS6$P|F zVhzGKN7)qVB#0Z4Z%=Al#2@jWe5Ie04vq@uM8*HKNbiU+2P(VpJJu7Y#y4fSVYP)j z0igzYD<>D%%kC;jfBo5pKl&AXcvOy+t;1?omQ=*ej^=40?hHfXdL$;Ij7PEwiGqt& z5q)U|K}$Fo0XpNf=feILUW zNBb*~%`%N1`~#fU`MDI#BH?uYFt~1Yv3uFmT^Vg_!!;-1pO`&*CX*A z$~Q>GR4%HFoJ0%dSG%}g_%?Z_Xa?TR!lN%LC_3a^g!oy38l17WsXfN7;`mpmtwveyaXeHET53`&`2MYWsMi)A1pffycF~YrCD-QoU0ezDMT9F7gZR}b z-JLQjiFVwwGC{MQk-xc}He9w2F1ORs*YWlLP!qVx9P>ou4R$trHyfTzR{71%ZYj#H zN1xN_k`z~VZKlXAr!(i3n+hGXj8j_nT@pR-=g-?;+o^9LR?C)EW}jiJ`<3ePiMhoT zD22FN5*M;HKAu1CvG4C76H2N+~n+@&^i|886^*cHsxEXRa#rw`KGUt_>k_&)`nx8Qc)x>huh5 zyEG%a@Ks3VV}D2wfO`tJmG@mw;U=Xp_o!}Lzdd~l_vo2Xqyvzg%OCfUObb2bJtWhC z`;J8;m-4?VOjhWq@ob)esk$T&^C$444uXu^xjK58|5cG(or)SiIXj9}my$2}N;{`|25(t-~+Zk~bE%21*nef9_R7czLe?KHEaI`$0(VuxT zRY_s1ZJ0w-KfOY*S=8~8I{=M4aEcJE3vpp6$6-fg(9X<`VdLhP{Kbp%Y?z3g6}R#R zTE~20is?qz#d~twI_}Mx6nzhsxBd#sYnT*n`v3>JPI)4_@){=XRNkqWog2z)m~>Tn zSF>TUE3fR|%iA`T_f(Q}rMx65e1{d)-dsjQS~8@8FC$4f#k2eprXE%q8J=VUZLf_z zkK*wWlJ01dY^{QCWy4L#X=wxH#%=KLq~);<{TyGLQ^x&+*;u_dvfzsALAQ#eeni(0OYanP4T) z+daBxytmQO^e~um-YyR1<+Pl)EyaZ0_z)p8_4B%Ir83j7xMpnvIauzgLG0(-wWB| z9?}>i$>Vybcdp<2M~copq%mx!4mR&0jb6kvU_rDQg=KcGzuA;5ZY&~e3NB1S;IQ_5M-2qL(n;5X=xs9c*qilIVS7 z17?F30=Y~5-kYjQ>ebowZhD90jh8lM>` zu4`a@w!RzOp9%JKgs^PwcUP|;>uO5f1vfMv&b3MM(T3 zxMxtFK&tli1g!^L22>Ad=J0oqlFT2o{RwN#;U1(+y|v=Hrqe@FriHGlBANP3!m;Yx)ZO7l`Yc49Pv+!1f&9k^TYnH-yL-#JZ-?ky=J3 zSjqEt((GdIZRxSJQp9ga` zEh7`GyZ)P3rpE{w@a<8l{oVD zW$-T{&Raurjb5AMy?qDhIs|VGV&1BixqBiVJ(nBAzWZ5a9)1aR1L8c~B6yh7d~ERW zQS-faT9)(BGBVK_sfWX6mH8MpgW42v9&R1V z$Z0tb_Y+4k>9`0RL?mZj=br9k_ z>>J9+X*mxQapd71;CDxyhlb=yU|`qu@BpCuBY0>K^Dwj^%g6*Pc8^m-zGuwaBQbLX z;=COk$}^42B==LDTxQ!|z}4|n$t#`p_@r?+SDl5*n#QMq0H-Pk9Ns^)r(zS{Gex9`5=Sd#fQN{26U4Ckxt za_>saee0n%2O+9@&Ko+F+@kvFo>Aee*81&oqIJ4mPS}->b7H9P-{r(!p6ka@ZR4C1 zGIxT9>bpV5d#Ll5ag{lGy2r@T%RDCibS1T<>MfruN0)`%sQewj-G%NmpBM{hbq-XO z_~WkIF<*z`qw>anyU69cihj zj`RV8^{-Mdmprr&Um~0SS5*|RkGs!{c+4}qJo<%dH|Y1p^|f)p*?)2S{ditUMta}d zi+duU$4&GNm(g}oAquOsmd$`?v#b?MR*c<&Y|{eE7~LMA#C3z^YnTVLJ~3wnL4Bbc^G zTufp&lwFnh2hw3E2O*`pkT4%ud_@+HkDDDR3%YnX4a_M>RQ5%O)Y1K4bQd@!nKOS+ zKfmWj;4P+w+M@=xyFOG^F_VIB@%zU&WW0CrwQRl!n+uV65sB+ju2tep68E6ot;Ads z&!9YkxQl2rl?0<{mq0XkNJ_SA#6?t?>1fzY9c=C*+Fgwru%Hf5MyF%cU5&nn6Yn7D z>;WScMb~Sm05)n&>6$&@W)1uR@*Bj>8Yn-JPEDdO2O6_DXkj0o=$e~Vz6tn_;^=DB zI3+uM96e@R2Y!t>ddy~=OwiJnO1t2ZTMu#c$ZZ4o&ye(y+j_r4^mJj@(kO*TZodNl zS%mbF+oyqHnvG7vBe$ZHxJiJxM{ZRpO%V6U%_vFqqFPKl|H!Qi`5i^jBey{)1C`Jt zx7|^8LrV3?&Da^o)+4ueik=?3?GI*Ok@VQ@NR;VH=&{?mC<~CN{73J(f9~cUyV*8g z%d5TrjPl%wWC`TOh#Qd@iqEIi#`_V;tw3*4c~lvFS=Mj`K?_%JpTyhzrXA1+W*>y| z08*fy*f@njGfrkjwuS4FSAu=f6;oQmi;(r&*}+~%VB=5XS>Lqc|1HS+7}PsR+?GW3 z9PXhaaTSS^P^Kd7kKh5nS>WCvA0A9zuXj>23|vOew?MuY=NuCMp!}u8$s{W0VhxEZ zx94$wAMZmPH1jEWr^#KiwiBq<;9EJ4ZvVV8$L@@qW?$t=){N-f9FFb;bpyXS;_d{E zN7);xde3upC#WgV^k$Dc58Z!&-3i*@LDn-=&gS8oZKO5$Z2N?4vS#!gm3jfFSrjr; zrJh0Je3S*qm>=^Drh^<^2vzD%y=CPzJ8bOC<}EO*&fzAk+<>@I@t@vW6y-EkopjvZ zR2+?p?*o4i;_9Fw`KEbbdycPz&j5W2p?5Thjf#V_mXQfoa?TE0W6r*TmDdsHY<8|4 zteoZxrm;L_&VB@bJ>r}-BzIE-yQZ^00R0ZZS%a9fx(IfW-TY*`snE%5xdS$0eoG(O z_~i2FA1pa%yL(_1<+Pl$M~I`y)`wGpIA;yXOR|Ao)7dsas}Y1=)1z)0&xy*8;ZzjIR_hvBL{Z?-v@CH8j^3M26jyccLlmLf`bMz2Nlh# zEqo(g%VW^Nl%aN!UR3CkW0&@6lRdvTE05L5UGA%!E-jAtxy5axDr>rfmlsAi`R%$o z;Fj!hN!k!+45S(BrQ)g{z8dIqV66wcc2tu2?jQNBaph<}>%5uoJ<107UDb$Q?rQFJ z@@^l#6%{%?({^-xM&F;tnGtP?;5Wd=6OMflSCb6MXZ}2U6VGY%P}v@B{DC?I_(6y} zfg3QXL(vKRht_a(0zVP_@#5$NZk$Zen)qUL0`Dk}PT=Q(KSvy$z>Sj)nzcxsz<;QQ zqZ9bm;Flul34AZV7hK4NXrv{D6ZqYLmx+*`zz+xv)9TEbc^34Oh&zG5i}E(&PT)pK zqAjW0;RL>s{I5mO3B1WXCgUUS1l|#)J>pK_#?CmlPT(IZ5;}oz17>THbOPTMWvCK5 zflo&{4B^?I_dNduZrk`QVeS356ZlDxPe5D?GE`C*?>o=)fu5`KqNqg8*%;ZNwMqjV zQDa=Qz6SJFNP$|K!3%%(t(n6efkZg zFA#TqT6PMLBM^6e+6AQ}QlKk9vylYNtm#_ST@4NgJ6L304IYRxSqWVYo`Nz*30)0d zkFpeTSA%9Y6U=%a-Syb8cKKI>hRxQ&*18%rU|}7gF7i&qsJj|`8YiAa(yKuu6-PU$ zX#i~3KL2WP4aheTcQv>Xxkt^2KU{5l-B5s!6bN*;&qlt2#E5RwapI!-q87?E~m7oW5CFr#fajpcHi=->T z2@u91?n>|ol<7+7O7LWqIf%a!^hUT6tZj}f!9=x8SArKpxIh+kC3qdmHA?78a5>6d zNL2QgH(*zSx<~0|fSF~k1Z$U3^GeX?awS*`mwzQ#dJ{9dtSsK?B3v|xNw0R~|JTWS z0cW0)ch8Xc7G;AH50Geb8fPKIT^N{!B-pYzR=%0kZzyZJFxVP=PsCjq7$;MQ6D|w} zfgOmj>+*A{KcnZgF20z`*OS7mymEf-0cAJD?ZFW!hat&V%v>-Fe96Px>R=Y$Pue{p zKkGBDKO6j+GLRv$809h~`!fd09`(FmR_X-KsNmWI?KaWw?l$7scze3{XFaU_F&gZ- zN4E8Y_oms|T3t}4Gi7UB^&g758F8m;L$dywXSehIssp}e6F53uKMejsanuPLlI7Pt zr;%~!gjaQfqto?&!LJlYr)xv9{F>+Fcf{9-qmK9k@b4jMN8BXrkZHc0Tu1x^;O|68 zPuCp+!?Zfr+lBLS32~?EYLu3UJ6#(kiRP+N+x7NVDo|9UA#YCzXJ4Sl}9(M({+I#E%FMi8YZ`8Zm?>y9@zVc8-ACE0kmm(w`Hm>5J$uB z@4$b9IByKeWJ}Ku9PiCPK>tGMjSOPL@9?~A=TP$XY1c7x825!;MXorV2}g+YaQA@A zX=${m$W=YXk%!gbTO!UwLvrUNusz3nxCPM75Ii)9d8q!f%x)vS!6iWM;y_OaMkmD+ z`2gq&oIZS0Ze|}4#T(-C-ysdc-gd~-$?#7LBCS|+E~&$jZ{l`b6nsz}q3!=+eWxX( z9_O;AI&CdU&{8)UyKjgalw&{E>O*bL;Cc%w*zcSiCsT)$S&^xqJr+oII)7+6S_jFB zCWa;7Q$Gniu^`Mtg%!#lr5FeSgJqD4oYY&wHwN=h#MTV z$G~Bm`@zA1Y@LF*!9hLmW;PnALKqy(+YC3=zs&-36cUx{zODgFqR|3!27gOHoxx87 zbPD3m;1{7RR6=L)>rk#iI!%L9{0>|0CbbOlLk_dbT`KR0RhA4xj=gc&4LRP0@iyXy z9N(jStAvIe@mbs%AmL7;W}~RCHJ*96yKD8qS0J>9`o2UPRJdlWcLy!-Wzq54RR$6b zICQzY|83w`BW}Fc6=e&=jrWX6JFmSv`QyDE!1obHcmEAp5i|=yjq%>D;CDv&x#6+V zit5nh@PTqTJS;J6aUE=};jsZr>i}i+3RPfD-5ZY|`^XnJ2D7N=>WJ-tNV&W5hD+)k zof=~>J(9c4H&|X8;|RnwxIcRE|J!68M!5$erSCq$D19Z}uyGI}^h-4T5UKi0_?H=FT`5Ps8a z2Sj>Oo`l(qhTuCsp_fh3xucq##!GCL%{L5d0W;a8(J%7kLSWzE#aHsALhm;kv@lw& z16Pn#x_29+vzZMF$i3TGpF{;xs<#!5P!xS40wbqMsu6l)vptx$hqh@$3;JYe4Jjpx-qgSydsLCkwQ~1T%9Ogz+DZ*)rl4;%@E%T%&VM# zwlfOj^C~Q~0>dU@UksaT1qEsa2FwP{fNBM<1#F57ot+y|=^k9g*?Efh_HmtpNc z^Z%h_^#isI5>F;^2+CxnlVHWiv1JLV^APt^pP5Ob;}wCCnTF5w#EhciFgU*f-N`iK5IQnWop9*GGY$iKMS^4+>#eDYuWwl&=#|uW+9R z=w!sb!o3t_v16%b4i81WC)Tl<%KG@{YUcxh?h#90(OQeLS}gZ^{a&Fg)50|>p99@p z7F6z!5PpyaEn${97X{(=45{& zriCEQ%`|c4cL&^6Y?a?1We2gNQZ3Q9He4rurybuv)9~kB6sl$Vb_2DmX!&hBR$C+=_lAQt7|p;%je_Vr{n&H^{33} z({bhJG1CYkM0#BOM~HBhD3dew+iXLKG;yaDs1`!H9@K!DXbTT~PeApcn*-VuaXn~X zlXSrLGus8sPDpxEHS5`E9|7q+mkX$q>Nr4S5m!YIMLAe3cTzR; zndsoueBQc!$Adaf$f#mI$6>!v7iSB4YNkBCh|TALI0tb<0mCGb!z{}-b-Q;Z`Bxxr z_ijhI6-m^vjF1Uh{)Y=@sSnj2JPiIp8BilziSiSZv$E@p!-yv z0ohegu?y0gV~Hy>upbQx)1g{q+bztAIy*phCSOjx({~C zc5rkbtmJ&=AS13rGh`-k^5>nry)7J_37Ua#Dvr(s#>oaP^bnjCZV^YJ=nTFSl6J{6 z!w#92?yZ}wl0J~w2JqG*r1!y&2@KQf+y@&1dJy97gYAhj266YnjFLoG>JZs|umj1T zEQ0QX%|n^1gzke~fN~zXSr*XD`-5WS+9zwoBIcWnIe*A6kdXIffBmX zegtI&;yNa?z%6cB;OhDTSy0Ec8q6vrDtqYvG^3DOpr=TSLoG0^jSpP7^YJlOKSbP} zk6%zWDxo_cjTW-h0^;s`v`1-+xRJOSOF{wRaBy*YZlC;-xM3Ndgb=6bS|f4GE~o?4 z74MT6btCZ}IMEGBN8&~*iat}w08ZLj0+K#OG9$&oTcL+`+Kiqz*1O%I9cn z&~9ZhF`RJGNW0uHi2pTcFTap}8F7R5?kJlfodk1(_Q|C7LfnYi%p_4)MV&$W@%=EP zuKETr*9oVt+HjeupKx@~!-Z4#d_S0bk+ge$*6$#n0I$8PHe!AO@N*)hE*Opp4>HZ5 z{V#LjZBT0w=Yrv~(IoG}OXk8CU_O^cH)uCt;s5NyZ-9RhAsw_&$KaU*{Gh$;BIZUT zZqU9t%BF}r$E^3@6KN2JPnysKN6{KszID@Olu+ z6vxuoVq+-kLa`XMKO>gL6K4WCO)QNkZb7+0EH`M+wz0Zvnx!)g+KbpjSMG}to|gp; zn%APdUg9m}v|xcj`%bc;LHp+rK9vOx+J8a$Nfz9o{fIE6G_B5{z3^i0LL;vH zCMb;%!lfa1Yu~3w(e>JK2JN>Fq)-joHv!dNG!3(NMCqr5hS}p#_CnmCy<@OonvCnG zLHluL?FjJGWkA;Eq0Ci6)-FIf4{?Kbv%y?=Z#P)8LHku;uM}B>_GKt{D4{|7V8_Z7wF%@xxdBcz| zj1A_GA^&K^?e^&?ry*`IZ-h)_TJVKY;g0HCwKt2vUnB!+d^ez6hoph43T`z~kp%8g zu@ty_0NpL1+ie48qMWAcNd>L3+fTuGLM;8B55#x7Rr1jG?>30 zUrgUk>>$#0};RmDI)i!TggzA6I!)8O`D_MnTZ}`yzO% z*nQ_=?0{yTyaweJ#LehfkMh0}n&a_3%D0G{d1BW108uS}HS^@0p;*(*lgy=%5%4f_0y${qsui0zSOsG$WV@(t4$ABO0IGRvDAlC+9&c_!{V^V-OgEWa6Y6av6GMDNW4jO{l*ubU3CBPJ_XhqvOmQyAeT6s6U5roQ=2%^@ikeyl1!e9HvL#Fw!5W zD}Y~)xWSA8dG1+@qQT4{aWt5@9sI50XfR_)o_~6d4vBu6P(Nz~91Uh31OJFP8q657 zAZXSib?G}u91Uh(1OEz=4rcBNF)%GHCT}qF5#aSAq=T6ifni#m3H3jL-iWxtOu=Hh z0K^SujFLnr=MQF@livh!gPE;SdMcs8%pjD3h#SlpJLA|I%xtCTX)v=Vm@y)0Fmo`< zR3$W+ISu6$Br1Q=d!9d-v2Af=TG)RZ%v=O{A>vw)p?IawTMKyKdENl@I+f=q)Eh1v z7&fWXCe+^#`d-A<7K0ZAc(~<9ZJDV`soL@^_@~8DZ7~k(gnOsL_>$Uk-6&sMR)b$9 zj%te`i-MLv^qnb=YRkvqKSa{n@=7@NriHz?8zmb7e=kB>Th;`IX?1E#as_C_)s{vm z4G>pbjFLnbf(KExdrG=Dvw{O-tw{D zDvqvZpVbi!XX2gfh#mlUAL7muhD)M{!BLf#js~Uy!b?D&LEKs5!_d#?wA5vJe5N=$ zOMC_X3&eSCNG`Af+jG3ve*^s!;VfYgf0oEBynyqBdy~X+GQo_^q_&D*e+dT~ah`q= z$})|Qin*UW?WrKh(>CC%5$CBPnd0Kvf#W^x3UmtuPYq({GhWYP>qUN=#ma8!C(P0@ zS@HIo09x`72c$$v&A0NdPPs^WSWbJ_QK1ke;#0ZpKkP5XhBV`;Z^OFBg z*aY&&A(+;ytl#;Hl#SNtc>f)DT(LL*Yver>)WL`wd0&gNSP6~1SE0OwxRJM6;B8eb zB(K*SJ_Z9CdH)UMPjU1rYsHn^(?Q(GyERHHBprFT_AmExx5R7K7clZZQPwo_-V*%g zj-$cq!zXLzX%yu&JKHc=-EjBRFdib5?D~bwiesi5jkPgVm0Ec?X|@`2^w|EDJ^C zw48&L;>f|*!M}<)2Mx)G?*iL%yo2k3zK`IbLCirHO5PLEEum`f3H$?g}60^ zbVuA3;;tyekuewK8BAZfRvR9t zw@|AZdnYt#J~l9-s$Kndjp5Jt+Zn@`S#ULm&kIw{7h*N?cAef>zb||hnOYNXj60sm zELPX)O(6vPDJHtzFc0MKe~g#kdw|-X7;}9o*$X zH7bT}WX?^U#yz@JK~Tl0q@Z%dRgBgst&lO+<;q}Q#h9H}F}h$u+38tKmt+_CTvd#r zb#jmMPUvt>^0_*k7Lxzx;VeJT-+Fi7HL|x+^!=jSy*ZpH@8pXSC~ExBxG2)B<>V9o z?7i=vJ))<$y^GS*Deg1QyKX|bJ80VTXEF6ST&uAA(nHf-CX%z!ri(ABnq?xCZ4aCEAm?3*}BFnv!@NjUUCvZ*cxRr{ryN<2Wqlslxd@%^gPXGg z>zOvHTk#}~Z(yeX;C-?D8d*y~orlEFlXxFx6;k>}-yA84J{0Nlr1Rx+XCql{u4g2U z#GjGa3Z(}URm>x`i7$%ra?0uz-@xYK0Cp7PG7>XUrYdnhiHA_`L`v6Qj;+A%{1jz= z8n=ulQRZi4#W(O~3phpWIXfkT?Nl22$FZ0q|burUB$*5h6uNmkU(HmSja0vO4Y@1I!X&V_fVkzJ!6t z%woxnm`1ki3qi2r9Z>pf3sSr@iGxrkD6tobn^CS+;s6rsP~JecJA%YQk!PZGx`|if z5dA6?moCB4yXD8HahF^i_69g61(!ZLo0)GR5>E;{Fw^GTDMVs5S@VI-LgJMqzCn2p zDZP{{Eh8n-A0qvlbbo9=NOzFc<7VdfAQfx!a4cB_uDnN_jW@7)0Qvopo~4`@%vLtV zeBUK*#@10}j}T-Hm-PlINFjF=#ow}Z64?`wia}hr8>G-d8n!K{j7PKiaPkjDlKw+- zn4*AoA>&WO=5h5R?ZF6OCxSm7DR_NAj#FHh^J`oge*k0w*s~CVUq7#uQdXNwoaMMR zn-_z)%%N0hk{`vgI<^(j5tDsHZ-I3aQji}}Zt8~0FN5^;7TpKIK7f?uN4KIb-beZ+ zpf3oXAL+`va3A$|fUZLd@}pkA4m=!zufcwa)HnhS>f$*9RoY`6fxp53sWS49K*PEm zI|7xrFkC{o=ahd08rNk|iaQ!@LAQ1cg|75{y1k1-LukiwOMXeZwN*p-nymgHyCJS` zGh8OxSGYw)VR{!&Dt5)VIwbu`lBKwyS(8NpzXm^lk5GuhqA`0OmO) z?b~h%hu5_HzOCs2`F-2lu-1y{`nKg^M{Z7wDEkq#>xupX^flu8w$Zn8YZY;QTieiO zyekrY+hHmq*SGx=0KW)eecQblxCL<*zeo8DaebR$u5asg8v`xG^=*ftOj1I9+dU|E zD51XXQhb`!)2jy}{J%+eQN%m4ZuOp2Mx~5Q$;J{*p8s zKZTvj&;`XmlRp*g0Z9BciDOY_iCl0khy0rm{+#BVP;b{YUIye$z^984m0ktE{#kZ< z9jC$=QZzY?us=)I9iT2lT!-5!;I0K%-Zk60>JV`1aGT%3Bsj!%xJRQ*MqK3_;7Qzg zO!uVQBL_lK<$Mv$gNUn~Lxb_o&*Fqt&bD`A2XU429F!B4Q006FWhLS&=Wd>zL{r74 za?YMgDXN^?EMs~yl2*=fp%~NhE9Y`Zxf9M1ScAlLm2*niky&XGWec?BCc|N5RUnsB2hU@AmvrgV?*V9S^%q@ZSLX`J>o2mM;VQ{$|;zuoL8`A5#lQ6 zvnUTJp~~6tZU)(itDJ*T`XR1zej>6?yyvrJKBAwioR0@bv(LEz=AC$-0Qgu6cIQy5 z2R!f;mL5NI5RuS1bTzP5h&zWGE^)Zf%YRJ%hlo3e8YYuse9yj-?C%9p&u)-x3h}*p zvK;RbcMdg3frEq|yaD-@i0i=(!>A+F0k{9|Ot*F#d!Qb?E%?@m>%k3KRF`8tcsHCT~stXIdjBD(NkAJGx8c0t@Z)Hr2zI3c=|z)nEi zIn?k>+^DtB-+LYz2#bvtB{J319G^66n9lp9Zz8MU*!MdELN!dHfww#OV;SVb6t1!J&bt~*L8P8 z*%F~nEN2$=eW8yrO%CcuZ#yJXue=J_02uvb;zbgpP(~mHg{S5WB*9cl$3Q=Zux)`H z0CsHhK9_9M{12 z7T`A_uKF0IpbjNepGUwxgt+Qs_`hlTMj}Tvd zj8RgTVb$k1(7!lFRB}b$QL9&nQogKLd<%&3dwCBG(XXtDKgeNO=;74C515D*g*JMK zY7N)=rykBu{X$kd$Ze4L8xq}7x*`?Lc}K)Zyf6x>d^)Sib!YRAo^UE6*P!XV)G5;Unj!RBXXa{EBkTSLnBRd^=w6@UDjcr-mAK5^+k1ih=Y-Ln zL&H?27`vbMHu-B2ex)aIN_{T)v{*%s$#fZVBt>3K)^EVRMB)V`2Cm={HB#DY3ts3A z0lG`1+miYdXF}SHtOLPJL86MU`WHs~otIwEB+(NB-kY?FGn}L60hoovzk_)Q<$h#H zeR9?STZgUUrX<#~bv06;8)p|RwEJSF*|dpdUfd$qMP{Q1nfHN2(e5hz5MOw2e{7Ot zxR<8lJArA3WL12Bd(!bgK`z(8j8`l8Rkuy0X39Z4P`mlyF^xlc^>6i#5EYBaEGim zd1JF!4Q3tCHR7t_e2en6xN11Y;LcfXu5UQ;L)7tBZ+Iz9+(M~V?8DLJ}H@SA{@2n1HkW(r0v>s4C&hSdE_1`tFB#pL^fFUMtKh{ zZaMvEtg3DQ0sc26N=_x!z>}gpEv1!T99Lc^(n4Tm57W|+s6e4L5|3LveY)-P#c_jN zoT_28L|kkQnyE|5kL?!VH$z-(jgt+W{jHz_l75PlV%rD!c8H6uQ3?X3ho>mEk00k_ zyEFLVh>NXp4C!J!mE3(~Rk1ZhVbHu$7uy$S`PeQ3e-V<#wnd0-PD^Qu?LQ(Zwl_k! zUL+S=gYuS$r+2Ykt`Xb&Vcd(j*cz1AL~4`rWBV-lrx6!hL-Lx4=h!r(@&l4<6(_}Z zHSkr4i>(0*0>!4}DYjQ1>tp*d_zw{mTjLng#r79+H_EDFYY0B=5d!AJM7`ZaR#k5+ zAK`u|lE$_}fabJZY{!eF*tUhxS|k@+gC>z_)!y=n#^D%;U-&;&v~pmkH4lVYw@___EP zf(s3gWdRxY3-MWi>9Y_QpV}xFpQYqphPe0`A_*3~K^LE4vweIX0>1)DhAJ6iM-U5yJB#x%e0~38a5-d~0F6g}BCNq)c5>e&hQb{HKU(e8$NJPF~|{V;$Qs zz<)wq<14cfU}%Cd1ti zaRI1}asil0?hM2Qzz|8W=ncBcb-lu>#&gK&{2xdfzB2?9w)vd0*7AZhpv$_wJ2 zKHVRwnw@t`7|jvaHVvAoOUiGXn}P3wxVCAWY~bV#I+ojjZad(;5!W`2QV=LMlu%rI z&0~kuHiv^Bin!Ps$B-_z2avnBtm?#Q2%gG>faPM_e~ypsMc@}AX>1n;Xim$;_Gpn* zHLr(otw^qF8Z?Pa`}cnDUKq;}7h8j7>XPzf`!x6`5f@wIWCJI!->XubH0W3b{58bI z)+hymV!fGS+vH>)+YiBifVkKi$B-_zKau;rtSYvKV8%fRST43#%=NJ?e;kWQ8r#JI zn$vQzeN`mIwl#!SBDvTal<$&w`oA~(ZZNh)%CGXU{C>~2#gS>4cfZhZ`@!vtxB%2f zxd4nHcNfG3zz|8W=ncAlZ;8UHhC2cLI3x|gO(6g|Ev2d7drc$-;7|w$i{t`e&?GYL z-ve+wjN_2<+iC`Y&w2O_|Jv`lL5CsuK8DBE8FZY5=`#=)pV}xFpC#m8g1Gn?A_*4r z|ma#}7v-;1R9JP+Ynkz9NX$~_5B|M$lC7L3)1YkUUH)FtIN zzE8n_jJU>UoNVCaHNK0jWBUpCM#MEfqZ9;+H7V7*3r}T-)Ujos0FSuX8pn_>wpHXd z5=xEF5QRa@k8LwqRcyO~-x5h<`(lV~PRqr1gh-0*00{j=a(w0?|z~2?FV-f;sQ_`S@*Q{=A~*fHJBHB3%xX*a9JW?Fu5DLbZ{Rkz~aEr`2W^(e~2h`U*32AHbp zi!%e^X4T7JUlLh2t3E(^4{=PxNobMEe%yUBZZ>Eo{y>&L zR`m6J9N$&5sU(UAv)- zL|lK+($k~Jw2T?@cf0ljItj`4ppw+!#C19OeaI1zrX#KoG3!a-{A_!CK=QZ_l}_L% z1D}JqKEx=jrRAMG!Bf?nU~pSrl_XUGpN!V!|w9SjB*0U3FbChc%(A=$f;O z5#yS3*3bR#^K?DcJ>mN2x{elI=Tvv!)78_{Z%wtab!)jbRAjp^{=Jd0^-LvZ_VyKx zOP3KRu{{d=5y;qjq#7eDg^1YRbVgu%GX4{hvGt5QjqMC-&sVEr>kg(lh`<6SF6!@| z64*Y6{~46A9Tu&5DTHAAxk6(54uQ87GPZ8zSyUlD)OWdo?KdR8LdMpuJc6n@RAgIv zg!{x~jIBE>F~jo=?8V)#bHzz)dlKnH#?~X%80irrVtY1YkfW;7J-Egf$e;1Rmbhd_(!9R?JCilmqG}(8!05VI}_MZA!F-SroRaB_Md$R zkvIU=M+RH*v(K0DtG7_=AM5e6Zvxq4kpXCS8GzHNoq`O2J9wOJ+^ZZwAH5X6QIJrFgf?9i_xe zK0`|6Gn=L#LB^-qWqjsP`yw(v?%;_ zKBJ6}Thqi#?K|ImB<4ld`P|A#(Xh@KDt5lb@Gpw2^SQGUGlkAq_Y>QS*q2Av`8-mM z5${ssI?vhckUlil#=j;qww`gPvE7E+E!3(ypF28YDTBmV06O2)vjW?L@E?FOw);o6 zc`0W*TOqNXNMM3OcI>&8M~sAc`(y8H5@(|N_+Tq`K3~S4ghOph=evyTbYuXUT?XJr zYHvUWz#VC9u?XNiVO8h57ymsd18{T%ke6}*k0~SoPY`%qAp_vnH1Se<0CPyZit5KT z0$`Swu%K<{OKKN3RcAjHD)voxFuiH;7B4*P`1y!6e~1iUv&-;RXLAo0hv9Qa8e1&l zdtOJf@NGb5J(S_QBCMQW+Qm|iujAZ+Z(9OeD`fcG%GdJ{YJbtO7l}QQ^-Z^yTSLXZ zc{u*Vko8T^RAOfDuupt2Ug;Nfld(@i);B#;jS;_;P~Tkae0E5Eb1MFGkg@fQJF`QR z+8Jt9ebXHsu~cL`Y-(Wp2L9Jj#`d~MG%w|B_f$xS=H~=HRmj-7HBGz}Phkxg9lw+K z4H;XvmRmzbw)Mx@VPtGQQ;C_vd9Nx?y6EVSeIaCQJyMMkKbwhdd0Jq*H2$TKvGt5Q zjqNCES5vEE>kfW-6M+RxocB&UFRi8J}jC@%ez-w~_I22T!$#JDndOH|S6mpY(BdQ?juGuSIKK%K5ylkofc>&_f~P z<5q^%gn0YTH;}{tWS!5g%%9mDDt5l*@DD@Q`P^BFnL_8A>?gKS*heDkd>*OBh<7P< zzDXCdLprf-ihm3;ww`gPu^mh8E^1Ys&mH{IEdtBgcBoacJqG_#C}aD6wC1Ip?dl4N z?P&x~Rmj-7HBG$K{@A;O#9vVT$YQ0A2J}2*6|bA4M5}Z=y9XDcddfdu+M7|6kZK9c16JdEX#o>=}0&Ph?rtc0)#LbYa5=R9jk$8?X+o ztd(s*cis2zU zKUx9Z-#e4S>1aib-t<741;RbO%c;Ipe%;f%g~CiUNCVLB3|qxaC0fCQUB+vpG-C5n zEDtH8foE?}cnvKsm)(#1f`5I6?2PrVxNlx!+8ulO=(FFk{)Q?ma2PjaN=Zwmc$VvY zg5U5UJIlE$|XwB@?Q7=XP$viIF1qp!{ysYBtAsO)~)5%P?7DA_`gTS)-#ou8Rsh+m)<8%V%zZ~?;$d_9;wDi z@soMf6@hIZ{JoK}^^7}>?ef$PR;yy`j*eI=vK@VCU^^E7ZYX2>N@Sata<&r{65GQF z9HNl1b!(b*FgTpY3RR8)ST%UB+jBYR4ht^NT{_a{+;A3K<`_raa6ii?{E5*O0ghS?6G2&fHT&G{j4(Y1pdHl~JW9u1r8r%1&ovT*W z`P|VFOGUPes#UT54gW7FW7{*b%}Y7k?GzH*`qOL%%GkPn(K zz{?65KDY9>gb;6k(eWXP_mTBYx0YK&#lHDH{%?`>P0v(frf|`*f?v>8o`Ha*ZxkM> z#*$x3i0f^CV~5l?d*kngjIC$fX>6CJc92?C-*iVuEEU<_e@$S!8~$BT#&+|_HZSFD zzfnkR4xBGk?lG7&qBu5GnJSrocAseCtY-0j{Q<( zY&}wq5kH%W?X+tH+kfEyJ2JMOai_7JMeTiRRczhS5lcn33#wIh`~Tp71!Zh^h-~vx z&UQ0}#P(wX|5eD?x|QLrA>O{*|3cy?RNpn&iswCFR!Y1?^Y)4zx7)MK@_-CLv&#T1 zK<)g<0Jwu^P{q9p`@%)XLV7C%U8x6_ARxl z&gYJfSSqr;@cO{^7yLh=jO}TWZC=XRKB|D-jqq=XG5{Aw0C_2k z>7wH)g#=&+0^2EM2bWvoKU0Bez^Ch)AnyMQvI+EJMP1Oze z)TDHKjYdfC`DUjq+V4C@-;W7oDV_uKgau;_l) zMPx2Oc0cPz3O67dyXLX9rGa>F>t4L~D6D&1&rx^=+1ND?ms`W(KG)k=-&9ujxxSdb^`H8IY#~zBI-Mj-a$qu zkUjB_Mb>{j<4)^8XHk2YTGa`}9hF!LjavVC^&hmV{__j|pHS9+UXPUWQWjJHsog}# zP9QHp6=nU$t!d(=_E(+#Ni3wKex2#oaxBGAk?qp>mqNzYGnJSrTy_3UoWyoD?5iSU z>yc`V__d_iE_G{QyAl2kk+JoRJB{sL)b5~G#nv4iu~cNc(#*j2eEjF3jP3i8ZC=XR z?x&F0{*}Ph3fZ~It=#tr@ukA58ov?VN#b^7Y~5OJ4HelwivM58*m|ZCGyQ!<5O>_8YY-w(jVNr6SvNZVqfaU*!HW z%GiD$+2*C3?IQ|_?IHvgR>;`8HBG$K{=C0DiDgm!o3NJR2cIuvBI{7=yB0tA)+DJGj*mye(Iqr_=NlWPF-k#^*9>FG9x0 z9sJoNv{*bqZq}hHKL5mjH_G_*iPpT7^Z7s_@%cA_#}qO?Zsop5h_~;2{~_@Tvd-t$ za%-sA`TmRl17w}gGnJSrbiOHmV*3I6cgQ-QN2)PWJnl}pogLDLM)f7e(jjB(8Fw1n z1*n}58C!RB#8!)JYid<&m&d;>%GeHwZ1Ymic5Q{kc5MP{Dr9Wk%AW#5y#2Aa6^SiS zeX(FGc0OOmfb~%8yB0g&9%Oe%2B6tx01l;gJTd_8;K$c-ufo32`RaNr1mFbx6Hx|W znP|;RIe>K(5`eP_oT-ojaBG@)sXc(pNK8ld6&e8~wNYU~+s>EN#xzwo{1w>xraQQG z7rZUEx^866Hz32;>@s|hQF{+EeC|kNi^bz-lRE>x-|+u}GJM;Fl_yDF%JKbKA>o_n zWqKIO@VPaOp?Lk!aI1775(_A)iw+N!V=0D;eRC=NOCal;o~gu4;i99zU(l_JePv{Q z(<9Xw@kT7W9ykp%oNUhlf+3E z9WP*i4jEgIRAZ#r<&VE7uzd&r+sN2@#+}CYJ8HjDt77Ypj#w(Pt*BLX``Rn~))!@L z_la!tQqFdSLSnlxfqn`ZTeqf(m)dvxWl1c9>Ia6k6wiCUj2|(ETHm#J-dlt0>c{{z zy9~f4)NYInfIHIIVi7=9Z-oHtjDJUz0XQN8$V)kZ)f5td0|@M=kO6ROns})_fMZD< zjq1lX0!V77gavKSdv;=T2Y>Ji-j<7wDKvcwGCs{N<1?Mw3y|?~M;co!@>%@ez~^rK zccP5X*^y6P%K7Z1koY`C;8BH)k6XF#5#sGT-zy|uLe}}*T5b&$JKqQR-$T~=KWo$2sZ1Ymi_D+Swc1;3nC}eEinkHUqf9!2RVlz~~G_0lA`Ft6VT?nZe5*MTT4UGVj+FfBm+s?;xpqi>1E;^Fh^G(%_cfyjsX_)(2Q%fGsXR9V} zVX%DPL#JiisfVSUo-Hq}mGqq)7B7ZU-sCJFIn)Z7TU8n`e)DHsLf&A9$ICm)p$zB!0ag< z%dlW5vPWlZ6*h`_<6ytGewp&e&2-(P$nhda3Q)#Pn{AjfX8J}-q<=Pxh#Ag$V@ zeWTclk;op%;Z9~Bis>v9AIPyO-Z6;z`}F9A)1q%ne)5<0FZchA$-QkR@UggdLN*il zSrjHBn+g2N7&<~Brm4U8VM3Y-{CPZ2BAW@^eJK;$~4gS81Z1(T{DeQr4_V0xi z*6iO8v*bRcm(Bh?Hg4z$ZAZgnH$KGpZf3UGzx}=EZwK-+S9R$TNND!&jyJjei){99 z_oe2G^HcYszBjVjzui;LJYi1i!Bh{DMH36VrIJ~~Jk%>uy#lh?zui(bOPoA-9qQLY z-SuPz_jF5kVXHMS_a*;gt2H(0mUuQtNmY;9aAQX-87BT?lX+`))UlX%LpDpQ`@6LI zeS+#k@E)ucWG|cj+hg;z#6+``=0yARPZ&3xTYus!*l z-5qanU?ZEedjSgbqr@J!@JmFSm$HrIjm#dmuoUJc6iB*XKdF>-Zku)bS~6KHTeRHs zHKye+y+GBfxK>7`NBPGl6gEbk3-Xs45Amm9LiOd!Jxa^7cxUQ&RA34IaR`Nj75F35 z{d%A?3v{IOlul#u@zfuuz$E^09))w!iiZ_8t49`iucLG>ORuE*3i(gsA9ql=4K1#1 z=z1wjX7jIyk-cmRb6+oKmav~$C6`@%3jXVH_EgggVX(RqIe6I28YQtwVjlGdu^iX_sOjI0^4$ z6#9Vsy0#{~5Bvr9g_g*sW%dY<{%Kl?Phox|?i;d1VsrQoipKMF7%x#?qT3T}zvl3L z3f}|B=J1_wE=MG?Ieb?RA)fiI5Oer0`foy-!*>LpRZupE?~L$?#6yB*^f`RD!7v)x z9KKU1oP=x+-{-MiPFpsI?=>u)fou-n(L4Kxte3KXb42sf=7=?9`IGe(m3hN}{5oR@P4*Ln?GQ86j z)(PVl3NukRoiIGY^oGshaPpXi^#Nsd@_32D3&_qJ?@@RM83zq-+ahxC(m@rgP10q{ z)rA%;XJ3uKA@dcoZ-&iI`(}9JyX+gXZ-(wjWBXZ~*$A6UMOWVpk9nT~i75MKxMSFq zB*{xzOn=0EULpHtNZ@pZ?3RDT|5iu%`pt9SCfvkg;_u_xwV9K-m69 zw)>OV7a3c(mRmzbw#VW>8W~&9RAQ!=uV`HQ7jY8X)3Be4jIBqiG1AS4hQM~kxqDpcQCVg1QsyyXOwN832dMLh=JHBV|zrj=B1qNX$tAMeV4#o zg^aCRxt$o|zlOK5k?pr6zDCB@t>xBGk!|^7x;`?to~gvl7rvr#>3rfOw!N|ULdMo3 z)fg#GWO@0kf$d`W7e&U_Gww9Dn^C)>S`}M&bi`8F4jb5U^Rt2Nz4-4z8QY1GZC=XR zexQ)pK1JXOg^aCR)5J^TeU}^l#_}eK*O9SxYq>R4WcwNZPmrIdTv2|;?HB@AK3jULjvGq(PW(p%3-+wW% zy#V_(WNbZBjgjIV&Uar3Y_Gw86*9J-ai_7pi`v`Ns*YQCbi`7T?S5)ipJmVDe;Q?M z&xvgFQqJ}=g~WC)fwvSgwr))mFZl&i<2m7L5?`YF`C%=^+q}N4lz55e?G zw{k-{#M=WHNn$lrzp@cPQoAWE@Y}qtGibYmXY2*<^4WGJkK-Uu0=W|#5VjoKZM z@o`5QTMP}_iS0CXY4MqW|5%jqxihRhN%B(8=K+Pp=X3&76f!<;rJ8;sy`CeQtW)btdw|(=Is>^u0do6A_LIuG5{-3yBsnA?nq;cp+P&iKGeSG z;93j+D3k$sDgww$Sxi@Z{q+6`z~%%tRmcFim0$jbczXc5k=O;*pKk<^)ZPjU+IGIA z_Gwdf>+cKQ!H+wG*Dog`zJpowfynSRyA0nHYX5``pF7gnViDis{|Wf+$A2%%@O>9n zo+NoG$G4M0!uJ$`CloS#ZcSsT{YA&?B<3LNn;t5+hKhaj6Z{_`>zkgb#7yC$yD1tYLV@q=LEJ} zvpQHLb!B#x)`7%a3 zg<6`oSM0dIll=`DfM%BgsDD8%G63#KV~e3dJMX=vebITZKmLVK2B3EYke9NU&U?M} z{t3X+1eQ|B0Jt?xywo1RY9v-g^#vLMB(=rEg0|;98`$9vZi5DI%SFdVG`%4*KFu!U zvkSG`A>-qYG`3je^SgFce2&F`G|Ko4i+u7@&S#}J1D`1bPEpACxRqH%L%eeu@8cl(AhoTJuuQ_8f(D>?L1v?X8fp zb!(byo>Lxa}& zcGg=V0Hg4aL>Yi}BY?b=#nk!ERY(9fB``)I1K`#)@ltyLyO7uk)kil1NNU@L1#LTD zQroksy5XWDsU6Z(-8vB59sHRmc>P&zk?w(P*#5}qHoJ`OMbsXPjIKM<*kY0HJ-Q_$ zy4}Cx768iV9v4=gBzY;P`-MWHyC8wS3K?CurZMzuSXJY>eMu5Skab-Tm0Lr_uDdG! zm63H_&s1XO3t!Q=^jN=vHyZl}$hxjasxeZ$)+>L)4yo(zfPXt=Y(3*nV|yaC`>IuS zU3YZEQju++cLUq6@PC0awkJonc`0YRu|i^7`kE<^6*9JNO%pGT_g!wd$uuvip2*m` zwcHvivRxGaBFNZ!rV=xS>%9*?X5(~CvOM->k+JniHAeg@PRH!N9|pE-;$H(9ThF-D z*zQE_W@=Sz-O&+CMYe~%7ucSTe+tUjo*midrJU`x3W@D>0v9V}Y~9LO!Vqu&k#i%7 z8<4SeD`N?pLq)dt;=czOTX!;+Fk}iJIU9+S*gk>%ab#@W$XLPw$d23zqX$CojdFx1k#z2Zr6IN6nu0cds^fc21jR>gJ*{=q0?`&eX~ zmvXizD5PU=6#~N*GPZ6_6EC$t_C}M~0M(xgYbkaA60oNXWQ?y!1iJS7b#?H-I^v|YJc9lfy8yl z*t(U6*@tz;P?7CD`0ql-)}1`ZK4c2#y$8fe7afmdpN)*I8+nR-i1^t|Z14L#uzeN( z%gER^JB{rp)PAT|#nv4>=RN`pnCSNFs8t=e>GvR#Y+mBdXw6GG+oKiIaod|fFNKV) zTNxe};{FCTei0c=Vi2nL4z}WX&zI47sHJ&(#g4lY*%gohXm%NZb*Nnn831>1>nHA2 z*cSk-tG7Y`w#2_V$^i6>*1Qx#ocE4VNC3tX*i9h=;8vdO6XNXw975t?R38{@0YFk4 z78bNU@7amX9o)bO-j<7w<7xUhWPF-k#%C(EXCUL_4sQK~7PB4APHf}8418|FeFuOd~PkbhKilu>+^euJbiP@_s?K*f{=-lPU`({;r4XX?eXo!JOeQc%Ap_u6 ze%%}5?Ey?BaSp0)(Fh=^?HU%e?R-h?fTrq(iw@?vYN~Fy$&}PiYN~Gdagp_GcW^Zo zygocE!k@u*UyclZv&-OrM(s_=;JYJ@EoKz6p1sDm0sdP*@}~ln!Jisdo+NoGhyO=~ z1pjjapDJYV-OAHXL%jVUvfoJjf~;q|m8YLJhl)MB_7hj}$a=OrdHQL{^vVa3z3Bt= z`eR=RS@>FTQ2VG_ z6>BhOyEa_jICSK z#7pfz?YsZV2PQJMZY{Tlifk9e-xnEM&s1Wj@M*u4IEn3&*oPov>yc`V_-DA-F7b0< zy9)l{$k=+uoyK-!YBx};V(X5MSSqsp$4`Onp7_V2jO{-o+q{&seODo|J)FQ{3K?6s zriqu@f7qQwVlt{f7}iq!wD)DD#7i`9ulRv8jqFrp0GeF};3{foAOqkIhS$Ws3j4yR z{Y}EEPy1W&&qNu3$D%bag%F?i?*HH?&yf6BHN*ARcuefKN)3g zKZ$JfQqFdFg>>v)Kwz3e#@4NA;-&V--nAsILG>>ik3BoMd>MaX4z)CIuh{wSAbT4! z0L?A~@CdaJBLm=$G`1KTw7=&rt+zq|Uc~=A$^iTr0pz7DroZQoRY(BdB`{YZ1K`#) z@ltyLUz7L})qiUQkkq>EkR{r7zN9vPQ+30ow&8O}De+SA!o!ZAJzz`q&F@GTNHG)eMOj_(SEgl~5OyDDV(+?vMF_^_(R3%c~k@M#k1N z?liV{QhS41Ro`?+M=TZD&i-Fu`yu}KQO0)3$TlzKY=2cqY=0#1y+X#;t!d(=_UFB> zzcUIB8C$oOTSG;*eew4}#?~{Hm?@n1E*B?VbPT~h7#UlSRAa=?X6o{nmIB-1_*X*4 z)-&!jwxg+CPpyirJ33;i$aaugRkt6De>aq|T_Li~OF7%^6%yOS2ppo2v2|;jc&UB2 zpG;yBs;?Z@QoQK!WlS<1YH8kH@w_*c>^aB)G`kGI3~Db&2EZK*uZepV_Jxa%#q?GP zz)bxAKpB8h(VCY+i1XeK3JJgi1nyJF0JxQVEFs<=z|$n2MD=xpE#BYTA}nZo-m?>% zJNVIF@U~oZyg}2iA>-5RGCp5Y`!O;;?%-#7p~Y-Rvx|;(%Yjere|*hG8J``ZH816S zj!{T_`Vm-AA>-p#W=aq7_MLAii6xPBKDU-zL&eTF0{<$=I-h4MF;nP#{rto>8v6#w zI-f_XG2&fH$K8Tec1RZ;+vDFB8C%b|)7TzB?LKN%ozEQ|u~cMxMJ2GEjDHf!*zOV8 z=B1qNOA3kYGy+o7~e9z;57G(g&M{8aRAv)j73JJhm0&gi~0Nl!RcSF2A zfG0}s&2TyXIeQ`U8V*MTm&m*Jm|GP-{Y8=53}DW|(qmq7PM0yijRblsZ9(63=t zjn^dilDG$1*Y!}jHB{`nPvZYKvaaiyO3ZxWD;k$R;5YDI$36#H*Y!v>MvB*ZqkFPL z>bjre{}>rt&$!dr&R^J)gjN z3K?6sriquv`z|-!Wcn+KtC6vFYq>R4WP3aQTamH#OeJOt*Ly?7N!KL*!u}94wjQa* zh+oC&jBsNuuzdmlbI90w#+}CYb86pFt77Ypj#w(Py|Y_jyKvf>^g|ijdm`Jsl(YR* zA+cSSz%mLMTeqf(m)d{itVv=GWNh79ZVeULZiasoWNbZCiJ8Jj&e`H5w!32A85vuT zRAYp#wwKtRIZt4F5dH&@vGt5QjqM54PEf02>yD0C3XR&=ym{5C&IuRczW`-yAC7GE zQWn$KybTo++v^BitB|pEEA#4yc>6Q%JtXcz^~Zv(_>tqwm`O0ywtVC~PIfjj0L?A~ z@G7-0BLmk z%%-9GON{`M+B;!E+m9Uk&~OJgFoL(`dapN4_d>>}*=2l&P&*JAA9rx;C+>94XQg`J zvo8L%QO4)vXw6GGpZydPpREXNp^))$D^H~j@%Ei>4-&g0>wIo4w}y(H?@;{Xk##=L zRAQ#k`R4Hx+X>hwBI|q}sm2IfZ7+4cZavr`eQ2DG|4d|TJ>yPednL7(sa178cXY&3 zXw*92Ih}#+J^1fJ8QX6n+q{&;)cGD!NNk@V@VG+8)~!sm9^&nfz1K<1LG>Slt=Rc| z8Q+paZA<6-gzQJi05rP{z|YkFhzx)`xb+kFD(nlL?_6P3=j&SOOgc~o;D6DYmvR7) zDkK1X3G`9O0Jt?xywo1R5E6q?y%MH-i`RR-!h*J)k0%W`RX1GkS>JRAKYI>dznqAd z%fngoO33gvyA0nJ)UJaJpF5aXJhWImexB8lEPN;9KM`g4mWbB8l;f-P3i!?^aGpYj z&#h_VrSV}^jTdxRleiLD-*juaHB{`Ix8lDUS>N;dmo6q5Y1{qt=xYO8vO6}WfRejSP9kEnoyY#$)ZNF+~vLMRXE+5(ErJU_p zg>+~xLtv;v#@4NA;-&WIy){Uzj*P8a%dMdz+fDFqjEt>kDltFI_fG8{*j|8t8p_y?h-~vx z7Snm}K83{gS_0Q7WNh7Ybl=hd>Ox93bifgz1d_RK?b1NWdL5L z_C;g>+`+A%xL09cIPXmnR(0I>@xO~Q02@SWUdjR7uaE$IOWOq_#s?(DuA%CpLF*10#4_E;@SAbPr^Fnq9_cFtr1a@o@*Ye&SB&e6G`>Dn4uD zUlV0~#zt#i%K5yhkoastU^9h`k6Y8kOYJ+~?j&|a*7@98ZVeSX-+257A?tjesl-g7 z^G)&-+eGXWkaa$fRAYp#wwF5J@qO7Lo!HLAe>yU@o^hwKy@J~5YE_-j9UZY08nw<> zQLAEm7ydg?#&-Y6HZNr{b-ob_iS6SAW-DZD-I^v|YJcp_A@M4zj}L1pc0ONLO1#w4 z`9321Au<5XE(7o*wcjHH;0|v6#JvjpLg%aMtq_2YE}cmQWdM$f*1VJhSWO`T=tH2l zLI%LCY2u~!00xs7gz6I-0VK64VL{u@m((t3s&2UGNNQI#RX5yZN@_Eksv8E8CAIsS zs*hr_=4~`ZwO;AJ)imC#vBy4*_wQjQLrvqoWwuHT%z*u8JQI*jbA2s^s}#D3S$aKGN-C$)IJ5aK zx-cQl=KCO?`;pC$>^|n1#TRGreTMp{kj;Gn4*G{m;l|CUs9oY%rskO?&)ffA&B#lXmaM@rrC_QqOd0&G^*E3*zmI znAKCW^LnCN(wBX<36(Vi^O87*m`f|Q`H|f@Pt5rCi0I4#f#@ovh9jFF*)z44Or$#+ z?*^z_cRHZ^d0Nfw+XM9juWv^lnY~+^{#{zR?nD%%*OC zHtcXI8LDHNsoN(HWP3Dq`@eABk8J98_c5QSd_HyiH`LEXHg)^D-MP<+Z0h!XD2zom zb^A+UEopLq(oEexY7y3=soT%Sb0$jCmzcl&t;pX?@$>t`($>ci%BOL^jMQ``yK5Tv zPvegKDO*KtJMD<3alaqaOk|U;C-ZbBKk*Nn#(nFpvy&7*4_1f|qGz;gGNd}+BeI$)6kF3QbC>)Ax8h6=j8utrXaxSuI+#jTHoBp9`+<&9+gZ?p&e+;X2 zCQBfj#(kE;n#TQbmK==qvT580#tnT#+tDzM`$ZV1W#;Zz@xJX6yyfIGd6}#FIgz-T zs(Z2BfjT#1##;APGv5{I!lhkU{5JJ-thvsoIc>VDl>DyNm_R$9Jo|sx{twyY*}dvq zyCUAn+qkw_Z3`#oCEFYR!`XKI>vdMvY|(>A3`CVD_=n9B?e;V_5rd;jmD0cyOUViZ zmQ$!N|FGGiJydQDh1sFk!aqtG%?@p|LVKptnz?z%@oZp4vqD>scWbr9svck2lIsQQ z>F(=j_0b2nR-5YS*2CS~rPa$hwlbHKK%zEB!2OdONDDz&{!?++l9c6u+O% zCiDoh?`Q5zV`hF|&$#rX(Hz{mIr0kjmymrw^GG>H=E>fTMBmRQuS`bY&pyQeKC-VT zo^hvrJz24n^M_j18}5!uEX6mRuP4_Grd7S`1A25O{ZaPyWcNrZFJ&=(KbxbFzMd>c zV3JJwdICtvfnmsmL}N64-X_$^B*&zWYYD`^Qqw zcDO=fyC8wS3T5AYgO%^Tp>&Ava>HL~hmu$l8C$oOTSG;*Bk-?+jIC!XF|((yXk7Z7 zIEn3O>>D6s>yc`V_-#-fw_6PjY`4e1Ei$&Aai_8UBenaeRk3wPM=TZD?y^K+dlmi} zC}aD_NHj0yY^N$Dwzm@_`+GKzka!pwTep^5Lq)bP;(s0)ThCNtrf|>Z z58@=Y?_!^ejIBqiF~U~cOKewMDzN<;|Ch+vdd8i`w$h7#B4g{0j@W8w)b82by<}k9 zAOAwi*{^OVM7DV;i|L&3xk6$)jKIDt zWqkfl?O&1caR)@_`_A_v ziT9CpKDU-zL&eVbJ^pWzbw1BjVy4jfZt)XaWnKtKdN6@UssQO5ShXw6F@MCUs|Asu_06WCNC zW9!y5@lyL^Z!C%3Q2my$mSX4gW&AKE)V6fKL&zSC3_!EX031*4amWC;gP&f-y~+Ws zthYh{&cc5N$^hIGt$8U2aG*j0a4CUH6fyvAW&BNuw+HZd64#^p1Hl#mB(*2Qg0`J6 zsr{#^y5Wwf^-Xt_5-%N-ZFUm-=092U-N^7YyA0pU)INp`pF7gnVrbA#-bXGQ@OAIa z7f6)hdnasYlH{cv-wg^0-+~1CDrETF%2S2 z&vZhoMYhi`7ue3ge>uw7eiE&DDQDZUd|-PEftd;!TetEvoe*z--g}tDEM#omT5b&$ z**=f|S!8TIQ;C_vdGC60(nZHy>~A4s>yc`Vu+{d`G5fa_0^2X~e~yf;XWVIQ)A>4+ z-_@$vx}zhOLZf!v4pXb@_6w0&0A*~yjcoH$7Slz?o(k!>U7EmB3K?6sG8s;Yx9|2N zNvwwIKLuOyyywe!fM2L>Iq!`jyAd(~%`OA56SX@a1K^G{wpawPtlkO%*dPDCCDyi?Sxx}PDI@^L5I9O91K?J^afY}z(slt?%+riWhRIBQI?&yf6(5Q938~za3j>Nwj%GeH$Z1YkU z)3NuqLSnlqfiVghTeqf(m)akDyOG!h)t3ruDRw?zR!Y3o()kW1dmu6Z%`O9Q9JPN! z2EZL@Y_SO7@4~9icLx5`PzGRy2p})z0Ol$r0GAN>i$Vs#t^5!v#M=Y7p2Xi!edR^~ zNp0P*pl#<%YFji_H(YcuQAksD!=GWT>$-yx!NKddkK#4S-E7#M$mlk^jPCo?&PGPp z9X$3vv{5fuJboU{!mqJF@t^A=N#M|FwI+DcU$hxju z%dMee*F72kiO9OHXDTuCb=ar+xb)wC1MdRt(~xytk5psCZyky2)@!jt>bif$e>F0; zo^hwKeU94O)vCI#J33;i$ae2l1KTzFGMo!#Y>$X+^HR?C5{1NeGXk3^WNh8a1EE5^ z{q^4NBz8r{)~!4csyS3-J0AZ*$k@7*2SSBR;d*blIO&>XBK8T$*t(GiLWM~2X1h%i@e;H+LCq`>t%Gv&)kl21i;6sIs zty_5@REW3#$oZMXkI2}%l?OsKhl*^wF2MaoWNh8Z1EE5u@R4(|IEigv?0t~2bt4ai z3K6#2UOH|sT0O8Gf`2eFw#`msJA&HbYE^9A!2_W}tD#Z*$XQse>WsT3{>@Rw_LOMN zOIb`GIa?_twtEs7tB|pED-VPU@%Crj!$};5>SqL7@gv8V@fi?mTRw6olbwVNK(osL zOr`c5WB}Ze#ukeJ2I#F2fEoBNM;U-=5kOwb0c@?10L&!t4}}bXThqi#?EySM;yzUW zOCx}!_SdkW?MIG%Xt;y(SMU})pq<#Brs*e<@o9D$pSje&hK!Fp(%52=&!{y5pZ~-E zE6VuX6#3+(oX_D3iBD}o{(y@zK5pglNFm<7^YtUKAhOQq)^cm8*!hOyUlLj8^GqdX z3Y~9$Ke3I#z6!F==aFiRu+{cb=bLX$c1Rx@qw#NmjIC$fX>5082M>{rdlmMDFB8*+Rh{o){IgI7;E`y}OF4k&6cT{v z2|TNi0dOmiM+))w0Opc-3)TPK2q3Aw5*D=Wd`a!Srs{_4J?oq9C?#HMxyke;YyKP= zzGj!<>%LHD@*57r=Z-YCSUi4S(~&HEYm!+5W%xb|8=53}DaY4i?SOAH0-Gpg_}rSt zQ2UFHT}kYWtZ#aV5e#9SF;wiE2jM>eS>JSLC1wg29XI#|-308%BI}zTVE{x}P4S$! z%=+w*`sV5Qryyh7>@>E2rS@XAs=n!tj#w(PU3s0r_GSDpqKxhLk!@be*&e8n4$Th< zyswb4b!(b%pUTwX=b};@y$k=+uoyK+*YFARLV(X5MSPG5WdGEY+1KZ8yo>ivXqxt2*xG_%B5nfO*2EB}rb&0X(jd0Q`f%-xV?dZsqYvA>JOqeI)*g>OC6) zB(;UZg0|;9JF&T=lz6Gw0j={rNz?yE#;4h3eBPq=KgjsFBaJN<`P`;MReXNM|1-+? z42gX5QqJcig~X?Oe{Q*>jE`H>#7pfv--0CiBI|r^Ew_e>oo`9}Ly&bo&s1Wj(D}~r z6Wc1-ha>BJ9;wC%TWv3OzSA~jhje1w0RMW(*m}mD#&$<)w^gg^eD3IorO>E#z8-2- zY!AbK2+G(l7un{eET+!4o%nfLqhV zOYH%?MdA%qU%L@NQrj#nXxsUc+RjbY4Hq3rZNH}KhMP=D?Z~F;hOz$aT=yLr-gRs+ zRg$$el&nj+%W(`PEA30w=WOz)sB`UtuWG*fv!z;Ta~A(j{crM2V+feH)scB#DfKH| z$>JUhv+IbL9rtd_0~u+m8OioJtFP#|x3}B9?il$tHB}wwUX#X>d+Jw|yDNHV!~l?TcsfQf%J$YX!W^*?!ggg&z!PaDTGiehjXkM61tj zoE;C-0D{HMssEO!pugTwfmJN9&gOG`N26E%0e@{pWc8 zi)?WHyaRZ9kqxf*5VK9HafX5)zX>4?u3s9@Qu6+Xf4DC-UmX6u8uhE96}vP1+dbvX z69(6BMD>QUXvnu)Dw!n=^WK5#?T`(wcT3eQacK9x)bEXKz^8jUVuSu>Y6$!`+5-*v zJPQ92$Oe9Trb}za2iKpB_e2y1*L$K{atdtX;QI4%oM$er)CSkPbDoyAMYOhAAbK^a zE0GPZ_e`xN6Y1WL_g2)cNVneV52PQ(`Y+jwq&r*ff%+?0UqUw2*0-idi#@&r|Hb@qdS6GcSc>nOzXRPC=}fvHPRJTu?}^^A6cenaq#?Kq z;a?^1M3Gr0ck&DkCeu3rx4Qpg6^yN@|Rqo_Y>81FI$l&^y3FU+9yA5Rj zQ8u`KOx%%=vsKh?(~f9x{Zg3vAsY&R5QV*v4X*$DX4z?gD<}OHhr#tr6Dka@pEnv7 zmca+tUq=I%dW&-@yn$?Ry=*qPK3$X#2bS94`lb2DBFF~U??+)z{X>K6FQzaJ+2H!+ z6xQJSw^=d=>1BiKkBQqcM%&RaxV}87Gx=X;w!!tc2X8sqSzZR$57W6#gX@>Tx+t>2 z_3o=?J|A2^hWhmpYu4a;ca@TZ)mp>g`UA1;k8E)LL<$ouXM^i6j_-$;Y;X9F2G@7! ztgONHXOlP+<%8?po+e(3K_6Uy8G-2v#liJ%Ew_fk;QAZ!-=It!T<@7mYv$%5uW!k5 z5C_-0wc28B99-`{-q&~_XIrl`;>~I^4z71cmsW4n;Cgp{M_dlHaZTjzZZh{ARAooX8weaxp8p)lbHUEY;e6Bdt}Dq;QH6` z%#lxn>)qEg^M%3npHlrXvcdJgQ1}TgekrT8!S&r2qbni%_HuK??xp6z^$THL0997t z=xfL@FH=azOz|7fP(n*0`^Mu==Bx^t!r=P#L1wobR>Qt3vMWC~GGkSU6#wS=_TFT4 z<+m~Z(a5dY;VVZD>Am8sl?3J;S9jvJs%P$ z-O70c`@_iCdZZd7{?|->n;f%iVEYpO7m%^_j603(|EPUWt%|KX_<2?Ymb2Y;+rajq z#kt3aGPaLJYhKFPo~Mx5P9!ivA!F-S=4=Y_csH?Okn-6i&P2x6t>xBGk?m#prz2zQ znM%wQZb1$cC$YT|`wht0dZZd7#XBG~cMNRr#eWYnww`gPv3-TwC)BFgx}zhO!h3Ar z)bH6YuU>soZ zdbiR+Vtjt1>0glXX?7W(9!qd!Bje)^#sS8i4!g>S#>zVdKFi=AiZVW>O?=n#QqJc< zg~Vrd0wWYMK5k_)>JX3psNn$Fn8avgozJbb*c>W$z8&#zkF4{#vl26f&e!QDw*9d0 zgRJv;q#7e^wY|i(whOD*2lCPQk3`1SGww9Dr&D{1T2<$BM@KA$My>Omw{u{775*70 zW7|El%}ZI#?*A(!wzm^wzd?wJn|RMY7K$ z1JLX;0Pj*e7a0I|q_M>!fN8?2&i6I`FHr`dZv>E+asZDjBml{h4ChtI0Jt?xywn~* z4^nlhebn(yA0n5YL`Za&mBzH z9a=2ndqGFC@QufR5X$ha8LfFK$Jb@IfNvs!2?`lLx2B1g+Fx{>N#b;5ebcSw)=;r; zPRD;SvcBn=O3V~4I4Dj_HnhU zzUhvRSSqqzcK5)xvJ`%lu^k=R=B1qNIE8d*_94()A!F;-H1SgV^WG2=gORayYq>R4 zWIG)HO32uHrV=xS^InHI>7rvj?CT(7>yc`Vu+{d`d9SiZV7oQ`Es?SHj603(KGg21 zR>jsG9kCP|we#NTV*}gc@gIjWwp&KFc`1wOy!W6&VtWpOvlKG6ZcP&}weR*bNL-HU z+l93h&wIYClz6G-yf>5VKac@vb{T*NsJ#yv0C%LZ#Ug++gjF5)Y5Y&348U#?KwioL z%u+}I-XQRrLI%LCY2u~!06r!0F{+Pi1d!AY4GY?y_w2;xj#A@_`(y8660=bK)UcLf=ksNy#7ixm?|HJ%A_LIuG5~X_eG3@?ccih!B7m-XD+J(6 z{GX!?z&Q~>UdjQip^yOlPT)6%41inH#7pe~)R$)CQT_Zz07>o2u%K<{OKLYYRX1F8 zB(-~+svG|9X zpp5S0VMCK7FXeQnDwb*?zsS0-XDTuC zb=W6vG7a$?ct2zR5n0#uNHs?M){(mI&4;i<>bl*Q;iQL*t!Lb6Z2v&*0?639qa(Ij zWc%>Gf$f#}uRs~w7b4rdl(YR&A+f!cz|9I7Teqf(m)c+N{fopy$k@8I+!`vfeF6V- z$k=+O5;KMCz4OFL*Cg*?e;XNFk5pr%_;EAeL4oa8_`g8L)-&!jw(|_*k0EMRr$u-0 z*Qf|AVB&l3fc*p8)ya%N8Qa&RH816Cw^m4OHzBaGLdMpuY2u~!A33{{*clmHx0YK& zMYadwKL8n9&s1Wj@R9Swfr0G=?8hQw>yc`Vu+{d`ar@l?f$iz|ryyhN8Fw1n%c#9r zt%|KXI$|j_Y9Bd&QmZ=S-hux%l(Bt3vdv3bOdmNj6%yOo1Rhby*t#`Mywv`T`znc- zQT^kvmf}Z_FJq4KP}}m6^C8*ykpXCS8G!Gp{T3MjcQCtq+^euJ99$FhRtP|4S^Ovi z@O8B2r5wP`3JE}O0=*P60B%haFSQ3Sh{Qlt|Dh2;QY&woCE9-E*oTHY_&aj&dbf(# zdn?fNa>)2JyNu6z)Q&>N#~q9V3@sK9km>5u;y*7-bBiJ3y@JKRrfmtmidtn+!K8Y67Ay~Opf z@$8U3G;YLy12VRrai_6;klK6Isyd%LI$|j_YMt-Lg9F=F@xP2RwtXVoyp+Y%`Igb9 zi0wxNK2*rqx;0I_)c)A}nZ%E%zED_8vGe&dMj(XRmd@98IetNe3_!EX0Q9A{4>ADm zNMnmd06%G8bZ`y9KNw{I21NjQDF-l2@1Fn+C$N%22EeUp;-&Tg)+4bFsxQ$9AgTQ! zENI*LlG@r$)eYBs);Hb3{LsPMa+7Im*1RP$e9bPyH=f$D$nd!%jV%`Ot#W97cM%!(!S`tm#)BmNH%ZQ{?VG3 zasZ3#{S$y*1bQfB0Nl!aZz0|uz(5iMP3L+}vpfD>QO4(_Xw6GGpY;_IpYa3^QpotYHBG$K zzVl5aF#%cUb8ERZRP20b;y)c(=krV@W(u9}qodh4b-wA?FGkk+JW`Djw%T6e`r%Pz zbYi;!|8>aNdd8i`_I_&bQLE~F?&yf6(5Q93gVd^yy_fO7h%&ZkMYeedQnsgT%y zNZ@^ijICSK#7pguy&p+@kLu@zwG=y_FDoTpYUz9(D>AwO8GvS&0q8?*Z)5=6k;WE_ z01nn$ApnE%4?-D$OCo^0lmoa*Apuy4zzPZ(0Jk#xS%|j>unvi}Q2mNV07>n}u%K<{ zOKSHtRX1F8B(>R1)eSe9lG=++)olmYzY$hZ+H%B(O-hDh` zPov0uaQ#^7cauj0(%r)Y^W^bC=!Z~$Fydv$z1#ADzd;(ww(+ryWYckPZ?}8hkq@r- znl!G~JuQRlUkm$~BzY+_^Q~w8n^~a^u0Nh_JPz65dUuvuGI77o!h448SN*^+XS5Bj zpKmlH=bxh0^gaI5%g569J8G%^<+>g!mmnMT{w{@=kd1RcJA{&?|4BB0boqTI5YjmJ#aHS~7DG19-F+qV#gW*5 zpngTEJLBBllV+YU`g&ce*Oo=2uiaA4EMdg;R#b0+Y@EAWDrSkJtoNXPchp_upWV|n zS&psNc+39*z{Wivif24Zs%sXE)fn;j*M_ZYfaVF9Cn6h)?F};#cm$Ir;ymYP<2_R= z$X+(G`qE%7CF_VHBdbSDWP3ES`f9Axk&UdrJ~q0Gd_J=JRq7u_HnMu?A2_8T8(F;- zg-wu+tiCU#`CEt5jI91%@0CVYAC2col#Q%@EUv~&@pQ<@>gA53Z+y$h_{i!-hI7J2*5dXQwnjFxS~eS5J%J^MAsbnJJB91?4^3PC1%;3F4~?u|WMzIz zk8EW1GYV^D_1-Mm9qDBws~?Zs@rkyhVPy4b7*Ed3_R|G_|GT#w3Hs^6W5+{9o#c8V ze?#`u1<%aWl8GJWpLp*^-MSY#Os&-)I?t0>|1Ep5^VD1Ip(DM4^)+NaUGS~xY_Z2q z^*P>8k^OYR{XJU!bg-$~WA&Hc@&BfE=%)*w=^0B|ui$A8{?mmXtMHkH=#j;)J8x@( zwOAJ(hZswj!vWPqfm3mn3yOR1V5U=`Ep)+JB z@nM|Ar?R?qI{%3$@nm0}na?_P;p74SzkJxYm6YdIy0qJg%x|MuXC$ie_ z(h>9gIUIjCv)Y@qdHOMu`%?48W9~uf??-l$c27C;gyZZPs-KcY$C+CynI#-sZ&Lj_ zvXiu1s%DAD(`VFwg6w#54-ZO<=c8;7b?$v*p^E;^=EGtTSPCO9EdJSY6!9(?U`CjCej^&cNJtk+Wqxb ze;~av*3q&TN%Q!ICPei>eP^sYBJ0s^>d|74@4!KL4?qp?K+je`@4z_iv3m4G{1dbe z^=My5uUN|7vqFzP8}FGY^k`4?ZcTWPz5@4UmQZ7z>lKdGKFMdn6lZ z5BYI3fASli-t#d6vXjLRQU9Pkr(KeJ`X)7<8Qv(BOBb>D1?rzedad`+P#*n4pXwPP z_qWCBX_Hxcg08Jj=W?pF?d;MY_d7gEe0&JJv8H!W z>0JKt4TZ04)$?7-inXZxH~wSYU+d{-EBPT?NwVH?m}XOd?uOZ?#kdvwi;_e0rwR7vy+if*#Ive^{)CGxa8@2PuSyGu<7Zsq|tn>6uDPM^n=Gt*~6r zR9ZJ*Ui&aCZ+NECW^C}$n3fNf`3848xv;?l*x-dw-!Z|b4Zb34TpPS=SgZ|xB(9Uk zbag9FiW_`*FlmF|h^D0P@nN|(_`7_0?Ub;*VT1eW{b$qG+8`tRUL-u|jKT(wU}J}) z*=YyY)}?LsJL2F&ll1L!&vTY4CEHW6HR`U&hM}P(IaUYn+;XovOH0f1pX2ZxCExI! z(`1Y2J72!n%EPWX9pAcCU4dshT3j_A07=Oy<;9nqLUKQwQXTJ9EtK200V|m`wPN9|F*pk&4UP-2^9}at_97~?5|F_iJ zzSs1^-vinA8uwRP{r-Jz5Z-}^*Vwb!#<2lK&%pku@}gr-bm}w{|v{xf>xlN zaCctf5jgfr_bvCa9T;oU)geaUoxIhLZ|cVK_K`y#!z(pz$G z*n@$#h!2&6%RMT3L+m{`4(m~9p5s~aRIv64)~+Y8@FHq2K(>SKNTRpw&7M$R(01@z zyw}LD9dv(Qa(~>xJMi8nzjo05`L;yA@8BbNA4cKTseL>u9FCWVceC+s1I+ykc-54ju)`u!c*3GWU_FFWLBgqHm-VB;ZoFxGvM9db7YYr`Qoh1ye)?Vvl7 z#7llia4nr3au?yfKz{9@yYiCz;|^Yn_Zs=NgYIVn_^>U}?>l%0-rG=o_5CPV_1SPQ z=f?11_Dfi-&xX0#V*fB39X}g-7Csw(il(I2ukhKBeG2l7p~c#KFwFNWCw85*%d7F9 z`1zd7_cqH%vnbuFVfntY{i)Bw$&vhjt@X1HldfTBN|#P#=@E*RwoT^yCrz9|Ii1OW zV$+K()V*txK2u(FO+L{VS>uw5{;@)dZwbl1ijTQ+;p7GWzkEyMAF=cZHCWpAi1YQo zZH~B7|JyQIZ`QC<(&bE!tNpVr;+vYiN|zpgVfc7kkJUW`_=nNDgEy%sX=img-9lPm zBv;dD-T&>kuojLw_WzRPNEYmhR+D)IF=ds`vw9%3GrOA%xmXlR({VzMZaJ9DAmr3$GHIFKC+19La#cW~MQT$05 zb)U%BvTwqEFmVtKkXvNdS?uZgRQ1Et2UX7CADy4A*^#6NWILTEvt+&_?O!VM*s!%Q ztt#U$c)l$4WYLlbX3oCh4I4+JUFWA_AAEbE>Hr?JwnA_*p>8O7H%_N!D%>7M79MZ2D2VjcU_#qbu7LXbzPBv+(Y3m{bNo3@f3w8 zkY3&O*vUbm@g(_JjW1eV^JB5lY#8t1dsE)-I(;o4jlavdWVOdGXJgcPciuI*R+iMO z-NzSse6c4FrGAJ!>dEe5wkdhM_pU?zDCFBVBd)UZepb0`b?K9}N^RRN*tV0^-q7o! zad8<}tPXwjobZND#dInv=?$Gt;XY(oZwjF_8KaQDv0c_;f<^`O#;(ghMj*RA=7CCb zm;%R?I_J|`bbIW0JjbA9eH{o>s2)p|z4=$O_)27N{>X#;VDeJ-Z$9k(&A%1z&1x#! z%KO4rmXk}hQh)PjOe^#c0>706xm&U&ovNN~4N-h5Qevibvn*4gd-OnKNuqJOmzW1Br9fS1h-k*2) z>d;A(WN#gBy{dgC)6+{ssoD+SF7l?Dc;}vI%uCixlFnD{TyQEO{hi=o0tX`70e2SD zStkC?;5fX0l3zREejdFM*B1PK@ScJ9G{np1%5h^QM!IAPZPp?uXtOl$&m~0u(!82# zOD1x<3Ga=z8k^WA2|PI~#`iE=O}bij_1m=;b(e=p%u>pTEfB4FDTL;&c8)nO5POlp z^T>#~lQViuXPHRsUA%MU7cqCGu@v?`@9tmY{SxsqVjii)NIWynTODwVHcP~kb@*b@ zyqaoDCKBt3zZ0>R4WB9{e-2$RDU`BJOXsh4nSUB<*%sSC5(7}TVbk(VUdj?l(&g&G zrPXmPhjm!Cl7DdCI3=#cOMZ>0mE5S6Jc4a45+hORUjDHIg>6vv*uUislwwn{ftjV1 zOXp%a6z@R_pUOX`P&f%~JvFRZ*CpAX(vH)%rmH;3jlxium;Bm7TeZ{qY}NYME~lMK zQTh`9xH#@fUdnd9yg<3{`pSHO?H~C6j=J@LojdcA<0{|LSy~v!eOUjAxNdUu5$9#k zX4K}U#a5VxBW^?1j<)tetyxVyNi+Y}n!l$3cQOq}Q>M$^OO(pIQEy{?-PUYKUWrIv z45i4Kl^lFQK=LbzpOGPXD>j{%vJDfG9h4E0?(1^8MTW$k{N^{NLna_u5Nlrq61TJ< z@rrUwD?;*u)+{7T(##O8Sx7uniKT449J>L@YFJmbHTOLvY@Du^KcP7tMO_Cb$M{h^ zFV}loW`D!&R{rlk*|W4eN?VqvUU5QFzbWMH+1yT4w^p_cK|3V7as6oBp0>99e|((> zxYR`3hO^o1p`AS-pa=*8iWQ}Z*svoi#fplG6&qp)6$>9=LqV}uKw($K^GuR^Gf8$fn=~o5nCs3b+kD~TGUzhGC!+d)-EbWD*um0i!RS7BP$tK6Vl56&R{pj%z3-KO$-NK<(_yQR20+Zh~Q8kHKZ zxDtHwMD{_j7=Q}T^I~5Ld!vT7?9?n2Ysf!^{YdJMkieRFPN8tJ1mr2~7T```%%yBk zUO$)mb0i>7UcZvU<*3*3!D1z8z&&mK7OHO&|5;cbpl~1RDoyGm*I(e(Gf4lMN;54S zlS1^5tX<<$!xCA$i>Uel<9kTk`kunKsH@nttwKL8KVu5-&?dM$`G#7^=k+F~hQd%L zuZ(LYR2amIwJEHLx{9UoAxznnR~sY#TA#_=v;l8OadZCB&nfb*ME&+>`Y6U(HaX7Dp&FiK5&ueBj-1ZAcB87z zc8n>ZLMLAAPGL)V(S{cfQMdzjIc{dwLLBvw78W$CyP5{BqUKjDKTGC(UX=QC4uuNi zdC`VKE5w);XYAeFGQ_?l>n?xs`zvlLt?h`b2mbXn^V$=IsP*x-+*VpOjYRR{!FNlh z@Fd^&;@<)lej#!Ug(Fd$)m--bDU5hx4f^Cm!`<`kci+I7q;f1xHkFTD8Mhn#0_$gp-Kbe?H|iJGDvG|9Y+<)Q zXsTP-UuorMqzk)~pIuhU7Iu(iWMPx-@grSWbMjycpRQckR#;a+EUZ~#C_;CHrwJ@I!(x`5{7TM?hGT)?fcZh=@pv)BR( zOBkBV5AH9u%AU%$`){nWQ5@U_=h1~Kywx%E2W7jvJ;7;v5rJ6 zpjm7IgxUO9?}=|OA8KRQJc?P?S+g2Evc&g%hk%kaJj4HVA#gGYrp&I zqSe{e1f6e8oOZrrx2Eedqo~bjx7uGwQ(5Zq-Qw>PMN$|d9=C{3Tl zdNh@NqU~f#(eQLfx55cbE!@FB<3VsLD%`+}8z@Xe4gZcxe28CjN@#h~s?cRLU%XQP zgalUP#V-`TmlyTCSZRj_zK3FOF8;pVnG(y>({1LBe5tj2FXEZW8arLfg2>a^O)xrrsPYGS?=19lSqt~R8)Vmi^yIy(>*rhUd#{k~FC3^VrorW@Z3UdPuM&f3JSL19{RrdC*A#=1TepPH4n zH_%(BGF9)^Du@1ySkZG)dbif4$trS0e}D=1pfR7h@UcX)^}n$&Bx>`6tCH3(aMfvF zri+xD%}(d4*G2TZjb(Wh&+8|oQ%AQ<7p5>xI)z`BubJg5ep&8GI?9mc*#o!}AxcLl z?@e@cvSA>1#gU0R5cznb1Cd8E@j$fWw5Pac>LweAd@|92$ZM&&45b5+ucZ@TWx^{+ z$E~&*W#s44K>TFVq3;cBRWcCyDW3OGHV`?`nYq!9m~FhO!yryXkPZXt@Kfuj<7mnC zZun_Ws)isPemZV^IzN6k?@Im?whccWig!42!%utqnXXQ&e)#DW9HUS+_9)dl>~t-Y zry(77x{Jarc_Cwu&ro;@$)Aor9^qHNk2L;LvhJa>`Z8eg9=sq%Z-HO*V#yJdt8^cj2~oq67S=(2Ja zS8=~$b1+vSvXc4z9G2kyKIPYO86RAR?R&B6Xjg;Zc(Ri6 zh~kHmhD~lJB;$ks5%>q`XqPz)k(JT}`x(2YxMAmps2(XHbH&wu8z1a|w>{!d-w2B& zKH|p*A4*o8A&Vt%L^mSqDy(_Fr8-n zqRhejsQ6`3%pdzw>gMgW#hQ@iT9{3*S~D*7+koP9N*%Vx@=Nhqm~p;;PHHrix-)VeG;A08t?=;LBM^<{mEkB{) z{)fMi_z5XnvlgpEA=_kcRtG6t%OpN?kIiU!yrOUtwym+Zl$bm_-XbMmddCgd2;2W& zb8J_~-vudK%a~KyE~B=$v?^@PQRhn`+v9I{Y&Y4Db10Ouo#EMLrHt(@5)!rp2<#vs zWouS0i*oUKZuu+O?n`2Cq-@PvtPX{2N8%rWl&xhFpLxP&G(7%TI0@U+u%CjItwl;c zascP(@+WLBecZ8~jQ>2OY%OC>WxJf(snV*jHAkH!nWB1j_pVIKSavbGUimas~pHRm(r@RHAkHyNZFc|+w12; zA=~B$aos#pw&vv9N|!m$W;8th?taI1RqP#*vNa=LR=UV`E+TACyvMQaj(yFR6@e`Ap#FbNZFb-j;z$z zR=Hw-`!b0akg_#vu{sp8{S5y{NZDE@@tN*6qv7#>!b!HLr}{0b#Ki|E(F_^WKo3e z$plW6kg_!^7n8bpQ(NTP z5=&9}+e!d@=jA4(Ke`+eH{L;Ks=sx%I<^|;>gQI(llh%Se?v+p?@}_&hs)WaBV!J( z$nmS|R+3HQZ&^tpvjzUXC?!*OqC0PhvQkE-=e>^1U;+arq-4w*`%vv}w?Bz}kajx@ zF(%~Z=|f?+8-sr|(r#zY#AkwT_m=I_F2OzpX}7aT$w#a+3D*Vpu|jeRc_;pvNZDG( zoXYlfYUfI;vP&~ZoiDjJOSihA(yFli6aVihW!u`b%}N>D3nV04U9&?Vgi^LnmpZQO)hx8tLJMa3TRIEE)H zd!;!Fk(F+6>*;&t`OI??QgC^fg1ejAYmkC7N9q92x(P%r8(++DP;TogO2SR_+LXQ z+e19ttdy}`?IFkZ69OMeNZFb-j;!Q&UKIz!UrGFkl&x8d)uE7W^TSwSq--sd_)M_J zdqFtKiN@O4yCP+4k&=(teoVI6=N@)!x5d9DQnr>cr?Neq+5@CjVQY>$Ukcd{kXB{8 zy%_(6C}n$sXPcEWw&Nru+wBbmu9J|mHESGMsdk6IkHkHwe6pKMxW_x)O)ErJs@mf{ zNA@YC0P-#c@FBJDA_ZWM*tZx07$|Rr0Qe36FDM0Yo(GVXG63TxBmhc>a~T3k0hl$8 ztW+C7YZ5I{c}gXKsQx-PA-BiV6Ah~?L{_Rg(O8W}J0m5NcPW`osqKN3j5%W8Vo2uD zM;)0F_zy=ZnVFtUR?5g+BOxI(hQLV@(oMsxab%_1-R?XRXCv))W-V5S!ftmX{uxNS zon;cA3A)|pwo7{)`y)uZokdDMVx394-DY!GA=#xZ!v7{xww5ucvi*zNpQTmlcIMy$ za1YF3;w0|r#~j-oXKq5S+eP(1R#fCpH27SQtNvfrd5Agq zbl|);Oyti)9%7LmK*}}mQm#K!`#e&v=HSzTYcU0s4kopG!f}0M1iv&uDc5Ev*{6f7 zlyTizLc(<}ffppCT+Pa3m|eW~VA3KIZzJurW-V5S!cMys|K~_Mtz{CQ2?mp%v4Ohf z*ndUZX)RLn5gQ^Bu0vmBg{0FqI+D*-NZDG(oXU1vYTF=XYmPeKYRLAaCmq{lBz}~# zUD>nEN*UWbBqVHCB+yDi%GRu0lI`ODbgkk%WDOFlBV}vWVs$8F+XsJdq--t2h1_mN z!8zWh!b#3U`eW~hl&u-Lj@w1TbG&Dsb!_*WjmbOeWg`lYmPc!3fZnN zt;)Xk0{oLv%C@^_o0T%Q!zCo!?X?7^Nl4k6mB(Ydcp^)Y24r6 zm8uRlPm!I26hPjk0N$l`AyNS5h<%G8fbQ~E2!NmPFGDGS{%+=6^yo_&fI}oC018L* zTYL#A0JFwER2x7GQVpm)(6#LkHv72=xr2?K<5^uHvQpJK-l{a(0V$chOUd-1wi{A1 z=7@cZA(UKlO?t&CR-lYJJq4r3m0L&5l7Q>C}7Qrgr?i~DQp%lO* zH}fdUN*RFnBqRVXCvd5R6o6S{AF2)DCK5NG@`aTEcshfdkn46lm!YB}caEpM(j0}z zN>zhN_c70Vkb=v*6xAo4w@N{*M1Ql(K!+v&~8w+v6l8 z8)cK@IQ*lOty$y9O11ZRtB_b3DOY&%61C1=SZu<)*M`|=Ycs)?D4LA*|B{X|AQ!H`-Zn> zrHt(>5)!sA5qMETy4{*Jj;vI>!@o;nF)A-~a|!o&@40C_)xedi_ITfrU5XSy-lYIa z$IF#C4uCm$9)w@348T=_RXT15{OwT+;7f1KN*RFp5)uI22&^L^1z^@VvQljTn~~TA zmA`Xy@h2Mpxe2*Fp6=4Dj%)3ltLj8!0FCZ|luX{GWDcTsFQl7>Ibz>px{B%N(tBki z6*3p$pMp{{jZU`DrCBK>vs6MtW(I-j5>hf|jUy}7?sj*RxD#o&Gi$Lr6n49p@xOqy z+gT>@nV{QEvR&F|*grzr?JQFA5$jCS?aqCb6_Q=rzxe+|%GNUGRJL7C;A2`O8%@>l>Duf5eBL*gh@Zs%-aw_DXs z<63uDs_J&*$exB2K;ESQuBP^KqyWqj`xZk0&E>5S0Qca(3#9}bMlaK&- ziog>RQUGS<*JCbT8^CKM=A&{?XY<`|TQ?!s?V|c!Dk^d(8d3dzx$26+q^SPLT=m$h zu_kjAA}cL+*E`9!r`z3!Eb;qDvFBZieZVNLdBLIB%@O++L+t0g?y!G7n%i@t6#L0; zL8B-uW!N8+kYN9Vz;X#GcC*GlRQsZ^#wT($Cel7_p<;C??9(gbUkPcSwoKwP!9`)e z{mR10p>!?mYas2@7Ag5iIEFX#Q!>)0H^$!wDO<~!Q`z1`?GDna97@f>{aigThlxY! zCvP~mo1M(=9i?o~^46@Bv2C-!u^mKUfP|E-S-F1G#cPk_?MGr?q-@Q~6`c7{$o6Rb zBayN-C)a1XOfZf&NjM4HvDi;T%GQkB(cDFBbWXO}PVYIk7vP_alx^OrY+s^wy0j{6 z&A}bbU8~`CyTzN1?W8e`J)@NE#on5gGPa{6B-`y&0#{2&*_xFLMP0o1>Gho?Zb!=2 ztXwFX4~1;!;C~b;TXS-usLKSW*RgOCwy$7+87W&ca-pb;*h#anowUfYeINh3NZIC{ z%Jx5MzmZmjtvR?*)U_J2z2+^)cK1`b-6~4iUgNDd)u*Xbt*qqMJd~vo^4jj*sd#!B5YSD&_zPZ)~tLX z=i;>wa~qP_0F`GsTX>wm*G=QuFs@W}obOL|8>9g8E(LHPwZo7CFh}fL3;`^cb&=!z z82l%p6u^^i=24WDG63D={SyEa37jn<1z^_LhiU`3g2ZL0{9Gk~sD7cFkUP%n>9y5y z!+PhcI=#M`MsGw)Cht-*bEv%+DH(Hc^LoF!ZY4QftgzUT`3C=2C?)fuw`Qe`On(Up znLi2qE+Hjj);O|K?QYlXG(HO>?RIA6ZWwN!J`{GluJ}76?RMtmZWt~Tbi1$KW#OdT zZHav|q}|SpB_FZQB;9W5J7nZgyf^+mkg~OmIhE~LYEP6_rQ4aK&X>Zi?r3RMwz^yK z-;7eW-+H!LDPwzsgoN$G1Rj)-vNdZQS*i9`_Y#R0QTazVm$2LY=B9DYf-6;ZyLZVh zL<%79QUJeDy9_A+bHu*I5Wq3=RtSLl)48?@r2vX!?6X@|$^hIbApy{yKwAkZ0JHKK z1sAUkU>y=`p>ktq^QYJC+=N`Wi|W^`sK}jOYp*m%A+l1{INm1Ab0ehS@-79pAGO;f z1!s=fw-|!ERSwGn?h*VCp%mN(Zb73cD`nu`mym#)OW*|wDLAvnK2-ZeV-bnBk@iXp z6{|yGuUv}%bELh}GKtRwCmJK|ByKtOUy=4oirlHAQnu#cJ{caE!^9r1_<>{lKm4bolx<&c%}N>DjU^;(FC=h*gp{pW`Hj7c`<++C zm$5gHxE3i}vlgpEA=^3lA4ba7GKtRwd%X9AlkD*pVqbuitwl;cV*4@KK6u?0qKvv2CTrMF2a4&(oC8Pk%%9FkRUjR>&coLNls{|0$k8u-ndpzBxSsmv@ z&Q*1y@j8vZij+*=rDT>;`vFoi=7@cZA(>M@a%5H-$Il&5N@l#9c@$-(jLcmU5;9#0 ztR^8PV^(ge>*BS$T^|y?kajz>a-WTSDC~B-;2(sv+nF=*nV{S4X1lZ_u^)!C+gYUK zBi5Ou+wJlRDm@5g^HQnr>c zr?Oo}?Q_zqbXs$89}o}BVd6Yw^5>52J!dfXj8eACyfrIjY@d>luziNWQxa0PW{o2& z)jr32lf)ZH*_yRj9SYfgivMGzY%P=cOmL33vv890ke{*th?K2GNs45xCSX(vlgpEA=`)X-;b27WfGqW4mM8;CtROVTBPJ7b_fx+kALad zevAK0q--r?PG#HTEbbG4l&v}He5)y>^b5IdrB&J2Zi;_nl(KDfO3AshQpR?Sgk-xN zNMJ_^DO_><+&3~%h z&`ro4Z1iwpbv(h^xvI|bUZK&Kk&?-~l+35pzJrvEId~9WiVm$uSk+QXnIhE~A)J~ID<#1t+I$sLeKKhMg`zrod zP|9|oXPcEWwm(Qn*e)UPfrON;S-EMti`U-jmXY`#m3MKru-on7rWGP9Rdu_C02y7)G1z^^gFAdV& zR&4;glGquQ53d9e)t}-fqO) zE6rN04u!q4VIt!UNPDGa5}yf9G#<8-xQ^IYLE0-VQt}ZyeUM(c)laOD^vd<|cSFk7 zGUimayHdNkv?{&Q9Cf}Fvfbqe$M$CYH=>m7R8KT3Wo*xukZhC>61ZPN%GRuLWTo1B zyq8EkkCd%hi`Ai!?Wg#cAZ2Tr#Akv%-de&*PBi|({s&UF7Ag6N?Z<@e8b3O=ZO-MV z3P{;n#+=G_GioFGhFGC6-?@|EwQac+d0CU8?#Sp+O!73g1W&Cqd z3g9UZAS-16K9P_Bc!$6u2`K=x@}nvjuMOZ!5?`S5^OXRi`bBO+ZjYzCG^^vsZq8M8 zqOqJte?>|r?@}@i=W)L&q-4wy`xZkoFUm$LWH!gY8A{14aWjvitdx=YTS7u+5P<;_ zQZi=cc8e}vyW8zYVsE6~&aB1iP}uEG#y<*ax3f&*GeNhTVY{@8v0s3++gYUKBi5Ou z+fDz46_Q=r9r$lW%GNUGRJN~C`=YceyEJpu`BKPsHEC7Y{(*lvO4)wr*=D7T?NA8` z+oqHFAc0c0X607vE?#@9YfqvrD*xncVYgfErg8sXSE}lE-N>$m6hPjk0QytA4N?H+ zh<%G8fYs%#5CHq*ABIu@$*J}MCo5$D_Lh(UIGVsn3F*dV);O|KZ2+f}I2DzfxViZA z`}S@^uG>ZRYgJU_PBfzW4Rh5MgGt;WAy-{-Q5g40$W>Q7?p?dQIT*Hg-j^L8*)(;t zoXiTHhxA>^yYyYzYciL_;Lvx)9NZ_twHUrDkN)P~m0PFqWhzSFm3_T6D`oG>4-%4h zX~ySzEMPlC$?H)(s+Zh-eW z_D_*^c{6gK1Q)SeuL;+iI&jlG>GHqg{~0OUyi?geeIZ|(A!Tb0?vvnJ4cV^ryJOq* zQhF~+*^cnmtdy}GC?R3noYz35QQNZsyny!@mzwww5ucvYkuqQPQgHPR&v0OCj46{%~v$ zxSSiKpp@-No^4jj*xo83VS5~bVsO^N4u)QAp45Vx=Qt}ZS7?thz?%1)t2mf72*;>Y&%Jw^IpO#jItvTv^ zDP;TVpN{S9D;QKkDcdtW+pLtaE&k=$K1twl2`O8%#*vk3f3kU<#H&cznzdLR3fX>y z|3jo~EtB|6@X6*9;UsLAVgDW}TZ@!@#6GVG+jjr4Lb6YYuH>0YWR$IC%&BZw!_gcm zTXWR;RztSy{O#DDjQ>QGvOV9k%}N>D10*Ed?YRWbk&v=AYaCgr_9@m>5?3N+Yt~|Q zC}jHp{(F$JwM^nO!6{ZOoP_Ob*ykZ-Ymt(V*ol*{jsA6Pzrz1HQnr>cr?M?y#r_s4 zTXWR;RztSu{NvbegnvVnvc1N$%}N>D$0Q_dcOcMTLdw>xTJ;lpvWFoBkasD7v#1@96o5Hm-(m=0qF|L%tZDeKK`DTHJb#5)Y&DgOvcH`nhgG?i5Q;bF7Z5YMiU;lg&#s`XW*?d6$y; zh}wln$(SSdErw*SmyJ}&G{2ffMJburJ(;YOky$7qA=8n-DiTsMX662UE?&Fabtkbd z(r#x~?z*23h23sP{M#YzcIHfcCg^sj*e-22_5+Z1JByTj#5$97yORs(qt2H?wwET3?G5;^ zLn+(!J=?65v7IX+VS68ednBZ6%^F8ms=dd1fy6UN*_yRj9SYfgg#Ue{Y%P=cOt8lr zDV&7upV)sx%GM$!AF=(IupLq7*tVX=S7%7sTE?8pc4KOLAZ2TgI^Sx@_J@*Vdocb3 zQOdTjXPcEWwyVpc2-{Hvj+cY%=`PLc_zj+ORh?-3LZd$+C6jk4nP$_uhyp1YbMPBH zzq)QEITkc+?8t12e`A!AIl)`AQbuM=2??1U32ZMRC1Y0Z-{<1ByWKt{_C(t4%v!7t zh23s6{^O8#JIf?K6Lh;zY?n3#`y`~@&LSlrvCbsj?xQBGknGZC;=c(gTg#YJ*}g*U zbJD8p(#%okOW{^`n6xTe-Ea7RK`Gnuo^4jj*iMy@ux)fLA0$x9)~s=4rP^EF$|P1o z<+I&f!frRoP2;XIlQ z^wzAD0hlHs0dORNBP667ms#V;O0@x;LgHjpp62G_yWMOzA=mAq`o}6Nawi&mF343^ z456l<4xEEe2d-qpM6z+|hIKBBbPiIkd6#m1j@m1bay18^4qS`jhV`Tjy$IJyGxz}_ zO1Zx6tywAK`iq2w>(vCVl#p^YYaCgr_F&RX61O1jv}P?cr?PE*9ala{tI}!BQRhn`+xBJ0 z_H8n6qLl3?o^4jj*zO`BVfzJv&m^R5%^F8ms(p^PoW!q4*_yRj9SYetx}MzwQnr>! zd?q-@TOyp~Jfscw6_K*FNXbX+%uU!HzJg=BCjPES*;>Y&%60&?eWX=kYmPc!3fZ3A z;MiV^e;P{Je&g9@rHt*J5)!s|5tt<*Woy<|k+QW+ z;xoa)W@q6fY=6W46H>MoDfx&ULWJ$$7LIL;8@SQ|DO<~!Q`z>Wwi{Bm=BV?nhHT$# z?%3{+e;7*H{^8kXrHpN3SrlP=EP=cdtW=A#Q#wFUuO#sHpSCRIwKxA z=t@-wn~TX_fD}O9r2y`r_Ew|-%)xKJT#F%qw`5&pr}!-Xr%?)^g|}v<3_ufk{{+AS z0*ilI@HXK;ESQwxo75qyWqj`xZk01Lds{ z0DIxz1Em0lxS2;$R>}a3myiHBjKCoh(v8ck{HV&sYXdlu#3)qW+u3}#8|fzGx*flP zs;J1F<7uxn2fu`J-m1Z*vzX@@NWtY@3T`H~mmmda4t@#cS`5LRwW0%;+>9Tk;Lh^a ztdxO!L_z|t6@e8bq~OfT9XedR_K8Lp5}lCtO0#l@j(jNWmA&xyK-w$K$sIaeCOFa9 z!A|0~!M+vJUTH?|(BUF>`XIgX^|q{#^vd1v?}C(V-l=R)r1l_bReGg4xI>3)HDvqI zN{;PI_+LaR+Y7ukD`jj~Y~$FzOJK2tl&x9g$V#>Mc;Auu3MpH&@^D)>Pag`|HoAq| zzawR9&ctVeJ>J8@Nlr96WAA{Jtwl;cV*4>+`{2rs?PmBlLdw=M=2W%^P`j73Ds0VB z=Sv~mzS636`19~jL@C>;o^4jj*d8w-*>0~PaFv9Vty#I&(Zy?b_&Z44hRWADTe!!& z*-a}%R;t?L%^~|RQUH0E0$51x0;B-U!Ee9(TDf)MaJsp?6$0RU{NJJ!z`fp@l`;S) zNJs$uL*Oq7DFCx_zX}(x4WRy3emRfI4>_CPWu1}zw zgp{pWxz^FeYj1U1lGq%TKXbOQ+kNGx6(TEDb-P{24nhhb?@|CqQhOLu0Op8&i{Zv~ zzhISacLx6PC{^>WaansJ?fuy5f2~?bGHcL{_T0N!wj4@hqg+^Df2S{x+_8!J*jA z!E><3Cnu)j=Tu7ni3S>wn`wJ!>Lhr}YJecG(W z>QLCHzrw#1X`i-C;xoZTVN>mbyFaimN7|@S~R%dy=b|1hL%En`k) zdkwY6NUO5HG)J8;g=|0Vzo3UqDl{-7OM-ezuLdw>xTqx?|wNJ0d zk~j@1TeEVZXg(COy#W7Yq-@Q}g`zGKoL=85oP_Ok>{F4lH6s^_x=46>-My=0I}86E zNZIC{%Jy|?=SZu<)*M_Y>RJuiZrR1LUHvZZ35HU(hj?pN%Gi#UkZiXb64*dO%GRtr zP|L+@ALn-<(GMwGv+_W#d?;jlF#i3KvNb0U)N+~NINwG%3ER`Lk3q`Tj66`wMeOJ; z+wF?0JGNKgzXU1Uyi?geO6|SUs<1T&57ct4hHR&<=GcCQ{}Yt5J;7VEQpWam2?^U@ z3H&S}WouTxkaO|c$N9Ru`N;(;pX_YmasG5S4K}V+b)0WQwiQwUd6xp{N$q+_0hoga zYPl9e0Mi7k9Ork$zdcF;oae1sDFg6^gap7)0((kG0hpBsYPooA0Ed$}6qTnqn?Jq2 z&P~W2=k-u*bv#hZxvEaDPomM$NXg_~O6CG;&qPYb96V6VwHT6lP&QH_GY9{pC?zw~ zTeDI|<{JqKnRx_Wl8}-yEBEhn@!H+)eG-e2c0053K&^Zz>~_E5{|RZgGbaz!a+#pp zO|e~Ci+dOfN80Vo$OE-pBMUO1Coy57ct4hHP6( ztHO2+{*zG3_CasWN*UYjB_wRmBQQ}y%GRtrP|L+@Z*|v@xC)gYbGESCJ>{lxe_>au z>UMXKy%i~dyh{N*Pwmr40hoi|ez_Jy0IlS$5C9+Ge-EVq=6h>a$^h&jAp!6$fv+W` z0L;n*wOqV5fWJumfyxV<&3C)c+=N`Wr=ZjQgG&oeTyNuL2Em3lklI5QgHvc1&yMtl!2QdApv(afh#4X;LIBPQ0)_qnIvvO z+AA$otPX{}@?rcBBJGuyNqiZxsGGI^L^YC45e)A{+E9EilVHPvHd_o!uCJ{`%6gKnw4i2 zyLjzA-Y62sB4ukiO=g={ate;!h{=Hyw$E)(qW#tSDo(YO`+jY!#=k!KaVNVv!Q zUpL40Y5b2PWt(>@+s~=}Kw1^H=HOYyuGNrjBCSe?Z+<^L5T$Heduvw8*lr>rVcUs7 zM+qrgv+}HB7q8vndy?pm%59x3+~ak0)3|=wm8$l5+mPJ?DS*670Su#dC{h6C;I1+cESW~B_krVlDPwES z+vDjj&FZ*+fpb-zXk1UDGmw(WyOhks)Xqjq#vHM4F(k9<`i{&}{GX$g%m6p@D9TD1 znIRGqGQSb{MM6r(tlYoP#cOxFMh`F)jxab%_1Tix>{o<-&T++4zLcd(mQh^$oA?G}<S%}N>9CcPZj{sj6-NV%Fd zj;vIBFli4GyCdziW-V5S!cKcA{^3YFtz{CQ2?mo+w}HA7v5!L9X)RLn5gQ^Bt}QoX zg{0G-jsHxfY%OC>W&1R>mrJYCY0XjROCj4H8#uOSJj~cLO4&Z@*=D7T?V%EqZT3BTjU3yz@Gn5hHt$rn%c=cTS{1hD;DK7M)sXG^y&cgl(K!+ zTeDKe_Gt+T+hGLuk&v=AD-YCi@!AKQV@Zre%GRtrP%9q_*`A00Y@}?>$pf`qCOFs} zBAkTnjo4=(Wot$rsO2Jd2obgi_i=0=$NvaYwt1(r{g~Q!q*Y;S4j!oGS`FELxuIj* z>`_)0rEK5u)~uAV?I4RHY*!)BPD0Aotb8Ho;ycO&l@~f&c(8fTO)ErJsyf(g zL3UH50P-#cFqGOMNCB9G2Wt7Xa_hpu<||nj*(n}}{}_}4_|jXmQU;)-yng~<9D%VC zQUGS&gReY{&N#@2OB+HSRD`4a;~a#yy-ML6)Bm#OUc|%?d?d( zn1csuxfa7sqqwmn^C|w1QA(!KIQwXol`=9LOGwE4L|~bOl#E%qf1iuj?smn;coHfp z?RIA6fm-=c*zG!yX^XVmnUe=~`;L!V1aZVpsfw zk+RJ@mFzIpuIQ~mEilBx3<2yWZ-oGuivMbq0+{5jSt$cBQ9=UXb^`&|X4H#;n}G&&6wZyY)$|gS6Y3wOAbr zyWI}>`yuUimPvdj=yv^Vmv%7r{gHM%i~`C1!wShR?R5NOkg~OmIhE~o)Ltd6 z%87U=3=J9lfx_GSEYQOfoq&o(P%Z2ysvuziofI}%d1W{o2&)!yp9CGj;X&vA1J zyWP`nS|PGhRk!>o%0WZ7RMfGdssz+5k_w%Fi+;ze^vQpzXr4`>$>{wWiWf<$b4=Q}m zi=!!wM5W>TWD!0Uxn?X}{-;o1I2FrSyr)U{cwS7Qa6W2$4lk~yFb!!xUFPypB)@I)x>>LDG{5PQR;6E?gFEQkLZppGWj?lEx1HOp zS9*rKdZ2W({>NLhQkp7XR%rgVgk-Z`lR#Gq>1J(KzEgDZe{D_`7t(G_q7PE8X5~A@ zd?@6)1OEO<_nGG8J4KiI(PlI}K2SKxsmf67dm?3PM!r*YkyBhm*nYi}V|xVt!;rGg zJC*IF)SfJ@3R`pVouX^iHL7g??(f(}&vKtEGAY|e6Z{8XUrJ-bw&(Va?FxjNqm-?M z_~7e8$J#1auNj<%4fN6teA!zdKU4=H!E~%N%So8XmtQoP_OG*tbB+){K1c zb&;MfB5ZdW=-BRze=t(Ed8e{HlG^>HRsG=W+Tw$+E4fCM?a&<@+iUP&g;KUHyfrJO zF=2awgk-zDgTQSP((Tr){07g(*RoZvU^|Dzqe$7BwOAbr+0MiN5>mF7NqnZg&1iVs zLpTZBcd;)<%GM$!A7QEWPuQ+Mz_I-b|5BuEEn`k)`!}_}ORK`x9Cg0r8dbLU@95aJ zevY4ip_FY~&o(QiF=6|agoJHZ0;@?#*_xHx+_<=H{DfA}-K*|!`;h33${n38Jl5MZ zzOQw)Ww*QnL3fJVk=+(4fV@iq454;6qyWsp_qBel+`6z+d_b_uv3@xIgHQ@!4R6g# z8Gx@PBmhnzaGZn`fLY_nO0@w@ATbV=*R2E))o<)3*g?7Cn5`$;=HSWB&Kq_><#Q2D zPeIBj?@~TDQac?fA9KXMMF(6rkhf)16+Tble*&d^w)T9oQpTt0Ajju50`n!Le9X#~ z+AdzZ^LOOJC$umYTF@YYYwi|cCETbm2FRHRoM2y-y5ZD2Y72%N@LRb z4wH~6$h#E4Nz{%; z3cwuPch|3#TNgTCFL^5jz}fiEL@9v1yfrIj01lUs0Jx06B@$8qW{o2&)dp}QiR)2$ zSS5g{euSG)v-3suC*`UuPMEcCnuA-5I`0_wcKdzTz0CP;r1__r1;Dl`*`h>j!q;xBJG6S^(1_eI(_EmHE4aG&?=?yQjX&B6EwB4ukCb1K^-s2wJ) z%7M`wb-om`oxh7?dlmjGP|EgP&o(P%Y~x)W+uI1-Dj{WS);O|K?fu@PBpyb})~vZ>UY%lg~vr-z9{oei(lI?ai0-YtKY|YA}?p?fg zx9?4&7b;)jY~g;-rWGP9Rqgk-CA&3J0C|@J*p1p{|>0tRruQ05}N$0VoA< ztp|{mG5`liNB|s1;1~%h0JFxCm1+YRM`A20-&hGCs=wP!sJY+M9h*7$8p(OBTlpQ^ z6q-ICDWAMc`CL!!RHS^&5&ITHJ_Ck0K2PAEgHk?^cs^Mv<15#c@k1SW{o2& z)$V-nlXw?t=QC@uIuv%kZ}5MGwDVae@tL6Wb+H}WpV)s#+W9O}@)4F=|AcF&Jy{{y zu{D{?&%=U^uNQSE%U?BUq<#@`F2Y@hLLvr-z9&i9^#gza_& zwv~{wHESGMsrI(FCy61b{Gyvn*!gT4_tA5;Rh{opvcr)A$h#E4XlhSD3cwt(Z!rXL zt6-JRcP9P`CbN3D`|a(xZum0SA)u7&3f`KPGOm|MNVxVV&`(0j)vP>%(8X(?>+MBi52Rep zTC5I*To1#42-01mWfGqW&h^$4PI5kSBKA>8*;=IJBjKUuuKgU_v+$pRl&xjVscdIZ zd#SW4Y|T;UOCj4w_Hk@q!#^LTY}|wzwM^nO!Qtj&;UsLE6DcEQYmt(Vu+;h|`+^IHIkp|~uY#1VWz4B; zds4fev?^@PQRhppQ9azOD6Pugc1Qf%qm=Dxo^4i2V{*6|AR%G94}qZ)QnqG|BP-cX zrE-5TlEes9UdzoTJlxo{LS&_?!_BE=#~=lecPW7LsGW!ufH`8{VhCU*c`F3KRrs$! zDS#dxKvv2C43v-nxRt=o5>fzWjUy}72Jj$>`%!trN&q~X$4#htxX}ZKIrv$C^IEs^ z2aM-w`dOrW@-F4GnA!zM`Iv*B1^AVAtI8NapZy)5U-AEpQa%H{H7jL&MoLKdB(E?N zl=3kv&z^Mg+MTZzi4~A`KC>39Lt*FZg1-~e&S#m#XM)bxU^}*+*t;X`d=@GB2urPh z!nOWDR!9ySTjAdVDO<~!Q`zoL?atDwbUt&``I2i?JKrS-IJP74k3cEgA)akkN@LRb zUX+lqJ)OX*64GtYtlUP+#cOYS7m%2Y%6mIo*!gT)A+l0c=bJ|M8l(X7E(LH0wYMP! zV2;?g7y`IduuA896#v601#plDkd-n3b0s7IULx?KgcN{TVOr}koLRr;kl zxZ9O$HRQU^aL08%{&^_ndWE-UrHtzV5|YjGLjvzhNV%Gokp>s9z0doB#CJ%!nzdLR z3c3D^|8J!GJj*0L6YTS1;Up&<Zl&wWdKEhJ#pKPzup^oh;_}fYDLqJ=`oXWO4 zwd+c&!qyyhzT_I!ecm~TIJVp4-wvg0XLz<*DUHcK?=cAp+o1&Zl#sGDYaCgrc9$PP z;&4>H$;~C)=h-yw5$S5H_IYE-o`e)Y-lYI0QhPR10OsKNH-4?$x^O_9C|IS_UV;BI zlmfWZTeDIIV2*?Yz|911l#l{2YaCgrHh}v{+>6ThR04?VpKudu?(=k~W{yH+rC#p+ z^gFd@Y5HlTeDW^kvyj@?k@7J|>|1mV>IQPFY^uWNXZ$~+l+QfRCo5%q-j|T@iC-fi zQa)ylBP(@vv#Q*wtw5qV(#~hrVs$9&e4X%jl#J}uER*<>pOM?Cb;r6M(vD~LlDD(O z`X@|JIf9juo!S=o`y%CP8FMPvU8x-`txCr;N1ZRZMwRP-hdZt#@E?v+u5Wp+St*T4 z$LlSNB3w@;Fh)Yk)vR%3rP|xwWD@70@;jB=oo-k*jmOox+N#UOt|5CBQUH0E0=SLZ zTaf}VN9uFC)8y(jP^>oZf9S;I<{>ZVkye(C|arHo5rKa&9rVQlOj;QHAK{Ad8OY+=e z*Da1Fc?4C%@C=ot)HFVxDJSykcodgdWSeKvml9jE6N)Xb8c8dyu$_;85>nunNvbmC zrG-{XVmjWb;uqlNFZq(q!;_ee_fEv$fm2wRaQ`Iz6Yz!!Kw6Ths0`HQ~f{q|P=iuY$Ef4j+B z(($ZxOSWBMd~~sSB5#Pk2aVr=KWg?rru25!=5A#hk7MF$)OJR?g64?4x9Gg_xMEvf z!CrWKh+kIF{8`ETeg(J2yQTPL1 z0FnKWuJth#jzYTSS(vBIxMpmth}rU59^MidrmL=Qr?!`P?W*}RhxwDdO8L@47bMd|)etBceAN!K|{R%9? z`?mOH1-??&R66*PbBOWtoQxC7q)$o}H(U*VQwuFph4DK*58 zB#k;A$JVn4w!O&hftsv$X_m=K)?}j_S1)Xa<1nm;=&a&dTk=?2KNBn2flg*}zs%%0 zY^RVIg$j@HVj6`jQ0bIgvj%upu4~FSa95#E;UX-L<9$TJ6M3PgO6vaw!`)V?R=h*(m z|2JyV9Cqf+N^UlC*NQ?19OXCJj!+cUn|bsl+=YdOmc@<3R*JqoYekm!MVYfSwF=F& zLrs3A0c$MrCCfB=c+EnQH>wBLZaU|tf@I~h)17S;?Jvha8Xj?i!!QWf0Hhc?d0$pa zn-&a1BqJF1#lJUF4CX9ERxNUc;z#ntlt{q`363dTp$(uxs(+ z3&%y}i(P)kpvF;~sX=4C(qLh$sLd=ld9{t`S*|_3xV}koW}LPcwRzK-&SXK3^`@xJ z_rdh*-E`fwo6zIa-p#@^DYlsF_5f{ubBUp}^hnTBgClqwi~5FdDQdHpn=byZvg!5x z0>5Ax#hSMs*R2rMk4~cE=KQll+omf={krpG(bWf)qxjaO`;nb_@!t_0ie{ zgqwLWGbx|)kHq&OK2YMvR>!YT*4>G=Hq`hHF41p85>qg@I6B={k8*EjVcLtQC(&SA zf*HJ>Q_(&n4?Tqw`=paJ^$ZgpL`NJq`h+N+maH_CiN7&n8EPtPV6E~y%E##e(~>R+ zpU5^fgsN6=@%auFWO>)6uqNs%w#ElBr5~@hLGhq&T!!lwj!TeT$t`6R-;i|OPMX{Y z+YtP_p{Txtvwb<48%7oODBf7uqpmPS5l0Qn*R6|I_w76<3pPFJSZJVy5u^`7g%U3= zqA&@?hd)v9f!LS)B211qD4fh9T!`%s{I^L1lXx+Q!lS5k_?cM)#i|Bc9@V&8;W8}q z@V+GBiM)89!n-K>A1_La_sv>Js#{pU)VA<9mTw4rB`y5Gi@z!SDJ^`#i@4cNSqr7= z7CIEV%{_^g=z^`;+jMo5wB<$Vxc*r%1edOV%fAaN7A9g@g+MzA{f`%XB%3!li#4t} zzrrV2)+4g6#NOeB{8i9yS`~~Z$E}YY<7oFKxG7TFgDDI|6||dGHQ;Fv!@G}!h4#@D zMxtuk_0=sH?b8XIDlG`@3n)yM7OH5Mt6P9}A6W^ZJ&n*c60D-ly>k3!s%#=pdlrE^ zBvgZTi|QEjQ`%1unIkcy-Ow)Bwp&Jvq%%y8*Gl$gax#d2y2_-6Z9rtp(n?(|PifR4 z*_+A9ApU9k`Zd|6(K`B?Ov|B-I$y^wq_C8#H<;%kHpVuR&^XQJm9W5`PhlRahTW;U1%v%Qfp?_^f&CqYZ={7P*qy6e zVCB!3l@Qo}6Z%tvRj|8M2Mu<45oeC57VOolV+Ok;kyRvSu)FLWY}so>|46SI*7IO` zLo$V$WCH&*ToG)&YpSQ^?TuO|Z! zJzSb|ZSLo;^SF%3$wdB1|N1rOyy6R1_`q4|dBt9?qA=}bG#+LNpQ2R@bHrn4arJQDK^-^~6UO@J?nqQJ5`u=y3}Kn7CX{rulM-Kf_CgVm#55~kwhEayOhTJC-u_KLDcMw zHk!UWjgLqt&St`$sOeZvq^@)8QHV~X0dgH)9Y+_ujH;*cJcbIBdGQ&A4^hLnd>WnQ zLUDABgdT`jDHOM=i<-TUS@b8Kttf1YwrfGnJ=k`o-Nq~N;vlB(hZ;K0u8VfKD&@$X zrlhF}g?5GYm^_vGs}Xxlnc>5JhE`h7ZIAIug~mGbS-5XQI`d~KJdK*I&iwL`#$B1X zfZEql<6gY@l)}gIVoP59M&TDEe@$gH=1({CD0)*CabVJJ>+v9x0n8>JaG5Ggn8oBV}lWEQr{Kvr=wVPm#0*?F{>-t2va;bX};KI--k$Vq+=xJ zOnyxWOi7R6lL$2IS_#TtrtPb4JdJpM$#Sf2`s{gQPH6Cfey?nh%gT&%iP zP4LD)#W*5aXG1nk-KuWDbQRLAY7vF`NVlqqF2soYON4BzYWE?166qUz5QV)^(|4|} zi!6{t{UtD_&~T9~&QhwT;kg2(o8Nv^zfP5Ie$O)bNu-3Y!eC_p-p6y6Ps>k1DLV{(#>pN3VX{7+02fia1@e1eb2w~ z%(9Z!M)8oO`Tg)qWRuhP+8lgh@Tt@*?{y;I8t8j$wLIK2@8dmApD)>SHF=N=8aae0lK(X((s6cNutXL`dUuPD=yE7Eu4bD{G)=n0=%i=kvz>7hOdD1i3(;e#v2#x|?ultP zHOek_J->C%7vrf(^P9vd6i&u83h6G^e4Lu%^J{(?^%sdp*4#YYG+jKlw)ap!3-PC0 z;74v7W;EQDq)PtcHIjzS&SCbl1-?S$Wu$L{IT>fqW&9TS9^QAvFN#@X|JTdc3~ zeu?;ND(|xyOVJV`u}0GIJXsXk>i)pC9O+t`uTFh_Et`DI0SVFC6Q>lTwpZG5btv8A!_?Fq2+P+i_azW9aYouT#6bd^v!%l zuC>N@dAxq%W+s0`{ajSIiWdVv;WtF6a3L?oQ#c9f&bzmp3wI}y^cRKpgC{Z<*?G^w z^C)6;mDCn~9js(0$AosDNGSOkTVW~x%p>)ZB%7|xs~!A`oSDv|{!m$w?o@q;=>t?) zgBP28%0-K)shp5pKQ%?hwJQ<=+6OWVIVp)6q}AuW;UO{n%=w43IDrO6A#L#)3UkmV zeW?*!_uT$c`=+9=TbNWZE_qhUX}3iQeetlB!3OU zWrACdh>NNf;941npD=!(nwwrZjyKYiDDb4H`1iQSqVpgzo2u5I^DB7NusHC=k@(6z z3rXQCCa*?)XVj}HcP+8DimB(vwF)aUwHMVr#Iktr%)%_Bnc0mBKQMJ`s<%W9+YZVs zCAGBdRBB$>mC3tMzY}WOg8SFnoSH9 zcRJpws7Xk-T>+8sTl3u{U1FpDB-Y1KDWu-K%I@ER*YUoJ;t*_$YCmAR z%Nh&ZkMS>&d4zCRsLmMNpYSe2ynW&O+^RYuZ=by1#V_btDE(`C1N)-e-S%IM)=anQ z_3xAAxtpq$aJEDZJ8`0AzEbL&5qBsIV{#AbyJ?FJ^Z&=4!+fvaL|R)OubdQlFAKj> zw*$8RsPG*x_MtFTbGpBN*kd0expk5*o1D*5$o_gHt`SK0*XAok;`96KQ>h=5wzeBr zCz-2xbcnRpEm`UQ%h>shpsH{n|D1<)qBMDIU~Zx2^0l1!og>Dv{BsqiD^RZvEQqzb zLTdbZ<)k-L3+wXFt$1!0pWK4Td@WPola2JQLl07YKhnDnJx}3T)K!*GZ$0!DuNEM^ z&g&^p!%B9wuHAa*Q>-7Oq$d{uRb;pz!livCyf*A7Ld%d|m}yQfwQ!l?Zqq0ak1qw8 zUYJ=}%574K==EV{EpyV{(1i5DCfUQAZItQbKxplv#OVsEe;{t6cHRu(2dg zL(0~y#p+PV_I&)4kg~N*;xnt*jE2X{FLG?BV!s+GTZ@!@#Cob+d-v;wj_vLEXCh^5 z8FMPz$EkfpT9s?>%u(k{A=}fWRbl%!{x?y|c7bP`l`^(>OGwy$LEtk9DO%zoL|F(T%1= zQC3Q0vSV9M7Dd=L{)z`ypp>myV;`!$?X@M*29+DTxrCk1rqQ^owN>+-Z!NNGAO(fISH8E+O5x%*t<5 zUA#7cLr5Hq$}2gW0}$1(<|fqad{KRmTy@2r3t7DQK9G*!NPjdfVSL_THcd9E26RaxacH<3>odVXuZ#??N~Jpa3#Hs$l3B}lZ*k$z^j$(tNoHs@{GKw`irg>J=BR@QCtq#b;fZoG+B<2n)-<*P z89bQD8*?qv!Gk3f-b6ZhFwTYe_$(m?4_>{BkPIHQ{hFN|(!ql>edDi-&jt^MP~Q*f z;K23I`9KBb0q; z?n0`QBz5rMdcPv|ujnl5Z;%y{kNW*E^+x(p{~`+KARRn-;hGc~KOd72g9q&h1%n5T z{Kt#|Vz9x3g*5Q8wOIcxyGNvh2V&E~gH4&z3+dp&kreiq7czKoCxu(&g$y2iKw%Nm z!GnV&EQ1GKzvBTgg9@=>=n-(TrR z-9xY)jCAn8e6jlc$JqmEdc#yl^nGIQ%B*DYz%uo|WKDXy-{JiRHEGHqjQPvHo#57oI=FCxZv(Ynl4o;6eQlbVsCv2kj}eMO|h2 zbnu`Xuhv0&zTC>wu#z7LaQ7|V4C^K+>B*6-BE!QjT-s;CbL;_xc0hWLZO+(dg298= zL8gNTdt=`V>9N-$MIQ+V4|cnrj2wH9z<(IhW3Xk+si&A{QhTzrD#v1Ta51G{^>lNW zWAU(SX;sbu?!$i%N>4FY@z$*5LY!k?EFn3?e2%~~64Fylv&NB?YJYxto5Y()*_yRj z9SYfghW`_!Y%P=cOz`=ow{VhQ%>Io1N2F{mQt}boamuNCuj?G!co~zCvbBskmFUgYr<96oHHusoOShk&fE1?-??|b|M)xjcK10|)u+2c*X_^_n77WTjj3iP@p~EG z-g8Cpwio=KAoI3+^fr%jZ@-jC-fo6qfJEl4QwxblK5S|_d9Wjj?LosjA(!&&7hlKM zn8Q}zwRruqFWOPS45(z80f({m5MTy4qYzUpH{f2`s*`If{Nq4o!1~dEJjxCDN+KC> z7J@S+G6S4iNIYuZfXh%^0va}IYCuvyB&=xm`o$h>bVizZR5f{U9Z6pc%%4h@`SSo< z?*itJGYT=qa(`aesVaY7hyNAbsTK0Bm_tsDHV zz`S*hGtJu#*}A?`Rm0|t+8BjIt@8C(s`7S6_}hcb+uftLd6daCd2p~qI`>8+*jFO+ z)~SWWqvp@OBT*ay8ukvklvh4q$2@J=>bn*z-*mJm0yChJWd@wf*0X^b;EX~{vD|KP;^Zm{D%T80r}*C3rkhPIC<~}g4ZO9lLs!UsTPIF zgHPcvlO|3cxTdyRvuMo&DPTT%;M5jX)TWaM&a12DG4dRsG~?ufb6Zw(D<%(|*}9rZ zs!b*joZ3)Dt(rXWqnIWhl^>wuwUjkZ9#k^&$pha~s7j^D9royp4=qdL?0Glly>{k!F2&lFx9X&%K#0?DNAIx^8Sg-4+{ z9N0637Z98S?3qHBrHMx|0e`0OHn=xStY-?JB6u9^dR53d-pXqa>1EFp`nELjC_Yn2 zsqRv#hWv+nUP$L1U=Pz>ANM4WvR&81bn~S72+h~!gsJX825)IR{v z7CEKrVLIPXtV%@(YL)BB*&a{)o^Alx!*s4GRcZWTx-L*V0WLiCOyP3j=3?&Xe};NN z!VfB8*)R~+roe1iIr8!-w_%|)vSB;;!-3i0OkPkI)lF^K8|t0_8=O*QgKyx?d=;sv zv|VoqHXKYcJ*K-Oq00-@NQL{w`s2Hf+#s z{ChXKjejU**#XW@1G84rA4E^*{*$%S^!%c3<4J zmgQDQZtIY4pQ?SE;<@SR(6Ddo$K3KLb`nz3R|B|m&3VCyi=wXlXW9+ zoOnsiau3}`Q#6}Rcfz?{Jl&+_Jf3LQ)-M7=Sq_wIa}b^T&Z(vV}hBT z*&S?`Xb&`&Y(&!lY_8NbEvhv>SGpS9RROd9`eDiyEt6SzW7FH35AOw|r?Hf&%~m_J zb<}uyoC5t=U=t-SDMraG^(g#l zj^Kl(oF2M>Iurisz~%{D<4l_;IPhm~oKmWqC~-z9Mp>HKEakp;kgDbhTKvul2eNsB z6QWCbl*u$va=t{GCs+}|3KH2ofm8YFYLK58%HMRBa%~hnfO+fGVzsE;+l}FG2+Uj8 zl%nQH&uC2HQTZfqhe00-%v+b#M9FR0@80I^aZd+t_k=$Zn76KRrg{4+TMtsI^41x( zF)H`=zB_}r|NbA3ih<1AnbF%k%Dw$sB6<4~f)^w*Z=K3_W`q2iQ2wUgeuQEvFmIh& ztQM7f`y>4CfqCniQq)}H8I387l27us=Fc`s5tz3wsfm*DW!}E?Wbn2F{Pw`Sb&WI4 z+dbLZU8%}jXVk{1+}joI4&Dy~j*YLjt=B+bJQFCT6iraNJkWcdVFX;aR z=B-O=qGU*!xBq$|c-xpZCJn&6b&WI4+x6JG8Zd92Q5#bYiQ2^Uv-bvXXTU!dWZvEy zz0ITC+v0t}+lvugD3N*V)I#FX0N>>%=k4_<769|ssr)J(@{FQ#Zy$yK5HN3@S&Ew8 zp3#`X0{J9w-+}%HFmGMLkJ=#{|8BC*+pF&n-ZF?xegNieCDXiJwa}O>56oL<@U(9< zEZD?(yN*&-U$!;;tw84O;z-S-+}poPr1N$pg54xCZ=G65Jo1}*nzpy&QH%o(kA_^z zC;gX%b=+qhqN-PAPC9*N8Vr}DzOAaCA)B`BT%4Q~coykqdoup*oEAED_L{n>AAzAa5W+A1qi z5`PYPjYMAo=1e8aocWrq9|3d58HJc)NYJX?kOzY^s}&oQRYB&=kI|Vt%48bm94C>S z>4l)DMCOcB3yDXu1~sX6o1xeQShaI%v07AK?e>5_0$8*P(^MCgYD zt9CA_iIVbax5{F6NJGe3@Xr9|t!tcV-Y#P6LZzzi!Wp$OD))BYzk;`Kz<&*7-WIRS zuG+a#H%7U)uSg_sKS%JXMCPqixluQWnm_CQK=B)Bs0+06YS$3f@#={XRaLu&62}FY z0hKH>pa)ym0A_$QxaJ5cmK$)DY*n?}9R5I%8L)Ds=233Is}jk89T03Mks07rK6Db~ z%^R=}ioHR@>VX!kUEi>xqS__(n>E=`@nLhTmCoSygTP%7_A}PXL&@`CV8&Il%((N| zIu)34&M3qb%Z+rgzvUTD(U2q=81eTF!f5-nyhFO1vGD zw+)X5Z+pV;0nA(1IMck{k*!0Os=RdukIhEIf=vuG&i{Atb_)DsLFVn)NX?_%+b1QG zw=)r(A(46O)I#D>^A&y$ic3Mm!6BFO7Vn6#j;s9;Rke6GqFo5gfJ&Ab@Hkr^0cLw2T;1sZM+xs+GC+rv8U zpA1n|wc7&i0AL1GvdnOX9O>W{R94Qz^bh?d5|w?%03-4 z(5LEJwn zYp;i&3f>NZKNw`*7U#w5gBWEpU3>i`k-XgsYR7qDZmVH20u7d?hC_(M`Ww2?FI191DOGBBQ=k5 z1AdlB2Fyn=Pa-qGsl4Vk$eTCdHWZ6MLx(_%)wXL`kyYEO+S$8e^NDuvM0wqGMw)oE zxNN%D&Yy?Lc`-2iDp_V+mnP6Yix-t0^U1r~aP|zgFqujm? zB$9oNh#Ej+r+<Cns`)o zb$c6$E&}FECCi*y!q&yWoN)%<=8L-^Jm>FC|&{$_k~=_tKH(Tj;r_(RaLuXXqN&rpps<< zr0w{@6^0q$41QFLdlmMDlj~FMi%zbU&~yZu0Z&J29_0qCrsF3A)Jj%U&St5Bm4#5EunYT{mo9{v1{MmObilae8 zuRtqrw|pJH+lH-GzhccmdnzykDp_X0jcmOLm;ufx#1zX7m?v9R{aP*GnACyHfPv9~ zJjxAtMIsrn3WAj+G6S4iNIYtOoc}iz>i|2soLa0Fm7iP#;BNx#WBugX z4*GClCznfVqQpnf~}pZH&sj{oh-`+ZW+K z4>E7Jj^5@`?(KSS2X8+_@PS0;ty2q$N6im7en#;}2yAGU;z`S)P z?+g!`-eI2@aJ(#^bPd%LdJkaUIA2bUwkKcI|Tlgz`S*hGtJwB*t(xmmAB5| zrP~4vln_-7I37p)2rvUGS!Td{Y<&xu0nRAI6vKhAeseD!3K{SV{GUK(z#$>? zB*~-PfO9310WDTwGz&5VoLY#Y<_%Z@#qywGLQ?~h`jf+oiUEg>D0~~QxeBbRaej9a zT?3dil`L~+09)4s=8Q86F~xFcj(RURa|rx{K<3QM=u95v&Ri#voH-7`WQpw5a4L7M z26?POO@5d^3&rWcs-080bG1@bUhS@dKMz>7b0&AL22JmyJuR)y^5*xf)U}_x8E>gSS08HYVLc=Ites znn$^}H7bg{-3Y-35}CJ7EhHW_f7T5{F%&fXGvrcU?XC*zc!DxSRn=}Uw7UZ{pps<< z9L3fNzzlFkA*NVv!1LM{Rl8a6XM)UtTcQDZlp9d1<0k{=Ah=W_Gr*~Z#G~d7xE{qq z&~Qgn1Csj3!-|S(m(;)5WJAR`KdFDe>E_B|Zc_hMQ$nH1M0!&Hd&TDJmsvU^O+5Ok zkQov$BkpCF?gn;TDp_`1y06IO9t=A!&M3qb%a6-JABN+yWF<5pJ1%weeGHaI`Ej{i zA|0345WFIh9T%tagGi8n8p_^uE_fM=kAPKrrxvS4<(2+t_&)-x^seE<8zG~&Jfks% z1N||J7Aww)Rk}s`SpNjZwL`k9`!p z?Yt^;Y9RBrL-aO}a&Lc=NZ$5E&|4z&)~SWWqvn6Z7=&UAVBR{lSS>2|b{F_N0rS>1 zrKl(c{I$*7DBc9-ty7ED zqH=G)g#S4(Z(UQ0nzCz~E#;HE{U7w-fqCnankexr7M-_Cz6jnntd6h3J2Vikai)3O zhpnpu^VS))kz4NV>z@X1PlbOn$h;j8z0ITC+cuvCZ!bh}zC`A&Q~6yp$eSNzEktoO zFmIj8@0yjOa&I4j|1V(PI+NcugQj=bCk9!!$|rgI7WCJEdFw=e*9?;KLDnsw2XB9Z z{~a)IE1Bl)%AFgN<$!tX41U)Psg`@&U#V)0u@(G5AoF&3q~=lX?ZFc1yxk4Kt`eEI zPAw!JH9y7}hvERxuw%%je2_IFtmEDMA*vc=9gB7nFas)CX25K=o(;?ZXK=|CQY<%M z104z(a2@<>L1w^yk(x)j0f$H=1MWd^mqccOQwxbl%^UCpipN01xR6UQAgP}mR#XhK z?Ape+rHMyX*EX+^=u5zysbrZmU$S*6FlU@mh$)skv(uNsnN_Gf z^fr%jZ{L?l-hPT;nMCHTQwxbl&7XC@q4)(foZs}UvykQs1Iq~=j>zy}h^fb9?rm&gooY9aBc zc?0%Fu_tJ_KI9Us-2-7oMYT)nmo(W>acyJ9IfF-+0=McnjDyK@JTT)bS!UevY@Gtk zIA`$aQb@7<%=uX7uw4|wp9wPKUXIi}%8gq^<0KjPPXu!$GUJ?DNIdc@n5GvWH>0=_ zG`taViN<{rR%FKQR(Ww}4ml@HJgWK)<3SR?ADBaxEOTfXTmJ*hA!ig~iscT~eHR=W zy#}{DfXty^qC4b>4^XN)`=+2d7G&P0SNn;RN4d9`N+fS*A~-`L^VX?+-zvyGk)~(g92A#=hT1?Y zA1?ShUVsv|R{e%?J=%r945(z80nf4ZK41nogHLhBy$bt6yEXQQV8FWFxrq&A2CNXN zd6XM)nM5*Ra|8n=G6S4iNIYtOoWB!_9e|x&PAyi8%1^G*@b?9Fa=E4yHD%-cwf*Fp z0R3=aCznfVqQpnf~|;UxkW><=#I0WAOH8 z_&75lWVZd>ze9}07N9fxE^VW&{_!uNUjF7h%{~WwM2>w`L-c~Zr+q2nvno^aw z&fv$#kZLH0P2qP^s;anm!@m<`-u8;rJj%V@MIw3oB!b5!vh&ud{K^;P&G)yjqj(iG ztQTnI6?en1j<@rNsA|CR8QPD58BobG14=z86EFjuQHUv)8?c%Vg$!5~{>su7PGM=Q zkU8(8icxOBt`f%B$TH_>TdrcFyD$!Jz3KjyBbkMuY45^l%br<{=yxkW5FpznBWTfU% z?(GtZPfk^zemJSdSF;8boA4D#j;coxOe zpyBL5i`DLmu%e>cCG|Hp*-$agPwMY$y18C#tie=D00#>VCQWGUU zJ+995sXE>trCR+n{2zgN>l$a8w`;G%zY#3lwDz5FP}6}>Cm$= zX$Q<(m()awUpL6xEt24EANYR*=B;a-Y2J=w>vl?20~Ke~#;Dxe$Nvi6z6Splka_!6 z^fr%jZ-19a-hPT;nMCHTQwxbl&0k^shT<2{@O{Xoyv6i&d?_Jpt-8W!`8Q4-U0&M3qb%MEx!wyMQE8~#}!GoW~lmpzYi1OAXm23(F{u0&>lQ+Wz3$eX{y zxCO;cz)miw7OO?&C)Z;54+1;6TvLjgvMY?U{N(yC^k;ybTrR1J62ETH$<@9loLuk1 ze;b&$u5qS$Tj<3d`$|h2ZV(Xhwj{+xqBj9_8NdA(6a25W!f9%v+}x z5|5f6>KupS7+~HywOB1G_x1w#{{ZH#Yf4emJM0rfo!?6oP8IiN=+^`D)+IGjQa;rA zwHUm868@vWymgH;&D$^7`k_*lx6Y`IQMtF%l&a3#71rg>9gumua`ZNja&PaDNZ$59 z&|M<))~USQBgmWY={G{L0ccn~(8?=rx3G>cCWNSJs51=h5MTyWvdn-nZ2dbh1DsKa zDV7^BU57#j91njA$PDNkGEb5`$_=n0ZuJMQS$~|isE9>ut8G;lKO4J zii)9*jYWJLUsDdOsw<3zB)R~YGnFiJW-(ju1m=u03NgiUXD+J=&U^*`3y?XpQ^=gR z&BiEq=D!ljng1d9T_SVFsf8$NzS_0v-I%ljR_$C=tQM75yS3nV16J)^!|RYk>3WBK zqS{ULCT$S(&45)qC)PxXS0*)S6I!rC8jFmAzXvdHUE@sib~;-pD^*oHXVk{1+}odO zgSXeiUkEa9_l=I`QSNO|6-D0OkKkU3%v+~&7hsS#f7U&X;wjKDCeX^O-T1JMyX-?$ zRqftJ`#LZKDp_X0&usl3m;ufx#1zX7_*wg+YS-9@5`oNsqeJFNl1I4#f79`k0jnWc zRU$LMsf8$N-hf^xdV+@Ini`PQ&k8Fls$EilX_F0AR~Xke-CTKvVb#_-JRlR;RnPhl zpir9tbGDLY&hE(8VZfYq29Fkn6w966xn*$nQ1}Of%-LHaHIH&?B6HTM z+jfmK`Al%l5WS^u^D5@I3r1;DDUOKPIT2d}EO zJzBFvsd-dr$N>k8*E6kVxKs zkKkL0%v+}x5|4bS*mNSj)R&@xh6h6~<<-{LrHMyX&-%AV+YXokl`J!$D_c7QGr$>z zm}0pBH_KL4+rIF7gUo=(q5*l78?aO&8L$O{%_K4doLWdcYTkeyQEU$yo@#19QvYgL zkyYEO+WBF{=89VszpdEZ4+TzCH!x zd|qK6$`$$kDVR0jb^-cpwHF24ATX0;W%+SOvFo9-cRZW=!RrIMYfIgctl5sGZ9psS zjVt-0fRq!9%RSDn+g=<1XEd0g;Lq&d zA{5p?1anNW%NdR3cHaZ}4q$dWn~G9lN3{D{xKE3}B|GG-LX4t)Ug)>szA3&6?fhbl zBHwr53%H*F{p}*VCxnu$X{)I2hZP%3GTZ!3*Jsuhdg~KeGc{0S<2sF%U0|#ZYzLi@ zL~hBGomO1Qjzk~0>x!=(bbcN=KOU9M;SLmEJLvqpERpX!xC7knK=`ZQKNR}i6S8k` zgpX`6u50}=Rq>v%*#!gMWM#vHVeR=F@v^2ze79NPC0S2|MSWf*S$+e)@$fq5XW<+E zY3HAGSj9f&P%3rRryP<4^|^;D+jL6Wx2s8>3-XR(1}&ZY{K}l9N@EPg-W#MJuy8KH znZQ2m@L>=o$tF6pOQqhIE{{kbcDNbNjpFIU4$k8Z(cX?N0&wu!D1WvxPX}a|3U(`E^nBxdEr}A`4N%Ck8%a^C!SQ?BEn$ zTmdD1R^V5*{|xN20?w(83Hs5~=NFFD9&FEN1?u|oOCqq(3b>|4wZ=c}&=GD25I*eS zik8V}mBc?KuqKRd#!{yCVFzcnu1Z^ut}W-~Xn$1e1N*RpYwD{s(cP`#ZUyYa4$g0= z<_D)oLfuXDa;NzSK|B>Qlic<3P{#rLu!EDBC8(gsBQOQ-v7pHjXj{$4r|;W`BQO*G z8OlQ+cJP$j#V9KfpX2Z&FbD3XfboDn?BI&_F^UR58aKke-W1woA9iq6hh!4RjU$kK z*x^A~_XGQ|gL76$PJt6Y?C>nxpB6_Sc5qI|et?v&yyJy?f+s z4E1iUlUKkCeW&jmG+%-ADHi@B_#ddLJta?|5R>u*;`jR6^lwb+L8|Zdbs|^=v>dp1 zE-qG!IWI=Q_#4!9q}6x(HYL~?H0mVD%j=Qt75_9WT60Gg{A*alp>G51L~&wG6uTsz zD0{*k3G761er+|ML%6E)P*oidf1L8riQ<|TF^YNkiE=F5qd_=PT+y;x;U~%r*r%Ez zX{lkoOIpXsGvPabHlV!__W7A28^`qu2RcdS>x8H&HT**@vBq%=;9Ui59QP=}zkrS7 z?uEJ|G#kf#&DxKEjpIByUOuYi7{{&Nk>oUvTXBQNWCdU&3+EM#7sqiu*xnuZz#rm?jo|hJ*}x*6vs;A7JN`JZ*a7Z#;@iL?uozfW@MFKb58S=Qw}C}qF|erQ zd%t@q+=GGsY#g_HU?#~M@`G_)KiR9H#R>4HfbQC22hr*VP<91r9-0pNkYB&P3 z+u6MEvcisNcSragfZ6S=LKQz2dQG_9#8;u6UyP9-&Um`?hr2$|pN-@G5lYhCR#lGU zhC>|$Y#cW?Q2k1>PUEMaa3F83zC8)y%Nb;s~cz-3{bhJPWsWcigD1-=WZ@G1YqQDAbQhIZ?X?UdB7 zQjpcnQaq%?Pa~^Ly z6pxX~>8rxi$mCTxF9RFvIgd$ucyToHG21@`Hr8_v-!l{^j6i;5^Y@~tb8!lvFBBz= z^-3GjF#sFuIi)z(_IBcJPS4<++8Fr})`)B$?SVRwuJAhp>p)!7qFUn}NME?U zK^W_~qGi&H!p5=Q7BDt5mNK=mo-;!i=_8>YA$qyfeD5Tl3Ykgn`pHnI1M9+_#2d6K=+14#^fAw>Z{&71qnZ z#(K_KA=wE|9P53;_K(HUSkE~flhI1Y$9liA{b!&*8|&4CFZ}UApb&XGM7>+(aMe$Z z^;&Jri!p$W^;RP22yCq9GQR&+kw6^ltp#^Yi8a>Skf1-Xv0g68BP*NLK#ldbhPsus z8td&wuq&{!o-0Z*<4kE|y-ihcjr9(IzCW-N#U(XWl6ay_f_o&e6UF(p)qDEFE__ji6^pcT z~&&4Evp3UxghXKXL3NKD?YZT={*HtTlk~6d2b1fkJXt*BU;) zwm#aKX&WWD1zR=)$*}%x{%sA!V<%3;z_hgrzB8M)2lj31d+C$($9G*rWQ$s}AZ^OM!jz*qLdyCVct%dZ-Hl!y702CyyEOBn{h#9bd3154pV% z7Cs^~4S>Q&dQTjmeMXpX6c=YNo|@Eu8F=02)CL~OFCSKJ!@w(w3!0eUxiF2aT1{A3 zn@nJ|q`y+~vd-%L)0X>kc+*SRbT6g68>F*Xc#7ajElg+O4T9G|(&`>MfQ2CmzR#j0 z4oufNT}eF7rY|6UCSu10p)e~_m^;|40@-f_IsvsG^V2IH7HOYHCo2b8W_Ae*T+|ruiBd{k@tNx-yzk!?VD@+7NqDz&+S06lfbI7Hv;HlD zH?$z@zajVx)VB}HW!c!cW>PXW>B_6o(>}P_>X>Bx?)881w=$`BnDW0Qxjo&hj*|6C zYgZcCDfvfmXxor`I(MZWHObsmtw*o4^JW~SbhpQ|rlVKdZ&eaVM+~-xqgOh7Fq=DW z)|j*hgLmy@$&OTA@6C#yU~W2RkA#E{?DPi0J?5re`YPR{#7Xy@o33h$XHDT?6lP~9 z;`~seG&w|0te3W2#sM%lwkE}`fVnY}U^gwujROhBf}}<#;(Z~BLX7-5v~)uncAb#N zKt4)>(E%PPwY_1!&YgJgYhukE%`QGx>cuS+1D#(qAhqlS$}kS_Lt5bx^_)6 z$O^u!zsmhA#d``2TD>>rUN%g};xm>%2FG4FlyzUOBu&lcd^v}8!?xkD9IzH24L&IO zZq@DB(uFOn0~&TVoy4Z`2PJ8mcG{VZ>#?DaHg+AiMQ!56;WZRGxSw|T1a^89TL#0~ z5?F0;T20a&T47w;+K&G&Y~Kmk@!y|dv=(&yClX8mNwVIq*VQKf3VY3C1Ip&>0qG>x zo&sT-6ysQ!LvS(ZE=JvS*4)d|ouKY)7G5WKSqqo3@IAqofWHposR12c)<5m&oxV-i zxvo?4`oQ}$w;$p`d;J}6|Ej&&WgU0>^)*$Q*4&~o=?b1K97SjR`T%WDM`S*~)qW&P zTe5YaSlW^ILV|pNU^+YU_JH={YiCA6*$vpvj3YPzbQjBZW-?310Na_f2+q`kcIHZg zO8{0~gLB=ZRRvk~UPJl}Yu|$K21p-f;R}M#v~VX2|0DPvV8E|*`5n4o#q@O9%AJyb z*Y2@)X2UNxlhWKjwCjEE;RO13N7b6PTWZpdhxXE*$Fa!Y3ifZ3JPz~pbZnBo&{?8} zK4H6!2IIE)g)iR&FfLxSG8z!`i``3(y(Pv*$+l5bma73Qn=?@ z%5qWdq4PT>ORa=TBrD-Xy;Z`UDBT8N(21vVa4*_U>+WNDk(K)WDOsugHkheBL#gL? zu~L5=wp*z`4+~c6+tNZPj%)96?cJHSMfo1rH`(L2_&L@0_&sFmFtgv&>ekjC57i#` zPda{4#{0u~Sr?FQl6;r`5sITd?heXqQ#X-rqD1;Y>>TnIamOaaLRogSRow&844$4I zw`Qm0?3%lF%9_w*zD|I?$Gg2}caW9eW8;^y_l~VO5NCJMx@`y1+k!#c^wYY(Y2C2F zyp;?L>b4!@+Os#(x?frT5lopl_Ne4s>wepAMQZ^X2VBF|68~j?9xWf1)7cBV^`g@3 z3~P1hok0Ccf&SqpHY6&|zGo`4eO<4-sW#~pQ|hR_n0?x~KB%u}%RrR9KzD7ZyPGxV zv2-e^dz6KD2%gr$^DL}2gbPqG;2joP9rHBbiI zzw*9?P3e68sojRuL3$YrT?jgXmh=CfXV;W~fUX4Afua}-EBvoMih z0;m~<)O2BH+Sc1V?Pz_obvSoF4N?#qD%DsPb_Cr;vr4t<&Lk?RTbfQVK?~}Z-XnNU z3#wGx>_V#wLZ#Y)CrI?iCpSZ6i~OTQ_8NKTmC6}>X|sY`QK@`$O)^V6K|;MZD6dpk zk^hyzD%I@-w`#$vIya>NS#5?gp%S9YSyr zuR>T6I1**A$Z_D)vroy0zE{(N=6~F@n1_LAoIe>l5_W!n!Q%NU$wvbNIe_ z3Z*QCc`a5*Z)EjBY#%GZ6)c=aaFQ0zW8qeUo3wCR`NC8do?-10P(LT^$ppp}@xs7n ze)P{SEsJ$=hH#H`2>ajWhb7!HA5`2$m+i~CX>0oO&q;Bq@++{=emCw72CZ6ij=P{X z`Bj3sg_b{R=htP^rf@a}X;&786Ktb}l~~x5U?i~f+f!%})6&t<;v(S~Gv!!qYOAp6vJ!%>9EiNdu zo1+vSfz}VfdP?D57PcZ7WGNi>F!%4o6g-Lrzp>EzIi+wswA~Smkf_z^B;nLzvbGKx z#M(_EUe2bmkj8-YLKcoDm?V`M`+CgEqnOoAg~m;lf{Z;K!D$k;l1EN0CL1d&h)0Sj zUoL`l0We>#A($^!VGNtzjahk=P1tkV-(2X>Q_aqC(C$ERn^HKEg+~b<0R`=$%L*}K zlH2}@N!t1c-`f}AKd%I|w@V4$2T4u0TWXVKu?QadOmi_!JCrtslCH}?-=X+MD(*(c z=oMRK=Rh8Xe3Rn5!V05RavhI!B(s82wYl`>+9)a}!(`Hxg^uZitX>{c8;~wyVMBtx zTA0tmUIZfme_j9kFPflO*nLSLojqvWATml9(|W?1EZGmxz94u5wEF6tT*JGZ#JI8@Z6+d}-B< zxVA1vzMl-2tQ)x&>NV1;8@Y?%4#1yvBWs3ZkS5Dic)F3rD!jUpC!swKtQ%Q7@_rVN zZsct7)Q!9f=Vc{n-H0d1YlDNNsvG$j@`n;|q-eF*i%EOrd!Tmu2W6wi{YMnvOJ$9_ zQ;Shv-nehD1tK+KrM)>FfHh+63EF|ApvHZ}n5{>CVybbUtQ6F^cSo>>Qc&aGpJ07U zL5<1an1V;K;I!E{DFrnqLlF#-$QpO27LyhWFcRWY5!JZw4rv6i=58Fp0j5$rJvw^X zQ7YQ$m9`AKI2qD0QmOwsgJ6cK)K0sqCg~v+ZS(z7scpU((uGo~ZN8S^8ej!<5p9}8 zw8y7PqypXr=MIU~9zRa-D9GAlSJlN#n{SU_M)9IlS%q_1Ue;(K`}mDAR)zZr#ZsxP z5g#8LagU;iM!dV)R{8z|g6|}KgnjW@CU&Mpu1RgSF+}$eR$s>7;+N}m$3G$Vchh4 zGYj9c_I=RmI-2eAA^jwIR0SN;X7$4dlfm6=8niF3F9&Tj@N-_8yd>V~rRA-*j$r#P zpp~kWa|+z54u|pErbWr~Vu_n%jhO9uPY69kVuz09FidaZ zg9nc^kD#}XV3YINb`Y4F0_kZw$E?-rfx zBI-=Ir%SAhs7nYg(t<9ct|hoe3%ZDk3%ZE9o3(d>`tw7o;UcOuJDYV1mr)ej`c-E! zb*f$8x=kQ`4B%`^bWs<~5{z73@+ z6SaI*B31Jq2)avT{i;)IlQUH``qc}zhNymZV@Ml9Ye4muzuB3Xi=SQ z=vR-1I!RjftEUp2EUo%g*Ve_zi|qaCMNlu0R{iQV1oHuZ*00_W&y`D6c>2|jLn*xa z)w`kH39MheIr6Rxr`|`}N%gCb!+BImTEFTE77~xD`qh^qzbHZ0uihP#_Q>}@{pxlq zj;g|kC_a$N`cVIMi9>s#wUDj+v3TodsK+w-bx}L-EdHVUTs+ z@5CZ_)O_dt0*dFP%KG8qb>1F&6b+*vzDXJDIK7YJU8$@ec4{%XS0}vp!#_ay3Rpkf zaeoGC!201$2>Jp3TJ1t3IzRLf+~c7HwrSJtgW=?K5SvCp+e5n1EKDbu4BFgBtLUOa zCOWNV)$|=!FJk*b37%)+4T4v+@FWX=5c~k_BFfdpWT~=TP}A;dWvPp(wZ<@H0Co|z zJHbv`&_&b~f}^#di>QkUW`p`$|BvgTC1KC}ddPlzvR3-FxX(Xk`N85(H0}NJF)6;!b!JbE3ih&T@kGCW6;Zq*lkN#TdmZ zkEq}F)z2?6TaRL^!`06*N#-bCV6F5j1S^58_LoXt z`#p*Ur@_5JDX8}MLeSGhYNef8j8QB&qAw*)|g{0&1o2Be(}-t#rp&1dp0;rI(<1 zLaOXIJru8&Jc@?VO7E(Y>o~oJ;uWc^m3C?|*<4l2Tj|dsd<3kOZZnSG!hp5XeF=I3 z{n?z?DzUU9NFkkl=w7>#ljgieLfcU~&3WBOa3!!gFV_^3Daw^Ouh(`$q&cr;aF$A> zIj@cfa(@iyE}G4Gjbv$aV9m8BQ%ufMGR%1`QZj0;{{!a?W;!!Lqt=48cQ&P2Bcf-FEWUZD{OU;Q|PLfC! z>Tv{*N@V?ui?}OQMWcV|vkOG^FRwv*1z7*`DZxitQ2$am2syC+#Zzceoo(n}mWR3= zu>NHYf-cgke{pSHjC?=6f9Vf(eQDLdY(+2#@MrzYA@S6FN`NfhSU6*pr1dYJAYZ%;lGwcXPbWt~o+v>!Ha|8d?UC<+#^#?W8;#9R zL2;5)Ha2%^G4UuiA&A!56_Hx8^AP+4SSvP<;0jAYt^Tx_tw*sHqt!oDDX7)I9l@_7v&QDU zj%V!$qr#lm`D{4_*lf>TA^jw|Rt03vYyaKJKyzLn!ubH$Y>)G3yTtR^o}bwMgVNGK z$~n9&SsW@}Z>43kJ%{nS50K4yIk6Na(MqbgRqvG{uP6a0mFB$Mhf?yY(q_)az!F zYtHK%BwqlV^J;lGFUtis=d}_+M__Yao<7STX12ES`hZuKS$V5u|XC(%040c?7e7^{Xzx)Q~|u zs`RTD$ppI^fPW9js<~77tYNjN<$olys{sU0NM!x0Q)`n$RW$n5Gxmh2e)UaAuLJ8> zzaaQT3+h*Ej^IuWVEwA6(4soq(64rc+5uRQ~3Z8K)$zU-bkFiAPoa z>amcImLTg_hsUHn@;y+$x`m3PsxSk^sZv?L>eOQ5QF*_5vP9}vFGO%YuukV{f~zbA z^{czYY&|OPS07ah>R0bVaEDS*zxp`Aqn3jD)qP_M9>s#wUH+;RY?O}R6%*-d%BjT| z#eyT+bZWU2v`^PGr^CRg07~<#cVx_+0qwHPzpLpTTY-xgUm0d7Na~K7DTs6 zB)?WfumUi@dJuHC6x2x{6tndx`bCF*D1C)>*c%||rxes-Z%wcju&XJT6=G6x&*{AT zD*^5KZt!f=A7F-bbOBC{@-EUmWMWJc@?V56@G^I!>pcI7uq& zhn-qX=IVs^e)u8?{{Yqx-%D`27Ss>FMeqvX&*r?ojs5VgN`N`9SN0(%&3XL^?KkN( z=hgK{zI*~~&dWuG#6&*lwF}#a1Do@jN-$Xqn)AAx;38lbQLZi~k1I>&ydF}Px`=uT z&f^m4#(`f5zSDv(qE?wmV-M^iYGZ=+L4EE2aXqwhO*XFa>mfZPnqB>@9ky^qk?nJK z^>Y9zj#3tCrDqY$0M>T8fSW!fpzVBgUrMaD^A0$-Nu=Ak{!Q?(7SwjWK=2%}w$oE+ zk$9xi=+AHG`Vi^|(rV7@dxCGJRom%`x)^23{C2LINi@^I+Ro((mIM4*+u1knZQ%wA zPun^4?-X8b=UULZ0c$(^Mc#7aF<|K+p4!gM;0#cb)^>V=yk9ywbCD3PS8$3 zaJ-3hIpEY{jAE5XwAN^HQmZoy!AxMS&K!bEEd{mG!(z4`#a4%_pM#ZxTIrh*+@KWH zN?9wyphY$)ji(t@KcpT*v7+6qBX0R@$k>q^qiyx6)@rI2~9k zy@=p?EvS`#k>DAiKb!M9G?sQlQb=c?y~B8N(wx`t(7u&Ub6)!&%_IY`IWN}~l2OW) zIj^V3Akv)I0ytL!oAdgF;2qFiG@JA4bqtLyu;$v6DJF+28RopMRx)a?FNJd~yM4cTP7Zd7JZcF2CPoc4V#oCS=kNSgXGe!AM|Za~Bj6k77w_wbna;lB(4@ z4gM)0YqgwOYEIPhK#5eLEJ_{I@>Td{{ZTH(yD*?mf&k?)xWs5E=IneJ~l5-Mki=&z8pbYz@POm55!aR zCKaCk86&sCUUtq1+5d?=>3TpMAi`jY< zTQOSw(MmzB{z(X?DFwCqvkA_%6x8a!6;tpi7MuqBLZzVAWIlp<64{iJQ;W$nG7{o{ zL{xis8>B_R+Pg;x9x|00?Y}}+#pG?NXsFWz!!EuA=>@5DpVx;3ADBwRX;;-GUrI&e zJYOm`&fi1&Rw^~l#VG{93g{vpewK&^`A~^ez~$hy6;};%SAxzUYmi-47c*_XLGFv9 zw^Uh$b6H;2Xd(Ofnle^}+Y-g*Qe`*m#yPJQLli}{;tgtB<@-(uc96(gaisFTL0h{w0!P>5ehdHly$0GtZ+tVVX&-3&uAah>3A4CS4^V%QIXkfEF&STD1 zJfHJAitQ7XmIhMJDI{~mVPLn0(y~ijIH!Va&dZ6VD2Y~5#jSc@0{J2dIDs|i z8${ z8#3<}qF6xM@t2i?+VPh8lk-)Z3+1jenHj5ouN9U0W9;-%qdcuRwiCTGjZE2$lk!OS(I0W;~bPRN<-d z->UGc@jpZR5m=2sJMumkk8XCcc&hQWC-L(o$ZEVN$df)nQdQ$SKyEKVR^u;_@<1FVqH6s5kop3v@q-AqFqLZjRWYm9yj(^#{yeEv z<3~W+MJm3I3bEusX=b-#5mrJgORhm-O5lCTQm9nn?F3n!vbwCzVpwvk&R7YkBA*#Hq!yD3j@e zq@**(&Xmnj43vt$u6p(0z?j>%>=KVi^gN0T^ya}`plt{2&4a@OElKhyq|ciNJ4mB9 z4^Du8IIuSlI+JIrqB>~8n+H#ZIvp?>;gs;^LEaO2LMY)bLCov0t%U15?IpYb>3P6P zxL3?0kMa`U?IoNKe;%+BIx|f?$`niV<`7p>HTAM_U0mIqc|Q z;ln5w11sSEv4DA$7jO@0WZ`r0p9NMxXL6kp)j<;q_%7790R?o57jTjnaHXK7A+!P> z-FQqW;CCp$09L>?V-_A|eHdP~jy2?YvgN^@En*C9Hsl?tE;pa6goP2Uft1Viq1nJ1F1)X{?&SKO9&AoyjwbK^--r zfYYF!04ShSyny=c#R}LW7I29b@a*rrfajo`1+0Mev49@M%qZa7Uci6Cp98Fb&g5$2 z|5LylpqHr9@Fi0YsT-VTDg1)#W2iN)oW_tZ5WpS?bh>f7*SD4a<3Z-#~0>twIZRrQ&ku6IYLbaYq z;_tLOwVmEecMkh;1{ieamQ=D+J89khEZ+(2U3D|;U3DL`_yMqY)eQ+RbxabE8fN!85>WnSe=@`-sE|> z&q%Bpo6iZBX+bkK9cJ+C3a}ZQxS$!E-mL8j>JJIK{{MZw$qfhkFC%-T!|}zg=Ul}P zz4*d@Wv@3GMv8-#pJs55AUFuv^_&a1D>WXP?10V&hb59dIsRdoneMs;Du$#fKnW6x8J?GlGDy?77b%fdh*!A3+1l<6Cc0G4OFo&CuRCuoE9#-LX zJ+~3G4S-$GO^>|E;&DB9u6Vkh8wzKLlC&8dPmqt(1WDEP-0qM^NRVC6ofeb!C_7Fx z-CU;qq-=COHx|VhsqB{#rxp{BV(*J+qiKjVQa=j8L|`NKQwUD76m)GjGiK{i>=L=o zJ5DL+I`2XR=PLzW=UqcE-%`*oBiF@dFZ;D=c zRCPs|>WXkSigTq(YIJ4jndMQmkbSgDJ`eU4rpShcuSYB1rhK&OEl*~jhR{_mf^{>n z?)Ck6NIdc{U#ollK|ZK^T@3$0VBM=T^_z5dXrm@{ug^k#8qmEu#YbA|I&4_@QncdP z5cx-#=tl1H!oE!^Zvrc*%%hdMuLc_-iPM1_YhM zdJPEv4C^IsC?1=6s|7{^>EAmgQ);f*EgK1}JWV5k8E5%OV2X_d+MLO60$|XR&9P!i zk7a#%{|w9h!FlQS=ka>m;~VDxPD?d=)-)R$oM1zPactiobk&>72Y#BJl1wxxljD0V zp@jCr@~Kdc1KAMbguqJ@k7S|#(rH__I~9#ycY7B6GeP~VK(87?_=YsuLitVG_{KBQ zY6x)!x=Vo#As!=G3~UJDnnL1H`4D2A(?~!=h|)}o1Z)VgF2Ool&=6u9f~|lJAv}#@ zb!t9@7!7xn#2P|OC77%Q4Ivf~T%`s5=o1$-gm{Rx4}kh>!mj^+hY-&taR^bU>xP3i zhHx2k6c`i75O0v=OUh7Vh~z9rXe`(m!UcuIBRd@YqcOxkhV~7{EllChRoL7{jjUhb2LgG=?7-AXZk0i*(5Q}5d9{C<<46%ud zW4{8S_(3WgLpZgVcvL=ym@1Jvx|&%Gw}5qY%M&aIvZwtYjoErsK8E<0Qm|i#5Oh-t z8bfSA(9crP7~NWDK#v84xvw*b~xjz{U{A z5FDiijUi4WI0a;5h)qMwNPAY__h3vr%^8bi#7G!Ix8 zeLKOerqUQd8h~gMx+Qz?mVGk#jLxC06_bEy8C^JH1 zh>yImC%``*SYe&XMQPmCpb3SY1$8E%uuk#9+8APFs5f6RhUh}C-E<7WO?B##lLqfe zZ7A_-(AZGI_fJEKU9$viC~;vZkcJY6g!LLqTo%^bP{Ie(VJI<{kBuBr(`Rxvlz8oO z4J960;6sTc8a07%1v_&o7-XM-I-=*nU3fHsMjaqOgj zGRm0LQfZvYhSNb;y&eCf-+fro=?XGDYWIG#I4?9rxD?98p#JAT@gaiE!D^PF@Q0t_ zy-eHVs@Z5YM7RarwZMi5ZxXx+Y>42RTwOjy*zRl+&=8@=xjbeFY>4px7&{Yqt)}n) z?`P-^xy_R%G>MQ>s1%AQa}s5U$dD;RhNuW337I9c3Xx=r%o37$$UG03r%ajt@6S4W z?fdBV{k{Ir>$UD(`*}W}wb$8apS8zx&R~>Xl~5O9G|CZ(brIYeZvu(FBx~M9m<)E3 z$m$}@M7co;brD`hd0q*15mG{3gm3xwOQfo0wCY_1d%05F6=Dxj{iS4N+I(E=dWL)a8$W5jw0PT<8^sYqi*riUxW55b{jVT4?xhj8-+0M$d70B9UyJ%kHUrYNBv!YwGX5bGhh1zsP#YPPY5 z@F36y;;M)6EXvd3s)yi=ilk*nS-rpi9iVTCs~*BvD9aH()%Y6Uv!Y_A*?YCSCFiS;0E)-wHiHy7J%0jA?qRZOr~A)Be2C_ zxuYJ!`Y<|*WjzFk@_^7tFYO^*E0UVA9uPJ|tQp%LrN3FwEW?&5Th~e-qWYmMsE05N z!d|kV9>OS;L(PJE2-_zMt|iB5fSX)|1+~|SF>*9vzDO$+_6&}yL0@E_T<_Lae8?4N4z` zk8O;17uN{CVjwrB-{33ANE_pi05w81ZH#{z`#`r5pO+suRj+?0yy2}h3;~$n8?Zf#2%r}Vb!)bLX7YkzhaC)G0 zS3>)6_C(nYvCWQdu5LO*sr=X&e}hbGhvcc?$0DI>ojB>gy3IRNVr}!yJN5#c%EF&x zee51Ov0;$hPxbMkZ4b3(Sj99ziTzI-x9#5`l2}>LqxmaQO|GuSC-A zP=BKQp@hO^?aLVMBNi^*0*_CNnWtlo;j$Ib7Knw*4N%q>SK-nbJU(p|t`DgC0Np}d zh0C2#c0l-8tKuY{GPep{x3Zvrbr6X6CsR8?1`n$$tQMc?44!a5lOEAf0;6}M=f5RGIGs(Ad2!9;b#H9 zS%fT`+Y`gJRQ?R<>RhHmAe(z(+%1*`Y=;(tYo!5uSCJIW7D0Fdv4H(5%FAX!0sF3$ zt!t$LdzvgLV1EYT6IoEe{srY{v!H z0xDoP1=JX^fW0nCdt)hJzZtVCgvnwN@H$-{53vWJ&5)9S?dV$JDxnG3^MqEw-X3Is zp;N$iFfYFln1DS=U^%oGz##%x2W&@Iga?HFPryDD=)p*=rw*<5J{1rCzegq|0ekCz zJYc()zy$1uilZva6EQzVSy;e!C<9J8;{kgzfHM&b*tet1QbI%H=TV+T_}C_RcX5sI zJ_d4Q2EKM98EF&z_n$FTS(44dHBlPz5u zr-B)aWLKaAi;0qo(yzd&fTxH+rPL;PFNeC}K-p#!{8_TC5Pu!8YXr4+!GTqYl5DdH z{sAY=g>bt_RthUpDIAxTLZ2a5#Zp)V=n=$9!Eww+l$OF5{QePQrQjIu_Kl^`S+-OP z6<1MHkzfxybzm{PkO8yU(*ZymfjA&-f#kY4NRcA$S zeXui*;qa#|&B)fNHB-0&0#}TfHI5dP=CR?vJt!Vr{is zD6g4qY^(PIIz(IzZ4N;hDX!XT=T;=mkJH=glYyQnuG;EzP$nUKY-lqh)s*~=I8UpY zpMmpgHLn781!6;+>k_V^a9naP=^!<GT?mU|EE3CFN{1GLYZZ|t(pZtyQoau1Rm57#Pfu1lCC7>GKgfcj`1FbTN6P zUmtJ>#3KE6DBCKbNIwK+Fv7>S#@9>7&{k)Kt?^y2C0A{YKLpr;;%RIASt#QW+ZyjA z?r{>yx5m%o_uEC#*7zkTiXM&=G6t#I_W$TzZxWBpd)Mp%B?RhCG5!k=mB@}c>r3B&#cPy>BEdqG z`w@!-PRJ*!Z0V!!=oRu_k>D-x%aAM*IH|ZgQsq*S6bY6?_*^9GwL6KI|H?HY!Q|@z zDiW*&^gCjaV2x{tABaVQ_9$%;iv(_=yk@pB5^M&vySR!3{ZY0NSCPQE6-mpEvU-wZ zFQ7xjRU|kBWhBDKBEb%+E}bOji3C;GE*`$IXHw!SIx=YYk(*+A{x?EGQDZ4&hZb61bKeClaib1x142 zAp9bdErU3;5Ux-`a`pGQ0ic#aDy}8YAQk~SptMs$5uiKDCP)^6Zizb^3BplJ`O*bH zPUe*FHW2z6NslyeD4{cwQh`CbM1V>4C}u6KrQDsebImt3Y7k%pfQtcNgxH$OjVRY6 z_80@Fm(n5e-E*x2S?^=a^lj%cR;^E zn7(ju>C%Hacz8Ob$IZchO>d44{tfd_#2h>>IasZ!S-2OZ)LD$1LK<0H2a-Y^HZy5Ak_1am#a9Q1+?p<0WX;oyz#U{COyBj%tZ zd91+yaBu+7?GPMvh&z~eS-ay+840!vadwVoLb$lgAi(JioIc37uWuYrh zYKx35erS(r)n_q_(oM0pNo9IkP5NHTSI0IuS_in8?JG;j`5EQjY)-^9?#acInU3$f zm+d-##j(0AuX$wDGTQv;hCr`J2ja?E(`#FYezjISlC7NGe-~NLnE#!xob|J&K)|FmA75u7w1f1mG1bk z>l#{!E4!Iz&B*Tc_vFJN4~YG355R+)#LYkxY>Dp7rrGQh8=k@Ch8(bLHifDsx(zYV z38}g&LVStNt`9BI-5h@i;alUbf9xG_wM5q!-WG^0(TzkIj@S~NbE?^CQH_nj-`|1( zEzw;MeufNaBk)p`XOz$q-Ex#q5gWC-HJ&XJeM#1Qi7r2rau8Xg*0o5qKy1{y1Il(v zXw;e#8nqt6w+A9s4@ax38@1XJ-O%({;GwxKsp!^wbr#Q3pj^@t-RW2yr~K4=osM!j zV!c-<y}ku#8DhQHuTVZ$LgU!NEEL3guWq5dX11~S+5~7LQPg{FkJ46L^La_d|voO-W^ zfEg*1)_Zk>`QTcO-s=f~j~5~9y}px7yXHrr-s`{0M!nawV4NYA^0Q$`;Z}k<_pH48kXf^{akC`PnR}7x`1l*0q!^9m0)o$AT(p z`D`v|B)bvTp*%=T=MUh)0;-If0&0v{8FfHuXDsy~bIm-G4HAo9bN_gO~lgF z@wO=a5L@$eQa+3jiQeK%BI&3GgBc`}dW#34j6kxrKW7!gv0`}-(RT432kIChv)=pE zHQg)MQUNe(=%RqBa-Rs}G_$V_*bXg(iL&o=2A2Z30I?Cny(o7op%KGtC@&ytfxVyQ^PE!=?oy^K=iM_Gl9uz%1#=c+%Xte> z<{=#fv*o<+NPURd+<}{^42xxk<-GG{Mso)}Zsp=eZ0=wr$^lAf?%;HkaY|_J;98U` z5u3JkbG6g?P36aO-Z3(*x!xziKaPZ|Q(9yNzPjbSZn28^ghO1;TkUhMwn)|K&8#@G zDTsH-y3BfokHs-;JP3dTKl4GrG!H3ZYaAT7Fyjx zd2lTqYYeRi0zE)nh1O$HMvJS^>Wqq{IoCt$nLsCstI&Ee%0&ntYk{23z0UEtov!(l zWjYYGKsQ6VQ8Zi5b7*mOq{^y!kaTh14dE^$X*qA}RIaY2xiJFzY>^bupN8-xV#|4s z%qMnfoIXJuMcwznzoU$7Id7Ykk!xv4M~h&s!8d@v5+TcGkHl~-6#~KiUC-uE7=MUm z!QG*S;96;LU+XS>Q{bvShjm-T0#|dCW=OU}b6CpOwG?HUnm9lf6x=s}u)ZuPxNm{d z(<~^sADAq-mK-NeUnUC*GCM=qQ6vj}4lRUQ_fcN~J}00;-@btMMlAFljdHkHcFrfH ztXxZ35vRj^Ea;q{17VVpG%euJLW!2q6x{oXq%yi3!lj6n(M*(^%z}dZ#FVXT=^0@J z`oCmBf&Lx{^JPJSei6zOh)oeVEuT!KAq+wPDH+g_zY6|k8Boyw1mzW`NU^kdu5p&SbMM!6*w2f`n;HM+z zpd)!BOk^icbZ`#PTM-;|h&z}{a8kd-FR=0%V$MF6vU4r9 z;gsemaa5YWf?t7{vySAxn#fL^=xnXIY z-R*Ynb0=^+H=D61gl0aCpsA^)5kF2#)tWwPc3HFRg4Nq*e~7epX<+i{HfJ_ziLLUnvBl1niq!xDekC0{rHpbxLY-& z`cT}dhOKiOo+GEW1XkRXKeaB~zM4>8GmF1?$NcR;iZ}6x7W|7{tKpS3;n*+!1Ely1 zfAslJDXme1Kq)m`m*UN-lsZ$Y8zMQC)>bHekpGlgRSg3wwVXpbXvFCK>9c^0kW#__{cUKXu>QHy0jhxGo!D; zTZ-7sXtYQ9~EzM;zGg|ow1~fCe6Py8v&5WLmGDZo_j9!Xz5n?l=ZX;jQ zn$L{R1$&#wni*Y!vRDc2=lK=oCnYp9ni85BZ8(n}C{ooe9^wC-89lUQW^_A>)n-PW z#m!ihOPU$&jK%d38&nTM*%7gEsT1xbF^WTrt0Pt3ERx13 z=R!DJBpbdvi5I5HHHPma9tEi3`*c88A~t-VgECtQ4c`}`Jb~Eo-7S>Y%r*|+-vIiW zxEj8HhVqHH8ooQXB58h{K79WT=r7`G_+EAw7Z1Y6W=8v`y1GQpGm!pN&TAmOCa|W6 z&5RC6xVMF496Vn*&5U*g(?KR}X4DPlgKMef^_LTD2DrNj+2DClGVPilfo4XVKSnkh zqxXlgjaW8#c4#5E=9i{O`-r50;T{lnM{Hnt5XuO%pqbGB74f(B?;K)B3Eni+LyA!#XFNR1zdq~YW&2sa}(oV*X^ z9`bv^HEO8<7#Qy$4^{5{U~FynH8bi^Mwqhi1LGk8c13Jp zd@{;$N@!qwHOgfOADbC<2g}1&7|4wrc-S*!q?yqtK|LUv2E(21=IKd@&5SyyA{?kp znHhcINl2O*JsQkmh|P@7Lz#ti5X@#qzbEwpVl$&|rZS9?8D>Uj$&6-3``$yR0kN6U zqfkaEp_$RiD3g@X%;;>C8xWfrb#t}T`Ay|FDcAlynbyqcQt(R<9_SN0l&hN=y){;m zRc1z4d!vJ6d0K2%9NEn1$7J#@VnMw8UZyihSP*wYKDd@VWpc6mB0NfwG_=-UUKu zSx^w)8f8nfpdkKwvfx^BoOpbNEGU@l4q-QuEW|mKSHr6y0X{FF0`~|&`y&?Ojz<|S zmd$|vn6h#$Wko#BKaB-d%=00fCz1tjhw_4QWd*Q@fGU@(0bPYyx!i_wi&%LD?%z^Y zu9ePu{v-2<&!C&_fkM#C<8j$H^ILl1Df?*j`BH@&3gWu zTySmmv!1`f_(iNNxL==wyKAYC2<{yfb9Fw-?x!DvWV4 znGy=_`=bm)_}G)lwr=b-uReI}^!qHRZF4$4f#y4}v9Mn!gMxBK*G zF`#buH{h4cfHowoxqwwj#Jb(xQMw@3?RFciRIF;vyWP8h-9cn^yAMY>Lal<17Z=| z3Hjh!I(sgLOPPPsHBmIhoKI zLYQJCb^RSmD37ERlp)o79v>7_XF!;aSWLYgod$R&|H7aHBXn3oF6@j@ThMl3wSkoOlRT4^iO}4#6Su5DL@MgR1`;=keh? z^Kjs>m!pSkL2ZSYhkhU-RBI~YtdO@AM;>kjegnijbR_eR|HH%HKzkv0=nyYtEfi(- zO+WHTB#Yi+j_6W!`YF11|oJie?(viuBAqZ0&gUa4rg!h zLlHY1NAd=e$WEMC;G=*Zif}j%@x##yhB>=QykvN3cho$*)0cbQojn;VCnDzT=II)B zEnROo`4){rkIqS$=a4m77vzG(C6v0`CxU;%Oo4p?=#II#pDZE+|di3}fmXgk9 zMQK=J+BvK!`9!SNgVu`BacMoMqG6V`R+Re1UsqjG@}8tD98j8>tx0*@)UOk2{Q5x* ze_AZMJmnsmeHYJ?zMq@&4OJc)eR0V`rXJ-}KRQaAa6j?pu)+Vrvf1#Nl+#T}Rr?63 zF&n;d{2|bd7q{J2Z^2c!{6Tp05$l$Jj`BWY-E!yfRNlxg?Upxt9Ruo?Z}KohLd3e| z!%_BDLbKtgpqz+Ux7=;yYg+Se`K4el5?S5yc__Clp>FxRC~qpEZh16y5&E~d3DSG0rnSS-SYhsZiH}j%O4X?-SRq*(%VI{Zn+!G2iH<`^V#rL zfLn-=b;}P)rd{(RP`A9}GO|&(d;=Kki)Gz%hw|F)NKbJI(kPMC-RlLR2V&j5fhgOX z1D_)P3+k4Shj6Nq)FpOk zA!#XFNNwMQq%QIK5Y9ua133d_x>-<{cznv%wUjMA-MwT%m2@tI+eNZ2u|o^tSe-wB zQw3BRJq&0eVr8@xWr?xWB|bl8HBl_O#O)N0G?DTSptrDF;Pnez;I}&JXE=_ z2V-5cui=nG3*j!=_X(3N0Bnlb@Mk#6P$e|{nTT>K!pCOA-NEv(7z4S(wi^Bc8L7*C zE2!&4(`{fjR7r6}hi9R#!4@YhK_iP&to zo2d-H$qcjM_sEQ9!@EAgKoPOo@cmGRDX|^Dj72#?3C)IIfiexT*>E>kJDuNDe$0kn zDbtz_e+c}8NT|BDc~;=7n+<;?R+0ao*>J~l!_NXMj%+sk6*5_hSP=gO<$J_}xD)ch zwd5&5yx%)`svzF_$$FtBk_B;x7FS2AJV_*79~(mGB$5SjCzXYEa*ZI~{at_x;#&gh zjaU%h6=g>y6vPihIRvpF?iR{xW*dX}DL_vaS3!I-$~odHhX?~m@#IFW=mADGx zx1rpE@UbBNQo2mL$$5hK{c>JG{2^cuA{NA7O}K4@BZyBDPC@)RFwe@Q&8@h>d~mHs z5Puu+n<8XE{M}^QH9rCc@o$ukg7}v(z7WfTxI+uUwbCHo`8`MqP`^X?6|n$SzKDJb zlFhArl(Ka#MblaN2FJ*Pf_QTX%@7OX>!Wlu3ku?2B@3=4$BD-?WkJDY3kW@pq#*84 z))pf@Wee#Gkrc#tfG_~DaJM(gP_v*Q{&ULKwUjNfxz+nvP$fMQ!r>xW5O-)H4A%Jr zxVwNVqf-HmMXZd@Lpj%23gYD{TplDAL43Jb3gTA*xOQx!_tV0D^dH z#a5O3=P*7M%l7&@v=A;)J|4vX0Pr(nLA=#dEaD>;#QUK1MEKaFfZWmYa0>=`_4P^6h}n;-i3W=iBLsJz~f0SA;+1 zAWzHrLPw%-TKO~&IY6=)?7-To>{8X|xjd~tjHH$jnu}zQ*lCiQyEPubIu9CJB%mHN z)Ctgfh&^J*aXfHEIDgPkZ+`EE*dulvlMfpRL*HzgZ0RE11SPZVE6GZ^A z;Bf%p;UYvoH%fkPk@?x@fRCb|CjvVLF+Uy06E#cyyo%p1LCjCb7i_+cE&J3Pi!{Q9#$H*;v;a=r=w*M5o;*A7fjO0$Ks(2gDu)ROcCb zxQIOps5MGU#0E=lBcJRhYyK#p4Z(I2S%al5PvY=M=ItbUuf`&$SqTFE?)T%Ctb8XdHG!P0z_djJp(fx4Pwm~+zfP^**E%aa3aIzzFr6ZgIG7cA4+ee>WTlO$9-}d zxbzEviUdypdJM5h@G8oSN+=S1gYp$(k-#mK*UUCXf`5SiC9Wbtou!;)#3F%nD{62( z608lhHDZyVGs=btABzMRrMk3*oF@`ATaNRJ1X}~!60t~dNy6)!2fVKcStOW|OuHuU^wCAVliX1xI10uQVp$|`Xd$>(8VN2CNs(Y2 zgi{cU1XEBZn*~LJn^U%~r8^Lb1TV>gBEdBfu9gKwf;&*=m<2_G+HrNJTFczVaUwyj zFR`FV@F;|bjikZ4lL|>IjRbp$q_xYJAS^{J8hnfLwGxU3f1#{Ivc6{T3BESrTJnMJ z`egTEjpwN@NVXrup@raD>DuLUBB_tx0>YYz^>I6)tY;R~#~+ZgbuDE}*FC7`sSBky zgkB<9AK#&cu#f5xz|H`x9|g1{$bmxJn&r+Ziz9^gHOsvL3`MM8e>lovh)vEoAsw*V$~j23W;rNj<64b1%T*rvvvXXj;pvCu!)(c6Uz3g2FF1VI4sPfUlKY;#*;GjdIgC#3! zzFb%c_nL=;=eUP!yg*KfdAN4+(6zL^fFitH92H>;@N0@!Zz+2XBBxqQoao{DKszFM z=wL6xbZ?luPJ3+*_TK5+ScE-bZibkHhb0GH%g6H2Io@0xIk-Le{)jo~Nak1~J8`0e zdjj19!9j<(gIb8OHL^bGFndMK`!S6C{%~gx#>zp6Iom%u>skt#IQywPI|lr5h&k&> zc5Fv>;zVc91UeDHS%YNfg9rnZ@FEKsw=jI6I zzOFj=#zTxx{ONF6>(Hat>)T~d{FyhMoM(JfSr+~@oV+MTcB);Sl`hJ`QRF+?4!Qp`zjRm9S;IO0?GQ04lS;ZRN3f9NNN&~gK&&U)^~JL zS?DR(=sUh7p!$wy0XhS*zT;&m)09x(aW2a3i1i)aLV3+>W8d*HppS^FzT=B1&x@v}>9FS>N$oWuw01#xOP#%leKE zEdSrvd@3=pN{bWIX$I&Q9 znFaM7J0=URCCBNv^_2zn9VbFKO(g5#IFwteRgeHr5>P#yivV4KSP$oVlxvNp$1V(r zS@FPjvFLWq6ibIVAJ9CctK#%W4zG+SqJ+F=m$u=m>gQ|eJUROA4(=Ak6wT253h%=B{2Q)sq#o= z`2*&^Qx-Pg>QLSgCTD!UweTv>asg!h?sZA5gIK?NAj&ofA6qnY7uN_cU?A6LyVF*Z zkrvI41$C%sS~OdR@+@MDX3nV!E0igVW(|IYq(!q9ud$gJu|>0eQFcc<2xg0B*N~cm z*l66%)CpBHFvFtRm%m^}qw!zC{DjzOyzT2;EQpQ9w?yfsL?2-LqU?#-qM4hko2p7G zKNiiNmub!NP6U4%!W#?Y=Pogej;nFRX2iMZE#&Fpd=sJjn z%dRLJi>q+yjEbZ=*TdyDK>LcTaJf6mZU`T1Rh*u$L07BN{WlIot;$F!2a0C5890f> zida~lr;dJlUor29 zq}PDIS{c~{`l%@+*V5pLC~pz|cEGoZkY#gzVz`!$huGUwt|?$Igz`9lA_rX2+trEu-`&iW)>8%r=@IND-GBW%Yp*-*ATvx1qJLsQT{Ls3fR+=1=o_} z#NnT0K|!X@GUjHGEIvAv8yi($0j~E4K*h&afLb6Hus1~MWGn^j1u?5a7$Ft`Z%?tT zO#;*#DGAt)t`&|Int=VT&G)l zqktZP#Cqz`YVT9=;D05du_R!xv(f{$YY9xi-coT?WjPM>rzneTfh>}E<&&K8fPEo= z$%qB)`6#z5p^1`LQC>v&*aDfmxJI}S1GzpshcZ_Dv_SR?s4qp+0@*fi(pNw_2xSXo z3rWpEY=LY!-;N4Aw|Oqurf;#&1F3y05&WTe+Bo;u;2=v_=lsc$XbEdSF#903G~_s9 zzHq*THJaa#k}bU}!!h~LNf?%}_K+=I8WX{shGbWu1B;20iqfyZO8`$30mt;N3@?Ye zp_gp4CO1#E72;|$<@YZTD+R~o!{k^Bd&`zeq3+vYkYEdB4lIUQ88C}I8vy7i5C^0MvfWZg z!L<|@Ss)wyH@3AvHUP@Dh%JzfK-pi3N&Ipw%4oy}J8mPN>?UizKz2IV2_kE-GYw^` z5*qBxMwzLE20JOC!Os1BdoNNoGJ5NS9UCae-Gm&G4Q(95S=E920@*Y07s5D?}#!Gv9{VRl-JBQw$=Lq-A7yvZH`1aTwJx)&aFtAAE&p~ z6M&8rS8erFlqm=w8`_LZHRWwNPpjGaUz}H~c^$B85F6T@mT+IiiuaceQbU`$U~ZR5 z8``+Rd~mI_d9^D2FyMtEWG&^n$+T;J1ez83|jvfM1FrMxI*>soqr(X4!fFJwV2xS{{c<;J;fy{ql za4H7|#J==wEZ(Fn6bT+jc^I)s-~^t15{;(QL?n1p-YXJ(0RBBBiv$iWu8vgsyGV)z z-$D3BBIJY8cew-c&_5-?)xQYZvq8yH>E~ziwDP0e{%6TF|j{?ps5=;O#4zWnE zQNryn9F1?8aEb&|!Ay}!iv(_vrae+>M1mQBr;Ct9g3Xd?*Zc?+364@WiUf0D+$xqu z0*4lYYo(FkPLUJ|9)z#}u}JVN%F|{+kzmV|t!t(4%J@+h6base@Rlqn5`2yFrCCs) zd1#6Rt|iBb1nU;Dpnl%p5dIX&-j(6dLKv-rGeGRd7ihm+31lQ6E4(k->i=#!A&%l3z*gAzH+1el3 zi4)f;Rsj78Vfw-$zD{8i=z1#TJCV!oL341se&x}@!iSUrVh(t?YdlxrH#-9Ngv;cd!f0&WJha1sy`QR_)*m z?%-D7`yl3^Bbh?_9}eyUbSDG{9pVnAbu;(85S}y#J58#HB{%}+K8QK!#}PucR_)+u zaa4k*fgg{UgN~$i`5z8W19~BXgAR!fmb@$Dxk%=jI#EjtXMJ|wgrym)kT+rG2E@F5 zHRb18iVRf9*5b(9`QYav=B*>y9~0S$6VLbKKp#c$)*)V;ws7VvLAG$_3o8@0E(`mS zVYm?><==3 z59xPay%v0D@6R~xBUa6jeh-~ghwnNHcL(X&`d+JPU2QdO8OhfXTQGb6Cl5QjE1zzA zPpi!#YQgMtAfF;tpGC-j7R;`{gBR1sA9CSf4MuqKUCb$H{yiMvp)R^nw6Q$L}3M|!_cqV|cbL4TF(o(a9sr+$}VYhd^?e!3pubR;*K#7iiT zAsqy(xPfnu{FELcQZbjrT$Edsc#y<0l$VuQOrr1^v(zML@3tqo@6TBo$jgv-o+unDmS8+;MhXa99w=<`{EWLXop8rogG*!OxHnR=#MH4UC&RsOZc+^KCF-A z&L+_trI!-pN$i8N7h)5bZl)|5^!y4J<|{j4(i+7v;EzK>?el3Oom3HSQ{DhyRNi;; zQ|>1IoD1?SBsZPJO(@qP)>Cw5WwMd7d$?WkL3(4>LwpGQgW{-%=$zU~a}GVk;yEC! zXZQm6r3jy@v9ZKg(#+^uv`2fcF(I57+E)F`r-hyaTCox5M|%<+U9EWrD%M@V{ zetzL-9Gg#?W6KwGEEcl!(~wejU@<(XGTN$s=X)`fTc4jk#LM@Q+&Uyyp!|eb=hI1L ziSE`59~J9cH?r_KM1-R}FCOKlj2-moQmv;CQp90KO$*Ncdp<0|g5`6sa7iL5!8x?j+PL~IVG7s_TzXbvVNGzYUM-|mi7-4si}=V0tSm)_C2xMab3 z0Oew{GS13{PjzZ`tJ^uZ21Pgqi$^Lyjm54-xe~Flm=p5BHI=bGS{m539)+T@*kbUD zknGBGXmNF<%CkgLck^`!uZm=2F(sue7#$sOp`V6tL*zYJSl+dh9gXOH! zB6fwjh4Px&#<5sCpluMl(l$ZqBCf79=T;;wJIdnnEnBDUb{9H#JppW zvIXb&$>dGM0(0&gW+O;gV0J=2xR%Z|fqA(+RbXBpPDdmQ%nmKCj#SyY2_yyP9uPJY z$pW*J%EG^Ljllf2fC|hz02+W;VBQC1FC`S1$DkaCSYUPw8f zw@MaVOO6w7ca#MMlkFk&7s&#%LknSJ6(qok0xAyf31|<*0`nm#BaNlGreUcpw-SrM zcE4CU#FGJ?DAs!<&Ow=EEZt=3tXg4Lu?Wz^)`X=1eL0{@#ZrKtg>o}u4myda^NB>D zZYz=;ycf*fA}LTmh4Lhl%_%vH2eCz0vy)Fh=s&^xH5jjmm0fTSuJ$z*A;)-uGS&t6 z35<`#%B$R$ry%ZHA`!%&6iMa&6NDc`vLNnICMR`R9>i;X$9@w)7Q{P}XoFY~?~l?K z;bV)?`=zse1_pB7cAnIpjI;=S7^uBP(<1c4D6^3cLfInprr(o7Y!UhqzWr{kxCnhQ z-=2lo^6Q9bKZMWZAdApdEyzHN&~JfRhS>6}d`Ta}T(jv5D@}br=Ff2m9 zr4~n*(cfVHM6yL_2Nn}06(yIrUEcM6U~V7bV~fyU4%~Vv+blwFDnAwW+W=czP-`n3 zm=CTc+blvK?xZddI*VkbFgBG!2U+i5w@+EiSPI(#+8VJ^a2%JHa9#?d`28TnO2IL# zn8s50K$)r(&I5Bc5^NFLfyFQ}17=4)8^BEhaX?yx{yo(I*V0NCi_mY%Pc1?(g7O$* zi_q_(yrYB`p}$4>8nFS8+sG%o$(k=h{{?oX$Ql6E`H_f^*Z`;NS9_Myyqxi*lP1YE_>` zc?z*s)h(3Q%r>^FZvkBbWRqn*~MpCTZr=wd6R_{RUZ3be|64N|9_4+M&E}E7H@&ZV@_=2DS#m*ygr$COYv z{e6_Tl~6bRFO*-AsxN=dTHe+5xbKfg<~?rB{$~>({tM54%Z@qgU$NkSr3o zL0)+qDK#R&nt+>%kVS%bl4;lc2y{{Zq-+!kI>P86mPG=G^2*ytFO3A<+d@+3b2A9t z5sL)+Rab ze4m2wq>;1;?NDY%S6w!Obg)S3Lca##6~wyGpQ3zh7PJU`amv=Ulr4SX>9U}U<5vhP zjHH2qLklHZM$;hSHAvNq(6xT$^$e>ivz(5n#~bcj2sY5%rbCEqD> zxs%o$+-}smu>|MAybUo2{WwCX)~X#GERIU>1@KD|bI_4o(Er214}rdq;Gjd&8t;d! zo7&Bhy_1JMqt+ss3FfU|Sm+0NiMM9f)7 zawAe?Cr)&>56~?ToOOshs~r-}u8OOgcW=SNuE-;;L9<-E2Ma^|8x-pJdaRbM>pT^E z5w>{j5lxH7Em;lD_@UVo(I2f|cZ=UsI(43o-`k?{&$-`NRPJ=_3E38s-MxrrT(Lgu z%9q?7Lax)g(s$zsc0k(p-k>Z@iSQ7bjNxM6aNRZ_a)bHhI3PzNxgAJcigE#x|LsKv z5Rp@@#k{zwt=2A8GEnO!9tr~f4#Yav&dDdXa|&zLZe|VRBVZpwDBX)<4&8ZdtO`L_ zR__&h?Go z_TeCKHf~6uKr%8ovH5`#L*8_8Q3H@mHO`dRSJ$ zbGn<2ir?!bb*%or%IkOONoxEMr$^N^KY~B$+_XIDu(7I=YfTKCpmy@R*WA|OIR1}E zieeO1)kEV&9jMG`g&X-}2D+`w81leTV?us*zLBX&+Pj$}69d>-kPtLb(jvJxzy!H%K z1?pZ33XLz~`+oXYZEf>&rdD?V37^!pkI3L&NsCuPp@Va z!fY|_$<@CFS8`YIQ(w?qAz1`0-j*F#F}S8f*C&5pu3p{FkQ4z2Ll}fu1au_#`9yZc zU?Ara@IbH!C=(*VBf0SQ9G`1^6vo9lA5B(nl zRM(ZQ%~uxgNe})1BZBm!n%n#xTa^X>k|ApRd5!992ejOnY!?ArNG|s(+l3_FM|l&e zHFkEjfqYE^cjh+BT?FJ`uz!kt4vFR~>xCxB;NtDs0m~hmMl+{EUVSS6ty=T0gbL$X zd8ICDSL|$zSTCR|+M`8DT6QRU_{2TpsLQf7_$?9Z1vrwqsZ}|#7qBbPoe``$#Cri& zhVs^bV6%I)QsQm5le$E2hht`6#Jp{s@~hUWy**GId3zN2BM|e}k-6YnJXPswBjbRc zg5a$~+*@_1Ys=d^W6q4iRqrX!=3S$QQ=m>p%)|SWht*oOhedJZ;dJmRv<%hhjbl#6RA$gG{OyJ0tS*%(;mpUlZ1xphgjKv@%Ej*Do&W3-S@ z+BPxMe4BjX@y)UD9kBHwbVO_<;haL^tQ$Fv7FJ!nDHO$!9>6z4@;b>*DJIP+#E?c^ z#5n`l4&VofqdOv;Q!8m{N~T4w;ep-ZXkuz#@Oz7+r6lK6ADBlBEh}{qN3%yqgFh0< zmX!vlQgkhqdqrGUIvwx?5kjrM=~5k#7_OyfR<_L5%{4xe=TU>c2+6HMVh+l!NZo^n zRg?2!8CPMUO|ETjGG9N=?+Zm3N8%HdkCYfq;wO|JklKxQs%96AUAvfXwvI}#4L=qC zq7;zaW+YmmG*+S$iQXu^kWlB?=(#$)I-1uwQ~q7GmX2RzQU#+OArD0CQg=MBjf&P1 zJ_e)xfbOIGLa0<|bX+lMts{jRW3^>8=%Wy;Ee_{ai=)~y1N?L(t1Ty{bMIO_6q^UNInX(P zZxtb{EvF}jYyMJ{g4dRZKrcY7w!Dh+GGevGDf#e4X>IwO-#-*VwWZ?kdZ7%l+R_ZA z31YRy+04|#R&CiurKj4mE|~TrskZb)>86Bg%RVT>kWlA>=y_>v@$YztclcVZE;k-CO+1du|Q8!etayfEl36Cnm@ZP-zs0X(1RmTSUVTa*@%U;t5B|xk^JR! z`ksjv@=5Cuz05bycdFYH3y%Z41;Q*@xQE07l>3yJEdwZvky@qJ3N@_NdnI316y7Yn z4dG2$knOKfmLvIZ?kG#VV$#-%{?z**-{xN(QGI51SAzdt1_~r<|HCe9r1&casy>NF z^xIN3H4MvdJS2OV9?v7vI_c0{FHYFk5w-M8UEa0TMtqwJ^EWm6&GU8J^oj+z4%XL1 ztN?dJ>5J6X5UMh^r#yeK&;v)97hDm{XCEUkfJ(#1@dJIY-SeA!zGe1*y0Z zuuxa7v`$uA$m-9z3OkP%VC_7_+?a!M6VkJ{+A3fbeNbNKn^%#F9Y`!k`B;fPNi_JE z1%IUCAQIhBHb#0LLt;abk3~6{Z}vy@sjEiMn{DnrlOHs6*2tX&<_yGUA03kqyMQ4~ zeW6lQ!*&IbX^3@|UW-Q^LbYZY**!Whi=+6t0Q`N3T@j9Cem$`xCteXtfIfrJRdPt| zDix+(e_9Nx{!1a5@tHOcs_$arZNxl%H|6D;PgbfMe=5ado_-DfOT;{NBrl?g?8J$l zt_1o!f~OAgPMs~+WkbRxaS$28a20std|{#T(~z(-)DPuIsIwwwp?SEf`gdgY$R{W? zcXe)V`QAaNLOqh4&b{W3c491DJ%7|r=lAF_twTe8SDh;g%me{raP@u)6P;&c@b){^ zQ9WE!vkSXyI+G{l=`?XENBL2UI6h$vy zsXsIM6V{pj28~!?c->=yR{r4Xcnta*#aE=}QK=k&~L*w(wo?R%!QT|x@ z=r}_=(c9cyJFL%t4eN^ng%!CcM>Fj(KiA~vzOBQft?6Fyb<5+&9H%e4Yi458ZdcZ| zLA-ut4sQq<H7PaXd#SGS-O<<(3-_WFXkSh;=C(m9K$cqgAqcZj3z#Jk|%MzZciqj3*MPqiA?r@GN(|T1?g8&ktOWf#V%>?lx%#03vF?OZc-86&C7sVM{JtS# z-H9Dh1}dS>=WvvvNL_V4on0`tx)auwID_BEiJ-2;%_!F^p{~TEC=VmQs~SOUrFrhL8CF4N?@osF{<{cpI*zm1u=swvO~M zy1K?r)etTR3n}Whu@3s# zZWmk3S5F{zyV%Dl?<=9(#X_-u_)7`hF18MdRtV*<+r=tIWJiXPsOhZhquY_*BhTvF z#T-$nfvvt>EU(+e9LTF9qEVmDlhF>_U^Lx2wk5vwM(ozHT~T&cLbr|`hB6YdTgTiG z1-7c6+!1zgKgvc+*%QH^hGe&nIg}d|RfqsKKp3Zyh_0Zez*4V*WGh0;?W0<#>vY zCEY9Lh(Ql3ie5Do0&lLjmrAWEYrzwhL?w zUmb(k1$Gh2`AX;ln~QRr61u=%Kv{ys3+(uKY&_|0m7~SkeXN2v%TL!LD+F`On1~KwV(FP+jc;yBZg- zLhJ&YgK{fk7nmC;t7*V5um`~|Ksdx3qBnkHrlwBgWma1^W-fxmGznJ;d(JbW%0F^v=vP2Vg*VW*!dy5XA1xyd33XC3I)ze3ZF}ZA^A+ z`Q%Kp=67Z;1^bN1+L*i?C zWk_~iIkdPsQsr6$A*tb-1>t6qY=fec%EF#2&fH;3jp1R*apRCQJzvl8x%iA z`4F+|%Po}G%rF)rb>`fP8eHG1+yrPNQM5s^JxW`Ik8M!=G@gxI zI7H5~L2>vFIIphwX27~5wn6cWgga31#M8g3FQW}pbd)uBnz%3$Jz6@lPqY1;=K^=Hj*|9 zI<%0qlr5wSMAFu|MG&4qZ0p=>D6g0WZ4@lu-}|?&rEJ;r_oOVSl70^1Q<3Zy4h}7Z zvvvLe{vn{s=odggBUVPm+FU%1cQ~{V7R$bG3qKyfQHX5{y&UBtCA2B@0hGHDKDD*%?GBcQcQ8O` zZvEWuHA$79 zilhtVN(h&WWKrCq)D*c!6u)6tfQsU`0lEdTD83NoekByeUqg8Xu_*2qcw_Ra*~TdT zInYnVRTTdPy(0-ja-JyOem9&~6kiY6 zx`;*b{St1da76K+bdZYTn}gX@CM}A)LEe}gDK(<_c7V4PA&cUNB-5^?Ges01CU+FY zhrk#tmPK)g^2X#yFOA|?i=+rO62gIqMX2LZjx`I4;zy)xT}$DVZRYREf};2&2xrQI zqWEPfmzV`b@iEDQYsql}a>GGbP&AnhVWyE3#U08UlOsK43uzCL6z}eXa1UbfZZXOt zv!EzGK4t4#%9h|fSr$}D--PgnNZA{cBdHJ$)AZ=t^8v5M|uVop)(l0ZF9(AGEh7{2;2xH3&IYpoqS4lpPMSr zbJ7VAju*-9kGw9P$`H1cb?y?~WDl(CF4409oq^c>k&a^{oN#`Bad`?rYs>6m=DBl@Me zwn1 zq2baUD07t1eVi$w;nKr=yAY}RC3@?_CCxgmdLO4_m!w-8AYs~d!_B3ZNgM=I>! z1yr-z575?#HLHVAc2z>n>H#Rj5o=c60^9bYt;|z=jm_$4phtMR5>KtIVBG#;yC)}FCaZwBuPR;6r zU>3-vHLGqgA6%=^tUe3)X%Vt!wSF?~nje7%NAr}8E`&E>ydjn~s}5ytCel+jy5&nG zYce2whGb0!$_lffX0=hu*0qY5ukPOJJ`@XTR%in&CB?5+M<5hBrZ358-3?*uIv! zB>iN7du#{nLr%KK_8?&Ui>G^RC!vf*>>gVu<%5y@9^1$H{b3RGpyzi`mMNioZ2v|1 z8L=^xvkPGlWyw9ZU6iH9P+K&sA2vs940R~VK}u*0H4$aJ5*kC@fN~X5^}zoz9QrdJ zSsV@(r(HjR<*RJ?oYaMo9LhnmU2^S)~RwJ3WfibLGF{ zbWiY`BUzkwDDSh1q*M_Izn_StOJD$m?L@LT{ck!U=g2jH*Y68Zae6O6LlBG8hoFp9 zLUH;8l;aVL({3RjT+2MIj?-rWJwsf@=}Sv8%)x#pyZ;H(NO3^p847#pxHpJTH?Lr`;esydot9P`XJL zao-30t_WG2ZkkNH=0~77Jyh-}PJavIYq2a&JG2n0wTvdxbdeNy{(`U)vADBFbIJ_K zo?_EHW$RiB8^q~%WkGSe1%x#bi_@J@)-wwl{f2%8&8(aNEP zq@^kbX|PC&Rs$exhgh^4in6C!P@L|NvUM$GOUOM}7F0bNu6sH|pDA8hhL0Te` z%Iic3V-PE^NhoKU1;y$0Qns#@#_6*(6i}SL6vD-_pg4Uq%8iJ{X{Y6rsZ`*^>78Xj zM}9Z>yJSFd`bm_>kt|MkNiMjS%I-gL`V|;2iIv6a>r+R{wNzll=?9dt&eKOQJ`l^| zv_lKwepPsn(<=ddhgh8M*@DItu{b>nWj{n8yT74(^42wfpo3<>Iv+^3+QM}moNEx< zZR$w2T}QTav^8Yu2sqkpdKdUR#nEn4M;4NnZbxQ&$Ug_b(dGOk_{YW3_7LY3la@wM zT%}9J(KYuv_*ao^Fw-*~kZY+Ni3b)7z5x802-)_KEfd4F8oN#Z0R0IPrsMbBrdL3|46z++j>^}>#~o|80-de=VwG`5 zF){q~YdvekNDe?%W+9XZ5UVoIsa1ocD)a9_a8zZMfPY3DRT<}$C9Sl|bQMQc<}L8c z#8H)TPI=NwtIWTu&Z;uY!GDfqRc27C0IsDX^D6Tj;9o?@s?45=;aZIyI_=fFQJj;f4v*a;N#$u_alMMaZhm@rmJDjVjXw zMgzpE%!VkP5UVmy$%kJ{t4u$B?=6C=%t(|2l~9#A9_3iXs*JM>##WVStI|`InFQuc zkyK@_M!8H0RhfrT79yd}#OQfxl=1KALC0Uy@q3h63V8`)RmM^In)p~{-Us@w@{3i* z89cNr=HQ!ksWRQ4K8yoUmH7e6cZgLPN7kyrQI$DZ995Zr!T&9es*H1Z@mkEMG|F6Y zC>&Lpx@$2mK&;9*vOIB0tIWaTsLHek-xA5H%-PX=F1VJ8%%jYPfIEqhRhcP?;aZKG zX0`y`6R|3@Bg#O;s*F?eq3nv1hG}1ZA1Z>X%ts`3sxptGJc@)mGot6ERmQ(#8Ycdlj^C@yOOXE`U*`cPMX`PHo}QTn zaTgZTs)z&=Dw2$dSutYH3Zh~Th@yfCbIu7A6DsB$FzZtv>N7n9<{U8x%wqcg&h5I@ zJu~}%`+Wy)PoGm=eWq_$S5;5bu%rlFi_)8}G}Sk6q@*zy;16 zt*`H2JXHnS*T81*w(HTFYyxZs&qbwVdHKW)-kkd&vKc%$#{-+edy3#Ou$X8zgZDQ} zp8)H9dNFCTo{C`x@8i8GM!nCmJzJ9lfb~AFAh<*e>U};)aIY5B`+S{X2Cx}CFRq+; z6wP7=?|!kR0M>>!bKVO_*cQK}kU z*irjJR2OzMr2T+(VUH#_LJR7`UPLevSQpky=+L;?Fw}S>)a#{H7xsRFd!q+ZxOr!__HqTvEe%?CC97sbYW+z@;bGA4ed){UDy*M?|kt%Gu$nn zy0Cx1`CUa?7uE~pj2a{jUD!^&xeE?px*EDOW6>V@9;i3kZ9g`nv(^GA+N82BtW(QT z9#3_MMo6SCSsw(81M8BlNU*$>prOX|;$}UHQ)zTzuTTlmV*xN+v!aB7aqqtc_^X-pF9l661j0e_{JB{EJD?we@sd2L& z#m&+i-AE-d{aG$BvZM`pU>Mp4mQf$+i zOI_8cAw4CPx~gvyybf#z&qbBw-xATe{De*AGkBjvoC&fSJZGoL46$i3Z2y0S@H4Re z@32T~QU!eX^8L8ovhO;Nq5*VChpC40eLfWPNM&787nPHbwH@!0E(u`~U|rHp2-ekt zX7COrI0*1(Gk9Ln4#{s6z*&5qhmT-On!&pk+8NSm25+rJV(QF29kHuP(VZdha zhF+8=^Bfvx@IK?y*FpB0&0u!NWIP`&U0XP@l6VxqDZjS30P=YfgnGUg>v>;R&sEPE6Y6;*w5h=A={!zp#dZDKYpCbmDogeJ7S5L-o56EpC7I`9+o7yOKIanjr~!XAgO|hu&!af!#th!B z2U50X@RmZdD6kp44GGrQf@bh`AlMGr44#+4ZVh=!NbcxQ zBg6lZ1!`7X`|ve^tXXv`&+ZL%ibGGdmVZg4Ggc1--6gVSb%AL1da4@42M&U$X0;!r zzQCH*RSAY@LCxwgf(?N+t6oByc$C#N9~s^e>h{vAS>1L~;#0sgF6T{KpHTUDNBb=9#{Ud`$xXcq!&R+ospJ;Q-Fr+8{suZ1&JMOw4! z1@a`;AZch;r$N3;f~;8`5R3N6_dw0+LE4NGVLFP(rLtz#sXU3belv*fmPk#;3d`(YPk?)GBvTENF={DMz9euzlIa+U?r%DT`O+ZqvFW$<%dv$n%jL5?5z^i+#W%2 z7_gCHmoYmPii(EQnC__pwCAV6KSc#-WOy>cMIaj)-Y{0dqv&1D$nXs)u9GTjhA-N~ zn_-WlVKl=tv|)Wu_o28)Dr<(FT2994fcIwjB?wOdYld5w;`$I+GrR`Da)3XZ!TTd# zl1x+q%;0qz$CfmMHy+x-(rE^7GQnBEX7F5;CMNP3yw_O&vILsJ`<~!yEocUBo~5Y* zus)Qlx%o$%WCrgC8gT1FZ3br;us+n01mm@!KGZ~l^R%Eo)I9{Zg62MZXP&ipLu2nS z(%#+-p08tKKili9`|~wrex!})Jl(4=7s$ZQ(=K3MxBl)0&eLOLnah&oU22WcN*=jkH|4%33p)29)f0_;5P zC8UW*@jwdQpNpYRl2+&G>j|!vR_AF~lw;&tKTqEab(*v~Pd`a89q4G%D9gZD`L9%Y z&eNZ&@;Xny3T+0k^Yn6&_lI~~yxb+8&eNa3`A9|DdD;t1W6=%g=^r7_k{~-zuNsT? z$oD|!=>-pCGdfSF%b*bKJnd9|O&sKLGl+&ur1MT!1YLlgcX|>mY$fPCy++)uNAa}5 zdHQmdp!0Np1k0!dou^kPSk+30xoR9>vXa%H2>U=pa23!Qm#-dD^MvLX^pLo<2h&`E@#i zQ-S$4ncyNTLFegB<7Pc7o~PGUS3u|K8xUNl5_F!vpWt3#=V_Ovv8ZS`=jkpgKzsfl z_)n?;ou}U*cnxId>1|^bJc{1coTooS@u^hVd3xh`r-et+FwWCQXv6xRenIh*RCbX)8YrD0_j)lLIvUP?5^13HID!dU&_L;B z1ebuMWo)QR z_I!&R!w%?>c@fEffgLig;a84fE3VNY^Vrd7bjZ99|6OTx$T*V`yP%0r!(ck*#|db3 z$b1X`YiV@III}~HiigZ&(&&)+3;rJ*vHksl73x1heE?S(_e z6_u#)(=vxl|F8Uz`2xvjz#bvtnreeahm0LAzrp=Qd>t;%=efUOFMJ!Cy|Y85!$7!# z4i#s0h*9MGT|D!_od@X8p6It;7$@h^X?%5>BRKn5%-7+*7`#P*J^W>}z)O-mvQq3Z zHRGlE6wM0omjmXiGr6}os)HuDx*pV_fB}1_gonR``^c=0zKS=&W_6rz;Bldj+acZt zSRJ>ETgjumjtfbnI_?R7cVKmNCO@o>>e@OU3iV(>9i8G2s5y!ct%km$oQzftnUI^| zH9QgN@xW@hbKHhUZP~`m#Yen`7r;LcSPh-Ye0ESrO>psQs8<4N=oGIZkNOEU3>|=S za!gjku7?~SJiHU>?I5dR;3dh z*D!jxX)NWOtcKkeI3d*VeWdS#>|2i8*e*tS4O3}U!|&mL3$kxHmffHUH7pHcC;+;? zvdcdes5rPbS48rK^--rjw?W2 z4p2v@#5!J2Ly)xjZ<+P5kayUM9w}+RH`c>?leTq3A6Bbpht>A;H9g?9<;ZY&+2fPe z4|OO$K53ojdN4|Y_L!xzs=X90{!5oWb#dY8B%4vkb-}JDuGuL`JC!&P(+ixDCLTFAe|kZujUVUHXiK~8haEvGQ_zy9Q_z8|D(%KUf3x`?Kxs!7 zR#=vcB4F==b|o_`D9hvdUGzyPS9KYNmb%klzTrV6*7jM3`FT!dtzWP>NLn>VpP9gilsgO9EO zou1{&yGwNH8SU?cbl@n-Uu9K!IkE{}b6eot6`tj;=ks@3;~WOW!U~4bB|bXs+$@{N zv#PWo|M-?lJBv(lZJ@L*3mXxv4HlE|w9-+0R6h5jajR@Yi`n~emX?h5`V&TFR^>-k z>pj+tMRtJ7d6k882+jaWZ?&B+N|Vk`|W(qnu)hV^?%a5oE=5?r8# z>sa^?!J{Bu^fsPP7x&Gh*u-B|YI{d@9s=!K_+P7lek}Y&@CV4Y-?MLae3z0n*@5yE zJQ_>eZ(V_J71;I%5-hC+ZGQ`bVZgd)uIA}aQco?-YpA9ejw1!yc~Px!m50F9-LCpc6EG;bQVIFTEP z@`i#`;)^K_pvKLs^vm2__8DW$QQquBe>`wvkMHo^D<}6+X-<~QO+SZ?>hT@tvW*k9 z(REpPf#BbuQ%^=nT~tZll99YjeW^1L>5(0)uEbr}z#iFg1i>L%&?7spB)9~09?h_( zmr%`0@W*saXZ<4*Xx8dWf={%dS*t#SX=s7XTEzv;T5ZCo>x1T9!guDgRt=BoxT^31 z^_6hPe&FpYwwLWo_5$^>l(?_9r}5D%2qpm=A9X>Rc;ttM=CRI^5gH$T0{*{2cG7k# zudNKVi~}$Xdp;qNPTH>^cv&JFAKg73gmWB)%@B_}6QagPKZf)nu<_9!2)@^X#z#vl zbK+*fnk6qGO+1Qq4dbJ&&^rSgAMHWV9a!_^igJV2$4C1??JKRuM^_~n0{FA>(J`^| z3#jspk5EA60_J-JU@3Z;9+77EUcE zgJmSdCC`SaljkdtUIupZ{Dj~mQ|Y92e%Mqw*+43WG)GFMUHlQ!EUEOK-trIvkR8sh z%Js2=lyHGc(BV86f>sl$b#PHNMzQ7N_K;0<+EG){3qcQHO~pWh{=k|FFQ6$F5RIj& zXj1{&+cn^?rUKMdY(}sN$i_i0iN<;q)39b7bR>!qQf1?yAH){dqqw__gC4I9>-#tW z#r{%RL+ex?lqhF?zUm|hM*?eTA0W6}3u{ z)ys!94`BVi5@?L-G=fvKpfRe82_^v>qjGiG)OP=;T+$fT^>D70NMls@6HL>B#;9H) zco`%ucZQl5$Ef_XQsPnEe;=dz81aX|`iIV92SRC)ANq$sK>c3Zy?GOG>T!UM$gOvVr5m*A0CBW)=yaG(l}kBoB$zZI{ma$Tp(S67n9`EsnF zizp~|y5?AwW{EwsPSM9fM0GapbLJD2PWe{YcW)IN#(@Ue~sh$mja z=3-CnaG2wP_0&!!I2l-z=t`dURJTVpJ++JAPn1SIHD{J%kX=Iovu|@YfV-L&EEx%ce?ac!_Mk-{TjtfNld3J z?{N86ti!b>#cTkq!*vS51hAMy?RB_H@zQk@7<9OHyO1iW!*wsRyHt)kT(1zk2(k{B zi_&CgiGG~-42g7__yf+b##4vOd6nd#jQ9LRc&aW2u{(0I$Tc?JPfSE z%+V2zCe7;hHnY@(UrSK=K0Cl)- zBDeu$+rK=N&>^{q9f%#S$06J&g|`0_!Pi<)hpWe$^mc)@1Fq(MtWtZ2YZ&X-0@e;p zAUISDY6os0xDx2kx>a+>=I1pT_-mJ|CsAp&mH&nIoOJ3|y-)Biu(r}QJhwckV^(o$ zU0VgHt^5}L*D645}fvg#5i(CC%^`=|3pH%vOJFmqt3bIDkiDm8~$a)+4`LOW-qDR9P3Rdo150)9?>ntk<|$jrf-NMnE|!aU^=FX#eY142HdX<;92*6H7Zsq(v4aT?QUT3p2Z?vF?1gw5t?({Z zI8*yRl#@Kl_DAQ!Cv`52XKH6u8o2qH+O7cpTE=_&osQ0~0QO=W&aMECr*_AJRB!L7 zhF%_DNQmOB6b;dq(r7^SJox7TYmA(ktD`0~Mpr_;0^ov^eaKg@6KeZ74BmY{n9(M- zK@Zg5D5lqoZBg!&RP;o|0ZpatO9Obgd*HtWzomPqs0~$a9u|s2l{?O68*ftVGwISq z|CEz?4(h=}gZQL8i+}7{(Rz|{GS60g{*OMNgK@~h=l%J-jgQj7{<$8}+|M3u{^AnH za)1q)JsAsMT>dmY6nYWK$F+249;GSS0aPTe^wd9n`6roYP72(MsH}IK*@m(LcS+J` zmOhoThfMFp@aQvxul|Gb<~e&|?%9KxURk6ki%5ORAxvKLzlKgLA|>-22>nT-@{9aa z*o{wl>iT>7{HNmQ{p`hdJ1nt}EcmIk%*EZ4E+a}U#~#%^*^S4;FLntJ&EAi9-|=C; zuNLA#72>n7ffkaxO26@Dxh`v$T5h?rd$Qnhe8gY&LYPFaCcFj<^wvKpi^!?_I1p|H zowR1Nz)zBuZcmdgLrY6v!sbewv+8p=GePqXf%8e>y-4Z9j3n$5R^-vfwsEp`XlcPQ zQz+;oXuna&FQD`t3!T>HrYey3p%wB1=zzz1WF?g6>fB?uOEGi>Xw|Dn=G<~4cjZpK zDi1)Z=*}Q(=Dj#N>2(ErGhb0pm%sE$1~i=16eHge)nj3Hq|!n?7^h@dlgjr5r5_Ov zA{d~BnJjEbu)Y@FWMO-PZNVxFqDlY78|Qo@9by#BO3Kq)nh(2-jXVu)jy6U@oZB%* z&Yfe|wJW_~)Oa#S1Fh3WyzHQTPdYV_>pe+2eO;(SbFw~%hU&QU71Xhe$EDe<--o^1 z1K6dXSGc92@N#Fy-q|_3^gAB@u^>s$ps(VhE`=!DPl?XBoUO&nz)7gi2X+~FC&8`2 zE(5(3PWpA>4BY*S)Zjkayv~4fsn>IFo_lc))w)vT|!W_hVGJ zbRM+tkbEOqXLXjH%DpM_u`Ad6YViMt@F%bazwvkunznlt6e~*=n!Dqp&ZD?beC5;hmB;4J8EN8?bMxk|?UYd9 zn~NmL4CETl%qF(Rrb*kxu=W9tpkHg&YLIVpz2~&~#sVj*=P3ViST@R__L`?UR@JS# zHP+rEuaPo0ueq;Hqr!Q4%@ez2>A6s1l6d47nVi&mEPN&3g!=8nuy8|Qt@bNXlSf(k zny8&a8nxOx!rvZPtL;p##iKfCLaV(G)V%uZ;<%6l%NRb6(rSC}te6 z+P)LFmq&SR@AcZA0{`HJe=+D?LcA)vNS@!D!y*=p-6%CVF}ZI?d$s^IOl z6f+fAZ9j?I%cH!uyGtW)r@_AqSZ$q2e=n+QYdan4^KtwI3uHUS-3&z^Eg~+D|)EK|!wM~Y$CVx|u)wXx6Z64*deavgy1x*XE+B%b#Fsg$l z)OKO03ju2D6t8VO5`0BDmg18o)OP6;rUq}9p_rwC)pn`4J&%gs9w3dpT?PKiz-sGE zevlK?Q4?yr5!4L;wRMWu)?Q$~emH{kGRjNX1}CJ_8cEA$;bXnAyzQ~Dpocs@mvOSG zemn7PZZEa;v&m(Y^JU=JyL&a?-_|MAPH(GBx%kp)kD-FL6~pIxC*^|q=Pkp+=XTM( zRahuqbWbmJ*_7+BXoIlmnFaqyXe(3`KNN*V}#7yg^lXdu)zl^7Lg91fR8z2P6> z&jQ(?=$7%829ILLyJIQ4*E3xgvXBjm4vz|t{LYE8zs#pA>@L6tMHeIJ0c=pzC26wm zAvF6wD7qf&*OowoqPr68tOX5<9zt*cu$TF`njdAO)}W{jh+fS4^Ci%L=z|3JYC!{{ zuMxZgelG17Y8?hd*_nA}&dbyVUv7E{|HR{>-$BWoJ$tARku0LG{;?_ZB{%c`y`Um` zMei|A=9#!ok~~3Fet~~X-Iel^c~;}|cljv&tmgAYMEhWgH2IDH{{|J2l6huy;E80{ zL+{2vR?Ls{Fkt>HA18~5*J-XK>C3tmK}F2Uy!?~Qa~_PLMCn%iW5Q1)Jk5k6C&QCu zcm5v(Dq>bP(Wg(9eqOUn(sl5uSa1y=47u*a78Xld9`engHpNPvAsweBitR07PnBMO zl%)kldMk<+ES(|ID;sxZRp}YJahYhrOw{vny#=i4hVT|Jb&LHiU|W~+w}2_8R-et; zonJjq`7uehL^0&2(>XEpp3`cwJ7?6k-fh}A1&k(MOtl*Fz_=FTe&U>58hd!swrD4- z?X&6V|DKu(u2i3WdcY+(!4(Ra`Q>Yds*0lg{?rxf3t7`!2~V5z``8_ zHvz`m^j4z>;!docZEwZSH&gNWqLmMzz5(n-E1fo=5MVD_S(IRY&`CdX@M3tBjf&x& zDT~}hwKW~L6P#^8HiYiPN^)f&-VQPEJ6!?uY+!w-ZwNjGgVd>ZWi@$N%Hj=93v9>( zU%(*smz>v>ya}(SkF*7x4FP{`&xIY=OH`hx3Rx?bjjy$>@p5)xXytc>m0Q_+p&3?c z-f>3GaOqa1fnj{EldkuD3p~PH73P@ONY<){GU#WF@%21hRu#Q(iAtICIzH)@%)YXk zH0wU6BU@KI7_t4h`c(Gdc1{`E5xfFAtBrBd z9GU3DN~^Ugf3f~oK+%73dGKjGHrC3D?zKNzQtCtX7Tu^dSrC*KVqqJC&9uFmz)Uc4htgl-F@f7M|nNXFxLN&MYOt+%D8ae;s$> z!?#)erYOvd9Tf<=q)2)$LPnSMqOu;Az(ZT-)3w|3mbe>ciJSCXO(eY$H6yLi+Epi< z<>z~pkB79j?n}xqf5>DOR%xB*1j%*ck>ck4fojgX*fMwSI}0HUrLvcm@66h@GM5VkPR6#vqLi9!1=Yzx?4Zz(sBy% zHgR3=`L&!pmySIkN$$M6<^2_SM+a-mI(ynb$@Efx&e(U}+N;CWb0qp$Z*M3wBBrzJ z7*?#Q4;lZ#qO$J0>(PT7fSab3+8$(Idn}qQ^t*?JZaN*aW{A{D&-Xf@_!tGBGxB_X zsfS2O&-?YcZfVL&I;PZ9pJyc6p?wDru8FMvmM&X*#(ymzA6J+*Ac@paO;- zPgV9VEpW36*f3idaEG=st)v;J)=w+MNphb3tFb}7NZqEDe&QJT9N2`@Qo|VG0(S4; z)&!e_Y_2IicRRbc&!(z+kK_z8e<(Cb`W(zS{=0)`QA z0|d7^se5HhKCP_BKcyl3GXdg}fGGmqJJ>%KJw!#%s`S5|>S`+MY)GdAo65SG;CiX- z-a!}f3UrBnoOfG^ba6KW&I`uVRMwzSIKA?WcjFz@TT@v!h4ll(uYpZrb=|l%nG@I) zmJ9iL62drzHHh^~0h>Y^POyy@G=+2o!6Cq=uvUuuM;XrNQ?-{%g!ktoR3hQlx*R`PS|48s1uqiB8(|}3sQ&=sV@Q?#wQ&nJ!!fNU1b3+L)MNV0>OgP&{Z4J6Vm*ck{;12#Z*DZylwP*sBY zrphsjCDaU%-Gt%>sj|tfO=1l_vOVS>Cb#a^b~U;6F9Z)uWRqLR2ThVZASXU-`9eJ1 zi8BMvOTZ?#J|g%)BAeWD5rb<%K1bLRlUqwEQ#H9Y3;uU1K$BagO__>U0nJASNjAB) z6?qz3&1t1B|Kib=90&RvA4)7;de?mvxE!nIqm0g=v?dFK304F)I`5)f9@I(s+m;>+ z-c11-o!=P#M!-g-U6aO5Mh&C%C5=e$0(T_HN9$cwZV+*$Q95~Zx;pU3N)txyZTj71 z)#Mo+JJe}g)k*g}pAPqA(ENVbai4y-d!9Aq|3z3qM=^*m$B}%P|7z4%02}6ikl8z6Fb^6dUWev2!oIL-M^!XCU>2dni4QozJxyck=*y(b4yzD&?fC zjvoWWeF|jW3qxI49H)pTIuR@46M;&+9rM}1Gi@C#%YxXT02uWPOdhPeMdbpvYU~4_NU>{-qL8u?rr#Q0vob(CXW#b>Zl1rc3(pM9B|%qiVxYTJ!(sWPBReOu?_Vl zY_`98RB~w2J8A122%3aAvPcMb!gHzHyikD?3$RhW@Xo~MA%Wq;Zo0K+TIs=qOUdow zZ2WB)Y%E=R*?a8j%dGl~djASaPqWZ{bEb2^obR*nToBzIL>)ii!-1^r57LDh@Nov$ zuz~CM+%=!mp?Qt_*+d^`YrtO(B&q81R-oq5n6LqfX1%3j7n)UWYgC&8tIx+lxLvV6 zhp=`mu=+S7Njxgn=S8p23Gj~tS$$^3`gk-?p*}-jFV^Q`RObV$&+H)lGdm0u^XGon z-V3Zg&fuPs!1WeXySnoO!Jq%Ye-dQ%DbLI<1L#tP=;5#di7uW|tk1isUI&BqeeK6- z(dzIQpZo!=4$Ywuj-U|vRfdZD#Ou(!1?O>)bkcX!8tZU0g^D=)h2nO5!CU~?cF*(e zuFogy0^9Baal0NBw>$j7uOSNUWHut1t+x5u%LK1a~=zyMYsXC#S7MIYYr z`gDii4P^Bh8tdcH26l4f;GsSf9xK*o5UQns)n~&XWcbYftUg<@b_-zjaYmBlQN~r# z`#l`|83lhAkfcqVIkpVNGSCd~Sz@u9T=1+Cd1$nCQdp7#52=;Zc7V@sigA zv=iS!EB(el$D=wLq~C6o3wh65D5AFu598@0kFvEY1J#$ozZg{hL{q(Uom^OM6dst) zUwRqJy$J4-=m{38hpdr{Dh;Ae%P=K>A(Yn<%#i2|7HlfRD^_g~b$qjpcEJyz44_8+K;?BEzsGPqx~LkXC|WV?U78AIbp)$|(j*o(CD>Rc zoTh_$Cz$Y;14Ja#*O^X< z%JfU%TnsGJJ1f(j%%kW;_Uyh9()A)LyE`kpoyZVB#F)_!Lb_i>W%M9TPCBt_M9<>q z;5-BDR~SxdO4gt(W$yd`riRMgcj3G(o_>Ylybj4`;*qUg#Z$I^3+HR`l&#L|nCvVb z8T!@Z@RXtd!1)U#_6|8Gc1p%%#4IaYw;`oK$jU3C(;oSEAG5L->>j|fav(u}U|H#s zG&x3_@T^>i^=n9=tQ<)&LJP{u(FFSe%Su=C-~!Y-)LzgYD=UwNbCg8N%JT@$(t;)$ zZy~q|BrP`=jyvs*Zg}<2^2m-w{!vz1@8BWC4*<(f=ciE_`Js34Jk)2kJ^QmPbx|dX z+_IRZ@1b}HwtBF-yIKriKz~v$T0z`~{Y!3lS^`n(r^T zr4ESw2-0&kq~|f8`8oU?z7VD7x?IFqdM-^FOM)yt&kjW93q-6*&y``V1S~zBm?pQ2 zNP2$!6eTJ>H-NJq$kWrw<&5m|;il_8+UWepG@kr0xpMzI5X9_e|ScuLP( z;M@eV^mJmUn4T}eejZqQeoinGSbDmIMsr*tJ^y0; zuM#Lddu+!~JAtKVKZ3r%($m#6ny7V*jg~V?&(-0qDv{E2D}qh5p!7VH;9!unTor0w zY&89|QsPm_t2{kVM0`B3^mJC*$Pei`5$Xlnp8Z*Rx`>~tg(@_p=XEHq0eN~lwc051 z^t=bb-N4fGNrLGrA*QF7(9}>uZF;_nYKDqYBl;=9$DsMPf?G;Y{f0g^r6D~#1`dC9p&t8yvh#1q;iL{;&V|osPG(g0do=&9ogy`wHHk>tqrKeM9J)tN)yQ_vu&#mBW zA)eCHd9JDgGCDLtJ>>nR@TxukeX&qLuH46^ieBCTge%+m8@2q%h^ zrRM_CX^;F^i|IKT_C#Rmc?ZF5z|zwtw4U08x1LY3{!s~(o}UxU)Ph>iUkQE&mY%Mr z^+c^>tVPZ!Jv;8unlu4R&+Y_mT2OkfPOvISS{5%HaM~NSp8i=LWocDtJvTu-3|M+P zpQmibLo-v9Lwb&cIzrpCKTA)iGI$(BZdq(S$DkMu^7M3SwNd2hc{GBffTicz1ZS#* zn4VrjQ$q>0>3KP-OI3{0^HzeJLG!W&x0IgQt#;u`H>Bq?@k;6(z7VD72@HQ&dOl1U z4}vT`UyH;kBG#nmbFiKPmYzDe7lH}RC7&ZG4dkM#WZ zd3Z|CesKDVr}T6lt*3aT=YPagdae#dT~uupd3vsoU|nG8xgEhaDj}w)m%tB&!k+tPYtwU2RJ*Gf zrRO+;LqPM-1-J6i_1g4YBcw3nqkJJs&qZG33(*MFNtAH{$kKCIB=!`sCOt2Nbw054 zbRw;%h@|JEFH@pg>(0(p8mnbuQePtUs`-63L3PbboPLX7D-9n#|>#`JU|ttUiJ z&sX8h0G6Ikq4k8K^xRQ3RC>;Y^NDy$Pv_Bkibr~$`4T*(=dW;n7EkHvJX%ljNY6dR zQ+jqB!J!MX^mHPvXGYA@a{&l#B4z2hd34$%|I%Z6_J!RCSbDBauqLqdbP27eHsP)3 zcC6n*0;T8S1mm@!^gNZ|WMJv(YFba!I>t7VGfL0Na4wQa>3JK$4O&oozC`c>NLqF( zvi$xPtUFhx&TYhUIaZ(z8iCrRP_0z5rQzI+4~hBWCHDjO5oG zB4z3MT6Ef@uHjIO>A3)kxq+qUiUi98OHY^3dLC9t&n;NLp#)0LqX~}Eg3|LWf-``n zr>ki_QR^7{QhTEGyc*7x5-B|&A-G2iO3$wdz5q${XEg`hR!!$lIl5^Pn}@SZ_0{}p zI1s~r={v|qiDpyIZ@@CuS!p9bWNMe4`ArMR{wz~nREeT4VRg*ZMN#wyd8WFk+9>i& zT^_-*z%q3x!P+VzW~!Ia)KEfgrf!33D;1+m-Gg8^(ELk{aa&i;z5VE>#*S$9^K6`m zrj&0-xjLGOR?F3KlyV5ja&^8)>?vYRuATzxBw)GfM4D0&$<_IoO150R7|tY+=cGB26j8n5+MS^stCASDi>x3ej`*6*w;g%T=e)ltNLi-ti_iRIYvj z=QHt?tIne-6^~qf;|+Mq)xY8VDV}oGc{HWsk*jx#r(B(T7w(k?S*|*frZgjFx!MQ9 z;v!|a+ATWmQA4h-33~{zTpdX;0$8rPgr-!R@TT-|)*mE+a`ifbYqX$Ty@%j#V7cmQ zno`s{$|lMgQdrS$f7(~ds9wN zV7cn7w2>cjbw#MlYt!~;x$2@y6gA}PFccetJXc**Z4`N~jzF*@uw31rU|*FGbJa^| zYAB&LS0|u4QpG4&&muSjG!LmUj$FOIy3le4B4am%Ud|%4HzS)g2>o ziikD2dONIJf#s?bX;(!gS08_u64kCg2IpTO&s8VWu8Qor`ZA;!MU1)XMA}t|F;_o> z^r?t3SDi?^3ej`*PdKxI<*HL?SD`3ZN2rF%)vlws&HFOTpa>uFvxP%iL|R3G4x6yY$8&Yt2;-hJ!;6+y-T{`YuBKf@t)px$Iip4EXwL4!MS0_0?Qp1!73DJXbfQob`d_sV0*& zI<2$_zxtdKXnMA{{z{jwHj}SsWmY{;F;A%6fh_z$@Ga=QUO_}_%y-%{D(xlB_NuHac}LA#J|a8$axJd&5MKz|ve z^3sVsQY}b)Rz|*V`(g0)WB4C}Ipu3T(>(r#wLhp-dF+g)7=?Ny^7y3>g2$cr;D7>| z#}9@IBuO6S9yh5f^0)_r?h={DPEDi8Z+EKocmRrip!w0T72SAvfWCt2Z2hahstob< zc~msS4zkrLXH{TkINw=j#wM&C2Fwg+q_OO5ujqVZ#(UZ?9dIMy?+7w8o{nbZQ6|#? zH@Ch^nXw;&eIzn7oSG&cwQt4|C=LV7|NZ~XNSfacE3?a)I8wa6Rl~e;1~;k(?!d5X zI(W>h)7Z=@z`UwwnOB#wb`mhJoRP*7i(Ym5IC%8{{QE%W)yL7RJj%UVT_Sn)G=irj zGOwJPCLXn)oNu6b4OntImG`8EZAMW@&d;EJ3M@JQAov|va=M}twT0wN{Y2MkPk!|X zEID0LjS@e~AM*ZxI-vsEHE?b zS!TuwtUV5x8O}&!iA6Jx_%xVtKKye*X2$GjMjqv6+%A#KxC+4(iOdYArin-Gn{fw< z+d%U_|GybYbMqHj$F<$$OinHJs9j&ay0o?Re#zcZU3yh{XKD9j=kQFjErW@rOXq#4 zLsII_>giPA5l~v3g)ay`2A!(M^7f1%qOm)c#`n_ld|&F=otst7dvWZ7&TAHUyapFu z%V(vzOPliXlB{1$obz|c%i`UE;=ESsR=Sdp*Jb@$fIr*hp<$CrGCgc^#AjiXqo9pc zaoVKwcyDKMlP9qL7;&^o=cF0OH+c=~uLS%JUY1>cjRHC@NAM&cJ`PfC;JR25kGT4@ zzx2xT!f&cl+Q;|dzYD6`pfmHxHF1Bxh5I$&==$K8QgT<^ibvDJ-KOc(a*s!L;4AtS z+FvOC0HtqP=)5-v45*G`lP=36FQDbGQgi8WC_UjW3`z&GFp!`>=y(zfYZI&q?0om1 zSQU?^gsQa6Xth(^mQXhbm4O`aH5y(D5Y$mKqJz;)I114&z|M`%Orz#}-_EFXiuPC+ zE@Pn|2<+VGl5&)c3&!eHu+YM2bZ$Hz{;|ML2d;6ZoeswC!v(TR)w$6bl^BID*xKsT zzTg|yxpBGC{Bjdyr-Rp`OL>&Z)K>pXBApI~B3N4@I~_PR<;82+iD2(g|JnLO&Row=N+MLfvi+xBko9ewE+*8N9t>41IZ!dHZqnHji>|yL}bBy&b`=5@l_B5Ye`W z=*m$4T5lgi@h_0I?SV?$UN0(o`x5*YK-Q)QCT)6%F7OSF;yH7{+Yh0?53)8r5NXpx z#Iq0WPu@=cgB{XwI}84IAZyd>nC9)k1C_qPTQ7??J#dTOuJv{Bb~gOqK<4fDk(x)j zx8o$zaXaThI0Q0poth>dwfZjCbZQntv7nUd)Ht;qqbMqR+ZX;)z`S)$C2GpPp;76P z@=51}RiLj7%v+aKqojB}dcpU>+hOoG1m>-4oN3-3!P*^Fs*YP{G{vas?d9JDZ_}|@ zBv^;>_vmdN<=)PaNZ!tkpsPf7+&VQ)Jn9oRReRhnilR3#Z=G6h6cxQ)7XCnB-nym| zH9UL5{^)ccDxc)-TF}=3=B-PrQBu70I{3Tb?dI?|1?H`5oN3+u-ey@DB%>w`qUBa>}Dnd(OB0RTX)ACW6x?GH;#AHA|3tA+_FKj^a|#(jm}v zEy|yDc>J?c;*rl;#_P{p(B1^hfO?i0@DOVs0A_$QcqT{OtFSM04*$@;sKI#_{?i~c zpi89YQEtEheSb3GEd*~!WCl2urBqj{8jd$UCH_9z5LNMznRHBCHfKl#o=aRz7^61GxIKL3oN>ag~vP~UiPU4~YV z9X12%S!Tdvti1`C0nSKciA4j({}>GDaVR5BATwa2Xh0t22HYZ%4CsfTuS8~mQ+fJE zkY5ruReNx)j$#O~gUhMqMp5zL+5!GHzz#0gRHEig-_WRZ6+gHRfqo#cgUcn=C>a_g z@^$*J?2rzwbKsu=%v;wu)4Y9@wKuC&9bC?6icu)k68Dv#g12qsxXlY>-fk7W&7(|) zO5CYi2UWC zF>yPM=bR7BfO?i0uqbPL0yDrFX)Lj5z(9Q!GGG<>D}&5{!=eFslpC;zL^5C_1RF?X z1~@fMJZj&79Z+lsS|-#QzzO3E3Cx*#mN|1A zYsUj~#u;fWvFOZ3zXfORf`13doVheQlSjET$4De+rXzS=c|(e**D@>!Qtm;g{*c4-POPy7kr9YT|K-tDFZXUo@K`OWbItQ zjCTf8<)Or)@xA^G#%~ROOOP2qN2KOaZu~Y9$@tw6>?)BN@6FL8kNo}hoO^mp`Q&bt6fr!67RIj*Re?$mYM?pa$w%N z#+l~rgRH$xr7EkP(G;Viw@3XIy!{IP7a;R?uIOzZ<=);Yk-YsA!EA}lTc@UpM}2&k zYc5n;j-c|uyme~1QB?GHA@~ad^VT($s3~;sx0X-3P+1!KlEA!mNi|Bm-ym4CoUL$fMkVF8cmtz`qeZCXpH7)HLy^eFI)b@githrq+O@dFAkd zpV%6^_s-xr2;2c-cjAfdLyCSMm_PL_^XDhlehbVWXQZ*jqCc~>tMaGoksR3|^JlH- zPafs|^e+W}dLmd@BJ;p;t9fmTdD|BTyp!rF%9yASO>zznEo znE_9+_6cAHID-eM$Gr;s!u8s=`YL3=Yw%wInE~5HY98eVoFS16_!Pm%5}5%`O%spW zH{d4}KY*4IwFV^3`-BhLO}?agT;1xLi;krEgu2z?M}38B5@&Fw8MwtM9Xq_rM=_xQ z%-wpHxw|%Ny8?698EGuBcz8|I zQTx+5{ZRA;mbxw~H;QUf7yc^1Qr9(=s3}b6yzf(Gn?N51EOlK{jgsPY&ffE~LrUG9 z;137pt!tcV-d@hy(JED`>x`xt6}|1+6ujO2XxdGXd3$;EHji>|*Of@#9*W>#iOgH4 zrin*!W~R2?L~$Z8Z=G6h6cxRl1ph){-nym|HHGP%jpUQANv?x_4KQzAQjL-s!3Lcc zpYIyHy%+v8VBWgMnda?htbIzQ%3EhN#i;1*{vCq1qmSYF9w77frs!=R<=$Q;k-R+` z!BG;Kw@ytHkJ=wmJ_p5Fz`S*8xlvT~b_)EN?hmwLljEQ9O5CuvVMO^@v_}Iopq^z0T*KP4 zff?Y8G?rLAxSo-%Iw_Wq<5UYW1D=is=EmTg4yCw8ZfqCnaYLxhZmAw74Ie5E2 z{JnvB>l$a8x976k(WlkvZekG>Y0!y9ZI+3oPwiRBjX%)9zLHF9AzC*HogWkamao zDeXJxUja)ymsF#~lS#ggZDogaN}JJCFO4zw&2XvMS}6h7mTaUp6* zyVKB~1k8YXmKiXWwNro@;0#_>6G|)|T(h+=I=CK!{{YAgSUpnnC^w+LzCRi8EP|&c zG6S5NCLXnKz*{KZ04?i;tpo#-=54|Ub!nG0?^d&-oe|{&YYDX@%9ggy;P*y>J0KVl z)AkE0^%*c{>sjXPpRD}_n6u8{7fGSSqO)7g6`Wn*B<>vtnX`vQY98gzo+^=??So)( ziOgB2GDQ~T?T@Uih+=tQY3tN-qo|m+>%w0LSlYU#5;cX9mA>AE*c$qlz|z(w)hO|c zSNXcsJnWFtb~pID0`t~2&NOewv39IVRcq;trWh5yy?yTB?b-0p1ev$TMQ`&c_x4kX zcIyFr^YX36#4ivY6mXpI)ifQYgG1e2-HjJ!1iuMs;2Gq06fEQT%JTL>C zk;W2>2HYWAmA3D}e+Og+oE;6wquhX*63KvX5PT((8Q|13@u+qwS; zJHp={WcJ+~sd<#!x7d8azI_nvC6U?Z)HLyEbl6nwu=rsp#sSMsr0Z-DNN@)>O&`!pkD|qH(gSV5}%||ZmzW;JEYva7XDOV-nzz_=Ivvwou*Qio6g|v zd(p696HV%{w&3k7_}_ud+eafck8*F1l}LwXdI|!;ymczS>k9Jr&wF#D=nBkRr55PE-L-nyh3C4M%Ox4jn#-mU?EHDKPl#+l~rmaN@W zrOI1pG{q_zdYebNx9>_MZ;wQ9xJ2fyQ|a9XdHZR9CW_NR z%YOr{c;55RN{L4e=eXEU{?74YE~<`vCm=KxV*e(SSV4 z4R}u?8SpfMrzA21oXXDw{-*(Npm+_myj^QR()@Y&pxyJHo!FegO+SG+TELRencRjRG==25(obw#Lf;%%@;Q;)(1XNN zO1@sP5Idw3+ph3;2Ig%&)4V-|wFjzHC7(064Ly`v^mZ|oDsRt(e>%v#{XJ6iDED>; ziRA6&2riY#ymczKp$B>U$#)xyTR_X-fmTdD|BQ!)gtZOH_XygDfEiHFG6SAx?X$oP za7G$SEE=%5z6u%e4*a)3Wse<0xvXsiX1+7%K7|sC=3lL!Tgm*%XYj-^keNR$Qu8P`{|$*`{tXDOlgP|> zYMOY|CDgsv{QFSc11z(hT5c2-Gy6aAp9GfKuBk*#>KhuB9=ijTQ?vR8^w)r8wo9r} zQk+FwZ!j8V_UG_t0`t~2&NOewoXL@+QkB`xXo^wM+kbilZ^xd^*#KnTZXdnPqukr& zdIoP#KyaKy=B-oH#H03S(k?`CJ}_^cT5c2-y}bth)xf-UO(kjyGigi8CwV&!`dz@h zbxAc!e11&F>|Fzbw@<+TH!yEq<4p6mdJea}s#JOFjHVbBz1^`_@b)=0&w$L^J)*aH zlzV%QL^^KYMew#n=B-oH#H03S(!NFUH85|TT5c2-z5N^hpTN9zO(kjyGievfCwbfX zTz(M>%v+aKqr~UO-GsIMRI0pnMpKN6-rn0gc>6m1S3&0O z*ywE@<=%cRk-YsJ!AyzFTc@UpNA1s~{f^>SVBR{l+$bt~JI8sP2!VO)no86ZX3~D| z8@ycrdK)lrT~dvbn}ZGV_SdC@w@bob0+_e1ai)2@Ico>2RC()+rWh5yoqN&X?S1g? z0hzZaL~rvb_jY}WL0OqYz%Z;LiAZ(!cK#+l~rhOAvnrOI1pG{vas z?X!yqZx4ol5Xii}Bzl`ixwna`B5zMbaJ)q3ty9y)qxJ`MC!)9jv`h(GDPE;s6Fw^? z9yN?;Ux)T;Um2$zP8WgIFp<=BArol8oT+D-Gd);4 zFED4EL7zU9SafElc2dr427eQfIrD0y=27lUw}4{oWVPr19w2!9p#th);ARW z6)=D5S>{hNiP;1g=8rSdSYpwi%XRTAf4ZaT1~PxvjQ-?N?#~Q~BbHjWf;LBUn35rRu!pjHVbBy`9}JczZtlb3x|qhSA$R%DwHcs>s`^2(FUI zyme}tc+~!}Hx0#Ipk>prmEw8JKjYPNVQoY5O-K7UFazpYX21;Az68twXQZ*jq5*$s zUvzMN1pfn&8L(|MAdhkb2I%{f0kaT%Cy^Q8)HLy^eFKtKBuNpG&*dmc3A2t6h{EdO&66LMaA4a1O92ia?>@Hs42{( zb@HK;OQ2s2EH_d>q<=G+S=8f>L2j;D7oN3-Z!P@&(s&dmAO))BZJ8@9( z_GkD%g3Q}fqPKaJd;6?J^0w(>E*(MUty9y)qxR2xZ7Aji=B-o9jiREri^E?On76K} zL`~tmH(EZao3uRiWr2C?l4_Lr*-YNT|!lnx5pruAdwxnPUYtLAa6hI&qZ-IXqgyj#q*wjR!Tf- zIPXnCdpR%z>RD#MZLGZom;ug6V~Irre$>9`y!QzFhd^e)<`A4%Gq}k*a0i6li5DGTQS=wU{HbS|KYz3K zH(>ragGW<`5{v%Ky+ZJ(+hksV4Kjc3i_|>I{aIfk`Lh&)J`$NfPE8Y!+E2d0C{_fP zd`>Mlii*j%KKyloC7)|5QBz31uU4XRO1^EOZw)N@TvCk^PbvBO#foTjV%r1$Zos^C zjWf;L!&rNWN>%bXqbWv3Zx2wZI`+TXxeJpyLN4d9CC6c#SA($eOdFxbu#vJ7B zC*NHt?f@-M23j%s{4?GJ9M(1@-{WW>1!h1!%M5slwJ!iOz!_;Qv1q^;eHAj`1NiTO z%z*z!1M(<0;2Mc!z;_6~k;n{iDih}a(}2HG{0UlS)Eba9e-J)sH~Et0Z|YXpTy!MO zv+GvZ%%oZBI-`_$v=zUy)?ZBBmP>F}(8G`GS?2C8tnCKOU1!ii3|r62%bxf9U$x+J z_v}l#I}Bv*c394jj6BL@TwZi3uN>UH9Kod$nY&Kq;ZZ@pUZ{KRHOVa~ZUUCNPAxZz zimCfB{0D)hu4^h$v$Ah!RJyBAl|2vrSzxK_l4_LrB#nGMZbNoRsrxScw}E-<8fTif z125x%QmIN^XEepA=9VwBH+&vNOE|Gcb)HLy^{ppI>cQLV;a>~P zTh}<#ynUUu_o`HR>x`xt6}>%amEi5pSMX*cka^oZdYebNw+~7rZx2LpfJEl4Q`5ww z_M4pJP#goyTc?&AMMZDVg?~0MZ(UP~nnIJalYEl5Q=nfC%v+aKqr@8$c{_Zy;O%Yj zZvp15Yn*A`KF-=lRI0pnMpKN6-hQ-d@b)eEZ-C6(#iO@*lzZEzs>s`~5PTt#dFxc( zWEtdsVyQhR{E1>VXjwYYicOAx#zO+a+J+`)&MAB^zznEonE?y3c79+6I3tZE77h4V z`=XQLlJJ)RnE}g21M(<0V19jnGGHYHD@bGpI5kZ?YTtnMPz(hvE7cm1G!G3QwAKeEW&$-)%qPGI(Pd&^0nZVlJfcfK$G?rNOr@Th+=Uez+gUp}Jqd$3+`?Hcn z^5-uEe@JBhI5kZ?YJV=Z`AU8g1uXfTT5c2-lW!sT3j#|%*HogWFqb;iPi%dmF9j_5 zTvCk^pCMK9t-S#|q();E_$veR)-}#FZ+BzuFqNw0b4F8)ir$V~GkE(f{HH(4ai)1YhPA_0s=ReZQ;b5Pc1!4k zYXxtgg8u}_yxli?n@5>U7dzieByZn9@R~&Cty9y)qxL6tzC!UCFmIh&ZWI;0tzOOV zF@bsOno86ZCUwr2Px7`0^lresbxAc!e5yv?p1V%)b};^7bMG6D2Zloyt!*g1r4XjT=y02U;csTCveM zK77VQw?ou0sq+BZdw>~G&oTpEVeN~+3~)voODq~NzrG3?@HPA|L1w@?VdF`XN4WtT zOC$sSK=8XnW`I+9Y+8`FZ$PK1%%Fpo3j-|}kThQxKFAskUU0TVz5&;wmUo|V*pG$QPmq>x#aG5)et=hgYtnn$^H|41b3K0@$;L}r~+)5Ie$r1nx{7K-mcOQ*1vc*bfAAGCX!n=~(4 zx4LFz#ZGI^C?y_w$333bl53evV(VsKJ>*%)Wuq zzC6n9TTLR__dJ4UB{KV*nkF8#-@Sha#aqBmYfddUii)STui<|Q?6l^ZO4Jm(_iOvm z$)C_?13Rs`q#7mOX_v1%ZpsenwAOqb7wEveb&WI4+aav&2FzP$G{sVj-tImucsm{b z;~?{P<>+l5<=#$~NZ!7RV1`8Ity6iZSCF^gy`PEV6JXvtwcIEwdiyi{AAx!6no86Z zy7#NfCtaykuEzmEulI6EHAdcPm$ySU3Es{Pzbi0rUE@sic5&ABR;g+-oY54cqPLH2 z9K2l({wg5zcJ1hG9_8NtB9Xk^6v4(4nYT_&6OYb!R*{L?{Zz-G~aJjxCDRU#R1DT2uonE_7a zpglK#;fJz26eW zrog;)D)#`?i;CWkhQALmZ=K0K06|me-ly_OC$>|ep9subCvp!!kPHnr$lKGl4&F|M zKLwb#^-S~j71lngQsu2PxCbDVTJ(1E7Qx%4Z{h}Qka>Gbq~=lX?F$mg+f@*(ERlKZ zRPF%?^7i`~o1)kVn72;l9)NmL(c8V@?+(mcXL1if&=mR^2gxUSdpz``fqCmh?g0oA z?>)%dFb&F79sFNq)rMb(`SK zQ}CYvnKLg&Y98gztSgb6c>}>~5}7kjO%spWPrI*Bd_odYebNw^vCdZ!bbHQ6lr!scGU-`$ydkD6Ru7ABU|J)9&-|89#{% zQA652fc73>2Gq06fLB=iA}|A-!H=}#UgZbZXnhqj;A{9_g3N%QBQ=k51Fn`x2K<5G zcZtjZr>2QV?HkbPRz}r8%j~d~*hg(%A-lS(OS`0b!I~BAcki83N<3<~%w2%3wgI!Q zo@LhcVeR6;taAoWs0!OJ9y>RvVU~3(!e1U_*7c6mJj$(mPa;{jE`oI=GV7e0CLXna znY%TLEkVl?VJp$PP4_-&-lT4I&5aXD^Nw|^Ykq>vi$LpEADQ^e zN7?btddcNEfsrI1@~X}Bs`A42Qp?@gm0f|o)bbF5v7obFYUzTK3F3<^Ph|b^66i&i z6A3N=i>XX|o8`4EO$CGW7P?7sn?JGM-(YzUtM3Mtflz9ArNnr}Q`(adrvp2sd3k9p zxv439v7^$T9^`w~DeX1ruK+uxxuhH=OBe1o`TJNjI;G8o{|T_e(lySs!}8ACc-E6j z)hW#xl^7Kd%Qc3F!}9q%836&=VL3Irkw^Jqd5A-IulfRjRyoMpKNkGPApRE*%lP-S%#p7?62;XY@9YGMOg0UXn=O z?uB3viOgH4@_Viz|08Uwc0}(m6ytz->r`GBUoR?pdn){sfqCo9O4NMo8yb}kmrwHc zV(62AdFv8h6CXA+E=c6<%sqm)H^9FRn78%JtR-UYeJWMnI)m55N5g_mT;}|?Q}A}p zY5WujWZpg)sd*Gcc)QHV;O!O&Hj~J_btWymgH;&D)z;dxc7sx6Wva zQP^RdnB8jU;O*P+-vpVr)1$X}lzV%sL^^K2M)0LX=B-n?SPk;_hx`6Q@dq$(omy@b z6}@e~hcQlI-nym|HHG26zVb=lc7whEFmGML8?8g#d=O9GF12g$b}9IMfO%WbG;ddB z?O>HEZ=KN;qoTLB?-IP-8vd3b^Y;1ZZ64*`ekzf?-2=gH5}CJ7O%spWzYG|M;tr>!7LduL79? zZ$)YzpFU->v^iX?ygha6L#iKF)09( zM$WR@0G`D0I8pjvO8~Cn8^7WI{c@ivnAl$1-=9yJBzi%9jjmrIluxBf`Fuv}M}+b* z1wVWr2A%SGO{S{w$=%<<{f8&v^GlGXS<0twf6u1_rglWa$E1<7takA=<7gtZ_)MCw zHf4*iANo}YEk5%Uf+tgaH`&5A2>JSi7N1#)!ICY$8xCMVaz>IG?B3VC$LSkl#UX$=q}dvKzXSke@(k zZJMPREOsj)Yu;mrF(9eU$>`4`l&yJ8scdheb%yjRwP}jFkY(9Ef3Ro!9{P8Pgzfr) zZJMQQ{}q$4{R+ckF)3S<^3$!}UVGj93&$UXvNdVG+LUG6W-c#B5X#m(h2Y7od$WX- z+;ntB-i1)MW+?`Xt!BdZ>O(!-Ug%dMl&yJ8schG$b#3WY*qWj)WLdU7q*p2X;pm4E z3ENEq+cZnr?j|N-yFZ5g#H4IZ8ac~qm;KQ=#uBA1{9dx_o^8uH%c|DB)A624D1b_p z0=R_MiwFf^iYWA$1+bEw3IT8p`k6!mU|0Z~mn-r1oF)1I#^!D1t*MwtPLW|F&d=#_Nlr6qh(Dx>^ z_)N)1F}){Kd}UkM)Q(Im>F#y{R~+5T)b%Ub4k! z+xV(#-&$3Cv+-U>D1b_p0=Spfy9otg3O*qkM&-xC9sjk0Rf_Lv^iL8AfK!4r%~AmG zib(*xf#EeVDFBm3&a&D7KEbh&C{1b!z%^XrH`FXX*D$l9xy4O~Yq+hVxy4JHTDqpl zIm_xZFEr`&`jG?so>01#Dy7@>5cmEll&&dwf6DJYJH2v8db$_lnM@>f9}LnoOX;p9 zCZT&Zh8bc~x+aaBWqT8?Pz55guQ_G zGV&J*EnTw|gC%>fx7BeBNJ{r3^a}`OYaUZ7+tv^B>Z9~3rE7}1kY(BKd6Z{69?v); zVf$2In`SB7i^U{t&%|(sn3SzaBWKxY8*+;mnJ&k18KG=Vny)rx+1`NudP3Qnrw}}u z`@O!xN$yGRLw*mTY|T;(7Q2g+W%2f-J=jLfM)$Uv0{=-3a}Lgt9eH zA$T&EoQs5$u-zW{wuG`ZOEFlomz)d6dA56_-;+?b<}szR9YgDA=~dX8qAp}vww(hJVF7Of|q{6sQg&C5G;CT*EJZL(NN$UNlU>3m9J8-=EKLzgPDt??MsEr&6VSy3*Q- zP(G&MrJpe9l+Rk@J)gDEuR$by{tnVKOZgloCgHOwhKtf1&?_ zNC0#U(lko}%oCFUX!97)uZaYJN%>Xm|1W^9IJyv}E-eA@Np-)WX7Ra(0TsSc&*(|gxc)Io>w9iU!_X%ZA|N$gyJ&=A20VkX6MiAGLr@0vFOJW3BL7$G|f_c zttNPUXJR-*Ogeu|%7?AJeYD?I%lUH|j!OxxO_TCr>q=9$Hm^s2Eupn(N1!`9wnw-Um2#S$p3J&eC!FM_V_W1~6Ux>s#bB}3OxPAq@ND-)zdNC9&0|VsdnB!+q*q~Uin@?x z*`71evpoy_BqCwEbzqxjDci@yBy6W)m?|b^Yf`@E-P>!gdpF~_kthxGvh2EN+xQz_ z-&(cq&Bc2^p#UmX3Sb_s&k_p26uk5kM&-xCO~<){RSNeV^luRffL(($%~Al5i%9@1 z!tj}x6o5(jE_QFP4d7QCKNF?Byvze|4Tt#+HP<~|*i69-7+%}opU<$c6`o+^gz~9W zDW5L1Hi}9nh$(pK$M@(v)C=P+GF64o8t7Le5<;_a?OXOv!hCdrzkLPP2vWNaUjlEj| zIhg^;!gdn+69{EnsZ_QX(>hst6}G0}JHLIeS+=dDS7CcI`WuOa?ZhBWvy|;XF$vp; zFw7N`vNdVsEUP{DUc@nk}W>l#?6&)tt!3`@V-YVfJ&7D_=?uWgaR-HFa3m3 z`LR%Z^>Qi%z#r(B5D9>@gEY-j0E5IN0P3IQ&*zB*fJq}~S#1DaaC9b0lUo9C4OjXN zHH*(R+*r}v;-uSh8TN|nOD zi`F#=g>Q-|^qBOQe9-BPQ$74QpXO3bB=BGHJ9jS4Quq&wN#K8q;bSrB>@#T;OfUOm zZ+Xk|6OJDUt!y*pt4-O;j-FvJgjTkB3c>S)?Pz55mVH34Bk~S}R<>D+!D1f`6RwX< zVL(#Z%cJj3C|mQGQrXU-bv5Z#D%%uwAH4Y|eZdvD`-lTfxM%~zYUY(Gc;DWPo5QwW~St#(N`3EN+g z|3oNTvlN3Rd#ioH*`96wc|IyjC|mQGQrVVi?MNtFQ`CiCvuvkL@@%(7zcrDt{XVcw zvy|=2ViLA{W7tzn%GRWjv#j>j{zx3731w^2e6=ad_9XNt5X#m(h2Y6t?T->p!gez9 z^9W^YmSV7Eul7fr<=M_ae(@r z&qbI}0H)yMHDOeKEL`n>ld;Ivz6<)!L;|3=t{r=tr2zWK`4a#uVOUX23c#ei#^UYP zNy|lXO&qHer8Zs`ZneAk4K=U!dOuXo=ow5cOC~P#dintIfNFUS&G48B_&+HITw#ykRL<;2%&7vV@hTF zI;}5DuTp%bs0&$^?HK7*=H6H67ZVBFUV&|zrEG5yld$~@!yjT&wkG9=x4pgg+-rD& zDt)&Evu!zNSyk~Zi?=JG04h}qpf|0(2nAq@DD;>GFjh{509Y6O+C&0i%>W?H zQUEuKNdOGRu$h8;`Ozk13UHHxwNRWowGM&})`$y9+$qtif?X}mv(KtpC%GRX(WLu>v%k~8H#}mrdl>B6y_hi<+MHg{!vhJOS z{2W5rnvkDt^A=mpgzaY+dbU@hpGGL#N~N-$L+j1btE_vb;3wOBuUWQ-O0P0+pGE&P zk+3}?NYgB3d$pK^?K>FW5|gquY2+-cUG|G{EFwzd{9dx_o^9hxseEhIy0--HuY>}q zR4IVEmv~!^PynXj<27Maek|N{944ni0CYy*iAVrU4AL}90n8MW09X;j@?uf|Cgn92 zZ?6qtbsPhT(kWgRZaOCW4K>$2UD!;)4XfAo_vbS#Y(waJFrj=ZRmx`st=kdG#}rZM z(RZjf9p_3(3!gFQk0cU4m-(GLmu4xS$HgRkPQh@Jn3Ru6`J;4iuU&i>;+RZm@tHJV zZORtk)#zssT72dy1W%^;M%uzQ2l=gp7N1#)!ICY$eJ^D|vamgZ{vkryn#YvN_ElP6 zlwPIyOi>rIEZZ+G@oX2PUqmEquMTX}EM?nG4n^4hfnkZ5l&wi4XIbsJ*XCv3i6cta z`MqR|&$jV*9KN-x_`2flLMVVrl>+ER>q>+IFa>`-7)IsCLh&t@vB>0F8~vI@0^rsl zO|uk0lbk;Ruo;F;#H0XB8ac~q0~mp0I8nN@B>>m(sNYbt_*}ya70oSfI$XoM70oSP z-_z1H1%Ht5wGU+e5>%(x{v6nTgwm~4CDV)6F@(}J1z)D-d(2L+%`WqFk9?J9&_qJ_ z^B_&Ll=ygu%oZ<%OvZ5@p`~lme6=ZCx>uo}PH5?xrw}|> z*^Wj=_t^`0bCBOkXz7}z7%bc6k^#w*c<@aONJ{rn^bZrt);y+Ew!L5D`GWK+rE7}1 zkY(9kGu5+w;`I*hF(P66Q(&8BDcg6%By3;D@T!=Utw|$i*${vHE${a}#qlwrY)zW4 zHf7oVjQ&SL*_x*iJZsvHMn+o-C%GrdzrhPegt9eDF<7qj7=-P@nVxMY^o@kFHIFHk z?RK=TAiWA(Q`Chl%l6;PJ==C~@_sInu>CKvO|z8k>eD>iW(-YYQnn_IoMn^!u3EC~ zkE0)$o>Oc`BcmsUld#<$`L=|zHA^vAHu4r>yX6eeb|3V6 z5z5v)rc}14(RzgRDr`+r7c$?eUe0&B!n1t`{aZxBwthWZEYmEpfvNokVv>2g7{ekl zDO;2BhxgvTjt#lRn(!BnC4{myX};Q&W!w2JCKRD;%~J@TKDMKg(Q3j;*shAa520+$ zQVf=*y+zpepYGXifqqj$*_y|c%Jy(t50GAkttsk4<~vok_g(4PPDMY3NZ57`Y||{U z3EQv5By4ZQFk4K@)})cMthEif1>3ne?k7si_`PH==ViYw=Pc`-fuM`xe7w&R3ZPP@ z06wF2A)x?F5rrPJ0PYv8aykDS{hvevpmzX}W+{Mg#3TUPzReUN5&$NRoMp8EEQ2E^ zN~^X6;2H+|4aw!a<=69C8(;V3Rf8+ZtW2jp2_;jhQZj>SU5ijMrien1Su(H5Bo#78 zpg){Q$P5i+(kvxYca`a=kHf781CiK@6T6X3s z1W%^yZn7oqDddk4T6ShB28$Jwl-&(iGa$JXe~A7)LfM+fl*%^u4zH+5uTplVs0&$^ zZC~kC*!ID*GLf(y5!j|#%6307$*dcQVLdS^Ta!l4vf8t58ys5^rQQ5qvSqiI-siHHQ;v>;8h6x?(%3AimW3>A}tGil^3 zt9_%fD~_EBtxA*Tt4-OeJOuqggjS__3c-`P(dc70amOJ)hR~`sOEFmN_CdJbeLVw` zsyrM0nS`=6k13Vyt+ZY)y-HP@qAp}vwohH-*}C`mK43fv+iL>bG)vk3E+%2yh^al1 zur+DqEUUfZt%##Lp=?c>uQp}bZh(G0LfM+95ImU`?@Hk$HyXPj-;q$ZW+?`Xtz*J= z+I61o81$nFWosT&D%;Cwoh-cyTT|49EX%f8dX<8I9Q~t2!uIySHqBDDJBmrzzJ}oy zG3mTDY2+-cUGSgaSV)xa@q5Xxcn|n({Lq@us#d(8@qSMzfJ&7DD80{_BNTus_=&nO zDnAxpH|Q>>LICtYzXFi}csfYaECnz^OafpH46BJr0hpBUGV%7>05-<45m9>H%RB(r z@V?(rvEu2HW^Me9gjWqtj>v^2Z3jBto=`HCDkXCWt$Pzn#uWUGgzwRJsP~}j&Guw2 zM}HZSkohD?(<~)(gqVcP4H&K$laetheOmz&s4k zib(;OG;)^J2JjA!w}?_}zn4&U%lHiyW#<}twrHrh(QplGR5Z7E9Z!qa6f6~9YcCUp zqFuxxeMTtPN|kb5enAKK3kv0GiYWA$omk(?6c?_G@hl<|t{eHCJC|lD*A;K}T$f<@ zRZPm&r2L?`w-3n$Q)6KOd&#ZGf9gKuEfPYD)};KPc%>;@v`eF3iqN7pB|j+cJ((Ai zrrHa2DJ;{ThU_tyC)8F|=+by-LxVf*%z3y=K{N zb&F>^;3K}`jY!yT8>DF#FttBfOfqMOU>GbWWoy#NSyuZVZ#a%>9ehzS@*!I}-iA zgt9eHA$T(Pc%~A{&yK@t^Q*ZZdPeXqSp=`}#N@Y8n){CWAVQY%I zkY(B4aI0tgC;H!sgze6OZJMQQ7l=vNw*4Q3h=i?4`K@wquYIv8<5)(V^7W1;&4(l39DTLN$m7x)bo7aP4?SQ|g^>Q#gNK*Hr>YdYPM zP%@P&B{P!NT?r*)iYWA$B~!k`lerlEg+xMTs^7VDX_k^1E+!!}3&Yi7QZgpx3r)Q} zR8Wi88Sla|htRS!DPL(?Y08$}i|FSOT6U)73roExQ+B`I#lcD0EkgbYp=D>nVz5{- z3D;ll#3Ppr_c1>tj7Qm;$CS!;MHJl#WowGM&})|M1nE^~-L~krCK9&S1-5CHvb|kQ z!gg;Adx}Zfnw0lGy}kCVI}*oeqI8p&Wy|h1zm0F6@L5&aor3oSLIG5&6u_0VP9+q8 zDfs3I-(wcQ@p38zz}@KYBoY8~gEY-j0C$K<06dA|aWN?XlSa<6+5ld|@d{CT)bAzS zJ++x3T=h7?%_obKw+~F7w6O)27Dc{%a?X_<-CgPYtXjPgtUv0`(<$37O zA+##ZQwW~SjmEKd6E_|C6@*r$S&G48w+~X4?g0iQRe3A=n+auW9#bmYS7?1mdXoDK8xzXbr1@%7 zmhHai_av09c?!XkS@9O%&%w!xcRccA2xV)QVzAgcCTtho=h;p{e-WW<&0|VsJD1iw zrB`8Vin@?x*^ZK4W!`>@{$nCx`)^>IW+~fQViLB$VE9Q)%GRWjv#fT(7eC`RfGFh$ zCQlu+D_$$Vji3JZS=EZSG~SMc0;p6efc~_uLMQ-J@T2Lz$1H%u9*=@pMVEHoh6rs|Ndlgd2^c z>2xfiWGYok<~&+YC6tUQ_-4c~Tt7&j@1H5fEMy)+KbJ_z3<%OROUXPeCLuE)!#pu5 z8I$to@!np$>^{Kp4xwddQht4{(v&T`U(x?aXxW*PUtjZ{Oxf*iOIrKSVMJ)znUG&! z^A;;6;kxI83`mx=mC^SQpZwNIrBc~$L+hr}tCXE7`1Lj4t3O%#LfxlxJ=eS>;9+WJjV_GGsa?|t6)w|s4G?x~2aIJ_or=65{S9+auN1n=e$+}|4 z+a433H1$KXis+`E#Fqtm9e*_Yz1TiC zjLpZsEcNzP@^A+JK)Zx!aR&ISxG>X_b0C~r$%y3)wE2S1 zpb{<4Kx4JX&cL#0yAo7;_6&5YcG%fi1$A$A$nM*1l9{WW-A&1yj&u97c@V1giFR&K zI&YSCbJ28KiZ`9xv3XnCw-(LWSEQOQ?s@5FK`x)0%I3Xk-;cm2C$H}@UR$rckpDdvoB+Mk=Mntr#>W#&E%_lT(|FE^Sr3fXJ++0+&< zmOO{!8A92bDPL{MvV8~rTZFPTPa$}owjGU(HWp68_6y{n6Ux>s#b8;Qmqz5D+{66y znrFKN{jY?wHIFHk?cU#V!61~aDe6M6NuLSZ8=mxR7ktMhoJiO%32f6Wu?gD+ViLCB zV)$B2%GRWjv&_C>6I14Wi+^$aO(bEJf_HBTXU{_k+5|e z*n4f6Ont(39We>ppE3L>CS_|<=8(77{=1994;&hyY)#77CsdlUY&)TEB$TZw3&FE& z%Ju`{By5*Q-kngkW?@)s)VwwR4Us|XdNuQ3R_dKBBj6*Osole zORusf?16qaB4OJ)NYgAi7GZm-n1t=&7!DJYvNdVsEVC2Ta^9YZV#}dH`n!ws@t#X4fJ&7Dm`>{zgaR-{6ngYjby3_$PK5xt1^rD#0$}L?Ak9($Q^X_y z9>nl~m=u6XBWGD{0MFxijwmhL5`b&yH@p;d7Ck#7^N!gk-a+Y0YLvC@=I0(l9gt9ehzS@*!dkp%c31w@ZLhzhzI~p0y z6i%|Ror(MmLfM+77%ZE5i?HqWl4m;={S-pkn#YvN_CZ=_ORvJ#6m=oL z&-P{XFA@pcT?5-ROW8gzCSm(O3?GU~*_xCug7fy;zmoX_j_-)lUS5{HXpHpR_&EWe zb;&@`!p;4{7ysi|0F^2Quq=u$gaR-HKPTXO%mSDqSmmOzI{E=b0^rCXO|ulhd@%`t zAs7aWNdcHNa+cKwFbv0bMCoY1m+(62nSMjX3pRSWur?~vt2U`5vk#r_MJSm{m6ADz z*24)UV~QyBm?d+&Oj02;8~t@eLgs=%Ce2bZpNUDx+>7CEF)107^471n*DkwfaXd+A z*_kw7ZOWG2Li7s=Ej#lRf+tgUXWEkXC-UD2EjzOmgT;zTmb5coVL)=ZSn5~)w4YG6 z<}szRU5D2Ggt9e7UFbE-wypFkZ1+RI50S8)5!j|#%671rgzZ=iM~O+LmZ{1L3*P*HaL`D=@Yiq}cCDow$k zzj|%eP3|x3^Cv>VRjL$R{x@C)Arzb``14oaV;0<|a?2y&I->7DB;XbXX_}?rCWuME zEr+35ObX7Vk+ZD!O>Tc2{fN@%elKCY`pIvod6VlJ{;Ozi@j|iUGX;O)=e2V(Pw=(y zHe}C(2*p>aQhcY;x(%WDOu^qq`X00RPJi9wJ8Ve@cLgT8(JJGs<^eSvkQ5Ui-+ktO+why77 zOC)Sp3T)FXWqXvEWZu4rVZNA@tw|$iS?%W+AL96cP_`z`SDUhIzeWEwp=`}l2%gOI z3n!d}?LWx>B9yIJios&f8iegx?|HVRKjA7NZ(5qil*+b0t=$M^Yl^y{&9c4xZO`^} z^rsRD+f@VGG)vjOBqm`y1;Zs`Qnn_IoMp9dbZ*3P9iePZny)rx**=N>Q9{|8rw}}u z8=WJCldxTY{9QuXnxz;lcKaf1N5AXY{)YZ1LfM+fl*)FQzxbd6p=?c27kbUI{pB6c zb`$hNh=lE+z&6cNwkyk_2-^`DhKotrnly5j)xORjh+}`EG{o;Ed!w_t-^LrlKC8OX zIR@`oLIG5&6u?Eao=+$MQ}Bjx7?mFjFS`6HW0C9iP3UhR5&$~}X_}<~ddv9}01sfe zPfQBHquGfe84HY*!dMUOxz8l-Cs-9oGO{Z@XN~Th!WWJ^K zQ$op@g74V&J!Ypy`}aMWZh!OPXCfgpHb~PfC9{c`giId{D~n0Vn3V6>_V(IkHxS1< zgqEF2`Ht;MQ?~4OLcar{WoJshW7~T&W%tDb4o=GMNaUjkEjttP9oybw#Uy3-`3HF9 zQhW~jNrbYkR4Us!w9b}Z<#J&PzGK_>nq_;K^eVINUG#4g3ENYGG|f`BGsPrqzr^r` zn3Sza`7uRZJj#PK^(n&f5KvOCvr%Q?%c%C7A{yhTGOfJ&7D=t1jpgaR-{6ne}8 z7$v7d01QIEK9K;pJOD_u6u>Mo34pCJY$+xMVA9B0RvW-mK#a?Y}<=NE^v&w~jCSE*8P$I*HWq2Nprg&wouu9wTQfIAEQBq9O#bO4uT zDY*B=B;clEm?9hbufle@|9F~8By7J4Y||`d zyOWrN?P?hMi%Hp4s7Hv2e4n{Kp=^>*!x45&-`MX_}<~b{3NW_!z_g#H0XB%C{1Gd+odY zA8>p}=;ShKzS@+XT+TJRfAQ$#GEX6RGI#ll7IScNN#y-hK8@0tOfIt&gT?OM^-lD2 zJTkeuqc0Q6);y+Ewj0yBs`M(8%M^7X^CwH+ML6*j&vq*MDMZ4yZm`XZG)vjuEhb@m zBZk>xQnn_IoMp9dHy*-qKcQ?*ny)rx*}jGTHA2~%rw}}u+l`%sld%0B`PYONu33t~ zlD*y7@iWi1b*|AB31w>@Q!3lOwDusBttsk4uUWS5f9l!pjD7@>uw5#!O|z73dpQ(g zdoYFr#iVRa8ac~qUu}=WaST!F>i3c@+_K-sM;?4ub-Qs6-bsW4s8lI{>u8-xC;(IN z9YJAKek>I32Qn5}xgJLUAdvv*6QpUD0_Y&;PXN4t;dwDB0Fy?}vf2RN$MG&v>hJdw zu9`#qhKkz_z00>Y-n;Oss=NFz>GTUi$yBP8jEfrGZzzF#x>BBlCrW$zy=2R7KfjIlHGEc8 zc4fTFNFVabO{Gc!tV8P>gaR-{6tr0YJIJXJ0NbPAmPh~`5dfrF3gApJ34pyZ>?tM% zU{b#4*V}6Y7>#2TQ5xrEq3kC44Had_?>M(;sJP4LcbqGlTioRGJI)o&EnY--4G&f{ zxA?TRmb@wWjEmPc@KGlD7w%$CU_i$cdR8h`dR9t>Mt3d>Ju9Z*$CrJNNq@<-Tr4+~ za#n`cHM-4+e_le?m*%r1@%7 zw&cg7A4h1(o2L*wKiQ5(Mt9f;KPMqSozRjuOEFkB;j?J+Pq-f1nh%Rg$zO*4QbO69 z$CS!;rB>WrNUu`zrl<>9(r3bUldnD7-CH-hU5SM4TY+twB{pGuoS0$o|SD!BcrW_libD3Kz=2mY|T;( zmiZoou>JQp1|)26Lw^gQY|UdzWm|01=pK*-LY8Ga^Bd20NZUp?m`K=u64<6$ z%JwZW3ESZqhKWhpnv`#u@%GwJ?e@p9AE9hb%D2o^nzC%ip&vsiTT>Q-=MFz6p4u%G zPQvzdjNgqtVH39Fzw>M_MSn4&Y%7(@_90rYm0pFdDfpI|0L)|J2I=o_ zJ==0aqw7W_Y`+fDG)vhIkV6r+t77OYCS_~V$XRB$@Ga-q9|r62rWvX?5`mUEU} z&Hz zFf0(00x&5*W9;pg6mApxWyL4A0hLN+JDAp0q*s|-rr>9ceXm)zyZ+$WUW)!= zB4JzH$mT_wrEDjQNha6z7_JqQvNb7x+TiWA?=c_1aSx$vO`5MZW!b)t{$)bhnx_yv znS0Cu!buAE8{~@#WowpVu-KiWuwC^h&$g}|dP3Qn$CS#pH?7NyO4ypBE@WA@_x|YF z?udQ|B4OJpuuZd+?N?$Fwg+GsDJErWQvL|V+iTxqjmI&LD8*iuE!-x*jXC7As(Z{c z@t#H~fJ&7Dm__RhLIIc}3O!~4+$UJ2aOa}GpGW}o_B(ej%~Akgi%9^?!|<$_6o5(j z`d4qS4d5LdZxN+cy)4{gZsa#q++*r}p0)AiL0(n$)NT=-enu#nN|loNht{77C1VP{ zcFFgcCG)CGQX#WS`$pHBNXTpvq-mCtDgNTgtdC(`F)107M$WR@Ww$ksp@f#5N%PgF zY}p-%em_FX&OC+S$&}rVwxpemd?KM`XO?2HSTRZ2&Hj}E$&z*j`pXDqYaUZ7+ec}= zPkNQIGeup*Izyj=(dP^nS?YtlM^PynWgLXTMhedSaLfNjukMI-=52LNf7 z0@zPX0$>jeyNO8wm^5;h)dp}Fjzfsj*p>iX!x?@1Ci(4sX@A$a(EOZ~@9 zZeM!>@gVXC2rXK(6ochjk3ov|Dd(S@%|}0vP`2hVrLwK-*y!GuUZrSFQ5Q1bsovv# z{JUrS9G+*0gzenGHqHFe^W<#lKRnxaF}y7%WouHtWyafU-{XCW;|oIBnlxW+%Ch|f z{Srdinx_yvnR~qJg_GQewC>dCS`o_DEX82S-sAQChXKig*cE*jLfM+fl*)D>t-YjI zVQY%IkY(8p`qQ($5dCB#Vf$oYn`SB7F=CQ=I}5|rVp6sy-=1x>6z{;`QMTqWrLtWK zMVU~xrlHS?ZK*_~%g+C=2X5?Xd9foJ!Zje zne*U&L;nkrfZN?4sB>wSf;&k}0;SyrDObFvMb(1 zzb)r1t6K5q;Jukp0F^2QFpt)!2?byZel0VM%8!K`jl7%+0k9DLM??bP>>y3E6u>%S z5&++0_*P5`z@(A0tTupuar{k`CbtB@8;^cN#fqm(nziMeWmPvCrLItskk@c4RZ3<> zT9+Y|j47g^%}$M`I!|Ue`e8&u=EguK%~CQuh)KxohhZNvDH)SS&a&ENHx|bcgqEF2 z^VOzo*`1I6Y(mSGUUS<-%Pg-4dOC(u7aC|mQG zQrUh^>xa^-l$|N+LY8HFob)QQuKhAh10rF2UtpVNDcd<>61Lqjl*OcMO&U4NYR|d> zI94S}5Ba@h%kFW%jo93 zr2rt!QUJG$NdTON;S@0`0Fy?}vf2PH#&IE0dc7q8*YKI&P*HZS;l~yY6*n5L;opkp z7B42bhPE3g_vA^pBcc|c6VRGA1>aKcwN-y?H;W^_no#VOs$|~LdOM-mO%a72v)F%> zi@IQcY1u~i0+C>k{mz|BvlRPEZ9Mh`7~U6?VmE0NOtt^m?rR)h5?a${%2%7RHT@U* zKM1X9^Av(7^T&12O;vmM+-p%4k%9)WF|rEE_XlT7Jh7`79WvNdVsEUW!y^?o?^A(X92 z^VOy-+cD^mB$Tar3c-_kv-*7DBy3MbelnqK%~A}O?3>jqlswyu(O*a?Tl1Jw+0LbP zmh>uYO;H!JEZdtJJlk$%u3tpLwqIbIW+~f`#3XF{V(23#Woy#NS!U0iTfSMn0gi!0 zX?4Gs?0RY2_?80STJ`*58@yW)3ZPP@0FI({cR~S}A__fb0o*KDwQ$kDKqLS*3;@zB z1@J#H34jF{-WQVsFlpp0tNr}qYaCw^I=M`muQp{T*I(%WAart>rw}}u=NF@GaA5E+@W!b)p{zXFBnvx$)^q$O( z&PT#Y3im7IiwI?FLVh&STkQ5l*e>Yc*%rDp7(&@rDwS<7TDud<))f3`qVF}!c0cJ= z=IsvXwb$((ZmQ*}~n&Z_7E$s%~`7 zzJ9jS4QZjdmNyw~=VQn!f8IwlARJ-i9#IYHnWoM>*wJBS6 z`=j57(6Td6A$T%nH^P>*6Om6KwCv1M43=!!4PS}@$&z+C`b!CAYaUZ7+lOhrM|zbd z%@lPZ%d&m1lV`gK{bxkN_KLtZ%~H1QFJqCi+Y0>_L;~Q>AWgFr zKzliV0$?``yNF2vm^5;h)dp|~j)REOeJugFhIxKNMcKKAw^}q*J-_&*qPfNM3oTkx z@M%AjuzDM7ozM;C>(w=L>3XQG}k#PM! zNYgCkdXSie>#`WSib=Vel;5WF_S!eOy>av+v}jG5uQp|ic0Kg#5L&e6DFjdECU=ZI zf!GrHP(q8=EX824TUX&)A2T2++TGCaLMU7Fm{QrELhB*Ys}!v%>Oz)fJGqNz`x*LA zh=lF$fo+BRo&tg)xCglhAyuJ2KZrzH!`#_Zb@v>~u+BW`>%ePkDm2F**M)#BSDwE3;bs@`6uCKd#w!7ikg-FTW+0CBh*A%~mu%to_S&ZPNjQ?~3@LEnqevNKO1 zcrs$fRw7}$e_)$tDchgLBy1nU@Q9d{tx0)b(A#Uzx>s?$Oq34svTWIn_SWH5&+9% z=q@G&VA9B0RvW+o9IFzglUoAdgO`3oMcKKAt6MZw-Q?a{(cI!D*EP(oXm0T$x@&m0 zqPfK%+qs4}Dwn6ATrpbNBr+(7qrr)&^ z?E2HZ83Z;U+N`-dGsf$9W9Bq|f#Lmp-vOfAn5HpkMiD&*&{DrOTQ26&WO446aYk-a zah{d$@$d>b52oo>G_%DiE%isSE&^DqUkdsIF0kl^1wliB}~ewTcmf&Lqx zU+!J@S(r{+{q_8(E8@;XQ4Y}5Y36^m!9@qlJ?#J}upf^A}Q1o)p zrq72g=xqSopxug)e>({7SN#a=%i^QM^X&@)TlwyTbT^{yiELTmrR~-2T>VLGJf7C$ z2pym)T+rsdHaaQaRR?$u+OtG212lb_nLZ3~8rrF%mjRkSJ(i%i0p5sqHsSxZlQB;6 z2kzV=pggdJFv+H`oXmI2g8)xsz-Lpwdu`k4uqZ&Q|FvzHYLK8 z>yEZ8dO0Jeib7`kFo0Fj_7%Mh!1Vc$1-%Vm1GEDP`KMFv4nKnKx`_q4#grR{bSpxq z+{0eFl$Yw18%67(gbvUY&RJ$tB22mC(HI`O~0)tvs@Oln;GA1LKn4XNS+|{1ehrbcAEiVhAl+9 zK=g6~OrH;#>B9;53+)oo%Ly=jA!I>sCt&G5eCUgie5?bvhXG(jcRia!-j_KvAeRK4i5=pUmCB;(V2}9Wh?M|ZCV(}`9rBZK0 zIRx!N1plhZ6uq1a(?=mQeHg$jv{#E> z24MPp$b#Mma0l8sg#1gY-H)KFZmO*Ir;t8EB-QSv_T6Dx?H|#)fY1Rx>=jhI&#W3l zwSSBDYthR9O_gS*4+H!g?VqC8YWKZT?G^o(Y=CW7;aLQc{2M7ZJ7Y&SxmUgZG~bY$ zzTT=#H@V?qy2)KmH%u|1cR42K`;g8~?sA@8g()Vpa}6~8i5}9T6LlLNZ9(WnH7A#D zzsu}I?cT>v)cw)#M<@nU=Bqpb!_jERie507zL3e1aRm&M(4J24Pbca^e=wPe`U%I9 z-U&@ZJVkaO6V=pdW)mq))Z5YCCVDxKrsq4L{eDaz2Jk4_hea;~FjYQeL2u{rCA2RP z@=qt~I(sIoU+p`gg-G8gbfRwJr7iA+{-X5{LI-FH=Pa{{7ba?(zAUGN4$xG5Ow{*n z`Y^z*XuF7B2571%WI=BO?1gqE!vE7dq2D|`=YExGXLmwtBU_W`AzO9IZN{Tb2%U1~ z$~nujQ|^+!e#(tNKb+73nKG*KgaI9hc7M^!fJ~ncne8J?xns~CP4G{rob#kIcS0lj zWvARZh$qPoWXhR3&1_19DK``CRic+EXZk2)rVj(S9qnzRmjRfb^Wcvw=Bkf$bbzLhf-~rCfL+mcA?)ACnYY!s@9wdO&i(1r-1JjcW7gbE^D5|9BI@tw!Elmo zW}qAr%%~{bU9~M>h|kqnR}2F5y4J+5a#i zH;D)Plk6uCPT;|5BqtGVKD;>XhEHQjHy1>$UlA5x(=-juRKi8)WrX$V5&29^C(FKX zN0z&m|J;mgHj%r62TzhbPPD$({sI(V>*`(}S)uSCirk(2=QZ@Ni08;*=^@%nDXF#9 zjmsC#M3Fm@|13oR5y3yZ9d&=QG|MXz`g%s&6Wn;We8YeITc$2IEUNFz(AsCtPr57H zg<$T}uZfu4nYa(+5O+5Qz>9|5~zhkggj1YVh@?>WkEiClLcVe|MMRgI^+&T(h+S3A~VW0=gaFZJ8~m0!x~G|$bIMW+U!*4wqGMT(ANHV zbJGtW#8FJ5c>tX>6S+%xa0$sN#7ogk9_2Q@jsKQzkKA2r*E899@GXs>5^WYd&tDq& zUY+ZKCcjC$sK@_zZ$QH5iN!MoK_+n(AR_m5Ur}hn=asmh|uGvBHXlH^YbFS zpQgcxHXz#ld{L_7&tyb*W?`vZjLN$;c)UdTgfSt2eU8b}j8Q2t78_ z@C{S`*fx;9u1ezSHf3|N!CuSE7Q zmOqKyWFB-`omZHM+!;JrnWP6%9KBcCTbhO5c5l^`yA{b0w1dTbH4lc7Y$p#c=D|KB zd&z?{vJWQmU<_MF6AigFlWBM)mB)n5^=H23`ZJc|FH9Y4O|v6pocv=feRFM@<>%7N z*|Lv_2Un0>PDFb!1I*0Lv)@T##XLRQ>{P14!)kH!pp*#lZCM((hg#g1#&r(W`ci_)KYyIh-J2J=C6vn z45ae4w)$h~M?_LvrsR6)-C^+5SsU@lT;34>a1PaM08tKGCYb-|Q(A4|#1jJo6=Ve@DNhZ4CvcyKn! zneyOT9$Z0k8Nt6cJ5UQ#d@=F0xYEJUb}Qbn4tqL;rU#JSA-;Whu$W{a(e6Pex0(3n zTQQwc?3Vk8%}cEbc_Q~34^|`TEf41LU_X-Gh&HQc+K_9MGi3vWdJT3*C~ znpB-NaSJ0yFtlACt+b`r;uR7?E3H4tDuh;=8KPhf=Y~ovtt(T2Sw0l~W<*kHW-0_z zm;w~d5HU%m?TlfBnxxY159hR+=ffQh0Y5Je4+1JW^>NpETIaD`V&>JrNH@nP7lWns6sMeW-Tqz9SE<1vg=lkhTWK9hM~m^Q^! z5MIjZ3|yzFb0nJ0wr@rF%#ZZ_)G!nz=;7=YB7DXI^q| zCwE-m`v%UMH|t&28<<`r^e*cYl7;d>?y`O)`CcB#T~>G?cUif0`IrMO4NH8V$z7Iz z^5gHd>T)~i>;1{vZ_1pzCmDP{UHd!IQ#(S}{yro<30?cm!0&zsZprDDyR6n5GHzM> zhoB!!Bx}D(`3-Mx3KNKBd;>8_$qd7=otk9r|I16$EG&PRS`Ee|YyUnN_9ArcKZ4|N zc_3^5i6j#VUHh%KDD)d9rCd5R>pa3Bw75@|sL?p7tQufbLm|J!Y$jLR}103&(E4db|<898R znIAjXf_3D`fT?=yS^A;Z>y%wy&gVhMV77QgBLhx_opm7CP z&wF|9@Z_a=d;Xf6-f zv}+1IevxC}4cQ#@w-WB`Tx+je%tu>z(TSVv5j@FF?zKn$JGS5^?ZG>yUbJU;LFUZO z=&FI;KSehW5xLGh_?zS#d9XYWh7aU>M2PxTd2j*AnM9jy2iLjF!?86z%FFXN7FN1j z#<>Sg_n^6pX!qWzF^Czg#2qG6m4{TJV=gX z5#RqSqZ5+F4IAA*qHXggP7@Z~zlm^oZ$K7)rYZLY{~3gOUBVSbz048G_zNM^UGg7x z(JOWBhhracxh}tX&NA1IqicEj@1nu3^r7$SYHl>#$V;!zyYq+frv6dM4qo^D=B7^{ z%5h&q^F;a^N91nd!7U`$5^ZF*7RDqd=l*_-!7eFunk*)nkME;-T}(1l>jzUYgwEkU zBt0a=Gf<{$B-7OT%7x6{2$Ly0W^?+LDZ3@kp+r$&n{h) z#k81!<5+RIh9TaPEI~RY_>||9erqx*PU~KDe;myR^R7zH?}NVA-1I3-n%qS+Uq)}| z5xFaP@B+zG#HKg!p!uc99fYj@HXi)T)?bK7-W;;-(#-BzqB;4MMr=XX+ac>YgvmkZ z8${-bg4;adExfhRu0i;B@DBC|ZO@Oz!^Oo1Ode<0`uVtr(L6xtClyT>sV*G#yR^S48aZmy zn^-5@06uqD}6`zEu z(1(Lw6Yc7vmxDGHpMB9i0qMago8KCL;h^jx9ptk|eMtdD$|Gv+? zMHT+#<+h@pNqG+ZfCg7;b9GYU@<}guN$#D;oqLJ6BsYT3)<|5Eo6y<0HTy|+^IDD< zyd+!c{IYAi+S2ajsOhR@_uF^uAtU!5J8sM&qYqkdz3d~Dzi!mteNDI?z1q5>%hhkX z9@oZbqcxmc?!4yYI9Hit199$kzAb)YeXEU+cl@tV*sZObn5+M91?L*qMLaQTHFsO` zO(ie18j7lM7ncak^G-(~e!9*5YdH9GDm+k5OuzGkPRB_GyEzE-DGB%iT9`PxfeD*5{B zkgwBersPL;B42l@Mvs7V^7WVcMDqO)CLh{S_uHNKFh^~X?Dvdg z%5K!fUG+H6`HB3JB=37A`K4X;*xK>zVASP${M}X`PCji}?Wg}|Xs+n0x9Q#5jk=~;@ljP!dZ13P@X#sejP zhJ749s?!&ef5?H3Zq-S?&!yV~9NZCYIzCI@I8r*^`SNb=$hW)5kvEQ$4a=SD+);6I zTCUuRylZkQ*5c$JwM?g(2)i9In0#49-s{s|CD&n0ef@`+du}+$EJ}x@|Tr;)TP!$J2 zG46g?-W?sclGEpU-o2)CM|bTY7z;gjUEJ0ky^OZh_uS{&_U`Cz+S1VTg=_G1*Om@F zm;Jk)J9_!nQXot9y!#*?te_8;?s@lwk~@0ErG~Pb*mZlFH|NJMtMhFeIe&}TJX{#( z-4{`>@tfq9Y+H6+sk|)?Eu-AD+l~mf7`mEs<2S3vD;#Akg|b}Pl#uUd9JCrxhcxSsv46aTeB*{vI|dsNx27mxp}$*mu6I=t)##xMNR z#D6dPqR9=4kJ+#6Hi*}N(uVOLqswk^TC{G`mgX z8)@AvzHvg?Z60smx$K6YTFMC7uB7UE_D3Z*sfEqxLMj-Q$bLmE9ik9pz@XXZ%O0?DmR}_^rw99Y4p2_KE*H zsOZsWr5Wm4*4vcrZxanyR+gkN0i;!@tjN~<=kB#kDFO`v*SAtEV~=x)0rDL#%`suyD9$e$THt-_!Qf3i9ez`ZjBG7 zW^apkf3fW5#M@FAx5t+~Sax^B`#;y@?u?%u(CqGtx9rmF?vDTEIPZz~__fL18;^(H zeev<^@&0%M=k9@c9+fyZzUqy#doZ5(OW8dX&*qpPj?YK)Nc`T9W%p>j6`IH5Jvp|= zogn#=CVxEby!CTs_gtLcr|iCtXH$LO#1DVd z#MdDnO#k1-`*Ie(k3XMLc0a_cF}r?@Kij12ev0SZR(3zfGrE-BFY(r&H@RQqPhTjz z-{L9EfhF;Y=zov@s&96G#Ah?oKV7fk+c&um$1YPpk2SLApw*k)vEACr72Wl08q0&G z2DyONy9;s${L88+3+hF2T^Bxb6|Z@vETuipD6^E_$<)rrBes;KbjMF+DgBh8*Tth5 zM4MZ4vye(JQ*wXoL{{&*4Qbuh9oJ27!FqjiEQc`R{`#%xwdeV~Wj$eTQTE_^9`;Pm zO?a@)_B@DO;|lywF9-XO=w+ki25ox>%g}_nT>Wco9C+z1O>RPcE*ZhVJNY#Agx0zC z2XHZ{A2>7SQQKT65q22(_clCg;I#>c7Z1FAI*-~VzU~A6p2nm0Nn5Xhc^2vkOXXV2 z6}G?YBo~uG>zCw^<6Qm!5%wMMQ55g{Gn+f+E_*4*K@w6R1Y$xU1VRhsLPwhPD!mse zg7n^d2}MAPQdEk9f=W?Q0Z~yAI|wL(fCaE2*iigG?>oDD3Gn^>@AH|P-Fcq(opFE?Kl5#MA$q86{kkOL?Z_B(3(4 zBr&;k)Ppz%)N*l>@J(6c*-KF4dFT(;a!N#6wWo2iu2_EnuCyL>vYt;o)`fF&xv()9 zGRA%T0>)Z#E2ku(v`2$x#5G=)gmOMIAqgccyh*rB_8E;>;#OrO;o|qlxFlTUzA2J~ z3)mm8CE;@QBBaX2^?fx77n^;M%8FYwI0+Y+LkO=D_w)WFbhRCOC!v$=Stbcx>K+^q zjEj9S30>qngObqw9e$3wrv}LN`Ej=k?V`ox3*i*lbo()vnEZ{2F@$K^ z=R+J{G_T-Tr0t)I`;bfCrF0@%P(cxgYhILSLE4GO=SsAolK9&`55qqH11aJ^JVD$$ zrp<4F8=SwaYJGbUitg_y%3UMvHp*`DEvpzh-0+FXw*&Pcg5f1;<2up?=T8&9)5QY#MLT!&Pl!n5Y!-?xwp;WCm8a|ORZK1?=c@flF+39fn&az2g4 z;cg1L^142sB#KSWGCU_qb8KZ)qsj*JMX*8&&a#c7)B!|`yv=DPMWt!g3{QthP)DO% zpH{=rW6PqgWTH zj0^U|5NcYU;ib`BaBzYMaDQo>AAr>zPk8ufBPR{RZY) z_8XeNv){<{Um!jAn-$n^Y}RMLl}Yy?$unA;o#}jLUDNw5`Af{Lm&wmJU&hT<^2}xC zN9->*ud%V~B?5{ERvj3QQoc*=t8TQwi;s=snZ{ElL z2D3i_2HYd@6ZF_1SN2~s z{ntp(>t>MsH_T4#A2!Fc|E9T~{iEiq?7wB6Xa8-}{Ugb}W2Uly%nY*suGyXa_sl8m zzi&Ry{&Dj)_CGK`Xa9tG-SYiEk)99DN|xV>{g2GymcNAkkIkKy|33Slm{%-6>Suf` zYo;k<>O|ukS2KMwrYj#r$e8JTkRT%|E%j!Wl#!I#^=6iqk(A5zW|ozal)d$4rprhz zUQR}8@eCPB;@6BNDMBbudDQ7N`Cw!fx)GmMRq`By|6f1a?kr4Z$k|hUEsElvc41V! zm_5UD0;2YD$4^4XcZQ4f=P-35XV>=aBk6q=!^G@*nNLHy{OmJc?1JXsUNTa20X7wG zHk@k@KvBMCSDZFU>^w1?(G5VhIA}!A_9Fx-sok^ZSU!-#Pv)gp>#k!fi;0;+vCXHL z8~6_$!S~KUyasoj^zADcTZ^S`M#CW;4X4q&V?)>VDufdwTg8gm9lUgWS}x6o#k<2J zPRkP`aa6>NI3q_tf}`)u@VqyR7Dq08Z-yU(+Llf6C&HE)W6{se{=sxt?t}CrYyrjj zE-Z5G0YNM?NNn~M)9ooE@NF0&p0NoAWwdy~sDWv**;mc*-6*Jog+bwOhkyb7Ckinq zFX9;H1{)5+$n4t*$ROWG=#%Rqw6TMfPsOyroQEPBVmAv?(i2F3Lcbu>GdRLWR5<3^ zg_CxlLS27;jo^JgSd>$S*bE{nUHzFn%KB5zKqvC z@rgOB)sPXuy8|0!;|4`5mK&}iP_ShI+8$Nr>44`Fg)``?oY@2Des#DCsw?324kY}i zQL@Q%Iz)eju(Oim`PO}H0>&n!S*r)3emoJMmOl@MrZ%3E{g4<)7!)e1to%1d%*v5T z18^Z3bNeNaSP+BBy~JUD5i_^wo-5&Olo1_v10pgBSQ$7MnSwFi$5A3?R?&T{i&!j! zSq;Ew>abG(S|miw;jm`Y1G{CzsBuag9kwZsZz=x7l>UaGaoYbuJO*rucap7IsyefV^#hV>PKnr02cg&*?# zN8O}I`3&V8zEY}B8VErlZEccBNsI^dxKvpth!7iRLk1DG5h>Hxns`Y;s(PL9&=8~z zM52R&kt{6}A;R}c^(H{V4&RH!nR8gGt(`ULTZhEaQI?1lKjqQ~QvC*VDMTV$jc}+G zRi1b(QiS)Ar75X?3QwttegSKQ)Ot*;Qb0u_b8e^1>H_GLRHdMU@~)+=M=Sf$=>PBl zyg?#WM2?nCX+IMZ=cPKFsRJh25~9k1O)(<8mn=7?yvGxs1*PGOCE`T1x2?GZl(db*N(gTUri-)<~5dWC@W1EYragNq&x`-o!gJVycW4 zr4e#J@HT}x`{nNx|1cGtQbG&>Hqyp*N0C~h7T}Sp=wtDMB9#k)FC)%(q(YN?p z)Krs+MDp*0zQhI7aB*zwrGY`ik<>~1>X?TTQRee;;_Iw_ua2NxK3Wo2MN8`niyZZ)qh!Y1*_2$ALJCeYV7p87#cdWaee!bDKzCj31Mr={r#yQDn~fu`}P zB%NB->lVI=Dr>3`9RJ6lTp$5Tnn6d#4dj$4x2<&|p7xfa&Om0&xDX|LkEzUgI0-}U z1mLs;DPb{@`VhtQg4zJpq(@c&DVvCt5>b92!QZHah8k`L1W{OM#(SfXCx?s{E6~J- zBX|N_M9&T*xIKrW5*fF!(8Tw$QKlw{TS3}akXWPMUlD>rD^qFgzIJ= zv9sugibB*xNG9-{!kmmH%aE=EY7|u~OjU`_Hg44o%Jzu4@tp0#{}v)2@52bPSF`Z( zNl{T^Uia|ywe1syoYyxzpVVVA55M$1nA?@}28KULVUu*&#L6)U8xoFr7?DF{@J{}Q z>7MzA!!bE2UNq=z{*lNwc(6=W^nTK#yk(`V)0pqrnin*N_sTmCeS5ShMNC`1T~K9Q}!uvO8l% z(P`3nzf^*#i3{mmmT1~k{ES)?(X&-k4mIdZ{}D;ld2+LkBz;VRc*%~03fQSS2HQn{ zB4tEc97htiKu2=bj)atjBB3+G`4e?6Wavl|R>oudbYkMp!ij_?DRd;%B1N?&4;SZ4 zoTzrqZ5?@^?;I(pWJKPC7mFfCS4!V<%276dt2E9aM@QYInW89QzN1;*Q**7uC7}7R z;kyAvDb?2@sc##`qJ&t^xswR=ei>JkPrMhbgHS5@=>KPYAN0nu=qHA+Q!=8cjQ+Oh zDZ}`-Z3$8Jsv&A3kfWdzj)D%1!hfMC?wN{oSKVS5CvW$ifU+iewc|wIPVc$Mcrl-p ze^kdS{+lh4DfXXe@)ZU*;B2fOD|XtPzGo4y^M}FjC3h(zy@CfFtmMxNAUJ<$7HdAi z;+m8y;jYpcN6TnD8cV4Y$@i`)^*vp_u*&@4DXU`9m*tnDda?2HgnvmpM}+ zbbq<0JDS{V)pa&nc@^la3FjJ0t!uwzY`*_ibM!d~e$a-Dv4m$ZyjU%RZaEy-1PAB( zrSTQ2{Q%%gfjv`~Wafna!~2PxBdR=_5GjrWQqnC)2Ysy!7 zo1ijw9;DJ>KIfWB!Z?ZHBtT_CFkKIGepSgmEjS3MehB{jA~N_dHF$;|63ecDdOI** zwR6TtETrP`orZxqLaH$%HAl_|aivYxh2FaNXp!TQ>W^`n^DN+fg(<$hy-bl4kSg$q zrRO6MPTC~l>mQ#eauTFExzxgc0rtCt^VlP2tgbV@^_^i<8L9T;Vow~IR2J!n(^Vw? z1f{>6RHX^4iSUMmQ7g~}$A5=aN;#FK8kz+{7l8fmAka-~PBp0pbp&A&z_|{AYPImu zolZ_&srsNMaS?0+VK0%Wmg>%v!gYkcxhTJ!7E&#m2nH4ChoFA#&W-h0rRHBEz znUjAJ3j;c>n1qFoNxh|dCe0$11fhyUa?}|G=mVtM8)ng4fI9Sl(Ai?kY>sERROzU1 z)b+@@5L)gCa=)OB86}mkmPL9NghLJ~WK01%?q+ibTJ$rZ-uNGM%MQ9j&3Oa4jjShq zG7`7SCE-GuQjmF6s(CpUGY70D4wJ8Jq(S&t=P{{%7+^8`fHlrxlCcG|g6YSl!VXv3 zgyo=azMC$531sZYQayrb*w|OWdf#DEkyyqu^Q2T0(Que~8LXQQvw*S8JR{XOTuqr7 zg_17|r!(MAW0`(Vsu6hX$Mo8uw!E7zd^eZF*o#sfZ)q_Hfi>P?7BH5X-%Isnp2b`N z))t3Zz*uJfDAnw-7V{ujA3MxDjb-|E6hwQAeihVPchiNh(|j2Fhg1t&S%^DO4WU`=zF1&n28IYaG~7IQ6FI~-;KW0{$0s9f}99Q&JK zec>?g%vq*q8*1QUi+&wc16SfZ(k4>QP!}0A)I}Igy;2HD1)6H`C#utpjiNLn62T6W zaMr{qPVsr1iJA^QdkcXpIO3wjRoPGDrvD5to%DFK3GU<<&N5#{SDw6Zw)r#r3(d~O z=zNL!F#F5Qh3qdkH?hCM+|T|>^91{=%s<(G%q(7<l(nm9VRcJ~iWv`5&8?_Xgqe!_RRY&w(ttw#MAe`|egp8#)5>-b3 zR!pQkFC*yg*iT>;x@%53DtYv+#eb2iE9w=AA1Wkn(5a{*F*r$iT}IGkM;)5pNC`7k z%Qiy%IR61(Kb(Apc_L|dDxCqV?ykOc--s&gGPm3p~n;62|ou;S>+K@=8z z1U^ukao#jx6cnBaybbM5FW>?m_%J}>`hG0XH@g$5@KeywMqZ~F5g1XjYdayHLx7~6 zq3Bm}FY+lcS?%e9UI)N6IO8Oxj#VW-whVBWxJRKX@yDh(UXo26RK<56!0}qOzN-*_ zLZl>yu?8K8)$$a)z;1N|L%k{pZUE;xOB(4&=U4jkxB-g}Y>J$Upw*Jj0#6!P5h?m3 zU<647unJadOzVkC5_sCj>P1>^f1JHj>`T}!(tfUulVe56R?i|yxfGrG7{=y-&s0~O zya-LNlQxc@b3XIq5r9vtKNjFx22qpOKb;>p0pB9ZRVu^s?Mw(?RNo>S zNm~HrT>_5v3%*4N464?g@?BGZQmtVPQEJ0ABq}S)9Dqy={H3y^F%5>$zJ#!mY(?hw zrGRg%mh~|p1T?cSoZTH&HBbc4CT8m!sP(`%6Ni;&KSudkOse9@I5P7UK<_y!ZaSq~ z;rv7pp+@Pzl zC`Y|jpidd9RMJn3>=)u7)>xAvbh$hfY zs(u)uQo>dOS{st~r2)pkzB-0Rl#ed}I$}$6g*K=Q5*22lLki52>NOBgfpD!biDWf1 zdu}~2mq=9}5)|ylZEkUPV9OQM- z{&lEcDgv!*zo8DJLC65=X&E?OMszhT7~?@h9pw2BFq%3n%9w(z!-jgVCUo@#<6(zI zky)&hXm)|vFxA@+)*LXF*(`m@AQ(-ExrM`;Fz90-H5_fk#nuiQLAEpL+bz_#ZfGx0<2#p^IQ=QQuslCc4 zf$ebQThl~k;Bc7A&e!rs03CD0HT+(fx`}HMiC+Npog-cDg`u!+SfyYaDE84*WZ<(f zwJ}3;WMmCI1cKv43!b+O46Rl#L_Qa$Y9Qx`BXjXrkH|V*G;taDK1@A0!BW;0SZ~7V z5-5C(Uk_6waO1@ClYq?#$i-Jr5Ryu^!*<1zHQwiP{*atAsuoY!f7r^*Dh|VTn{y?g-dO~ zRbD<0#`Z!i5x;s7s!vCkI*pOGd>!CXn;?9HQRaa;E~V;NCY%FyiEu8W_~+W;GVz2< znPkG>2zS>kXoAp$?Jkww3WNlJrEP+UUx}_V@VrYcL_W(J2+wmcA5HxR4!G1K-Su@+ zb^_L&aE_Sgeggw)Orq-(&;16DxzroeHAl_{G2bTZUY?&22l{6}9FjQWQeAp!qTC1e zVUh@qu4uM6@QX`*gKH(ld>ZZ&QOE+Vlqp5r>J?n6DZYQ;6fRB$wD5#-Al9uEdKBWw z(jcVSB%$##Zgq5;WqdtgjS1JSfF_&+S#C8v-;(bQY+y*9@m#lxL{~v(${E1sh2&}7 zLZF#jUBS#HcQKoR?X=~sZjVXr-RctzPnh&J2p>Bn-R&`{hg+E=Ez(sGes@T^+hfvD zxB3O7M+pXS1gJDuN5b8Q4-4!!wwOh?Z^JG#N5FRc>(icXm z?83+NC*3Ln)6h&`0P0$Y?p(nv<{r1|57U|XB3Q2%Vp^m(-KzIei}VEu-#esG1Je6t&3x6LTy5i`ZaTJ5mf}0mLskORwIY0YsxLm zN(O!^qQ1kGkVdAmCkUe*5|2R(lm*jkD^)eYqAvyYiNf>(in}QFDaLFZ`vI_yIZW26 zGo5ulqLin;#ry`Wf9_@$tc)zPP^ps`AF=irlzVx&0=ZBiXPN$lQdsY!>5V|`a5r7} zn7Lo6NOWAR_+hYS7iQj>AMYtOZfgAMoT0v=op9pyC@j3u zv3w5VWk-x7pg*CRNgkDsp*ok(e_(~bHXh1-t4m}0SdXgwfR%=|pdR=i^pLa_&oYnN z0Mj{(KY`G-dk7XNK#uGgkE*-Sk||Oby&hbF^5$G487qo6J?b(toujA*YO8zD3lt?s zanhp(CRs9r!Jq2La8dG~uC+|R>QP4;S@g$1ec>MTJ5zzJU-%y~Rx0AW zswu`VOuq$caSXabWzWT`Ggo(WY*st3a$^9=GFjj^y@w1>#PRftsJpgXIfeHOMNJOfVZeY^Pln$gv8?=)!Q>t4v&)yMa2%q0`icW;$ia zry_eXHI*w~HQXx5Md)0NTxx54VDMutktg7;^_f(z!$Ds_eYCP1TBrIJj$Z-7rvPood;sW)hXm4MI-Bh(Ad@| z_!)YjY`7X7XW_kp4ZH)d6t3RvZmrjw0c;-O`YvHFM#q$&dfK$)v?YN^D(e? zIZP+^f{IUstB37my#wm0yXpF=ao~KoDu-6WCj1JPM19ufU%*&;UK;p0T$Su%F%!Tl z?=TA(%gkbU7cIqNHUg`Q!@Sd2rk63*`l1$nG^n%hrt7E1fgDrqENwBL0P8u2S-@C& zUK(g(s?B{Y<}t9oaF_**W#%wb{e(*bXTWu^)ctk_+-WS+C!1?%9a~x&?W10DusnDu5b0b(UIm|naW%_5P z^3AsBCqO-SH(ft94t!^-OT8`TpI~`#`M#?f(DTy3AEsK=&0?m2mF+MK7|YB=pSomM z!Uw?W?J(~&mg(hvYIqq-@gz_e-A&g|jRUoP>eyI|`7~I29cF=?rS&g?RzCG6dW{b= zQL#S+>uZNenQgTgT5=NT>r+uP^(3YIi&#zU44`D`^)G>=KDD8zMJfqG6^G=gv&Jl} z^9P^Wf@{kjl$dM*>d^l|XFCcSQs-i))st%zL{AV$6M5%eP1ctXhiveQ-uO+=l)%g| zc0wP3wa+WT-%c_MR^MBO=Q6Y3KN%;A?UHJE%UB+gya$mV?iLGO%0rRjeRJgNq+M|$ zP}S=#+cQCrX?)FuxDW1*i0`2RlXJHroS?j(lL>kN-4ud7{)ey=v+yb*9HJwG{)DgOwMY?oriiz1S_v)k66i;55xQ_&naah0Kapv^kI~F& z6}Lr*3n2bZWG;cb$+`qGr*C43hA5^$b37@9V+pELT0J*o{?ldFAC)UG&QOUPQQ>QY z-x96>RnIsxYpJ1nzXVo4FeW%GuDINWnR@rqi4MK{3BgZk{nVz%WQXAiB6`H@$Tn3I~;Mr)`NO~nDK0wT}VX8XbN0BwbXnGIU|Ct`r zKjv+`Lh)!zG&XwGr$OIJ^U-<9a`gI9gWi?sJtH}E%aTN~xRv{XXJW*3#9>57JVf3u z{2ib;d%lf1EkeZ5eqY3i#hLC>pTt>Ilc`?-ym$w7QO!;)?8#6My!zKi)wz}@2TN5OpKIQRw&m1`dzD;o5#`B4wVIO4Gk zJcOPo)w5V7-su){BRY&#d<60Hj*4!CP$ERRVx=L_ErBYY%)W+~l^PttyJExR1#ya? zIDBxff1h)M%N1xqO|Cx^xc>a520Wa=l**vhaHvz4{sc{P)Dvq_B_2Ry5m;{9u zgZ3k{pkC2oPk!WP=pBN}1F@h+(P0mKRg|G`2x=38sz-;>*V#znzXZ{xQlt!=iMW!Z z!+u^HCn$;(Tn3HY1XP~9*Na%BALYebU?oI{C3{N=+Vbm8hGaZh$r*@`8WysFI5y`9Ri+#bH$Mz zbYu`mKfdi&P3z5Ifx73 z0!}vYdxlHfRNP{C#8#3_qrBkvx$veC0z}%S!%<>so96TBMEqim81{&WmetILqmeF8 zer<0AO1fPA2AGX+z*{9s|5uUwu0m`xw0>U z1|_^%-wHC8$w$$h>CHC%eTm2e7(Eu65xLT^T9S&&GP!znexWcw9S1P<0V-d ztO^d3+JvQPuY1i9;PrrYba1jnHw)IJ<2>q)##Evl0@n1xOr|sQOIZPv!1G>ydNDEhBT}57X%z1PBR#?CGjUeY zh@#FRIv9_RAU{iEalt_WoK-TS=!LZ83jJ}XmS4+o--eQR5dQ~cWFtyxg~81M)i&H? z@=y&B{Cx-_Q}Q1$-05-X0TCS0!IHwOnJ7D6+**N2Eev;kWJU@I*$#)?*sqX=73n&Fu-vC zid;8QGzoB=hnh5qbF(V?i2T8Zo1R)%0-26mJjU982CY3)3>R@kA|*9K(e<2Oi9{s8IT1asOUco1BHz9rPoZy1C7proN z)Sc`#dUnhf#bsNWFQ0fTUby#w>Z$2D3oNcwEN)@rc8FME#C5}4^RBpN^Ww1K*b|SI z5YchRKX7AD%*n+Qu&3m9H2UeQGAN5Rr1+du*opSFH$lwyTQ~sS2C$Io?+RJhd zUgDmP-+1BAgn{{TOBvhbhdn`zs^f+aB$JQgjcg;X=8*)LTrn0y{5@7Pvzs14i zwI9Zax;y2ExO31E1V2fzB8Wa`N02W!ePrui=b1~ok8grN++Ww@5W~I);t<30CT!g) z2SnMXp8KzarRkbC-ZC{`et->16mnm9j(GNxraxXs{=|)V4X^&jEgXUD-6@CRg?+L{ zjQMpZb}sEIMAi);o})71Jd!H2R(j%v=bDTsQ)E^*yyolaA`>VZr2h=UvQ}J0**q=d zDIerM<41VM2Y>w=*#oa@KG?OkbpHz+F4i&;NVIX+Od^eXHXN6ytt(@M=d$5`@jQG|vH{q(JCxML zuBDzMhC3R2N>WnfVGurcNEBqypYR*fkjE$t&8L8_@QWSF|&ivEN>A!nLBCxr@*Ho5$E6WL{){u=yAK^fzk2xRvF? zYhxZU@rhTW#L7xZn0Xcc?ucQVTr&^Ts%vm(F&L*pZj%$wCW`Fo)vW+yo9y`r=H6DK zO)|r^O+HWuk0IZ{9|w50$sxEpRjWST3W(k&TfOfQ)jMJQ!;Iu@@)|BdHNH!;0_tv) zKTQ-O=l*0J;PQPX^XFp0Y0cO@xMq`(@s-TLh<0VISRY166oQCrjKQ7{59C@}AoSoA zQ1W7zVLq2A*h!{FJxnTNe3v?SY>aqxxchfh;}VG&rqJF(L*QH~Z=n~X9z#qRF=n)Q zbgf(FB`{|e;H3_Qj`ZDXVqJZ=ni}_LN%3eM^%{1nB%Q`n=0DrYnSt7#T#lBuIhVt?U7>ftDCB0Clt@&ZC% zv!!(W_ex0PesSV@A2jG)HA`TZXhZ!mHck}329tk-@L!}L9%s6$sX4l;`6=92{T)c) z{jMvMW3@zTPdo{N(-OYFhs6t3(ombm#%sJ0u;wBB(biEy{UFulA7V7#AJ~u(UKV%s ziWUSLmPK=bEehdf2>)5Cp1)f9p9c1d>40YhNAgR#vPa|m3N@2n6uu1Wj zfQtnhfZW*;preAbRy4_{7U)U7p=Srgi`A{%J*wh*gC5?9_OXUJkXhwuXiEn3q}9-W zF-l*Z>7Fvw=6jgG7u>fTJ{KzUN6@^XQeo=9GI3UBM6kfOAphzJaAx?#Q5c4{>3%_H zoHTo5<0?3vaH3Q%=4(A6afF68Ji zrhN*^MVn@Xa%Z)1YgMdJjSV$AjD5ZhTyHk(+3e#KY*hh0vkksB7VaJuv~`P`WMtJ1Y_gf zEKUHvtF$XdD7@4A#tu;Tg7&ISMej45z~d_Y>jdt*J_Gc%4eOh&d-M=~O8%JF-zp)B z^usMFt@2l}{&ASB&dD6% zrx+WK8C+6Cuc>Zc9f0|zi?|T2saZ6e`uVhJZkz-o>2A}LG2tC-3|>cl)e_U3jgf_I z;aoMqGwKmp# zGThnm<+?Kx_xZ4OdbhsX_==fG2QCJC{oud2PtB8~=WqD>U3 z48*%o zwCbB-5o>_d=5C_C_0}TPcdr?*_7t&19s+%$Bf<-BG?A_=YbL23sA#+q+Ded~bchth z*AtOS{oejRfz`*qC~?AJGIC6Rmsv$KohX=Kt4*2!z{H)-eU z>YAF$uVyv}}8Gqxo7>sy#X%kRa0dviAXoy?8wcQ^O3 z-^2Wb{hsD^%lDTe`Ceun%kRm4Z*!XEZ)CrZ`G)0x4S&E74Y68gdBjVD(TI%Um`mG< z-sfINP3AX@75BAqNBt2au3?HsZ|f9>>cf?-4P8n3`ANl?8YRSiHQaTNCI|{G2Gt=l zQFK?(WJ6sKDcsfyuQ%JA@}wrDkWNL#%9j)=G}1h*uzw*kOHkVtP5yZnkJ{U~*S?55 z9-G57}l{^tZ28~n>7b>4cKGJhcJH3pZK&au>BI98T>~iQE_SI5+t>?iI%EwOHqdq z+O&zg2mWKJYVV%*=?+ZfxxU6#r(M3`dkmr}t!9-J?H)C}348HXgA0aOLi%X$Cpz&? z!1pmYi+KMg&d+K`J4RTl(ifrl<-AXPCn3a}`_B8kJYBUCX{pA%ljW(QCeqvH^G=ng zTudCAi|{YX)82X_y^n{azw#9u0;JU~Ddv5hK^u2z=?evU$pDA$s z+ApE-O7u8By~JMJ4Yir&I}7W)yMKw`PSLy1KIrp%B^m4Mtvo}WRC>pm)8)D`J9 zBV$E$Zp-j$xbf$gxN}?kx4!|kX$`Bzi`+I*wE%cBiI&^m-5m`kV<_H#gmdiz%^hFMOLui2SrRJ-A#{|D82c%v^0X6fZcq0&$?`d&gc)DT+iT!4;rvklqf+hlTFvYbS_`gi#)#=~0d*9yLpd+=eB}Qvl^i zdOu8X$$8UKR^UWew7L96E@#^~Zq1a04sv6-p!@X>rQe7W??Y*a_M;<3G4#_S{qhYe zqUXY^4#%8LbLg@PYL8V=Cw3=@+!uJKe@`ZnbN9M^$+6;7P%px{KB6>oK~X;;GArhR z^NM@d(pd2a@PBQN$edC=au(S%j z&zqYdlW5aEKQXdP?(m4*`=opEj#w5sfWX&D^b%>ULXAGRxJ;q~$zEL&C*`GkIVMGk za|!N>!_D5&4{#;vHqrh61nDr??S<0@YB)!_H@}&{F{J>?v|)W=$lic~L2fv=yQ|Ueen5^#)XoL-0D(KCl+_uvFD5fXKiUq(QbvT_V8?$MH)?7TO*wsaI zb^$+d2ZweN%k3lG;iuv_u^$7ccWF3d4A#S&apabeNnC6Fl&N{ud&HyErpWMPBb`#C zu-paGeH1tNad_5I63+D-ml{KhrMvOF38D&u8`w~RQmeqEWzv1>l~~akguV{xUs9sW zaFuk|KCSmKoD6&>ag0M$hP16|?sS<#4MUgVI_ZvDnZTUw;L-CJi%Wam<<6BUw11>7 zv5nF_2UFA7a#YZpif4$+wrhBsbY}u46~DpVw&8*Wx?8$azS1gUkt<1XmI^NK1JWG^ zm{e2;RL_PB7U*Hr(5+Y~11q`!#}3q5g)RtPpzlg|8tN8trUGAZ2ZsyvW9iPA6w4{! z0(=*7D3`1PqCtR>o5qG_BxC+Po7iTg#C}9BOA^YL-Es*K^$it2J5xgVeHJng}*&GU2F+w9mb1$N(d5^qX11H zIDri2eF?D+W74m&9F1H7=rISj*I|_Ht>N83_Bkl6!{AGS{{v`Fzl~mA&fDz!4+P!u zK2wcafF2(_TaDUZv6#ZzLiZ2j@zr)K6vT zO?BvT%s?+j@ERL3=tz{?u_0b$ZQ_nlYCXr*_VcjyWxz)raw;j)`_*QBQld{{oX9}P zSHQn7%t>vX>=Idjs<$rSrVEgictoJ!Tv?=o-#g8ED*Fc{L;9#A&B6|ZdmhAe4>+oXQoYc{QgR4{w{4Qpcnhg!0cR!WfnBw6O9}47MOIg- z{`osjliVn|XgE%mK}UKeaMqJGKIXJhXPwnwD&yH$Z96>@sZSDQyO!|LHrQE@NOi7M z39Ysp2m^^kS!tMXx3c{YknnHEgPYF#= z!-H0;`?o;5SKX&CKiGAjx)YYC&O)TmDMzByQmT*r|JQwL?OgY{*){xPdJNb7{o_&h zDe6$&XWdTSfBj|D{b7h;6r8In)it~BUwQ|1e?Ed&+K@p503M|pd+X5f52(8>%JFPZMMA%IJHTF zY}XP_-LKcmQrj7XzC@y|wMcf|_y28angYW7J2csKzy6FEo$p&f*i~3lsP6hHp{M0= zOm}aHml4U2_bE2z4=Iu#?^|paB2Iq1U$J~X?_X>c`vZ!tho5*E5AdGIFHMi!9y6+@ zW1W8%{(eF=y9A3 z<&)^N_0c#P#wT$VKNE@hP#0Dk@&V zS3Sy3b$>iovHXvY{5;9f9CyzbJX$Ra2tOq#J-@ao(#viS-%M$^Qr#=cJ`+cPNIPBG z6lI^~P1%w&iB@)(`>i!D(Fn}uaIQr#NND6G_rOI_q9;NhvJqny!-=2zMA^gcALoaQ zsel$Z@H&Dw$P!ORh_WZ#i~WXJXJfd`euvK)%hV?;=3zFq?b5~=Ic#%}%Zw05z&S>| zjU?W72_f6v7lsxQUn2B78__eKT5yNkn^HvF0#pRbSkQQiq>u4}%hYFzb}Jhxb|9n_ z@QlJ7?AcaXP%+{ln-7GavMPPu%i$tA^;MsH3P#ivBGPJNoki+llh`6Hh?m1tkMN17 z?bN=dMCx1qR>#A{Ea+cKaU1~6p!o%%;kW&}Jkeqcpj{43Qw}1NUQM3jy`GF}Y+90-D;Jc_0nQ4m+OL5;RMnRU??n}rY zh$a1(D0V>PWm}B2a%P8Oqa#af&3TVVt%!{(hq}Z!5V;PwT-t?1N4k`>nJT(dBLp>v zb0u7b;^*Yb7Whmp&S{S~9Trc|AetP)Mo7)^kYWtN>7#Ru>E)vQq(HOQ8fsT6SnI)f z)?x8P8?y$@h9OPxslJ>`_(mxRXKWJJaei5&fYP_*EaLYtRC9a-m8_RH@#lv19Dhhi zXw7(5z64)RjR&FX-6TE5&xSZt>Y-gf69;$44hGv&+Cgy4xN6t|0|)owmB70sPprR> zUkJ&H!h{8Q2Mjve^o@Ha=K9tm;3+uQ(tlB6yzX|bQIYT)7cm-}1n3~#J2pkP@0VG{ zx9<9GOa<8xn~Vnf!dJ-E%FV;mrU~(f5vb!AZkDRtHaZ+ZaeplhN3H)!60dTHxJO=* zA_3v9F7&p^FVKcw=;uuILinV}uIcC)tWS!p$5uwNDVVK@Js51~lOlT`z{S2Ff*-aa zV>sj1Cq*g`1U?&BzK!d2*q;;`1+uh1De~t*eBTv3xfg$jNMJl!Mn}#kMW&E|{YjBz zWS1p9M7>l$QhY$tzv1t;BTYxnCqq z?+DHSM}m~FnDa@IeYd@=QBDJC4iPCO&L>5FJmg{caUf4RDBq3k5%~G31RLI@qQJ*K z8qC1hlR`ot`#AE7TgbDJya4B#NxJQieVlKOmHEFTSVD{;V;8|%M5SYElHw37j$6XvjfcK+{czTZmk$38|2q9^w z)NV5|?P2efO1b3hlzQ$#B_=?_Ryboh5aR%jLOZ3BB0qum-YIp|63OCM3W*zZ`agC` z^=*q5aWF?mMp5e+ot;w4L`MsoUXt4(Yhv8hiFqv-9kwF}1I)e4u(-EhBRzh9` z{DUpwOh?Q*i``NYDh(Lrfpfh8h0b)u)_;p|G_o|HGzYe)BaXFJ4AYv~Mh;5T5xRm> z$)*>rjS2dUYQE_pBvSEb)QHGVf^f4x=1gR5+$Z*^zikchxqm_ z1$kJFUJw+SFO2tyj8Uo;J{tTS0$!%*YC(-r2Y>pRNJcN(s7m+=nNRtj(Z51doRp`%*fOSK&mw&I6SRogc)!GNT4q zdBki-Iw#SdZ1d}1^|6+A2!GJg!q}4DFNd+*!w4Va$R*P3N59C; zNM@`BYontjaVIe!s`0SHT%*#zkj!`!talxqRlA(ZxC%h;_F1{tjRK_ERt zDDA$Mu~*#~rWhRuWQv0((ssug1FO-p?DF*5QpT&QTUo`7&0uYFnB{4gwTw5^))H<; z-vIJf2&H|?Gx}ETOyxFh2%N51WSK~$ z`PhtpRjHO~`bVn&`}j;AXw~8B5uJ+PVEQCX^_+Iqie_~kf%PVw>#2iZY&1NI<;Mb> zQCPk_eaa%^7xm&a535)Uc%!XCX!K9j=sB%mKakgK1z4Ve{i-qyshT%(v+zkkUpm4X z4wtIN#b}QHCZJo6G|vuZ^e#g!B71#jBpSQS-g+&ZDaojC_rY0Bf;N55=u?B5gr=5| zYUL?6Q<{U;hN#>o?$yZs)D!gR{eegHsPQNk&Hd07oo;Z4G=E!({G@}__0~aC`ykdn zczmq|O|=hB;GpFfYfx53O5Pa12x1%4qP_G}zcVnzI2I2~L--V*tC@bNdXu1X0YI0O)lfxNwP~gw=F{%K^ zROQ}@)uSQsmqQ&^T&u>!UyWn(k12x4#3Y3ogXF~2I11K#aIOfLA_g&p<(p^z3KL%=_=*h~v4m&Q{=LByGX95ENTQ!mErQ+m zFJU2i(FL#@jJQ(k@o;yJ477_a|>{Q{aJq*r0VM9Lc-EA1T~JR)QH zrCLAnv@{m*J@QYOkP8sq*%E8nWjhFeW;zv#8cOXX59f#|)k^)OSaqYZ(~pZI&Kb@vCp`KXEU-YKls* zSiS`O4VzB!8Idx6-Xiw?XhOva^G167jSpTrf3E zO<#_vN&(Dr2wWMcOf6RXF!k}DFuD;KtsNGt$)d|_@Ew`=*`G)|Z)zGG5T<%2hA~r) z2Ysq7BC_aG8+;ed7fTc@HWuxT+~i@B+zRGSVppTcd5_cJ#4y$UDIaTl3()(HG7ZlT zQ_b_kSo{*8D~@y)U37!*%Sz{wT)hWsaA}x|e#2yvEV>xCLU6h@WzmH<_@1mb;0cHQ z7&a+QlT4Cz!MvZ?Y#DEI8pLJ;KQwb|ZM}dEAe`H##&?FPrrnj6pAKwpNS-dh!Tn*X z!55J_<(q(Q4dHYN4r24yZxkkvkR*8s*xMnTF2ce0!<2tS5v~6`ux~>+U5107hp8I} zA~Y_RU=j$3CLt%_l0n}{01+Esf#P{B>=P~Sr^#-4$j+`2C>QO zgZ^kCyCHlaVU%|6NrWaSms&psH!o8FE-6GXbnT)|PJ`uK>X(0g*#8!c9X3mEavH4S zQgz~#HsMWR?-H(yfW`p9JePX-l83u=c@fwT4xT}qptf(|e(5&u({3Z!i?L<_3$y6i zV(=}QozE4Q#tFf`E;Vpv7&B#M(1Uk~&`2Tpwyd!}B!YFYbuq_AOxX{A50eNPXyrr6 zGg1VnyVUj7N*HqhE-Or+y-I^?Tl8cqa%aH;#Qc?E6oB}V`o81(_;{sF)*96}xLsA!MEV47Qvtq#IZ0B_g? zkxJV$wx8pE(_`vRDPkF(dc)~VruL;{;e8x~!`?HwI&isLVPM zn)EdYKNlhylq|i`TQIALnvI(ltQ5iXKRBIky2j}3euMRks6TR$Z}$PLU=u`q#ns^= z_;eA~6VHH+`Ur1pV|u)x8}YI+7|iT0qRM4?g)s<>QH59{eo%Y2Xdj8Us2>1f0l>8m zf$jvX5)PslZ|^tUJ+Vir@jMtu9TpWu!5CXU8710JG~B_>n2S9F+GU4IIVpTA(XX_B z-*7KJt%rife;~M5IMw<0dcgZhcd%y>&Of6Ruq+$rtTS{uzjzy2&_k&{L-YmBXbRSY z_hQ}{jWJ|@Fyl<_uZ&S(%_64LPW1#`&r$=?bB$1{uX1VTQ()=z@ffOS2DR1+N=;md z@5vxR#vvj!AKvgstkFHjWRThJ&|q|(0m?f1GTJ+3RJ@i%Zc#@(7j zS!r?JbdQ^-tE5p9c*Q~-gNYUPN1)GnN~u9x4AB6Db`FWhR6HEkq}@tgnI^>`5XKiK z>5-52V)l;f9!=$D${VWfQeW{iOQM!=`aXAtd0$e(Y?~=pq{to z=%k<=i}39TDdXLRXy_~aqj4k9a10he(}d08`gy!Q|rzJZ8>t*A55NA(lawlj{Xui7 za1s?brcEcV#@!=@gr-eT>_WL0MR**XYY~?#e?EDe>e>R+nwbdBu_0p>;m)+_&e>kE z4k2xTcPq?srcH+xLFE~4gSuh}KUK!O?guefMsuQcKkLkiQUaVg(diYjbQr>~z!@7U zH;&^dG$%@W`~=>6PBaU*=_G!;khnpo|6@+{A1sEh0CRL?B&%a|=0s29krUa_m`G1i zb~tmQf3#I>Xdef1z8*zo;Y^T{(RHXE&-qyxExDD@rr~)UFV$RqT=(ux(`97}48Ctty|$6D6ICzl4rr|89I;2MmvVI?+g9P6on7^MEyidk(3!w1qy>S@z zVKLQ+`}|D&4uL;90=*}EhfK?nswv)JG1g)J8%{@6fuY(`efqgqBq2E6hK$=3m&O}P zHF`Tz^IC zKE!UoodBF`AeD!`QY-xL@`Io$FcqqPHT2nYBm1b$HvLhz|sikoN!iZE&t0Wcmky!um^1Xj+I&w z%_Fpu0U!*uNuiZmlbS|oC3Ar-xA8kxYE5WbM3bHcVIPqw4-7hTR%$)NX|q>q1?swW zv|oYqJxP%5TEbbWm9W!NYd|&vu7Fyfy;7^zQKod<3&?-e4Cw0C*079q2 zns}ua*DpWiR*zxZu(rs15Q8$j((^dDdZ}XJ*LdgxrzQJ#0*PA}aK0|zW_qD0^XV*S~N~6BqM#R?Eb3DBAS*u-_OhZVYThBPq17moAls7xq%bytq-vT52nX zR%mP0A!@fZ+Lx2t8gI~<{&^rtc&Z=tRoR3~QT^AYsQ$YDwrP5?UR z!1VP?V-o&E#ecf^MfEEx@xdfPQT_>zagn4o@}s)BNh3v(5QC#l`)sCLRR1}GO|0f> zWb%_r>3#ct$vT9e@+EJ02IasHc$mEz9Sa4CuoRB&S6l=-YORAv>-Q9&hHgkT^+gTM zBIrkgD$F~82=N`_$a+cQF$6yW=ekbNV#(Mosh0Fk5-%bA4I9&0*qd>;;r}}cYJq+2 z;H>*yUf5OLYZN=WI7yHte-QyDa|8tqh%(f~>?BbFSXl@EhpdQy15m;!3}?N>`O0TkHz)y8p_KBry{@=93=z3F5G;$_E>h z#0G?JvysA8c$BZQ;9cU2Jus!DIfmM33I64BMer0?q|F^Ho~5iJSuSQRD$ zAK8o4y4RBKc#2h5m}sfq3)j#~1eGGF%4F=TSluhLNR^+$Q?}eZ73nKKTAnT1KZ3RjfsMh@QD2DZh)bI253`#zT{5g&3h z4gh@9A^bnezC6z6>i_?obMKw^EO&-$pJDEx!C=tPAlGEl$W}tOY}rcEq7Ye1Xp<#L zmLef7WXV=pvX)ShB_Ueu*&`zPJzuZ$KIc8xSD(k@_s6-9_dU<&>vfj*d7t+==Y7uW z#U-?@PvmQTrU`aOY1^%7KsR8UKjHXnR6Rur`Gs6P615l;NIg0vl^2YAyf_VOoDBk@ zY&=V)!K{qn&p{qkL&}K88wNt3yp}3*fi<=GJ%saTmYNM>oSEpbS|CO~1VSH6I*lur z)I7#%S>7d$Li9vSxuLIc7DaoipKie7U;|+{Ot01-p?Yvrtm*#gLGl5#7r`Y6;`+LP`HGAo?7z zR}CJ$P(p_R?ar_MeF`#9E&%xp68Idt6kXYc5;`G^klJ&h4FryoXHt0HjG6kYv~g%WWJOR3Gl>0%{F35(f<5}7SoqkI;m=ZQ!q zu?r=_iD7sWkZBg>(Xc+}LpLU`8r=#kVdQ*(W=t{O62`joSV!0e$$ccfnrqx$!r1;0 zhR$aZebqo}J>hlQSeML zamKPKX`P~7!g&9~;)3!Jk36d%s5>G-b zdY9cSXZ#Kv)98q(ZV3J>q}Ob~t5+PSV+SC5xPg@a$Nab9iM=Tz4l!>7pA*fox1rrt z9D(}GfaW$(w(`bPuJD}R_px~x+c_m*wqE`L^c;!&$l2k|n;o6BRGdDE`3Uunz>xZt zarZe*!eJ3v9$1#aqo30wAlv8k!(z$IlWjrnMgnI6E4s4JDOt?2&*_`qQ{LM-fRoox zf+{ECXNHxgEBl;I$^V?rhEW$z|0_^-lK>S>(bfNWPM?JdLU|dSSk#b~ASEnjpVMV8 zC9_6Z2BZo^q>|X@v}2*idLpvt=6fP2G5bV(x3ie& z1_k2~R1)sGdJk9L6G68$MBvSzh%${zviOcDaYcXsSPIe0 z45Z2uzJQ0dktC&xElCy?5VZ}2ebFSXKcv(<3sb~dU{@`kNlG&5Kt`mvQgs%<@Fj9o z5`oiK8m9vpkoPY_ZZJUZk8-WB)8J8ku-SIl+Cq3klVjHK~}0{3&ak z`d5magZrq8s;H#fKfw@?yOG+&5}AZVvXmNEAVo}sqPIy|7Uz$lT1x#}t)y6p=oJQ1 z5f87YRGAIQVjHl17SHwYJf*5#O%`W?38c-cRRiFPN!9!9M>d-()%uTQL1*TZK}sWH z6VmaCJb?Ul-CbN%F~X+Pc^DdNOoRcj$XQvoC<+<61C;9Z9>8JycFH-`zl3N76}=Go zB*{KN`ZU~0IiH`xA%4WX0%$D3-3jIuy+|unj9&;8&ntS7ZpwLTSurMlj>s>qK-czZ z(DSfz_7^H4b|QK&L7Y@3Lysxv=iPW0Ao_}d)Z>(v7VQIbcS}o(0%*r62rR0eCS1$+ zRn8X~$)XytdQrGmlKB9o|EzLa+*wkz0^vbJ($)0LtGPI^JyaE?+QNA-T1bn$pq$0Q zl7b!r^$PeCjEuWTMk{HN@yfa5?-Zdv0=U2sL<+ar8Opi+qhz5rB7U2}bgmyf0DH2L zIm%g5G?~ras*@mS#k{6QH7i2YF=gCZ7_R`#^TP|gc|O5B&u3n{!>x*=-L6py^FPNf zJi2%S>iB|k%@>pdzM$L87tL|ejFJ$Fcb!Fcs}#~FLtT(mkQQkp*!c7|1`ZS<$KYoI zf`0&2Ja7Ms99GVj`6a}Mh@MZ-3k30owa7_0nZ~i@^@#q?K`#l+ zl_piA4Q-LF%H7aL0Pom}TvE>Lp?F7>T8OtE0;j21kcNp`T2li)XUQw*dIEde;u8ty-DZ(OKIe@kCB)0X-ig9Fm3;fsB5;@~>Le$Y-vQ>RkOI_p(@P6~|qN?L9!grG}FSy%a3**<3g&NRvlFlt*Coi=x? zfp)J&+W4F#bWXAv7!MehZuvYLinRAR&#fvh-i3DA7lh{wNpW3i5_WVQf4`(AO$K3> zC2@sm(wjc#=|OP|vphJuMHYvCuyi0JKWksYcWAJyf}ZjlW>=j5HmnIsGQA6aSMz82Y~Zsp_M?7};;!{_|` zP)R1q?O^_BmGSnq$WE2b2VymQ4~ku*IFsacFawKC&UkxT1lzw7bCR{TG+^Zj=f_Ut zzxkZ(4_x_rz#4e+w0$iCAK-hJmDDAF5ZFT=PTSWar+m(9FP6~w^T1y8aN52W!S=DM z-Ch0f0(;-XY5Q8_lFykhlXd>T1h&z`Y5Q8_n$P*HR5CyE@*uFo9!}fWBFgXdNh_i8 z>%am_Z28H7b_71eKW*U3rvWSH;k36bQq=F%xWBmGTUHNP1B>(CvB-C-3>ikyj;Rfi{Lkviwd(7?h^W9YQ!m6faq(-0pX#uPMptI7`t9AaDzHlc9}rkvsj) zNDN?P2EZCb@N@)e^H`)QJgRqc%Xcpb_ZyP-l^tpBcS^3)iO9!+^(CC2gCK1li?qfb zx3eX5{fq%N!INjaz2AAEeQ{kGp8#8I<#}^hdvD|gzfuexhYtu)0MtUD9H|llN*dt!@Yi# zkMuBdF(3Kc@3a{OY%1bsSS&aYqzVA5TLNp) zo5_Ck1>(Bs&OqG*LQ6x^+uI@o15QhHmg*724>TAL!`wE?+uJ(%0wpVeH5QCnmc_-) zSFM|11i#fxU*LEOvivz{-$YY6-$B}M7TFzePQ9=DIQ2VNe-e|PI^DwPFs(?TEn|^i z1I{{(zf>Fsc0~|$6>ud6dCS~DwXVPNxS;RTetMMm4~YChu&D+&(LCM z$~)T%tDxm(RqgTxZiIV8etWf4aTwqql+f7;7HP;Prosqr) zhZ|wr@DTLqkD}4`3~95R{wVr;W!eWP@^U+3aTH5q#aDYvV^elvXK~C*^nwWfJybbn z3A+J40Ln6m&NPtvjd6Er?7P>oUF=R^_ZVE4#O(F!4zgVuTX@OGJoz-pLrLH$U`1DU zY3v*cn7w`vc+$O{8IL()6sU3`epXm%y0S}StythT%q)Y09G@>BIQ?HiIY$CiG(}hc zV`=P##aO~Fyb7oO5VQm-VKKWjHh*jaYm{|Cs!v2JiCr2Cmh&^*9!M99R%-qzOn!Z? z7B)cFJ_ga#5O|;0N9dJ!uOG!`(ZBpD-*Sd-$OBKt(q6w&cjA4r0<^F43w!w#mFmWZ zDV0X$(y+uwB;4ufR46u!zHet?UJ#WOMXK49KKD4BlMpqoyt}F0V4?RDXlq6>-a_w~ zrvWuUd{YGfUsMrhq4(WR_yW=e(Y+0%#D3s*y}kM6SP?+XNZ{k5Id-8pCIjp3?-@|H zFA*w*h@6k#1w^Zh&DLOSX4c#3e%aN<1=n#<9^6w1DjrFx>$vh(7fDZuz?-iw_B*6l zJnPH+;)?$M$LeCy20`(lWmD2RMZ3EAi%1ldhe1RtK-FQ_+g~53IHMCSWVZ~`y|9b# zl<9iZoM_8nu?I?sV-SeG$$Jo^o02XyH)3u|^{6S)j=>B5WRZx9vw|K|d?u+Kk@|N= zhCK$i(%O*8*M2-H<+UG?k%={C+I3iB13D_R>(IXz{k^;EFb>yt*CG9}yAJ7(-F3JF zM*3$V#g7pDVX7{(>#$wjWU&gdn+&2d7<4tz!c_>iyAE%Gm)^@3t4^2* zbwGsKb+{GAWbLlQ-;t-vi0x?*b*BeU zQj5nVi@|_ivhdv={Ej*{Dp^bg^uC3gdhmPd-M5p)=YYP6f)%UKyAFrtVS;E-_o*?v z4zHnPAu5sGb+~?3anT$JB(B3t5W(M?QnR}bU&l?L+-Cx+PVj>S+g*qJ5K+9{bvSfV zNhWqeWOplIcO4$BiOC(JpCgEqvbzrF!gksOL{B%6>P2bUU5B4RbTP2i7U%798pp1~ z5hY8A9l(B%!nG2+>+tcd$>K5yzV&YU>Ip9q>^kg$$xsPkw^*EO-|jm6DXE004XlyH zNj`s0vFotjr4-Q#gvTw3O5&zub{#%?p_mvB!Wcu+x61B1EQ-72?K(Wy4L*>ijRg3D^2!%fOunE-#upcmIljn4OfyOg z2R_VM=6>)pL1X$kNcD!Z%v1i-HiOp^#7lqPS>`2=X-5tAEHl-Bv}c*GokA0VSiy}D zrHgz&ed!kQ;SGD1nI4o7aqU^=58l!WTKty+&W}CI+!o93l+57&pnGSTM-C_{UI*(f z1ph#4lJ+d~#ix_STtqK3kQz?7J?U(6brsgb)!=?XPN1>Btyj0(m2c9u^)ygtr643N{^Z zG^RclA5XYefV0eLuud%B0yxJKNP&8bSoSRQ>?SE<1qj8%;p#aZS~myq>>Ut{WlpbO4QIc1$coMkS04Ed`G#@&{694%hgj6KUd4R0se z5saROrJrnbmifK8#l+jlu^a~cHN#O{RlLqiXPIBbSdmHZgRsz&xV|(AXPN(jF+C=2 z24R;aQJ%cB%(s-lsPhkiS1rNbQ|~PE{U=eh&?Y?M2)Y7TjXleZeMiDO%lr%$Nr@@* z@YBSIcxRbAD9grK=1bd>nIxYEb0D#2&>gjBnFIJZN7}|COd^;c0DG4CFh0*w8VeDY z5zNxwS?2A?2QTl^S?1@~CNoJM0P_&BS(!b{eAr{-Ec2`b#h4_6-(V3CLF?wlUOLM> zs(DGREfZLE!daWfah5s#DEuKI5qS@=mY%#h%Ur1=oD~xO7_g^3+?-{;`mKwP2KI)B zo3qSaM#4c8$6>!ObW? zf-b*3%X}Z)Hp&dd*C33_&K-hxmbpq(^cal+J`hDv)MJPgbC&rwco&pUg3;fwytB+- zz#cL+NI4GJM8f&@2F+RKl81DcE*Ah>YH@Rx`EAsY+>Gd51bI2MXPNh4$fFmR=`8aQ zEI<-dUc*o9mS_=LkEXNChddFSWnR)19-F|Fx8f&4B9uY59?V(hOL*n0763a&6UF~v%eCAbwtwb(VS&owGI9i z5iR%Q=QqN2Wty|hw_i)q^8Wx+Tdlk~%N(8s?~x>53RqdfwY)jY+@(ixJ+-b2tiC62 z&N6@bcQL_}_m052S$TVwdFVd$jRO%s!pOQU#hhjC49nMY3c%Tx@G&^@%;2Mt}mY)C}H?X4TPp4wfGJlOek(s`4G3rIow}Y9SoIT6DXCr+7k%+rijxS@dS`&N8om3Ke@E;AKPb&N5Ga2V=sd?_l*E!E2fBtuberXW%oNx($qa zQ7rE)^PC^>473LLkR{Lv-Bn}GGXIVypaz5Sx@A#4cmoZQV$L$xUk~aW&=y%L)ueZp zd3`J0H>fQjY&RqkG-sKohxC0`e*n8`aNQ#GeKu#AtEK4stcre*uU-iMr$v~v%m;nC zzf$$Ux{sLlIlbX5bMF_6anGjufThdFV<>x;dELblnlPFO3;2GSv&_p!pzJdd{|P0* zy#qUcHy#~Pz!y~Y^b`@dkhv=88CjD$5tS24>G zBq+z>XClG(K%q58*ZJ-MCnM(rT4G^ijBZ2y0t{~j@`FXm7@c0jqduzh;%dc3=cR{> ziHy@TaYP$_V+#L(2^{&2q4jC@8^agYZ%j_V+i`TJ#RM5_4`%HX&@8Io-a&{KlcduN z=PhY&mJ6skf`2u=4{4d1fAkU}=@TJJCu7{VD17?Z;1&F-P%=@8^w*0LAgZjnMT+z{ zoD2W>#TZ0PK=5y($3P>KomY4I#0QA|)FA2yf?KlSbmz8%KJgWx?H2yglb+#3t_HD#stYBk~Jn678%>yhD8|01V8-|we1=c`~-s5nBexW z!{RC;Vs@golYYTnD}f(tOpx@22s6e6-zyF$P558a@>7}b8WSvwKgO8gU+`2%wDt&H z4BZ+NtYDcV9C0zsjFDiCB4#G()W!tY|E#slK>Qr5MH>^W38!|Xc_qR+!dT826I_lm z8)Jg$CDNF21gw+9q@oIAOt5<;!<^)ds}W{K!CkQbf}nL8V}ieb7iK+Gf!szY>oLXz zryoyc*?WMr^kixL4`YHK9o4yg6i6QrrO`i(2`;au>);h2V?ES0Civ4zovS%O=6R@V zOt2?h6jG@+0NHHOn;8>q4==vNIE`?@GL138mp|2L5Dl>qf?Iaim|*v7VSdsp0lC$p z#+YCh-A~t;VDEZiX0!t9L1J>lqI9h>L26~jnBata(wH^^)UigfVmccW91)+!>Sh6( zAFYn?-#@_3rDWD4d`CDn11)ci37#pbRU83)k|_GVv8ln!j)D_n&L>(-Jc2H_H72-W zxh~EvfGQHq!q%8zMHqf2>H2^gS!rWTke&!@Ot5>MG^RWbT3@TFRR18FK(|`-NLXWn zmD-1yG8we#R_o0k@(}d|oqwN`DDpn9t-sGawFj@GXYk{FpILGbKEfP^qCZI4<4DSW zpAn^Ss8WEPfWVL%K)C%rGe?BP5X7VduNKXzL(G%@pRoT8!G9lM zMOXHVVJHZtkMZ3dLNvnR)UnUnEfJI0;fAkkNgflJBdgov0o%pM;2iCB#`qKt@Pw0{H<_3 z`DaZ-{Z~WauR)7Y1Rk|fY!=yscJs=HocVvH*D9vb7s&~Gu;buf(Awn})+Hmhem(UB zC_>aQx5(~u18|d&zGoZaYTx}Vfa&t%$Kyr%(Ta!SVNAYs<+Gb(MfwS+O|L{YKRpw~ z4-x!SZlTfB&OR(XlBwS{K)xcBZjOi>@p7DQUm;2}XImJf4jRFf+K1H0jh{Dy+1ptg zNmYOfA^2aQdZp6wkIp$&g$V6}u8cpIpjl!Bvl3i0f+4_;V4fISP}~QwH7R?IvSUUt zWsU|!FU0mUh?+>S8Nm!W5fHBcnqc9np7ado-LrAx13;fz_+5f|1j88!l>yRj!^4ia zHGQs3xc&#WJIFVmfFZ>6w^ZEz{U|y;Y@#;tMD6%N7{z8L-RBeO)0F>gRuVqKq7y*y z&nCqhnyvg7bNr$-qAMFn%_qDoi!M-p`A7kg3#_Td7ZW~OGGU4GPli>qt^gmigwMPL zK2!dGI|s!Jz{Xpg6sUZp)yn_OB76Y=VVNaSMAH~%$}Wg~*b`Z>7A<|LEZ+bM;OXEi+yi*Yt~4va zBsCVyH;K&|NI5`kEXfzo0Q+OaFEyAVog(GF{wM*q_CE#Jn`#T9cHcl~S`dyx1}Ntr z97a(m0bYtG@V@-?4JwVQ2)oqTOUYtcjyzVV;PCZGf0J?!R)`V%D92R~VElui^H+`C zkSvjvUh>#maRgyo0Vb)AV0I%mS66V^F%0y#!N_W+Piq?jY`E2?@tw-q)*+rIz0h>^D!o%~$ZP@{4j_-Qw2vKfu&Mo4=(n zhMj&$In6Ey_1!21tSsStH>!O^cVn5XL_LiPGW!_nCO(NtstK6QJ#882%+k*&r{tvq zB8C!r6j&dtEy(zv_@3}iK<9Q8u-C2pgB$aZ8g}AWuBQZdO7nmz%8qz&>$j+hL>M3K zE_F^f5k{%F7`_Xvc>?CvDEbin&`lE$epm>3D(Z8#4fJa{@r#vXEZOIja9p`kglRd> zORCQ)iyGj()b=oTQd7p~bpKfCa<=kxG6qws(=Z1kO{$M4#~x@Z`kYm#0$OggC&w7} z=Ql5xq~$)ea=~GkcBj{k4IDZmMg75e@YVtQ7J=`Q`h}m&H+G|fQd9}*zGaBe;4??? zBy@}oynT3Vn;iJV13{4gX1`5ZrD+>{2lgR5cETy!qEHp=<^7Muc?TyVlaMZs}oc)n)Q*-i8R6%q`Saq zW?5Wwny|>{)Vd3V9sr-TgnSy7!jSG_97=u>;6zIx4LTj2(Um@@3ml_-48l@NI^*SI zwaQrlpKu&!BWklZ7|$4%en<0H%=GgyftGO8Z~>W-uY>Tm zAt|oR;Lt(n3V-!E3)jR68t}-aAgmygezA}jgY?5bC+_0{+*IT)VEc>`!RJxZkNceZ zi{P#hO-Wt^cGb%BH^y|F%2<9;H{&80siz?5CZXYTKBvHATD%6J+X>dA05YeXew!~l z?+o<>(HDY1d&AL4F5fcPGSQBD=z zTanq~6%1ECj|;S(mMESDHqzpBTU`9>xIk_@DW(AXC<<3h;*TfkANif3yHICzH`jyp zT@+J)JV{^bcOG~nUXzZ2@TVn_oJ-mn7kH|H`y-Djp`1S_U0P2|kf|Y4%S5!wwK{!t&z8n0K3^M78 z-;w2D_n%0?V=#S!pp(<2m#G_u0pd9?>Nk|k0--LE@@Zm{3OJQIx|-U6(DepQotmI8 z_}K}Ro)#3%sPzv9;U%j{mySu-oWQD&VH%f6GeDSYHEGhUoyb#Md?2AwNS{L52*MUa z(xyeyH^&4Pc8JxT%3)w<3Fka>*U5*T(?>vtuyDzal zcMgA~;NMJGZay4fx||1@16-+P=gtEb{121w{In0q4Zi?tMQ9`iW?f z;JyMF3GE0tOW`tt8;Ab{Ui}EV_}rpddGPgL(eWM+IP?CF)y%43-ElMKxnH33TEIy> zT!6DE+kw?RiYbCja$=m|Z$3>L3c@Rv#0@TI*O&wmo1UPO&H~7!f9Z)z-QF=Q<|1Ml zv2Qc}Q+ZArnrxe@{|eb66w>4O^$DRUpwhvU*jdUvH7m(*#f`@!vO1nEzHL2k0u z`z}R7DUP$?`7qbyt61$*YX<0rXdc2SUlyu>n~-EFKwzq03j$ zusy#PeFr(oxWC3H@=}Oh6NzhxU3?9nhjp}-bA9|Gar_8p%7gmjWaX`&s{u7=2L65x8!aDVCiSulKEw~Wk}cUeee;H-dt81mx{WhlS1h&WGOl+ zRD)L+TFc5bL**r7y?jN*$*DfN0PZb1`FiLnG8bIHa|3%@qsN4W?=;#Wg8vix<~Uk1 z7J?nB2f`u^@s$jw=*qpf@v=%6+}j#_D}1sD`JL0Z0>%~J?iv=g!0m+4ourqOX5ONo z?w3VqVNl-+c+XikI?S9`!5ims`Bucq3fv|rUe|T1bh;J^iC(9q zF!6svIAq}bw;~fQI#sK<2Hc10a8xi}dm!Zzdk* zVMTGo4>(W$GoJv1QXlXJAiQeE#3)L-`X!^^%VS#7sO_J@H-fLx{Z$ z(ikFgB3|G1O9#E48+X^?f`S(@L-eN0YyUia!Q^&H=ye&lsVY1O_Us zS^-^RtL*zwKau-U{PQ7k3=yX(fq&_>c~&Ezw%i_%!#!C4MPNiv@?xnV70FLf?sFyd z>K-v%eZRIo9V2Sv|6Nupkpx`$c=;s1XbY&Dg$ogUP^Wp(sRSEW1AvXTc*o(W7+%%n zl-=B2YjiwD%m8VwB{KY#RwSh}zL;OE1-RW3C?l#kCFimN(s{CZk~j*+CCj4xM6nX2 zQzJPj63@fxD}t^H&K0NFqx>yNBDW;$?JkNJ)j`NHB;6QwW6Q;p^~=R1Q3~4Ig3!&7 z6jzT+x>Y)J-wZNo2na7*5?2yW2yR=E(Ozm}g0pCs8qs{R6o}O7L8eXNS3s zVZpah0u$v9uzw$kZrVAJ&1 zSZ)-uG_dj(=lvqN6Km+pOQz2I4p9A~S!|7vlF02lJai3r3#{mB=w69~br82aR#I~6SeGf^soyd79Q z52u-C?hNTf>K4>v@&|xDXz_});XHRrHJW=$o@nO2kBWgC3gXC@@H5(ygEZ01{a89N z%i}aY2iQD|b03tuLOQ7%aRPE3;=d(~o@_;pPoEvny$&yKrwWMY(M8CkAe^_P%DQ2o z^UEFVt`QQ*+xT*0m9w*j)MDX_Xg~;B_pP4pbmiE)edwB)U>M0a_!>eameu z+TpzP?8ckcbl`Fm!(CS5|b`pXn7o9lxXO>+mi^+8}onvdkZn@DpNsVfHt zjV2UJ6h(l_2!8IiI_h|p1G7fgC&lPeb^)P}C2{3wW+ALC=3>|V7No)TF$%1SQA|BU z&z-NFt79D95Eg*&g(Y#md4`_50e5Y=TeCYsIAlqjCRYQ`&~p#MYuQ8iD1HSDamlR$ ze7VU+eoiZA-1>q#sT5%42&ZmD>7-~HpIgf3e1*jT&U8HxniwVdNu{x<^G5-07qSNk zPu`%3Cf~XBe9rz#?(_I62yfn?iAi^1;pXlCJDZ4ah`U7aNq__ zOzP@$8cdWrPnSXP;mOEfI+}dvVo5miOq`y4r-G0{B!0AX6)@=)pR;0hSQca z>pZ>Uu~e}J!docyZFHCRQX@3Z(|0>zaS+f63m+udI8R@XeJ%e2ibIN8`VhhPWcbGU zVL>rvfmgAd0skU5n)9o2PVdm1yMec`oDsyy{I0!rp1$zjG%*m^D+u_!o+Z{|@QRD- zf-H9GlqpKlUmCV&2`Vx!s&h{&Lezuh{PZurw9{!<8amq3t_^<4ciOcRu09bK6!Qp? zx>5C(HKz3L!tNT%%LohAqYVjk==6{37@i|KdNaa2#OR5&&YZUy;WJ6Q5$I6sX>4n= zQXUNh#u-Dy7=Gs_Y(&#KColbsRri^T60`onT&&WOSbS!Tt3r`87pr-g))%{qHj3cy zNqMgF7a>d3JG3DQu@Qsl(a#mdlFQV`6~dx9unq=SkCC{xm@spB;i719Pa&os@aLmB zI`Pj{U$}>#0BE{}dAwYuRvJEqeyN_m8Wx`dT4mv9ID=%yW#(oTUpg$d1KMw4N={TJ z3;8p5CJo)0%KLdP0KQ@B9o!k>xN4g(`&Xz=aMU|mb62#2O&g{gncpA`93v)iIkcGvWvz#ZeIy4^8 zBm;{<*YY4ZuRJ9sR0X~Phq6xMW_WvD^39E?ZzxrIGQLQ6PB>H=&Hi)>Husd9RrP6f zNyZ|`8z{*oq;QQ=Sx(t&Ii?{h4T?W~14BNIom3cDtI^IkO ze)Ss~2VDtvJrQh_5=4yM7#5;G#@h0(ZDElOs_cNDhpjYS*^ObvSis#F_D-R&;Pgj> z@(u}5(G*?%kBwm$&Y?uB!THWgkP;TN8^aPig;}FK3eqVeQc3K_urq(b$UI{42~XgY zjf?WCM%!I&;9}bgRyc!bl#1;MhkN4sE#5B>#vMFhuqJ19ko722Kc$MgfErr3CBfFd!cqsT zofd0Lmv^_;octnj(R;17FPfTkS^<0eLVO*b);rkBm=4#1uIse?JIO{f)!4K zy6w`~SEz@Qg{VZ@*S@u{u&qp3 zOa}I$#YsMYPO;qoF@`IvK={^@s3c0KWb7-vn-&(ofpE%@^sTb?75bwMc=i><@2P^G zjv{!d(h%}jfU&PI3Gas6faO`7ByO;;aE*p4?ZJ4+vaW^j0N9?DKfG{z4^j7(Q8SFr z4E7affN$(85X|-!nAdL7dV1nvR^cEP5ZGkGRTPRZD6f1$#pDZWWPH)eT+GHrGfGQ% z_7(1YTMxKmVo(D9Olf_^9~!EmG6eC*NzcB*kApO3?JH0Xc=i=m{eva~u|6b97x{iB z&@GC#uRsq9yfsVDzQVFSTEU`dSysggI6v0DLW513zVAQio_&S0=+e%D^%sJFGBrtS zUt!^^VUgfSQ4E10HIr~_UxDs{3=wMWD@?vSEbc%=Gb=(@u3VIT1#4PiF?wzJG*~Z3 z%X~o9q7yWx6{ydbA>vun3Kxn)dLd#~Sm}9`No!i+vBP1p4cI=5FCyHURw&#S3eEwP zv8I%yKrJJdHLdXXyO{rgP}!153un*$D$Wk&VOrsdm%<_!tkySS@;%ZiW05C<{#Nz| zZE!S|Q`Rh)R=AFLh8z#ZdzN((ja}D_HLdW{ap+nO#yZ2&54AC^FrrzSSb-eNeZY?x zj^e7arWJzdVweOEP$B_A-*m1oYg*ya6jxI@5N@?3%9CeWp)8Fo?*`b$61W}EJ@rg0 z42nh39s^^5Ww9D-TH!&wG(6J^g$9I~Dc=SCeIw$TR+tuJ*)XjTPETW!{1(g|#9l** zYugDhDm<@D8f!ZV=)6^?VJ!D7*ag2Yh)#&dlZc?Dt!agmh0tKEX@%YRv_~X)JAUdB zn;#@=TH&0>hG~V<_op#Q_5|~BVsp-{X@&8)MTEHeZ@oW8Q8t)10af@5i3O%=?@r*$HSi-0#6{+(~D?D`;Q=ZuX zmqZbiZe7N-!UbxBo59#-Se|Kxp3U7XoB(!~aD5AC(oJsSBd2t4F5`n37b0lfm{zFM z7^=%5`c{Ix99q)~Dco?4oA{BbI5P#NY=@ujH;5S13gtZ!m{ypF&&ui@t{5}^#b z^zT|Cy@(ir#`O>LqGYD`K-vp^JvolyvL^C-#%^VhR zYVL^(`7L1S^6?nTnpPN$)ej~dCBpZ7zl>>x&+tN4 z*AO3zx4AAm4KS@~g{_zJ9BT`K^%`3U_tr;0Gz9Q)BVlbJe6l$#NKn3wpZ5sFYl^M z#GAP#rMfk4Non~{WPCUly#mhUcO~g zJ(GVY1nrsp0oWcl4iQrk{6V~)RWbb7Gx?OQ5Mky_{^{jm@g@Fmw)~RJchBUP#vgMg z|Jyz|;SJhpgbRjl&*Yc0%n{B^C?!UTB3J}K@K++8`b_@UwY8Sp5MPHd%B04|RQ*QF zHAj3KD`(E+H$|Dvnfzxlf+WTugki*FE#^#qbIY9M+=Im_V$4SPn3$Xwb0+@+-i4%R z9l|C;S&uoB|M!qE%l-o72%%cGz@4~Ba~$VRo!fs2DQZ#oO#T5(wW$tD0V(UD?wR~9 zjkM-EKyp3QJ(EAAW*Vp44oGK<-t0{NBN)39V>rSqmTAu9m%+%D&>0AGJd{RlmDW3# zSL#9AY9JddYR=?Wqx0i6tF zx=|qPnf#p?ERyhYK&z~inLT0U!2}$sgobpI)VClO^}6_i@>g0c`gW zK)*!bP1*E^Z2;*+)bdmef2hRzHOS^>T2@>@fxRakJ0bLi!uCPRXyXOi>YsSaphs81DOQ4%AgLPCn z(?3pR&3A6ehIs=($1SXjusks&vQ{}wUP=_fo?zZNk_G!o^UEcOk%$=v{58vA z6`F&+bcHf;@B^ILz!z8!>*;VLoF>xnR{tLH2NAeV=#N_`RF<39$zD`k&Z`GvQ73a{ z@OmlK2}QYevQRqT#rj2YM5iM7U!`2@LM@VaNk83xQP&`9f(L&plP;kL0Mx<4lL^*N z3bPi=lnPEzOhZ(E5QbS2>u^a+WJWNg%H6E7Me`hEkcc^)2C&VbH7@d&WK7GFfTTjX-8c>6h0EJM^75GGp^ zD{)EXRq=OrCot(#5LQ_dYtj#Gh6+^He&5utOh`(j4FQq$s|w}eKFFzvnt|Y7L6xPk z-&JT+DW8zb5Wm)7>i6gHZG~5DvvPgT<(eU}5h8LQ2uGqxymK^bE_{nM#RTIYfKHm5 zf+86aq!S`pYkkg)+X@PDpdrhEP=QFBJ$xgMO?Ps{KEm$=*3c*sljK`rDEJ0@_HHS_ zJzZB|J*~Wpf9rE5qzAd9d;!?YR{mWrzuo6#WKyrB#CyO#xDnrl-GvYO#jpD@5d`)% z;heueCGE7y+T%+Z+b)4?{#Rf}Egt-8c09%kzG7|viq|(r;wCrLhMB9z9-_Y$m@04YZaLW2H`~^dll_Cbgf1Y&ed0sMV zgtU}Gd|ARMlkPmPKlZqhTy4bPVdcy`FTd@zkFbA|7~K#aAtq}v^Su1F*E(bK4lza} zyg^LPi<#$5n56Z53}hjptjEmrZX2OxHv#$1lXd5Lp);wR+ao|udZ;_ktM-*Hi~klW z;t||*-FaRrzFASO$^yyoP<8`U=8W z4|V5x9kE}GhF)`k%(JMO=Ut-v>CW@k?8E6dFt#D=BPKU2(ro8>)XK~}FZ~DXj{tZb zAwJzLx?(!d^U93U>e7H!BHUBQ^SnY>izNAaz?wwMn|a=l$y!A>z>gRecAj?;}r@PMeyXNAn5jRvxhuHJwdyVa?vf&?CvB9nAu&~Vpvsei?#Y|k-O(Ia5+r;Fu%E0v zXTJe&KEUkGR}l>&R0C+nYV5!AV|F(&BmeBK{v*g?*7va^%A48U_N2+XU{VtQt0MRd zQl@xUXx6cU|3Xn?p1K{6r8KI1hSj;OT`}dJ42xc1Ka0Qv5Bifuxz`Hxz=QvD|4p*O z%-lZ22i!^EPebshP;zGG*7&8cScKS>2GKpbnYsPm5#PT7{bFD}bAwGEZ{{}PQmVK> zcm-Fv=2YZlcm_Db=~^#MlmLE<<**8!zu8XBE!g`5sJ?|+`WHTNm-T@Y#GJS)^mPFK zu;s7{m-Dd`7ppnX10Q8MtjEmXo`ccA>3}}6ur7!@e|rmComTJ%-=^f^8E8o_QtQMdgf@@I4+4)5=3xsp*7uGh>Td*2jsCc)5$mR@hn<&2kTeI7&ndr=erUqgHn5beIf+NPg|_+MZYTbnzb z+DU}iA^s7(faFj_jX>~spbD`={NX935JAcFr<562L{_u8;nf)Tb%2Udx2&ZalSuZjAl9ybqI z6D#ix@rUH3@w3ze*rQh78{&VAFVYV|ek8C_H{uxLxA`?ykPEWez&<9N^XComd+gV5 zj19mxTig!uW147K9s+j4;@%K{@+~_5e%z#Z1g+o2F~pBYFHU_yIbxuS4*Rg9szK{5Y2>gnm zjBo~&``WOb1U0#guj@hpqxj#zH=}q0`1Qw)GOxh3L{TvN&4g`L!QYG(JefTyu4EOL zpFJi18xYyw6uRq(+u_KyWNy;?vg z-Vt~=!x5F}kV^J1&X8d^v^fCL!wsaUwEF0F_OX(Y+fZ?pR!&5fFHu{I#|Zfeh^r9d z&cSvl-4ZWR^(@^XzRCKgVT{8!Ekq3=Bc~4xTGU(_yiyILnfj}7>sE)p#hK8*pzR+@ zej15uWNj#U0vZUIB@q}=R12ad3vLKio(!`*fa+Lyo(FFX^}}jiGe8emc#)@ktJD3( zfOs6xPzyI}fz|85_z_kAfdSW=C!B_l#q)ic1ddup(i%DCJbD>T0TGJ`;bbf993Bug z&m?kbtCZ;!D{5{kTz-8(>;vTpLfkT}b8~G`A$3J%`x_*P%1BYheRa2VYibuNBBz`a zKusN&!F#i?rIDh9uPkTloOIsksyJWOZbj-VC|?@7Ae}E)2RLI*2wFo>=F6WUW0!C` z_aB_3MD#-l{*45UmW*AM&PSqv7>xLr45q8PE8_tbddDds-Uc?u;;j1{9%I#vQ$_ZT zh=B<(xMu`mOEgJmpn!7bhm`mQ*dG@Eo^p{whjnUBh275y3E2OD@&*w&hq`d1W#3d3 zK`PaAL!zh*uqJ|6pH!9`>vOYwwOav^#dkx5uA}}l;*Y`N0~+6e>R#h}Di_OuQ1&dP zxRY{Y8efyou>%gVlMSK{5NsOXw<|FN1hm}3zkBe;Q2pts20*(le9Tk6)meHaNt^(5 z#lru$@vZ*NFWTb>Vi9Clog!(|_`ccb7nGT*gmAK^@llT{svLd@HMFVlcjaK_0+j9u zTv?=z3#sS|mhj!iC%EykY^Wu2l#@CvBnsB_$zV-9`?aa^L^A?n-6jY_C7Ck|aPB^( zJe;T8=_XiEI#2(APyLAbmY_=n)ffWfmo?*LHBuF#__817B#D}ZrPJg}g7^oVE1n*P zib-eH89W#0iHg=RdUQ)FAw%Kaj;Ms_TM_&*)LXet86QK6ufhrd;@cREZ(RQNoFPMz zKa)gn5T3Cl&Zyg-Gi8y-`o;(<*6Sd=9Zk{?MOEn(=@KIr0$XA6f|M2Ao_9&-TCGH( zwgcR630za7Wp)?8sCkQ2o6-_QJnA?F!QP@;KMslGSlxQLe0;}lXyd|d<8k&D!vOkzw6CXEt{WH^__z;q^Y>`tx5wGEqonnIZEva)%BK`45HCD|`5+kem6JikE zPPU9iNsG#ab+z%mh^(??my~55LheM5y!tUB8^&Mg9O^KTUqkReN@eaxWlp(^@UhZ4 zzYU)O-UB$#5cGUsTN25hE(;g=Bu+dFnXf?DZb(`SH<#?sr1M-i&5?hA@RubWEsED* zkXGxn*JEDW9UVO|S+Ev%0wVaIqpa`|hwQLSq&k%RaUgpuK61hwCz0eG_{p>E<~?C< zCL0f;4~OIk?}X6Z!qvh*`9*eV$**h~A|RM{0YfT$y3d56zE_ZyfGkqFg?i~lN} zIRo)_AbcUPWrTD7^jskOh%DHrt^VY)4cKmr2YE<#S~?HC?B@6^u)hdr{X7=W{#!aF z>)@+O5Vxv0g1#5Uz|xOOwof_hN1_E(0a)7-sN%&6#dk9vHX5EmL%I)Wd&_u(7+3k5 zc6Nd)+-^t#zFV?C7{j7jDZkdi=&+qsUnz`^-vzh;p|u_Har2-osm^)FOItuT76%w9&GkF50k_{ zDh^xsL}{$&|6A8v&%Xric0Iozw#+t!u9gV?LQtei;U{`MpD?qYU-~e1o#Ov+%P+%x zcRjy6{+RXrm#c-DHV4#shHlsMD_iCWr|~OTFa={9!fs;TN;>s={+pNxQer0&&J#wN zbl3A6z>5XR#nzD`2|>%X`hTRolq@X;7;DRbrk!1D7VXitn^TKJ-_p-8r=zGuZOzp`A;6u zn$H8d?4j;@e)9rpoNmDgo__?l9_SoTrJmWe&$cpc`meOY>9YstW5B3`kZYM{J%7e% zjkW{Q*+bp+{7qO^r}g}2fDEyyS} zpkpkTgYAn5{yI=^&z$#~2`CrQO%0^-7%$f7XAlozN!^Q`h zC&z>Q4hh^3SkaX|bKZ^wj5Cr>o^)@ge3gRYBT(h{_}Ocv>B^ot@5Tb|ne+L-6%?Gl zKv@eSaM2W9{f{%}-(p51tAkVDN{|v3vuDnIx5JkiaM=MrU5Q8~v1iU7TM*Civp}A= zDBqN^_$xv_WIE&X21?|XTM-<9`BLqy?ua+$U?w)jd)t_UpCY zxu7UTe??}kuTn+11u8fUn=m&+WbgkGtM_zlelhwhGDptPskIo4WmVK?2!T^u0hm+s z#3)K>vE2`9vA)lu--JjbBUY=gD^?d5x~eEj(O=Qwdf_u_b5GhurQE#C*}`y|M7nQvp(*}ET_&iywBf<81A$%`_8Vp1|h%3*+0O<)4cykK_qwmn-PyR}q;-nc z!oaK8E=PITOVBW?4r^iHI=-t>UM^b58Wo@tioExxpuo5dtMIScI*PKl;i(E3Gi4&G zI)Z;C={2|EnFf$*i0GCEQeP2nZ-Xcs7F!V08~8KP9OFi64?g$G*MPlcaD6A%o89?&hrtG8po}cG+-+v`Q?hw!ur1(Y7x9dx)-vMm> zzmDkmyIe?(W8Ce&zrib2rU9#D@aXRQO^|K(edRceS%4>-B@HB%UQtfzE|FrCOG{sLHV8psA!6={zvz{>tU4W95@m+ zq$NlRi`nk`v+>weNSqXqN)wSvV!QA1Lc_Iz++op5jh<#-Qj2~=3cV3M7y(^NA3?W@ zzdccG7I(-xWv_#-^!4>r@+H;d3WTSCHaowt$EI$hk5~*)gs63HkuzbjstbHcm1=;u zM6@rdwFxj3W_?N39vSA>-DwD4K=4z!tuLwW__jx{(;(CoLh#eg(e`yH`yxbXwrhD1 zXZy&%(tEAZoygC&!vZP!SE`GJ)Y|+2)h17pH~LpPiXq=aP}-XmZzILlztTNxaFPJg zuNg?~CEWT~n(=a2%m6mm;s*)${42%cqsLl+TP@*`mjL`LJ=`)Zeg$^U;-o<3Bf-DY zmW;57K^cl6a0c1ErY5m}r7QSMRRLgiL(tDbJ`bAJpx^pe>giw=27Raq6oPLKeUwXiWvV& z+^(&ErFx6POj4)8yg+Qufc3Am;cskuh;JxGQ3S>m>Gb?7ZT$d*$^dKLKrsH5ieN*E zx(8s}XoB^xL{$VUGB@|H)EPSp91KR(SV+HVG>HH3uXGM(kcgyK;%6PPxw@=>rQUsA zZTo@!M!2qS_P+%GN`*^d1dV9*5B)T<^2WbXsE{jP3RqdfwY>4K)DEny&4Rz`A+3@voFJ)V&)+fDI>{^;`c+^z?cDm0l=<$ty_eWBe>6wl1yluasOI zR@kW^n}Ka3T<6yKSITMY=Jo`zvsT{vSK9eAKKj$4h+tzVp_DxTO8zuArx}D%DxQC( zz86z^KJ zUx~)wGDN8LuhbSsHdwAbVjqf@v;LJXyx=N-9)xk0L|1MK#=p`Wbhe&#=p{J?E9vwiMt0Ieh~C+ru6gcHvW}%V+R)Lt_9{j z#J-ts>tE>-mJGUr)zj#8Jtx7x(y!P%AcrD;jKTD4rx;a?^{?c#!H{4U81pTQYtH&t zy3`7U4FJElgnSy{U#Z3GARGpG(Gp05VwUxKv93<7K1O_Q5r>(XF<4XNQx`d`d3ifb7DmFi+cBDJjv zfTmb!wnIYxmA1B{p1}B5Iu0_CF%VnFpiVsK$A*8UB`+f9#6E+ci^SG1 z5%!-1|4Ogl?rJM=9~uFITQcKc>6ePGd^KR%gllfN6ckrvaN~asF&Y{*_`kVCM2U;x`aR9VJ`Tb_OQJWOOM-u;6%VjMawa`B&P7ksfDy53t`2 zuDd+zUnvV_E=jMv210BL_inl*vICtC|4RFD29a+T)1dHYCr#((iv^ z`GPu?2EdvV&ZXzB)B0B`vlH_lVErvlB5r?Z{3{*&9R4prm>NyuuF(2ddJQ|d7l80( zG|4lfK>n37wxx=lARLM&u_o(Z={N2ijDIDy7)G2ym%;n-{R=@CqZ~a_*1ys*7BT*n zs=wG@ZZ*so3HkU!(+m?d$8^ZY9{Z-vo~@vjt<3;Sn?D2CwwlKd-ik7E5R@jv)iYK#d! z`BzFjqDQ!S;Ij`Sn%VpB!!`rOb9@n^bW@(d`3v%|v=){))gW+3A@Fhl{c)EAxY6){ zgGGb)`;i9xE4>is&Lb9syV?lSpZtO>Q+@AN?O!Ry?T?Ow<-^d?=8gR;d3E6p{YYL- z-{VJDl(Gs+4#qkk;+@N#NHu84`yX2PR(c9j&cm)m`aOQtv;lgk?hx!t!mqvsTgX&B zTu{1F^ds0xI*p*&Lldnuu!p7+!*M}&(+guYfei%?!TeW*%3ubW^Vz>JV@)2Kx?_B6 zJv42>*PCyU)b|MfYt(K%4^6|dCHpYq&l*h8)qi+s+Kuh|h1%fgCju){&L7ZbJv7m% zIz*uL(Dd#%VP-c%WHXWqvVif>M3rMbH0^+)G2-+?802w{hbF2N>!E1}CiujefiTD8 z8V^l0EeKJ(_0Y8DB0jt!?d^#Ckp#FNtcRxdfQf$=;i`f2y9I)Wra!K06-7|W6a-fV zy9I)WrWXN|iW-3KFmQgiK=9C{>(=;TqM2;IFB_EUoH+yN4x+R98a;~j!?Y9otzU!A z@uc?~Jb$=@#t+l@);Rx#_)iU{=;}ZGFwrLp>xXGTO?&_Y_b|dAB)x+)TR%*+1ZVv) zb$t-_XTb>}Tg4GvuJOafcb?*{AEqnoU}Y5g>Laod32?TpAEv2*iQg6BF$3qXaCnQ^ zy;-Yx5%_C{=GEA`2RTj4)`dF_x;(u+iZI7D9Pp0;1m*CLa%{P zC4kbU1wvPmB3&%>UPY0nG^JMoLszhX(gj37MaA+J5UGj?sQjPzo!z;+i0JQspU>{? z&ilOYw0GW_ol2#Q_uJ&+R)6&>bob>v5s};t5ISKf=k*d)1o?!aoJH;=u;R#{zFqr^ zoPEEvOc9OY&>WYuBo)AGl5(^ywifRJ*TFVLe&$pp3~!;H)7MKLYHmVU^1iIsI7PgM z_vMPK8ZlVp?~h>DnjIkRRpeSk{zm$F&0PEm+JB&3QS^rpivXXk(EWa(5p7h8u3B6i zZk+>W3Hrl4FakUBgH~SADI9t|^6ew(o6yYSXa{5i(N3W#I6=OFP7}?nG8BG6`gQ<5v_U$jjs?P*San~OpsxV9 zpg^2P{6&=031=tmkr++SLHu#a_*0ltGe$E% zxtPSlmVmTE$&%!$n%O5-vhM+DpW@~tg>v#L@rMzAD&@SYnai*#Jz=z;al1ia87}%% z%Gpw#zl$Vzp=KU@ESWJ{d`E18i%W)!cVx_2p_voEvxHRxEsN+ZOw!*%xY4jAKeYCs zb@ube)PZL^H1lG(74PRj8|kOh6pow^G_!mqi#{K;#eObCqnFG*LWcfQl+vBIx zG>)8;ntA)M<^SiPedDLoms-wO$o6YioAx$n_Y|GaC(7BJ!7YA1pC|_#rqp~snK4@N zPO#Outi+)09dpiW=2;YOlA%2U+M|kIqRHJDk@Iw%>>VTbNSf7=^E;9+Jz2Dc3TeaO zI+i#n`SgygRn)7N)5{~-h$z`2b+aR zWQL^c=JS~3@&q6^K^D1IbS%&5P@$adQQU6iLxplC>E=Ova1c;S#jQMXaBxYvWpgtJ zo4bzoS)fM&XsbXnPIQD&&W<06wh ziL#`T08Ggzi9wxkGI4EeWk;rT831qPlSCi#InNvBFIWS{U;76DIGIlpgXS9M=kSid z_OAeNJ6MwX3gJc+*&aT$iE@j#52VJ4a8pC6e(`TH&%0xph{7mq_HKdHXxHrB0?Sh6 z$)>bp1rN=c(^9XzEJVj@1sj8+b_;Zuh!n%%FbS9QdFYQ$PdZ`LZh(=b$bCCqwSiLEb8wXg*9I|TIC3w?4wlny-5l(NN1(&x#-x-YIsXTI44JHmz z1`0RLn6f9KS1f?pN7+?yvH?HaK#GZ)Cvn#$$z4EsLQzZJt)Di3ngH(5XFnZ>bq)X>4g_)!3b~e}*aq(JnSoDhAFVL(pp`c@Zj_UUl%vfaz5fdo{i4^G7jtIGEEGW)e4cAZ}TVS3f#t+65*!I7Sk*V0Edy(+Y6oS-mNBT#=z z4mG{%s~HI#(AJ8i4sfBoP;;#)&{?Dhz7o0~z1|~cfkEkj^qF;FyGBYt2cmTx8Sh7M z=I;QH%zQtC%zTk{^2saNH$h^)?rxp>th z1}oYuq6znD#K=Ayrg><<*)W}ZVSWuIny5+`QHD=|nXEsXlpuCP%3hK*kNvmKhWR=x zUYvpJ_cld;(@&nOcdp?Pw?NV%m>Knze)0mnRfb2zf>czI*ZIkB=!;K#L?w_K1d*i( zc{WVXb_t@DO|?|sJ{x8JG$v1U2%z~X>L7`s-(gq^G zM`U$243_|MS7*aqFyk5cIUK)H4C-u{vCz_A;e3Zk?3FqjX6H?>haZ(SkVl$&Ovl3M4b&|?u-+I0T`)3pZGn&*)VTyj}xzg zwph_Q_0`!h9bi}UK-;V6#2*+^e74WdOc0*~a8ZFMCc5;=J{#th7V+XQ0K!mAIJz>c z)Y&jELq+^&!>oBKUQp>M3v>;e!#W(tJ{zX(kMW{8Xk8SYIP#qhBQ7QgeJBv46^fHl z8Ex+JWqo&(WlU>$5Ox@SRqp_ApAAD~?yF*4yDR_m%Clk0Jg3QXU*Z7f17Iku{6Nv< z2U0SA=x;x~hli%*SHRgY>4m*KqUq~{7zCdUQ|^O!CeMFF60_v9IPnKUtZC1n>5q%^Tj!+WKElkqy7^=4 z1PLk*Ksg2C^pYUA!yJpk$C8==&_;nMO#V}1n!Sfa?E~VA3c$)hdFnqUrgt;~{R$8Z z6^g~EQ)1pg_2EAyrpszCBei{iAF^5er^I{{uF&YoNUM;*Ang|*ZxdR>sk8o5VkVW3 zXK4lcV-W-{Spc}lF%zf6thpfB%Yjsd$jq%yiOEKE{inn%=orT!tuv54l`wTm%wv8u zI!4~VmcSrwI*_xJY;{UZ=+7Q0Z9QmjD{1PKm``hXCI1o7KK1j*)WHr&+pv+#d9RH5 zWzc@{)2Yuf^L>YTFv3cir~#TNh)c#TlKLDo4>`=2y>U{08PF>D>D1?#iG5mbPq65Z zf!4}Tw@-=rd1EXa0j)1+gZy;+l$e!|CrJ8q&}J#RIwfZMVYHN2!#$5^WS4YO9{(vZ zU)(~$ISAqxK>%H9mwif%Q3I%JK>TK-{HMeW4~dgOa1F#DFfJ_66X5R<3+bPg4)!TA6FS9Xlmo=Cf&um^F~@JkvA;J#7K4I9YM&A_@-Ywl;{o|0 zg802rr^MWO*9v}30P5LtFlx{xLS*8Um>G4fuyz8iyDdaS+NZ?CuJFj{4+m|mpWi+u z=F+e6GOi0jTk7YxPl*xzyz;B|UC=)C^V_Gyv|N=S_`CTl(7spv>XevU`(S2nllx#h z4Wy>nr^IYp0!{IPSWE#T$X0mmQ(_)!3L9Jl#5y)W*r&v}&RRyP14vKXWSz{D)JJ)u z3r>m2d?QwxuW>-V8jNJ`Boe2@bl4atksE;89gJiHDUmoOX5dh1#I!R&T@FV24X!#R zW~DDd3O0wJ>jRh6T?(x1L(Pl}G2N&T$slW`0muvjakTuW#GJ2=WN8URCxxP#!GB6j zm+w$c27&mT4e*~5Q)eoa_a(S5wrQ;0Rw1@ei5Z=W=HnJ1-U~wcPl=iTkO$|#fcT>V zQ2WvnW1kWez90_szkzTMwIfYY4D``HC8pMO2uua6yn?dzQK!U|DI3SOL4Op0mNv+L zO3Vlx*vi8DfcBzIml`4S**+!a+YT0T4p1xZhqOQ7i^q9kt$KWM7af ztTzO`rNU5bEzF0;0mCDs-y8H7f-pJ*)hRLMyTpl^04z};Zd3UuIMFFFmH&zrTL9P> z4C0p5pSsp8LCg%z^qJAR7j^7kI&IKDDKxW+8S3aU41-woo>|R|e&&6&e;`7KqqF-p zC@JsQpIP0EFM7!<;^6GFNwVc6_bSP(VMZ_dG*0vdOC|sfZIC{YgiO+s?s`RLrdgmG zKI-@A8d}tuHO)}j8+8gEmKF$NW*JitE8r0$z&)8HJPT&&O?hT1XX@{^@ru!KeiQUn zHbz9!4p*6#Ont)Zv1|k#AAq)B(TB!{!^hfY1UKIu_w+S=!$oEtGlKjM4RwribbKjZ zWEMA_jc0pA7}ALQQ|Q6!OrxOaT!poyvMVQWQ1}Br%=lZ(I!$K2q%R4k^XK6YODQ;5RYecAI(P0RHz}x;jlS?w2r9OsTX+QnFzA);{=C0edc8MU zT!6SMxSWef!R=n@^4MBY2Qms5Q)C|4z0$qPB#WXTmA1+HQsP#<(zAa{7OUXW0QBa; z819umcbUU$ANWn_kaqnPjvT_u-f=IWTZdfK%3eaNmA#Ziq4vt&0a*CD8uIhVk3;ZK z|BPcXqI-%c_K~}C`(&{nq)!$33nJSqduQxV7Uw~_p~&A5S+3eWt((=RV4rBXL?A@5 zxTFu0@#J6Gd*a~~#$>>?y28vROlgV{Ez2ErFj;hk%K%(|kG_=p5&Y3(Xg4HeXgMJh z2#aAUy2AYwLTGo@kM8a7wx5pYw0W3Ds!e<&@)*P?HoJ>avsIPWAj#xWMQbW;!*kf3 zLFf+t8RypA`>t%p^BG*+IXO6Dh}cm5;PEpmb`0$*1&lqfnGo0 zfOTECDozxcY%csER*)Ck0gyiNle@;l!vkiA&DL=L1(2>Na%8h3@uJB4nt69ON-LbT zP$X4BTr6FuaEg+5s(3_^g=W8FNR>3uDiEDhjU%;B>j_&|#ETOX(vY@DQmrWv?QN7S zOWr34giT{YFQYDb2E-vYK)kHeZtX>ev|1=bIUST)M3qsjUOG|~8E&2`CQo70)`7HH zk;7(97J>r$c;~J{%!x&a-4uwlZavY+z?oKm0D8Z3th#@xt8=Wb<5{G&>xKkeJ|?p1 z2yoDJyyfGf?jaM>i$n^se7c$35UK@Q1}^>RWw0c6s0zyXDDpq-vwlJlJgjVU86uJP zUMkjRFaIENEI6uCKty8NJRAjZ=wSld&jT^*QgMr#Yid~r^LKD5gE{aCX%IJ&=l3y~ zE#H*%0T6V<%KiK`pbIcp!PNng((-XzgNvYuVEYh%0Gle zHUJmz4psR=NYoYh=&yb_rFqxJw1RG_NOQ>#OObj+`xWVICh8v0hT+oFt_CPltgT1{ zXGJ0xkv3-;zEz+|hrv;m0-==WUcj?bB;pn|KkY<{^n@8%XSA(Iy-c(38mTCE$n*S) z)WojsdE}cFns?f$`H}+@U|P&^MvfSR93YvNvcBdt7hl#8W@xZE^+& zll0e#u0}RzUyl__;F1J-S}?}mvEWC1<7+iR%eLv#+`pndTM|WevwkiCfbJmjjs-Cg zFMX<55Rbx5ajbuvf{&5-JLCK#@tcc*Zw~ktkl;ZaZfnPaWqE*ag7Z5zNgvL1Yb5@a zTp0f2pq;hpGEDYJJe3kP692?Iv5eDncpinzIR>(HdQv0tJ8)nCJ|e=iqm1{P15^~njsHOut97b{+b!!%sZ<&+d8Q74R$n7L;7IH(~U zR@fMevdWxr#w&Khb)QYq-=ZkX-2z?fJW~pLL>^qe2K{0%CXrUix`r3M3Fi`v(UatQ zA@m-S#ZfAGHMZ>AXjWP2WghPYjaq5Kxr0P=xpPg9D+2W`h3PNCwZ(jWH5ySs)W_A> zk0iVAniNNgTZ)d;aqTo6RlSVp2h?Cck|vkCrWGac-Q-+qbq~OIn*+;w#fR{9A>5V{ zoD#^Q9yC)jyewoFC?DBWIW4>t&DD3EFg5f~k$|s3{=tR_N&VWK{+JZ-2Ph^oNTxs6 ztfgM>4go)!Lzl&|fE18RDhNGE%jBAxxYY~YA(v7*Me?>ee4pfL1-IN_9^R(Q^_Qt( zh?P=oD9ED;LTRhB*wQ^+&=^xQUxQA~0qqSXf|Y_5HU`NM_VHn~e31?QmXn)OFtN`U zPOGY;BK)d-y{%Ww zhRY7n_XcBZ)jkI2`>J*^G{uSMCa$~0`x=S1Rl8V#YFGKn%ZQZ8_=3V^AuZLWR)($G zPfti-L?fV@`H_}te}S00$=OzIfv(JD@O2p6Mi875NU8RhZ^f~YIiS2@Q-f8z(n%>` z2grMDh*E7AsN~&gT;JJLOMs=?17~?T1b09-pb|2R=qX6GZLRL|wuF}epkgrG*6IzP z#&Tjk3UXV5P_pVQQEBz4K3>rWv}ctFsSoo9!-6gg?e{o_{XtrcE9?(6I!U8t$k?(4 zYd_@_Yd<&l+?2@eK6u9~n!7e=5g)z;wQ`uw7O?HE?s}yDBV>A-EsGVQ*tX@nxe0*% zsYM@}iq71^StxV&w3uUfLD&6B7;vG7k3gmT~Fwt!!zM;&STx z^3e&RF6h~~ocqa0b!AeRuJ3#^R&;{%Q#MIIL3DYbgDXPUzi${XPQz&o0Mmm(Qht=K zAHvAjo1m>%^s^-7Rs9Gyn|2k{_34jwmgGuOab2JLBL?^2T-PS) zmx$h#SxbQxLnv)Q>!#?}{QPBf{Y(>&cowuVihk2i$5DITkHw3*psiGN;@26pUTcT| zHY=YXw%AnJ#t|7m`cTVm)(XFhuN~b@5#zym*ZW#LMG!}Lz==1IaqZR2RZ9{CIq2GS zR06o1cPJ3v@I1u-pk_Lcqk}vN?hg^oNrhC>j%w!rj)7JU?)7b&HOGUQPiW?nB>;2) z@o5E!rXs-;J*1dZntA%F7h7}zF*OKf`GZYi?~X!u%NroBQ-Fg0fPAl+lPMq{fOsMZ zpp$2o7_3tG;6-$t1eITeHNuG+de=}~l;0;EsC zZJHlV9SW`;TG=c{fA<6$DfM+Tra~Np^gJMU5?W@2Paa(FBdv+jf9y@Omm^@2Ym z%qYXOj>xrNt3~Ec_Z!5nXftsMcE5)b+^!tve>Ha%azyN2h~YVUpos7Tg_R#DO#JW~ z5`rHnIr)Lojvpv}_~!^fdZZ5?K-SY+-@ zYyybOnM4}-6qC9-%%e>`;yE~vvq^d?(Peq9=I~NJlGG&kWS_iTr`wi&*t z9(oz$Ke#v&dN~TIj3l-(X^F43dZ0B`^vXn+0#-T94`AfA9v}`@01}|r@T1;xm=Un3 z+7uvOQz#N6QKdO5c?ir!k9Z4!y}=-ggf-=ck=q?+ar6Lw4%C(VAmx-BMjmsR#eRp+ z&Q~;12$zgt19alal<^*-taLcd-89@=5{ODRN}2_pOq1K$&<=S-Z3IJW3VM4RBa@2f z$+!}o=BV*;5;O>a5emfVB|#ZZv&@=!37QAMQU#(g$!RjKx=ynmR889f;sFI(X3K-%v-Rt9612yL?%zwt^Y(N5JU0K0Vk}7^V*~T@}Y0ggc zFi0y8WK}}5PRmkR(UI{c3WbH90QrQH&9iA-uQ<)xn8rw6j>I*d$Sh2f z7dXxD_j{Oq5lG93EJL;#EB0_sLfMlj+H$guYXw5KE}lW!VIWT^VLaK!g{@FN_oK0< z<`#O238dY@O}uK$=E*d!olbMyt7z{L-3wX~qI1wBeXrAOJ|j-@R|l=OpFgG!!gkbY zMujKHn0ElJi=R%DZCq!Z=2vL&QSxcegEq=fr^z<1@0@1N6Y*01YoIOh(`mAe>u0BV zysk&mcY^kwpH7o)T)#Tak}t%wk3TW%g2!v#Xq={4+Nwdug(atF>Vkel3nc+FBsD+R|j8GH9}ltGuJi z3x1X-4YOCx1V(CK1Afu=z={V=mT~nr%x0Liq~8NEe2x_Y380xUt_g-&<>>_W*9USL zg80*dA@dBg3_7GJL=8Z09xR0?!?>0iW}y@-_)i1S-YHFB2Sp;MhM2$L%Y|j$1}bcx9b=X$%_A*rbS(-o?|ko-$cKQc z8jSRtTb@eex*B3uL`}znTLRiC2rj46xJ=Xhv8e@m7J!LCAdZ%tO5=(*%{DWUWD9{< zrBGDE$f-20Qs}MUi)`Bs;$9mdI;T8|0@lPdyM)JaTSWgKXxzS&6&la^aJ4qgwwRK_ zanR-i(3%8S;O~bLjtu&8aFe??eNMQ@ovayY_+ZgXz@;KCsUfTYC23MlZUbW;I*as1 zpf$7UaypJ{n`wSN47@$zKE$SRDYJBN8@h6G%j)58zX#M*AYQgn!u#aBSdm*>4?lMs zw3TpQ@2Al;p4L4E%l?upvQE z;iY*tuIi!Y40O2aQ$d^)4B&Y-xtEOgnEl70eGBxR!I(&zi<7Hs#&xvK8FUhWAA&%f zD#A-snsReBqs{l2M0E!U<8?bN*v9jerre>Lk@&DRr6~n~Vm3%b?ro02f$f6Cy#V4b`2bV5B#7Ll4rAz0 z0Kyh%A|99D%=5{p!aEyNKV2_{nwxebq!~bDDHJzSd3usWy%uWf=#bDK2cl;%N;W%} zldSEb=G;>l3x5HKslg~Ii%}nin&YlR)*C=<3P!Q43f#d_%29^Cs4`BYf#|C0NTNBJO5sWHQX}76T9l(M>>?5Gzu2zp#$;yi z6vVF6>pv{EYm7NHQx%%LmOiS*b`_grfj$5$2$V}k+E@R0wD2|7&F9J`b3or$q%7Kk znik7-{xeD3fiq8(qGi0Cbw9yHZW|@z=HGsLyGHv@(_*}`r<46$ei-!-%dYh`7&*3| zx8gaiz;x97n3K~EscH|wQ*S;`7@)p3(e8)cUJ;tH+K8C_209$eV%kK;2E$E5nZkRd zxJzVQGR&A>Xe>^FjG4Hct0|^WG3}~h{)BJk<#66;lXQ9#8LJm~MaD5BiX>@~&5Jli zMp%e>uZ5S9+8KbpCYHBJ8qdSd_`!&J4S~@3)T4~}5c2}&OA|;7S%R)HTo#(Txih{s zlB8@J!^!Z4n0-*g6G*FwTXltwq(Peuv~nsfjT0ZhH?1{j9f-~`k@PYl=D9cH1SOO< z7_^Z#U3N}K(!fndjSzFiUQ5V)02bRIA?bB-WEbcxWCv(_ZMr373C5)|nuM6wKlDh@ z*8p535T$}nPtsImd}CCZi4j;Wk~+mRnuVCZp*G{dyOBbPxH#~VC2|ePZ5v`f9cOu7 z8Gt$j^2?2+QJ{>R5c4mLpRuGI0G`Mvi5m48-9yat+q^R6M*%Q3SQ0A_D~Ox*%38ZU zA5(>Dmd26~F2@t!3@FDmCaTKuNqm6iLE^W#^w8^w_b+(zmtz`vb`$ab<+wLKJ&C;- zJn*yY^!g9wc=u->(Mq9-SNf>R@qvdug2K>`Kv4*hxUAU)Iq{V^8B%r^H5+3ORjtcP zEiw<_uQlq#@3LBpT!S~yjlp=6=8xx-ragh}i?l8yBM*Vf9b)WUQ(%u6t&2~K{65G% z?UQ(NZyV`YO7K?w1^K~zBtXN8qoHD?yr}TPC+Q{efFNq_ua9hO6{|&lgjZj`fmkr=)xsjC$MGbQU2s%0M#7%M z-g%`0<1Ocqkds{TTWN2bC^>;p)U2IQP-q2U=Z`Lf;Ib+4qQE9i|MdkA557mhk>h)h zqlSs3^q}*Qy1EJ9i|A+~wwh}a#E+-2!D$-nG$-ecHXBU<^0TS>j|GTI)1N6UBVFldLq2I?Z?%gSOQ~v2 zyD+zUFTsa6%VdNw_u4Znp36btDDKzAGDx8Z|8XCcEun`G1T+3>6~ zUI}^=fb|5TRM6?kZ^P>%&-^xg@;C9)-_HO#M=X>Ll116@&gf5I&+hEIw<;jWHrOfT!wX*snu`l|!bHT8AAx8!z>{rsEmFCL-=X0Vd7lM5h*c9B*uP zz&jDoC_jw`^H^$FK@=}88#P_{`eEMUs{(nW@b-6JDs}<9O`8>fefeIGoD8(jMANds z1zqpASeE$Sa8v^m{-R5z+F$JbMOV9D(XCmeGrFWHYWsqMx9+~dBhdlDtNsKEAq6jO zHG+4zO&kZ$i{243Z{cwKck}mP%ThC@5_tg&JC(e!ZQib<@oc>M+Fm@+<|!}kn*u|M z^p6vapoS{x1DK4En)$(xLiObpk7ubdQ`a5}{A|Y$fzHmY06S%%2 zYA&dpk+CdxS3)J24f!5o0)u zrih0ywQMO+Y8G=?=dN-Vv-+yh38P0R;6|w_hV%#DhV|%{ScIv>*}cnZ9)!04o6{4; z%0%6m^eav>B!68|Bv}6fxBuaC4*d-hh$8xbiJ`=mH*{kYT8g1)aq6x}#)hoL)PGzO z%V|wy(Z9zTk68JwW~{}uTq!()8L9wWS20N8f2IMuKsScAvW15-wmWcx6qXBv6#m`M z@nU6~W*qv#W-yuIRe)c!8ASg*`<-ItHHUHPQZi36)?FbC+Xcw`3RYtKl30=5r!1;^ zB+A%$h#uxJ+GG1N!ssr8d9LF5p3S2(WjD?6?_c#T1U}PY?8Q+;lEKLgMb=@|2bWA4 zdeRSrL1(TKG0VLoyKmV^4JkI41tepk;JDWii`}$QJYrompf)!9qz6(+W)F~j-IaX)2A8%pD)#iq~SF$Jq zKye!+`VaUK$y8S}%3v>QsSjZswuXQ_reKleRd!3wY=|9i*{>%-d)B7wHAtt~uaC9= z!LRH;%@)|wlO)Xq=ye+?ORp*-{)zrWMn9P-egka2uAMC?mV7!BeIiseKEd?`v0wY$ zF8n)m0w0Qw|G_POvPm2SlyBl$uAM635i6QGHWo_|1vVgusQ|$Fvluuxa@=j`5haxK zkV~J0i}`pRyg=_?B~(=E^Op-&FZ@}zsJgvg2$JzwOCeUYbm$n}8AxD?7y6}_ zYmXcO;ZeunkA#?P6W~1lZ8+C+y!f6FOO&(kk&jTBUDu5LsN%?md<&Al9zi|dh@GQ4 zHbEo$cHBe-yCzb&trHA7M1R8Ou$IM<75oWprxE;L`ys zU<=&Rjm3xKxyqdw=!pnB>nXs_Vc%L0fBW{hT1!T=0fyv0{#6jN%tM*O%-UV8P7G8 zNp}eXIDa^uT2WJ&o`i43CsGqSt?+Uhm);zZL^7xkPUF>>4^SXeGj^fhijd7A!0(gv zN_zA zU93Hw#wSlDFyLBXh~;Vq%FDk`jrAwDU!+X#3I^7dU2+&Hzo0n4&w6hMB*Oon$mdTW z1By9}Bjsccjtdm|U(z)a4gCUM-6%U)rt7}{tAJ}OV?~$Fx)Fl50A<5P2*{r?lg^>h z4nxvyoym}PC26M^d@igDtyP0awNb#QFagX{<{F`6<`6Xdmx~r zAbl)l{j0{C*FBu|v%t^as)KqH!1#piUmw#USuA7>#S8lMCO3@2l~$z&?yw;S`7k6e3z`#v!74 zuTr4TgDs$PT~6b#MlvC;28QVWDM5r?)oTu_dweC9(L zHeV(4M1nXs`Nq{q)vEZi&z}D)mUQ(s9y{k1&p{gVQa2%wLG*)5Iqo!+U3l+O*SxQI zQCXZSVnsd`u$@4u7|0|bXMcI*LaA=T7lGNZRI#657S96i{$0R>3v|nOApqvwxEL!4 znX(<}KzgW3zVJOsRs)qwaZJCZLY-}6xP&*Q%7vcL4V{AwL1?Z-N$W5fz4kbMV)JR-5vQB@8tr<5uj4#$Dh;Cq3)9->&!uo{-hUKFl{Dzz=}}{zIUB)PkexVd-cYg3z5- zMzeQx6Ta(jp|iA~W}Lz3C%HUEn7@^Je=LKGzb>QN8Xcw?ai%dH8xs*=zfFaAcca2*{iiq1~ z6;>|Gw7N#8o5=2WI!Q#IGp@|QDMrBjn|XNZpUeXhMD`U-T7h|ZWVJ`kvwc+NVLDu_ zJw2%hT6XTIi$oaV0mjA&a?hWm6bQB{D)Ef(LkweYeD`mme6aQDyBJa?vRs;q1f@Zw)hAgn|-3W2VdnJwpi?&@-<7R~C3bL_jeH`DMlB5-+VPov4X5L8h@FK!N5EA$av>#DI`|7l1jaS=# z1SL?uY!W_}I!807T#x5vkO!1hUPtI_8;Nq(L^IBzjy!z>3*AWUQDT1`Kt{-+Yg;# zpR@jlvm&EgYsRVAWO4A{_?X2vz9mYap&7d|97g6o`~!GrZ$R+x!^yr5Sb<56tJ~ON zh4`C*Us-xtuaYx2uDCi0z6syiUeXAMp}|8oYFeNGS!l`mpR0=I)1Z(j>%Wzj0zQNQ zF6$4jAZ}uhR$|+S#W`fI@7Qb)H2GNt3xVyJ!^jKwiZUM}ttPCH)|MMN+&jpIoo|b1 zCk~%611wOlzd|LlAJ|k9{g)U|ns7?(=LiK9e6 zdPinxSO?4kp)II5fYg4_X=6}%<4vo4uc8%Bt+>+Yk0Xmza4-0&*$`w~{H?fPvuT;! zt)Icq?u{lj>UmMKtA_3kM38(Wt;HZ!r*<}2=AIK zwh$Yo56R%q&HJ&jiD2HWE!9&*^is{p#*y$B{>@KmP}YW|U~WnqL$P$ZGgj{|*T zPtqs$M6JKnI6PkZQJocrUjXufk(Vtd;s9glIaRYr1BhNR<063<8^M|Hzh#-9B22od9XI z_$;D#*oJQtx(Q#49@3t##(t(`F%E*x2}>{kY;`_+3)M2Bdl_T4WJqETSka}I;OP2W z8?46E+OVQ~`q5a?D&1+UuN*6yKmf;*4p-r64fMbb>5H>b%d0JW^w*9-SF@7)q5=l* z@)tc~qRqSdG$j@0PSFGNChi6=ZN?>U##z$yl=%q!+lG;cBkag1AEv;QX3z@Yfr=gK$cyyR>O6Yy&Gs0)lK_zA`Q?Nnx@=g-j!{U$Q8F@V~J53gftN zcTdykv{%~7UjKtnK&15D%Sq-62Nzp?mjoo`@y5eAtgc%1y~87(XAuX(H9XNrJ`^uj5HA%e0x2J5KOyr; zd)WzVpsC^ULX`CKd|(7+yH*N71eq=PhUNV8Wf#y#&&c8*aTxw8gG*@PD}sp?)Oh&f z4cXpkPME*hL4P2FXU^$#CJctrFz=bVfDTl|VIYe!_w7C&EkXho809n`kCUAndBAYF zrf~d+1U&yV5)dY|(FY0QJjthm@?e{Ed#Vr**U-#wTgXlI%pXP57=ZKu*J>9h>3=S)%GkEsyAhJ>m!QD4(@ryCqH5GE7+`k0#YiU?I6Aggjyl z-Gpym7Hq{kp+*Ac#!#}(CQMnJ)fi;f0={*5X+@U%8`z3krV(>9N$e+Y@THL#2@ zjo7=%BJ7hu7Me&)pNRKsSn;PLTSDLbcr*bo8OCjVI+Al42w`1k4BdopH_m&dX3HPC zZ11%pk0{D)uV~{d`PJuJdKemtPwOe@E+*Ps09CUEV*k}3y*&Z?hQ!@PM^Qq+t{|Vt zMfe^%52FCgIBZ%&>G_R~QPxfPo?U~0Xqr&~`O?VFb4vVE!82lDgO3TtB5PevI$VcMDY(3&no(O`6f3Ex>|i{$Y%Slk>yJ z5ddmP(aS%7*bd!{aHCh~w=blf?nP{57@18)fQrjMM_xPP5|uB98104{V%`tfIqK?4Z-GsNh1-4IWI=M=973eu`f#$G-%h~K~Qre5NIl)M}QsLEH5Mu`sS z;W{43m@fo}{2{nOA@J3>mLytj*Np>3WKHEbi6~N*1l3eJy>XF}bsyD@+p!LcjPyg` z&@cK7c@w_Z8bU)Hrt!xLsUaOfR|z8H(FRWCNKN=Ax6u^7nsHLKR(T}j{6Iz-58~mJ zoMlT8dJ1;O7U^48V(--+#+(&GY28XY?W1v z{G=(5E;;uv1&n6sg7AC>u~l(WGFxzU6TU{*V)*N>oheOyGXVeHZfB=r`Z^{W6u@Gj zK_uEP3;qVb$eu9)rFyF|vSNamYh&0*shiTHheu)24uO0F{)pyGI6pcP8)_NiTR5sr z5UfmJ!YNRhQdpUo5nA|t(QvT`jNVg!V=M%xKt|TW?5@uxQ!pF*=p%~g_mc+)3gPDzmrqhC3EDV}hOH;8=_#(8daLy7A1 z8z9+{FmedSlQm<-K3lqK%1A?)J`cwkw(n@%s_hZPbRkF#&lvR$9V(SLZj98$qNo3s z3<+@hn-ZsQCp~=C=(tGgVIzRp_A6bHRepK{Qo&b^Q*TQZ9AM*uRZwI-d?t=ZkXx5c z5X%T;s|Z_n`bzZciq0*qtoBJ>W+{!WO-|b^q%8NV>9`r59sWVGD7?xTRW?P0oq;DK ze@o&G!qxN!{Ub5}+_rg%md>PKIglhKUNu~olEj7=u=hK0(T;4it+;-OayzSKCoHwZ z;P*TD?@V;ttZ+E|8O*kYGnm`e4^Pv~y`M_kG7@b1il1Ry=q9q3c*2D5l5QMY6C#$8 zNPAl&?u(Qil3A5AW7*%kXwsgx{Usd;t`Ox1Ik$p`+`$&L^*_f>ncAh$6w&ZkhuN-6 zGBay;At3@J=O2F>a-zI*z;#5=`!gYLIn2kRuseQHAj;hbrRJdeXXU0ZBK3RENcspP zGtlBE!RFUuseWk{V@1JtqKw*=VtG(xF=0xTkuUm?kPvj^rX!*KPxrW`erYJy%v9Hn zq8Qzwxvu+(uX9&9WnRvHrH%p1h$Eqgww4Kf0YLrIvye+SGz8NTfU(iWBVFZy??Yce zkiC_-lITxTP_Stpt2@8|vt>q9gsL-Y4x#@e~XxWN%8t76&V26`?Z z9uZO$=Ijd8tlTQY=&>tVJPmoT9uzTidV;R)j&Dm04v;rn_k(;#Fy0-8Ox z8I=C4@z)E<;x>V)iAL(nN>57)rP9-r@XEkjX+1F72&o`9e0k|#SUIgFE9dtd-RLu2PJ7-?tiky$GlhfKG1{1> zMY2Nu@-KdH@B&!RM;X_llhm3_Kl|XAu?3UCTiq8{G|x0zO_Y0P4+U$Lal4{LTRa5V z&MG4txb8)6m-*_!(f8+0`cEGwkd6GlQ-b&&&5Y*6Nj8#G zXcP|-B~6Ov53a444n7|)&jG`V%^g7GqSH-C{c0L*%$^{JN%Q_C80-h-qQzPz+Gsjg zvR?fcR?hnX)`)1s?3%=RU-Ik!5P4Rc#NNJSv1n1T`AxAP*e=V5OQS5Ge?OVa^31Q3 zMPTR`6HT07zJaLNmEl(2Sz>J%YBAC_(hDt3aolNZRmjuy+NIzW?n*ywHteqAsGO?Ow8d2zhZz6pK z4t@w-;VArd5|h{FBQy6HhjBJZoNFh9qFq(?3 zHO*qM)t7jW1ayZZ-$a9I<3VZ_LoTO?L^o0JIaFK?-XRH(GU+;z=q3shvcV1_g&U~XcQIMLxFKJD)lZ8nNx;7=`FCaYqQ8!8wlZ`Wq0Ky;?^HP zmsg0&<}pIN@grQTNJJmB*Va{4h)nYaA?nwKYfXtbkHWvMR$<$hdS;>TftYayuJtA2 z8!R4M*Fec=WL74`fD(|=SRx`4@!Uiqnwjkg(eWtwnoGnV_~KsILLu6i&l6%}bMUp5 zh|cJJUe`_`I+_azp;I_INyPNu@tms=-OSyDc*70X?h^4LvTR)sg?P$5M~K5XEM{FV ziKti~h^G~zpQ$7H8+F50FzcR?h;MOo~lu9U@K)x^5#=DO4oK%HA=iLQ#DEGxejAcP9sh$uCqeBuq!@89!E_E?EzV+UxH=nzebCygk=_?ct1_=Yqc1n zx?JK#m-Alx2=Sg?3>^LQG)D@#zpodohjS(zvzwxTza>_{?WT6&Q6Z@K<8ht!=)9@b zK>$&QiO`$c|03ig%4rcCpt7-09KpZULN`TgT^V03piE8!)^q~t+S#$Fnm3K{Q#!zmKGLCU7Wj?H*W?1AUaA%#h(JM2d| zjGH3F+eUnGJg05%CB&J$a-r+bBPn-18zu58SOU{W3XxYij4Wwr>L%Ffyej&s#mm;ZUup}<8I=`f){)B|etHCd2Q}2|(OD4ZmO7{<`a&*vjNqzIraFO>&A?jayDz!O6n3v6= z?w>k+99|mn%iz>c$Ka)L#1sIArS`yL(!9qCG(cjFO5HO9FHK|m;bly!Y2u|>Xda}E zP3_p*A@W+p?8VEZ)MFd5^-BAwIS?>2b#52Ha^gM#WnL<^obo!xe}R`JsYOTOr4t8d zRqBxE@sb-xS-ml}3ufQvbq*g4MckemGtMjWx^URuOI?ZO$a&pDzkz_gB5@C_{}z+8 zr13ro*xFXpNSTfyTV!*paRxluy3!Ft&gaRQZla(Ux!7PkXxl#3A}?UqA6z=$NG~jq z8;&nJjo5}*Axh7U%hZCfEmBxD;viQEZY;7uJLKRB?s0PFoAk{?%%!1yTR+noFx2Lg zp=_`Q`n+wsMt;vyBoZ(W?MdqP*_z;pqywi2u_ZsEaalxU>na(p!!}iXr$wP9w{?Sb zZ+xXBUb<--rRrS*aSNK>bb1v9Ny{5|M1F6rqs5SW@ryulqU3`%?(i5;HDzsHlTdUM z1q)NE?m^+*_9uJuq!PeS0e+Fd#_5!tTV?Pj5i}q<&!&L(j-)NNX`;crRuDdu6Y6~> zoaNf7<*o=upCd99|CCza6O8l1LNs>t0pe3B`W{h9H)Jk0SWOvmh~=mJWVuRidKCrx z0P4dg;9_fUM`RrS$%{t!K{l96AzjLn`VpPeQH4}zaXv>XBn@;#-YG66%_5`2)S$*4p2+u&j7+_s`jUwA+Ikz~*-GW}geXQLtW zaxInK%^a-HZ2!rEcEHl}ttpPk7Wk)PawCA4zMwXUJCo>-g6h6vCkP3~Dn=r2kE1_I zhO$KF^pIqM-&TB};z!)g6gRzzbS9sTqd#Kmr?@5ghq2(^n?!%)FkNv=;Y|J@j{b;y zo#K|{;-$fTF^T?&`;g+6!kK(Nj{b=IC&kTV-$}G#wieKm=$~9-t_DV2YQF@zv^WBh zkctGN2Wdq(*%#?!$K~uqE12eJOv*AoLM!+RoNwDCo##80I+~m! zV(Oc7@bSchevnoHmzvHHb}lE37t=aZ%G<%>~4=_Tgzn6`J4#LIY}i_7_>3_X)N8a2@;zYfmZY?2K9 zQSJ9a2!2n@IZv^`BO>OgPPGEQ0^np|kYg(fU7P{a?X<)jGI| z^e7anqFs|(R}j36=R=an+wEp|>kdlK;>*yH^fkHCDik?#(rkDWka{Joei{3EKqH$i zoQU_n32RY(@_Xw}cps4PFeLDMR2trgBn*kN-p3LCxda?!#`HuwGofguN)MNTGNvQ! zeAr{r%9WZSh>1fY0j^T19Egc@G(*v}yJZ4$BmmORhH&<((F@UTXf1q? zWW+fmTsLv-R#|*JWO$u!M(N&uWAIwm>HPo|f)e?Qy61%@835fL~hy+B%|h*d)D^(|i(i(j4t0(2m=5S(nKjGrK#@PIXTc*zn;ov;}%IL#$pEYBwaFpEHxUKWUV)EtF#Q_&J( zN$UaFo=?&mk~AKtAmB@mqj3U&ukuOa?NM<8Yfe2O_*lYQ0Q_l#0&HD3#FK_Xgqviw zYng3n&#+qo+C#QX__Zgi52Bq7^=gXCIh68SX;0lpFbxjQbc!sKbRHd$d-*|o%-(_8 zGYkcUklGyF77)vLl9pj>&)p#HNgIUiwFtczw}T3;v?sPNdKba3{Q%leMCY(6?WusO zjSjWdoWG$G#3chLGoJTjh4x&YX$dI-K!y$SYfmAxm{>?7&|2GcO9gqSJZR4pw2wGm z{Q#iDbva%-J^8hV=4<%1r$jN!-!}kSM=TV0$)dF9TjT?K{t*Dj2}J2-fo$!$JIs=F z34q`7NwT$P4eT9Dav`G=a0N=TwdV$!s+4_NB>-yJAmP0^50i##IQ4Ruu}@kDxc9^* zPccITWxy+Kcc4zRXBdTbt8MEU`TCN!dWsNc3q)soxzIPk?J-N@#WQOJ(!{e2eHprN z4~P2%$4E3ewpU7PjnpEb?nrBT$`n+GocvwZA)n8Yb;xVhf5cq*UK;;ZN5WCnAy2?> znm}rTQ=feds%FxT_^PAmRCHui+^KS&H#{qPJVaQ(m~ zmyJKgO0;`qxqO0ON za}nt*9fz3#<6kR6XQcKx;5o$7j?s4U9mi_>MD!xNkxddgo_919TZF)ZAKPSm8gEE2=Tp5!aOXK)Sz zrGQojfT{$dcet@Gdsp-(<&j9VY6s$c<^e~|{fO<8-<=p#ap!Vnu(D?}G-Zn`;Ky;-& zr*{QvPxn31jMQcUKA%{QGTPRjLyWeyXWkqPD+8pxkK4xzt+Z$LG>7;U{MxsmohLen zO=(ZUB!?&fXHEM9oq)KQo=W_t;kX*MZi%)v~YfRYH(eUV^=Th(E0hZNCZwTMFT}4Q#PhmVu>?6FD`D z0w~fdwI*$BKOGH9N8`ZYgzA|@n3Z_993*eotFzFnj;-_aW)_}GrFKulPk^OlhgR@EGyi? zsyMBWu_0+L8CokguRZ0K?^c#2_qN`xiuA7TV7gtA&PK4@yWp1{z4s7AyCN+F@9l~- z9?xlezHxCr7es*Ve0~!WxFV(5hcabo*@tNN!nAm43ft)ThPA(4}kntJ{z-R(dymWf;c|XWsh}*# z>LwV_hx2xuq+cMqvLLAi11*Rbhrke0JBQnk#B!O@wgpLGv~58urYAEf$wO*CcU>QhJKYPyW|zsUOEga4`pa8re=FE(a*v9>0z!Y6$I z4n0y9WP2G*l!82cC|vob3RgvZ)&&->gwnx!b|f9!H{6T#zh@^*cMlPw4ZP^39<+z(k0TE$9jkV8*s{6Ee5|I_+UeiD%!fEN|X zyph@=x$M<8lcTUtUZ4f}bDu@G zB02tm)uOUGgj*w6?kt4ewjd)BMB9Q4f%morc^=PcQNyT>JUn_XF<2k-T_J%}h8FzE zl%chBqFvgfbdVB0$G!*;upqShA>d=a_5}0|pM9oIu z--4_f6KFwN;DjDRYQ8Xp6qmCJqiqYafYG)E8U9v0gS6&AwozzhK~C+C6OV&m>kryc zqI1}k1?d7hWw|yJwAXEVJ`3{77nYDM0PM0sehZQaIt%#>v~xB+p9T2@t74r1$+jRny2lI3KJ9$~KDI&9f{;$I1))81gqvjLe)j(u`|7|b zj`#hUy}jfta*<2!q69)N3c(TrBv>FMxCV!y!QHJCcM7FQftI#ZXlbE9aWC#IP6en# zp;(a?_&x8;-ChFp^Zos?GV?s|JG$@8&d$tYrQ%V3YK{+n`rWk5b~8*Y|D>;pHBGNH z>Lwz~n*RK;4{Ms?z3h>h1p^Mlq0Rurk_A%DJ1ic5#e#2!8&Q4@Mx&p2{wV~jdzV>a z5fiqW0?v0+Txf0YQ%05D4^Y?uAj1eRo&1O@hFnG*661hw8S0xGLqeehDW5O5RjI* zBWEI*1%e?s1X4V4NxdRP;>rN7=%#3i^TskvN?ZdV%?KS#s@;j(e>8&8@78()8R(I9 zC2swJ2-Y6xbRcszS&=yUc^k9tL0p|}v9gA5NwsVSBYc{lgKa4nD0gbR^ci+KJgn*) zV>&lksz1QczWa$ZyDJC>=W*Y8*wA|8NnAD2Y2dZP@hq@qQ@iNy?h z0tts+{}uLKqA(h|CB%nLYO6#T{jugpp%aVQnuu6kRP|j}$#=F1ZV9}e71>G0NO_lTHnDEO*aAE37muDukQlj+Xb)DvkGco{{{wSYf+#Y+r|Wz0V|QT1x)n;( ziC7RtCl<5)Vz9`@p3j2Bw~0hQSM>g~a4)Y!#-qwzJR+C%wEsUPO0P#4h}GF?fg%g$ z{$CO)v#=L$jdXo^?1t=zF9*Moz``pI;b?ITzl|l|7VdRhe{=dr&bql7#S$Jw(_d-w zLy>7bF;_Ey{mX3^aHRlfPJ{=S@rvm-5hSiewZoOtM)mVW(ipDz;Dec!u)s|Lm_k%4 zkg+j}|I8VUgKEj_Pp@Fo$Mqu5jeU4YI?L zXFvh7#&N^QQC~Qk#5J1(M?>Lg8n+r5x3#fwG>iLmARJAFqj_A^csQC1M~k@T?ciuD z94+Hc;4|UYcEZsrt`TYLC>;55t4LdC;bIj#Cg--`*XI=f*E~$pPE~vaTLq&$wD3Bgh zw^U={f>c+Kb~e%f1F7B-cXi)ZB9T?kX=d{S@9r7g$#&UnbdFNF*_3kT=_Y?B|g>y>e3C%m( zjBoP0gE-ZJN93zTNKEgNr&IuJx{fC3?EF#ZOBo#;3@$}S8l_yv1ZdamL2>}ssbymig}k^-6C>QS@w^Zb-HJ$n3Xz-ATggz80aBXvvc>4 zf^58${ooaZ?YslNr0+bUJ4hfU?#1NH&|RgBeWLhWCW@#q*ZAc;_*Ii-u$^BbSC;ZG z5t<-amfg<+pJ8H-W(cadY&Zr{Ii>I*KIKA`;&93#56rimRriq5P09RO~i!|ny}?bt1B^!+kkT~YA!C+4AEq+ z7dhEII)gJtOj)H#ULKrfpO^z^yl4gsibGC)D{L*b*W^C~{&9!UpWkZ{YYkZ3%;|9W z_|cLJJY-+ih09k*;`@}TmT(RU)xZU_6Y5`KZS5W`Aq8N`AWT6rKWA>c*0pU4+> z!tG&k+Zj(s;J0q-Z8tTLg&Po=ea!`jnq!k^T@cBz&+xb2Oy05-25)OrYSaup7 z_I+Q8N?k$o%`L#xqJ0fzq2_tK+jNC@W9eO>d1qIh4euL5#|X_g_Zu{3`>M#gIoIP| zyDhxSNgZq4-U{8ZK#K1=UJw(-%I%{H^A~(eb?i78PCH&|>AoNCW2p9*{;re-_vw0Y zIt?Dh%6%(f?Sgq7`_d#~u126c7Wfa+n0pWAcAr6Kr6+HVo4|6v zr7Wu|vuv;CeV-qk%-H@i;$hj&<1y83UkBYa!ey#@qe|~vF7p48$9Fp(hJ7oAZy-Kn z%DOBBw)3bYU_QFi}a}cESA_VOpn>1eGMqO@(p7H%}3t_sE;FN(LS@2GI$cPA8gj7?goi;FV-FrC)(q ziP~ZDM4W@m)i(&b37Zs1FK1SI+1SMC9QY=}u+lf%AlhmnC?OT6G&&JbiP%AO3ao|f z56s4#tiZG;I5nixG&-Ha$(j@f1wQ#8N8%JncY*C--~*rH(X!?O4eW`#AaVwFA*VM{ z8j;xfmbeqAF$5^2Wn*guPMU-06kfL*=69A3OGNU+6JE!@H)S0k5%*JgWXHnFd@T#@ z5Ip5Vj(NCa*$XV-rio=g*EQ&E0li63g#dCqCP-F`IMTJuO45GeZr@7O#SRjuOcb?&8)ajvU>pxua=JcWP2pt*Tm^yioFuu$F;|Os{IM^S60D&IY$8b4@SFmu)HII z?w1b2eFX=Jg>OQ52QzH_h<_ZVda!CBB_VtTvfyAfdH;KF+-J)Bjl{1TTA4V@ z4|k{`m))_4q7!$hk#rhZ`Iev^YRvUbLCxJ%8;$}VKyn}9P%_*n7IOr%_708a);+kA z_i=(KPvuY0)*%JhNCnT?p>aIm8m@Ifxce&7F1$1ydW~B*;Yyl9BB6;U#4BQU+HfmitU8tkgi8!LiMLOiOFF73qhs^0D;t0Fy;bg0R*h=j^ z@$9c8TqH}>(%e(kA^>q=E;bP+qL(|mGbFl7?=$2rIuJr6yLmRS)nYNn-C~d{M!B@x z=50sGuB5G_rcFdf z;*}&$(&GvDL^ft3B^{p&=}HnSHF>FD;Htz)Y?mf4aeGI|V-+A>N&W{-UWPC5CK4z4 z=bF60!w*idvBT-ILifXn(BT|$Uv0*48>@bJIXB#iM&aMP?#m9p%Yz=m!K(h+AH4T@ z5a}{hov=TM9sW?d{Hty&0QL#@H-i~k^=1dSKIh_PHoEGLPH=7HA^!q%RyCm39Nx@D zvs`uuUp2_ac8cGq^WA(0zeZsQr?Lmmy?t%ifvyRv72gNvW5n*Xbnb`q0GtqkJZ3BwNjSSkOk5*U#=dd1H2aKpOaz$2R<7|7#6*;yZJ>Kn%dVS^5q z?j$&wyc)+_cf!04g2zN0YR+y{f%fRZLooJ8cdRXib^S>sy9~lFT0qNp>+uPl?*LeN zJceuCfcy(5vr;mutwI~BcKenGRY%m5$kpvUw>~VufCxOw<4`+OtVNyMuk`KMklhmf z4OXrBd=h=agGQ4mxw<{&)?1}8{}~?rNVNM4qCrxR^I;Y2zt%WAXj@5z&C>ZdzHQZg z3VywzeUNE?#WuN#`$Mnc{!XcuxM%S?3mm!GKYpq(ot3EROB3Ord=DR)8~3#y$FSiA z_+A%*LP8lpV##+2o@$N2Vv~n}6a=Ss2O_f|F%6Gy<9QJW$3(KB@O1!=byK8g;i*n)(O8b`6cXPpMkD83QcY_##;QM5aWzpMBz*diMDtXr}*X0nZ4h5X+*)asB@=uVz86QCq~)!QJ(#gh#fwGuyk>DIaug@Xi~ z#$aQ&HsM4=0$O6*&u*2hO?x`n#?KXOUWWO;IE<@bm%j#3znzIuW|}iE|MHQ1s(C2u zmS}z4#LoJFIEKj0esHBiM1@kJh*%h}c60p|W?@+e6JFNch^Vto0|)ajj1IEJB2B|) zI9Or4RUeBeK-+E{YA)#z*%5E*0ywrZ#a?G6aMWw#LRn$e2)bvw#O!TwRVsA=A3PUF z>KTVh3l8Jluk0d8>T>uhAL8W6Zf0Ew;o7wp+L*H-D$rUQL;sX~#uJj);lE!A)>#Mf z1+zBvw8o*fxsB*_rBflD`r*XlUq2Sg3QA>=9JdlJUWcd_l#ZjQa%*q$3H<;*v9S~y zw~mER?EMSy$x4iCg;YTe{|KIIafmQj+>KrcKD!hN`^QcFE`$}-iKF16V@F|1UO|OY zSMVY9QBTZl{sWW;IE)kC3zG>Iu@uSBiqANynVnJS#@eMrMNMN)zfbTfwPSkFXrwyv z2fQY9%!>IkOzy7^`FFbx4~D0> z+=Z%@n@j?c6e>@J%2^SQbV|4%>P&8csf_$k7U(RJa;Q+kamNBG&A# z9;99tkiN#x(e{$eDi3mF6p&HI%NR8vWV;8skOX9^@yn_bIp;wZP6e{oxYkD^e|eDK zk8kFMln-V=J9>)<7NoK$~VN>B9U>Sfs1VKAEd6n_!AccWceVQSR^(H@A$RFsq0 zy{>5@GF>#VIX5;&vQ}e)e=Hx#B9cHHlNBOGwFg_+CMsu^a*0JzSYxip{!2R&C>GXt zFc>d{wS9^^tdwjo5!G^CrTDU!#A&$Y1#uBy5!I9-==&k`_by8DOD~C6-1SoEnb_gh zmC{)3;@0~~Fk9ka!O2Ba`jS<7!I-d=e)uy<&$7mV&a!n(CvobF(OZFXYZm$nDSOZ} z?^VH=^?9T)&23*n@$DeuKeUOA|5Bn9%e~l_WJ;^E1e&=8zIf@k!MWZ@}AIHDAUffU6rtJ=?) z_}Aj7(V7#*$RmpcC>to=3dNMAe1c`|h~$k%@{9cdq7+Lb)esp;su(O~GB#*}z}y8g zRqwteKy^Y2h%F~mqRc`dxq%co^O6A70x3X+&$6mxYqK6xmEi4-u<2QuqG_avQ4z|{ zAC;v@EET9M)v5gHUn0}jV8bnXx{9Yoq+3)_k$Co)_Z`rOorsAzoQki0Ct}Kf4V{m9 z=bW!{;}BvDTXg+4DOmWQ4dCzY#A|cE&WxQ6GA~B@qt6B>kze%L*rYY$ zS}tjmxMn5o5!d=j$HcXD(s^<1o^%aY2*hwHP=-r^s$2@x<5Hj{mjYcl2{_9g$4sG< zWeqBdBAqfyfL=58mb0u&AZAgEM*I(>ecUAt<-r; z4yuTWj}V5K_T;jZcK8=zgMQT(zl9kyAPj$ruzRS3)o+(Jutpf$oQ8?tk|27mvJ*Pw zXb5XikoI;`s32^4iLiK!h{IaU-T1izCVol+b$R8RVaikd9~*Jl_Enf5{PPk)q@rEg z!=FQ0J|Y>8l(|zucEOd3f;8X8_$d$w)m|cqAPUktRYprw39}6)LByfTpQIsoBH~bx zmUljk)dXR@B%Gm0Cfp)|NJYD}rq69c!#gi(n93)Q456I*bx^2Kff#zkSz&|8!SP5~ z_k47U&ik4FfxPoN2ICFq0}Qv|h?~_7Z&yLa8Y(Iwwzk7ppYv8R%qDx<2O%JDULCnQlaRAYdAZ=~BZqf2NJC z1oX)Z@N;}J>{3&I+Y-ul0y^x5S*GXBzi+>Y;>d zi5Ixcnxb-J!QK`8^?+Z>FvMuYsx}%I0g>!IbLz*yvOqddBb4Gd&^HBvYP?6&8`trO zUx?*H+(g{d`{awn+HuuDMCO)7m2hY7H>fY3%+0@txqVQ>KgUUCE)lfMeeZo6+Xv_{ z4)q5QQeA%^;~n3@_cu49{3Kvk=FaOB#{LE5ji7~~3wC90!c{v9160}#7s*@^0V^fW z$u}W$k-83`3G;;e5)DP>Qswky$&k&klK`g{AwGLWDb#+Gri3F)YQY$|v!ofG5Koqz zeJ6}9gc`mVCz&Ng(6Xfe%`kQj&=nkNM-Nh6Ux-C$f5G=3H==YEuq#Ur)Uz``1na;d z1YNKzOZMWglPQ2IyWt{PA|ha=#5q?ymer^bG?68jv}!~h6z0sW6D8`|jF$=2M`F%# zGo^+#FB7Pz$DH?0W1j(J=C^JF?tg76a-9sPmg^~&_w1~GoUvtwG|vyfM;)ZEoT8t^ zQs$3_aV@P6z>j~)JloP=By1(~9A})fFhp42G)X98p8Jt`F0F4JD(!dvON6&{Fwb$u zH)ezg>pM~sj;}@8$zhXbGhrG_>(f4ygrzSLR_}1I+=<48Upj=v+f9V#o>a(rHz^G| zgs|Kp!M$xEVxr1b$tuzmeMxOqoUztzn=s-EtexwD6um!|(vsS$()xeU*(WPs@+HDn zFFVT}ZB$D;gz2b9gyzhKB9ULJsH4bI9#V5tTEF&QsIcU{q?#gaL2YUaO6xncm4sr}& zRs2Sn=G$3BwxM?BE+aEU4D^n#reLnvfWnR}VrYopIb=fuK@sDFOJQt}cY|3&oI@zs#PwB{gRmFiaW_FJ zNg+tWZhTG6K@isg-qHw8BJ>m*j^Mi?#yxda6y}RV#7;@}C^*XXrP1Q?QUEIyBPhwx z$1G$xB98N*&z6O;a**Qog7lN>qNNEC(|J{T)JgF{3@=89!lGLrI$n@ZevY03nlo<=@T+|ppWU92nM(?D3Dk*bP>Hyww?sH$R##QG)r zRLnmEVe<>5)l;x~*Qi)3e(sQ@Gay`WlbGew6&s82RWMy6L{xZw7uX{We}hj)6e89} zcS}T72}M2jY0QrOg-dOAc)7b$kcUD}d?v1lqF>Lqp_k#W)Co_4MExxMxK`N+ALm^R z7!jo8>Yt8uuns^Aai~ zXzpeyq5%6)0V+L$?vxF4QT2j41hnxlP^lP|o{5iG6|wHNW2DBdx<3|`lLjJ`VRcpxG|S?6T;;b zedezq>;ZU8BS`Bd2$_n$<1Ta*t^xd0Bh(Q=yi*QOR*s^dTml+&)nWf|h~Q;Kk(RBo z5>UBX2+M;AcY;vfO>)@`Vg5QO0b3V_Nm2t4@->o-i!gtE6q6bMU*`P)j?@UG*k%3( zE2eMFa%Bl$0KyU?H5RxqZzB{F4|W-yFM)0G;KFi^RZQguyX?(3z`l3mF3TlI6BSd9 z2$zyaAm~sqA`n-4gn65)n9}}rX^H^Bsgb1R5~Nv*>C-}&rkWr$&`81tzNrYSGheZu zNDCEKr;D3_+R+4s5zc?Y<5M>DKIXSt`vbhhlS0B+RCR6$pZCV|&>is(&7)$@C}MD#o8!koi5qXeTmgoI&ic=DVhIjRi?jm}VfxW5W!r1m9J(Bd9 z{?^;bg-<}(Sd0W~MfOa;&U9@lOs>B|X*>oT#1!yr{E{Hxuo(Z51(w;uv5+fJbs~H7#KQsQtg-VX2l(?WbUVQCRQ zr<4HC)dVW!W?73l>Sr=f@Wr2~@(7g`$fvcaXv#TiBB|(D&W($qEb69DHdcgo0C6$L z2f35G(4LfzT$2{Us994cPdC9*c8?xyVpo04!|Et(#86CpxfX43ZpXw>el5nZ0&b71^xHd*{K^^*kROr3`?(+ar5P@fACcj=p*i_w8g7vvkuj=xy|nLY zgej)&T+22mXJZKn?-dxyekx^*C>g~zz{BWwK+dJ|%tKR1FDCj#_kzlwYbwU(;H_84 z`ST{ldpEweHGq$ry^Cnw59DI{d5Yf@p`HE<_fx8o;r9zd`)_rl#7r%ZcE$>SsvJxz zqknPwQ~Xx*#4(KhTHmkm*H*!c060HfgjVXR({Kb1QI1y=>d?-4#(xIO$YPuVpSJnc zFvFi3C89d*GgyRD>U*ihA7Qw)=*QzbDQTe{>6o*@b5s~;DX&o?s#}Xw%=M&}mKr6Y z&Mr5FKD)A;yws5}1}!p>i0Vg+!7TdP{s1cB=xbjGP^m^=I}ku68GY?w0F_?!wL<|^ zV$s(Q2T<0Jn1VX;n~$N!&rxas6JYVp~nnwxuIP)cO9dE8E_!G>Z2={AdQv~UI z-3&8`>m>6O;Xm2@i?~iP*AV=vW~$}UH>R0wf3whmQ(HUATZ`Dd`X@TY3wRH?e}Ms;lI@bk@~%Kpu_k*sB;F|D?&j(D0qL#C{- zWvSrn&|LUy+ijpNqDm z9F(K46x(W~nMuRDMqu2-F1fWFpXF<_MURgxHvj2(b?x4b{~od(+lh2H@0 zj>e76z)zO)?wLA`lkdpfgyATE95NoUaW#Bd-Xqg){M?$}>v=q&3T{~OrMSk^CboI| zE1pLV@z{->%q;JzuWvB^%nlxJgHtEB0CRk>6}hG3#xY$#QdM1hafZZxp%kv$PDswXT}Jw-+2UW<8pb zHoSSSbH5oFDmeU7eMP03iWr&3Aep42jKHP?N+-U&}M?~5$v`Xq3c5h zdILk8rw7sfAL1|b7b zbr0;a7n|@#B|>TqsH+=Rp8kory6r^-8Y|6S%nHTh10J7&(>%9;$6mC;Ci;9e{68g3 zWQk@k43~lJh5vCkrqG>cFP;>$7jIE>{TJ}R-E5D&5N*E4UXb%ed*Lz>q6`wY24Ldz zdAxQCGGr%yn+0&!#X@ zknfYm4Op>PWVqUK8KKsW^eQbW2VX&X&kq(aH}df3lJbX}Qe?>bgIg%)+L6DmkTu2! zfs24V6fMFmf4~TOaAC!w8l$#StlbYTtXSBmXx?f}^1 zU=Aa;h1i-EyLS;~GYkH2Xqq%DcI*PMkKq5M8&l}cW5uYubBN-C z6`TAI%IjbFTaX%0c~Q*&v%I7gqaw;**n&(ttXN_bWCnS;GXqxame$ByBt90WX~Yhr2+*C!icu2(%ZgpVK8}k>!A_hG7gwNJv4VkNET|z! z*FpH*O>*T0tk{Mu6rKSI3B}>b3yS!E=7qFkrJ$^~cPQn>$KG9=y=28||Bakz4Xqt< zsD+dhZY#zY$;qL71fX#Q4<^`c#lmtVya>qK8tS%Ump*ijOKb$RO@rN5OnelJ9WzVx zdQRj2jYQ#Bar#x`x~*7xo=X*LsxU7cG9K<;kA0O3jsle6hLy1tSGN`GSk#J*SZotK z-WcSTZUK)Kiye(R+z0-H2oqVNS+U4bz^1`}fg4lkPP1awDIl%avp5wtZxitCZnnpY ziFXc<6(i?=STTaQ!xDf#Sr9kPOG8x%L_wCsA*ur5BAT9wsw|<_UKoz^`o+glyfwgV z^1s-^hLD;fMz1W&!Fenb$%WB70O=H$xtgZPNzO}1BN;u9ElP2jtDA3zim9yIU#4h5 zvHWf}YFlBhPBcfgr10END9qIdKOmWRApa1DI*|%fGgnl|Tr*e3e?tX{M?p<24s{l> zHFLH0D-=Q%_}3szXwuBpNQ@xxR`4%yV+!4Q%oP=`$6V#NLv~C7VV0XtBcRA=m@D6C zbO+YJe;W=@xlnjT%0)}Q$Z2V=D0B0B&BPcznX5~9ZD~ke?#zI>>QW1(_>95?sLuCf z2Fw-ZkH=gE=7$OrPXaTI*vlvabmuWwlthoYdM}j}xI0~?(fP{;oA9~#N$U3_zb{2ZeVc69Q-_ORqWn;G@1H?Oy zZdAr$JG&JnTn61JZ*RDw#n%#l-KfG%V3rWBAYC#kxfL5c;x8L}*ivCnaj3m_BXcAY zAN=f;gIN(mA`XGb?yMNFqRF=Yzm!ogZ#*CUAmq$_dl9)y_@Q#f6s zoq_c5pvHDUvl8=K$Z@doKqh<8!qJS~s-5^bK3h^y%YnS7p(n5{IN;{irKLhyKt6s0 zph3*K0*UEvK^z?c5ngT4K1~~fEqfga#-H+G!AE@IV2%`@p4TysdKXfUNOCAeH(@wI z<$XFwp)2MCZYT}`$uUYPn(pKO3{Q13uyi-Bj3@b6`Uv32^11nrgH3`5ZvwnsaZbVo zj4e9q_~=3q#z0_WG<-Vg7}=xS5awv;Q|h>bk;g*7ONlavP>e&5=*S!`tb&{T1-{le z@_qK*b+GN=>~*VR$@GcG(b1>TUzh;^-zyq|v5nv1VAfMe_7h(17&a1gY%r3atqnF^ z)1|?OKHXt0p}jA%V^d6zAr3h>=PyJ{x5gewIMfqhiAurd>O`!+O4Z>V`{ov;T=D0m zvMG4&HSRa0cAjo9rEs%j*#hJu2C9iS3Y;0lqjV`3NUzurHe`sUX;mRYaFDL<9DYX);m~3b5 z0d#SL_(ZxALX^(~M9hBV&KeCu*!nvZHAbrW9Gn)C0C}=S%I%vb=D5lo?=OMz^XG!I z9{6UB^M-B-mDo?*r`@lp+=6k6P>PQ`734dS``@%P>s6BG>DcDdaf2JXj71}`i(>u} z1<1;G!*Jperj(-XL00p(vDW=|8S`r14$B+k~vJinqyfXpm5(tA?!iV_-DA6lV%Z8VSC8&QuTei4Hb9w@KK;Sd!!?k_c9FMz>!Wdli}T~8dkZw z)c66AHKg&l7T&#T(e?@w-3R2bhPtPdV~-fp9{%negj6H^C)_*N;A;_uRILL-qIhT_ zEkLeQ7Wn}Q#-W}s8q%ORi6#Rnuc7XckS5YD=9J!RBIcBqr@tQG@2}dat~z(Lw<6fB zhA|Ko9|G=e^OKX7T_30NuVF#vgG9qxH{n6DU;C3Nuv#Kg_|%ljy3e3bPURT+V+QV4 z^xyA)ts1_kDA5yl|Dali9GUgI^%IX=Xpx8SOEBoNb+#i-hF8YP+3hU4 z&i8s4zJ-{~*Fs-f4TUNns_4Af-{Fpd2aRk4v_1e27~LwFfkX((HL{0sVZIxE z#MeR_EE5QRfaF)isl4NPj2DGFzOJNaA3%<3vnCG1r}M#3Vw9l=1V>E7x7bG|Ot(1s zK8gw7kN*|41)#Qu8Bl8C4xhw&k7X>Qjrj>&&g%0}9W&Y+K5$ECbc8hdW^}Ur3JbP` zq&txG1R-r5jLQKf6b*er2uV4QHXs$<48Or4B9PGoD#$mZr)4=lty}@1_9YejaEGe8 z36}$kjaFMZNQy;g^a~=r(HZ@NdV(08F(8OY(HR4ShQrW)J#JO@ldOZ87a z1~eMpQ{0e3t%3`GN8fuX+Ph`I)@XQX+$rQ_@f8*sS;jm&E#y(8#!vJ=o`l44z~2>@ zASa98^(CS^GjNJWVuSw6&oS!!9I#)3D|&J=tq4P^-K9T<*_%o!5GoWW3AK`RME{Nx zsi_A-bB#3EliIWTE|{366apKf;UfqaeaDQ4K|?P)*jRWdvw<(xI6{ZyJPSJfn@w`o z0pG51gdWGl3=7Nf=K3#gBerJ%e&;609)P2M1}cOJQ{>ts&G!I4a}yL1iX?<_(`#GN z=L+hAtx<7^GE-y_LPHyF%4r7;6#-V)2qMFzhA!N+@GEF&39z$95Sb+jeYt5`G;(V= zz=;|`l)WSTJs*}aotwV?9s_ub0j_Wpn8aprlM&xo_y+jza$~MKG0b3M8FTH`se~;n zTI*QGd>%R%dp#48|ANy^l9)*O9{<%8FP1UKPCFR6$Zzn_wAFUO;elNhX2&6`tYy(; zs?FSVBG&cItvs;GgbQVkU(jX9SjvD$+C(2=)&tz35u^s1w3hKiF`Zn2y!{5?MK^)P$F8Jo z4G~X^rOh_ZGMLV>`$(wZU~US=zi_y6W#pmfJae*?mDC9RAf%ka|$ybYJZ5Z|-`k~B*`+c3{!Ijpr3p6lz} zh)qomS$6M>FkOpvt1u2=Fl0r9nc%EP4OmuGNDUusSftEbXku9<%GYa)&{psc_bn_d z#``MiXR+lM`?9P!>kqfW#O6M{9Hi56s4c`ZEMTW~c(`jKXA?lJ2<|B0rY*5vu&i$^ z#s{fx@&SN`d87qg(YMMf8>8CD=K^|DlO8#!TX&X~<@+4-@2LDf1M;ONEYa$|OSalY zdv_GbX-!tk3d%Ir{W}9=k87Df=>c<0(*z#ZHal@2{UknY8ahJJPZGlJifh%de(20Z zKdBaWL0mJ#YN7>>ev%b7m2xNgpIjS#fM3n~<7NBblIA74-EjuSpIW)0JnaqtG>C^k zN1r%`rsh0Nr;467cZrYSoo9;92KD-c_$tb{g0UfZ(PDfg{}bW`zdrPnu9FlnWhz0`vvfye zB;NxFRYB7u&;ny^{I!koQM_WIN6#o80#_IM8!bU%S-LAeqqq@JQ9S}J82+tD&KN$g zh@LULBkAEn&loT*N9g8D_={#nehbZ9PiWJ4uPcNJus(Ir{~;n$(kD zs=L0BUOJp-P0DnD2bFZZbU4ok)`6qmr7g(C3xT9Z*kb3!VDT=oOm`0B5s`d&YF9KPRZNMgz=GjrZ9mwwPJI_)=r z+#&Q6l1u#MCSrOwwW6=Dcq1?(EI%ABRLDL^+E-a+TR@Kkl1!)wQ_4O{91&+>RM^=- z@-%b>-{0GhIsfr(hQMHUt(15%?cLcjbnO`<+X;~opubKc``}QHXBnjzpT}btdo$v zO3`g}OeEqTM2Gi7y01`@Edu7e?B{xw{X&Th16G1?Dk8RA_X&ld^04;p{ary=$Y40l zJobKh`S&cP5%?`UI&qLMoNERLp7a_8`Jd68O~#`<7afrO!&{&Fw1L? zkb5!QXJ$!R1(h|x)_L&Je?vBrJ7cG*q7o`cft}WH$CrDN+;Tj25vCj}zrz1d4YRD+ zV`0v8{B5|kmz4GH5A%*grq!};6XIQ$TXwedVq~P0IAAs0xUyles}3kPPU7w_oS5Zl zO~ki3_Z{AoGhyP|g5RBFD1T*@alCdFPevPVY_S`Q2gU%LMFjB-h;T&35j|#SCmy@M zE|wpx0%Lt~)`OD>&_SJEXCXJfZt-KvAuui!XGvXxHIT=CanKi=8-Ve+7>haXsHk2e zxv~2J_qQ_VEFQb8m4zu~0akJon57pQIp+mfiW4k_zaR#Oc|!aFR}8)Z;UbY_43CyV z79ZmYd3}sB1^0kG_TcI_$l{Yc!I*89cpy3kb{taPA@rZ&v7`P*@t1*r24O{FC<3^| zW6xJHGo>-Wwl5Gw2-kV6r45$o3L7>J5O)H3GF2awdSYQ?)8{ zV6lt~$N7l<9J5k)XM!@TIvR4GgwF7QzJu7~2C2V6T6BgR7U>K(5}jdoSb2`Y>5802 z;NDf{~3#oRd>YDPg#KY=zHge^gN z#0VFcoDsBiiom8fZ?qemT0@~7aDgai7rjJyZs zLU&3PI;p21IFS#!=f%p1#<`D@Uk@6&brfK!<1Ix!xehzny$7FZ)!S;_eH^M2#hMiQJ%*D_##3_3tqlR9y_( z`v0I7RjumO(DL|g?ICb4XngUpx`r`N89EQf&6in46&C2!>VXJb8ID~~aL5`!+kLxO=cpq0 z*QqtzB0HR5ly|da|4l5Ca}L)9{QaSdJ;70V8-S4SCMlw}Nzy`Hz@b_ONg4#gSdAoV zoFsjz3rKrzlBBmlSf!D~Ob1EYtP41D4*Q-{aN9vRsF6grO45E^z~L05BwYpJrbeRV zG0VnKr0kT=b`LMm^t^Ge5ttH)Lk)#qR_0j_x-x^6e1TaBu>4jNeaXwZ$a*>*i=n_P z!#9gW=*f2BzvxP}jPzr1gtrFPk#MP!W{*0DDEWQi#mk6yv%X4u@p5LN6#>o%I{!g$ z`v?*KCP>RjR_HE6Gu53#mHdx|>`;uWIQuE>gQzi(vd?t3cfCzQgr5fKJjsf18`E+E zr?=`q`m{;t{tM9G1Pj#?_E&A=-!ckuzmfR>pIlXMkTxj ziB|)&7O`bKKPC2XCBM6eT}q9d-^yQ*cyBNVYPu~;vE8aOMGd_>+bXrq1U6sOCh>GN z^0!Y7Qhp7vbsl*?v^CBes%`J>7HXW=?Vv1_!SlbNM`)k!$r!7Wpn!~?iF)hroXeM&&glbG!iFgbJIND8+bMTz~ zmG&h>y`gm^&PS?!&P<~q@%O;|*u$prDdzyCeTs+et+z*7y#%rsYP$pMp{7mZv3mQtJuZ3c7<7Vhxa2QltkhXSZ{6kelJcp*suHf{G!x4coVD~J z+d8|Hv;?8ETZt$R))@00oK5vs`UeoDeI(#X#q|hEfj;E(G(VA+w*h}xT#JSNYU>=R z54b(ROWL5NSiB2Oc&{EeL#PIKS_E7f?=FH zv7UBWs{2+SFszb`83R_b#uO=bbi(2s=M}y2!bFsIHNU%(QF#)2@r7)cRK$Aa<*c!#$!{u$b~ z_rUnr&0?0hGl8A*4p_d}RnhhVyWqw>k#hAv1^t$Hz;KKli?X{5s&!(qqSk7YN7@xm zpdnz-AFjkFLMZzcf<>Mw5m>SzW%os28CXZ~hx~_(D~Jq3K;!c+D=`Puk6uA9QnDh5 z`i7L$vo4vv;GfrIM3oUI`E&?+D?`fZ1FrVs4yfkW-O2aRUra@TA*I(1{KAGTYApB} z{~_Z_MIS@Jce7m&Q*%)Jy@LK?D)t#t@>aQ0F%A6XuaJ?}U`|ON<~(Qc9fMYwwD7M$ zJw|kD<>h}wgmyYH2kp7xylyc55rQ|DYoPt9X{Pir%R~$uI3F2;>R-^yMY!IRF#d_d z)#{6H9o!i7VQC+U#{o-z0XG(iO8 zQtJ!q*q7-p#h)6jBb)h1#czT2p~fr{*$49x*?maXDYInm0qeBJED~A4ykNA>i+6>7 z11vVhovarlE9f_k*8V1gRO|pX;bl6r2<8K$^$SHOnYF=ct}%;5w$(I5mYJ--takO9 z`++r1V-|_5UiL78YH(7W1xFVYkRvV4^Vq^uqhsm0iZk16O z0_vof>C7US{Y=)~{av+t1z2k}W|7EN!N+drB$M^zT-VFhA+RoJ%p#E$%q1r4t_)W- zxC@r|GCEjV5dN`mSW94g>gI&Bph78rbJx?INc3_9Z6mv7|8$ykBlK z$L?R_&%OoW2aQA{E-YztEWY+`HOEf*7PC-+J#phKYfW!_0Jv*T3f7xg7{*{dYq&+j z;`!4|i%y*x!>9$DsL&WZvr=KM(A|y~lPUh-2Kv6bQYYss+~g7D#GDDL3Ge70ErCSs z!3ikTn!UYW$Lnyy3^-~|Qa8MYZ}Zc@or6Pdb`o?6O;`V}jt1;Kc&~LsikSZ^W(C%q z6KFlDX9W=82Z7U!6Co}+Vgf+T{;8sUimhPOvzp5+lb`tu9)AQfO^}cRbSLK!)Et~D zwns>yFLgCPFn;(GVh{_sqDH206d@5yV-z*l`JV7L3uU|^NX?1ZgHj>p2h{ABN*Tc8 zY22#jfK;jnTx{r2b4V(7rf1xhMa)Y1H9<*EqKe<{C|;Aja5Jk54VK}vwogt^q>)oX zl6jee!DdFIXEf%nP!=e3$GXs1Jk}!k94S=TyE;k); zT<8m*RaBosPWM!n-~9(c=^0LmZp>5P{@GuIUYjIDshr`pPy4d=T>U)Qi%su*vSwq+V660$-`&LiIa*iLVj6mXw)0UB>e;;WTs0 zlXw|f$(+HaI~>w{mE--A3k!;=pGiU}IXlf}j4WyZY2iFB4H z^=@tyq#ebSxJf=nn17yh?sGX7cdfW4S9FPVnJ1;KlbUGSiYGa;2)odf7RKk7rCQvD zsw~FR{imYlx#m}0_7Rh<!k2hgpN7cH!J&3Ih3c?MM}W%HORXr4k2D_u_`(g! zcR5?!8EA9IYad#*q_mnM60&XD)_N zaHxGr$s~oQl&L(a;l_EGmc$oDlB-$lx(@z=RRzo%McDM5sywmbM}qCslh|!bZo+R$ zh*gNAzs6p|X<$v|1+h~d_;>*S={Od;afR*>0m@mGCpTOsRDO&Plq&C$>~~5p(zG3< zy(A*?Yzdcm-=q&=6=@9m3b0?@xcr&O68<*2IVvBL9FyQBlyIo_#^F{X@li=#&}}3o zC4eQlakmm07E}3xMuCH4zEW5HO{d!6H(r2tzX&&g^jcGi`l0MwK$qMwYcvuPna!ie z%tvfc_;Hms+E`}mV2Th6FZ(VW4QkOo$#E?{#^2Z4+8#pG5a-+9&NABxhx1=PZ#!u9 zYXu|eD|i>IV$AFi5%C6iIdP@2UtVS>JE2^x0*zuN+_KMt9i z9e*J?lNFlPmp8|O-Qv&}1UTexSv7tmtU;870N5>V$C;5z$|PZLeS*j{ERpa~j06)ISG z_kRG#mOC{XlM4w;zSJ58(95&|mFEMvHxhpqg|>)J%Sb4$BNa<|k@qa_%`wnWK{yO? z_e-MCD_W@P_{Uwq-`g@PmAHg2LP2poBTz(XCH{mXH0~kxfyhi3j_?&+?*vpitp=VN zLv&k8Zq08(SxKZl1&2)Q?aF8%Wbw6$3}Z7I=vZxljb24qha?lB8^8e?;mKNP5Zad? z3T3asf7T1wT!hU33}MUR|B)Meb@4GP)k){jWuYuoooGpTlV)vp9@GQNSc7Q}HH*7k z36J*-f8X0wtEb?naq3Lr@K0Xg6~)v^#_54k%olQY9O#RY2~itn;a4z);gEl^zA)=f z#3(28jGd{GrYA>{0+Rc$S|$H1Lpl}u*|b8BiFlwDDh+u@Z9mI-?UbQrdqRX?EL>ho%1uOOHIGE3}Gb}{f~Ge;iOvxpwI)Robgt% zvjCk$UCVj4Jd&veCd2+n*6bCUTsbGBIbj#2XhR4jTAN0%j%1Vnza+9&bwwUHxakY5 z@Za+a5$$1hM>qYZmMM=Zeq&7=evV}KULjg6exhdNd`|HjVaoV1g2le|a^Acwkuu^n z2g|N&n$tnuWTO}h;i+jbkP{1G8`E;3HXvYUqmDBb>NkbB}3Nrg8APL@*jp^arH znkEdzMw`f`6-7e!ND@_64q^OLCfySO*Suj9L0oeOOh){F20ZqF7H}+nK9XJ5R1vKW z)wqDgo+Q5_V3y+CiZH8~LeUV==1n=^zal6RQ_o&cG1&>IaEV+$tXCML(wSByn3rts z%f*r357Wuy#@dqgJPbcx5(uu{S9Y$o{=f-{9A>P!R6czDgnh?8>o~~iw=+(?mA>xuDSb_AkijucVhg<-nPV?wd7NWL`* z23>?Hencz(MvI47!>-%4?$Qn&-Oqc3o%U+K|*S{yH!G9or#3 zz+cp$Z7>e?7@B{@`z~t!IKs>sHoF56od#@yhVO)Jbm5t{L$u}TN5D2~xCQcxAjMM$ z##|wtIxyTyjDx%<>8%yqFVilzro9f&TW(R=iXk1VB?faCg*xbF+XR`@^L2m4H6bV6n=*`#WD+)9`)WIhfE;_#`>(99nQS28_!-2 zby0l;wJc~=ic=ll1tH8UiTn1A#oEv&09&~UEbapSWnms@r9r6bakH==zIjjp*|nUw zJgh}E500a>)DQpL2qdxQ56H4O9eQErAtlE_N#p;t2h2**`9SwYmrxeX&7=G>+hO9? zJJ|T8-fq0wn8yV^gZvF%e-{)_3_Fr&XB*OW>@GZEN~jQ3+SXYiPt0^(zX83YhNOe> z6G}a7PCj~zgGH=RSUDW(GvZTQqYk`-k{OK?le9_aLRoE4TEBuefoKV&%sks?Ng-CQ z_5*9&%S;z(p3e>ZF_bR=;iH#H%F!=0bqjpn{SNAOfOX~-%*hmRcsgDJ%rh!eKE*n) zxuAJbSZCNo0{KHoJtfH*B93GZ%!>og(9cQ&R^nw2he))1+|6$X+&}Aj+*1Li5iBIb zX}rxmy)r$KvGnMhSA-m2V-pPC4zvP|8cUD9`JIpvJMsDeUp^YA*ECqXiJ7NWCPQW= zZ}|YfZ*RFiM9@Bg-xnHPKESK(x3QTKvH4+~PHM2UV&?zH*>}KKQFL$5?A|0d$xYep zCb_vGH-r`ly#+#-5}GvWBE1PJ(xs>%SU^FLIdj9XT5k8}b+FE%v8_RCJQNnY}u|8Oc*FYvLhH(u06wJb13q4_VFfG^Q zh~1DQq%EvbJzYEs!84w4CDWC?eP)W#o2Vmd{n;zNP6cCMqMk#OdegXrPoaryfYvTg zQ_b)6M9H1sL8E!vk!|*|`|=b(KM~ke4bI{wY_v#w6{CdO<-JJ}(rt?$eBcK9M9ZvA zI44T2*b}vC0LT(R1rPidNV5+Nv>Ak2>!BFtd zYw2PP^d?ic9Sf$LT`&~R=oJ#LK(N3Q9xW)C8ifm{hEp)q((~fJ#JxjuKeSGHns*jV z?X<(ooLf+?0d$kVUIhhHC+&AVWEV^-(wqTji|vA`n^o~0_f#aU6?A1?AR2k7r?rwy zNi1$Rg0LgQnK`#$7`Rq;_%$5`Q(6_wI5ZZo#ZVyIriz)+n@8QjESQmY!BF_(88lc3 zHhIEps$ja~wgx@NDVR&wbudoBP)jct7kM1t)1QIXHBYlp!HldA^$Ka7n>YnyAW^As zzOkxca@k@krtMF#uS=4ZAj{K$Z!Kx1qP5x|3Nj)9r$x@Tbp$VmAbb zJmHHJ=1`_*#hvSk4)Y6S7hJiplU*!pek-q`v*XG*#B0L&UZsJjwM$k|oY{n}DhNw5 zoKd^UR$cvTxoaIhy&t2;?$t8CPQg(a)Ae4#;k}I|GG=n)#epO?!ae9r@r5*5`!7;otHc}jp2*BU)y z#od5^1;7s;oRp}jPQiFhug^0B9QX!3qULo(AGHLv4yTf4pM#;Iu+y+bk9a-?sPaJ6 zy&a`2_fy#vzKBM3)5SdiboW5Bm{nUIhQocrQSJ!IkOIW-zT`WM* zs{kzWK+1>%>g-EsfTb2eTLIYZfs`fn{&%gXeF=3@2*k+m066b~?2{(=en_ofeKBis z)~?i+Vo3mJXPr8tqB=8SwqBpdD9E-v=&aVCzR>AaA%(04bS-KuQDAju!mE0H9+BXH z|MG?Y+!R!x-T)4C%?sQ}XW*m;UnmL(^fFfY1iWdK)0oB}2Xw<1I#nS}*^o;S{4POk zIU3^@71fCs^Y!}bfQtaP+iQu4;96|#5-GoicZw=@BGr)>uj}=B3Wl`NG9oyLhPis{O)Qc( zY-`aGWw!K8Q>aluj`z^7s?XqSB}Rmv#vP_Cfma}#OSuypj}EF8jIf4c-eTt0L$<}! zf5X-<8d2u40l170;YZ<4c=EumH*tEzj}bASws21HxC+?~%9Z^9Pr|SDb41MdI3AE| zQ<;n&oDOHpFH7DNTkA|jM7#3#;nvk5tL@1r%ckh%cViLU3SnIs&T6v92`o146Dhc< z_=9Zob(%Px7modW1^3Wz{^0DP=gp6Q5qiPX(=b*A=d8dkka)ZWhU7LyB0lJip7$1{ zYiYRzH+(qMI`TRZ(FZWJ?1t=+C$9jIP)~+=#p~Noh7{%~i;W|O%*XcP-$XBWEmoz5 z`c=8j-NhbkmZl!aWd`J>Z^z`Y@3iRvMyxJJUJiDom7>INI#BLb%*RBPp&2i z9%JEvDn!h`7ulTzz>6M;Nw@E}FIi_#P_)SnRec>lOkj^wz5~#^1lCoFE1Ap#OK+g*qaOm3YQckA54kKEl~0tV&QV zXxm(^U1x2Y{jgdd@~XtB6sQGio3A6PFHBWs-x88`p0wm&*e1{Glvd_~6Tx7JMp3M) zaPf8)xWe3%N|em44m-W#M5A>3Wr?+rzfX)^4E^zd)n;|{p}e3i zJ_ym51>)SZDWc7m=s$7a0H0sv?-2c2AU+TZi8i~VXY5F`#R>0VB@E{npNu=F+I$vW zd9=O#BP&2utw0=y#X*~eS-(B!B)=6zT_{#rWPGBewHYS*n3GV>c}&1C$R8;%p~M5t z_dBQC;uj#A>zSa2DBtEB@-QT3947MB5N-CvYR#Md!n~l!d$Z)$2e4kqPS_d{c}vp6 ztGT|b!ZLEf@7GL5q%s)Jb`B-1RrS;aJw_jZU~|L*KVD^o+`o2X>9V5Ez;AYTio zgwDv~Y?aNF&M!F~3x3JzkJR`1{i_Tiqh)gVDiqZT8enp{pNg2&w(4406h{t~4qcBR zWaCO6Y{`&z&jdvpxDs$abv)!AE{NXHLWF}15f$>`qv>YYdut3>3l}PO%B}DDMW~gG zxG+9l(6H7Y!l5p}PJNv&xcMm5M0VlHoc=o1aENUvUxrx#iFL+c`#aRs=7M!3jmM6(UAv^;vcnV`Z$IkvCf~uXkB16F!HmHE(dh;;HmroW%dFjO!T0FxVJ^7I41G z7a$C@z6M!oE#u(&kf@Ci*$=XZUAcW(Mc@){M{HS9%czApM}ejS@bc}T5TkDSgN%C! zYf!lk!jIv+-+5JZ1urYv*9@qs!C*GJteecUu#xcftC4UX+FmH(6KA5N{sByf&{y=g z!U=EGI4F24x6FX7v@5sIr}q+G^RaXr)DVDHw}V1+a*(@QGVU0TCXx?A_$XZTC%9Xa zvyqBUQ=7&)%@A?uCeB4|c}2!$V>?XF1@s*k&ZOIL-iEF{I0PHVg>EN!6xRo;Ebdx^ zEUJT^3+m<&_8a7B82Fh+7TlJ_`qMJb>d3#a7vnbuwwkF-scpt)z!(@c7c!;2Ca2j*BR%2XSR`PE3vB;`f6i@$h=o3|8yF*F2c@LI3KSob7Z|_ z@;ghBtk`$){RfZWu2B(759lMD>nd$T-5YxJ@2#pp!kXMCm?&q zlZW_POs1*V{BR3Kq}LI?%#~?;{X?jSk<4`6>a;6eu=GEKe7B1cOLeYQ<7FT|3&-rM z#q9SGp78*4Bv-rfvTn>@`Su+L+Byuta83ew+iqrYJ!XpT=of>mbb*}LerA@|W9s1^ z0(Dz&L&%zWa`oF;2jKgf9?eU zF1sKRh+2%4bkk!-R&t&T;?Q4$aH=RYyYZcAfS7veSyyL-1h2l8RRE~zf_Sm%7?C+# zw^$eChKS4&dKQuXP;gO5WKNVt^P^D~W1uqyF3!F%(7j*RyEo9jUw5+Hx-eNBel113 z2J8~XLxlG*!PSQ_xE0*^<-0L4g&&KmvmU*x?*5<%PgDY-JzlyexGCX9-(f@k25iIv zvPkP7u7a+7W`!;)tIK>RX;bl(>brmdjiK6K@URA`0%O;(BFlhUX*h+jlMubDNxWe6 z)rTLo-}n_cQoQ!=plFuXv?33h-n{|kLqgQ#UZB4wr|6>H;;}Wb56^GIVDC}deEAZF zj`{F}l6^cUB&H*LwkKOmSx)a6=_0LDOwZ!DsCp%2?|X9fBepHSH>Nu-8r46C>?=>M zjsu$e->#X4oS~|v(rYowrmFyaZvKW?zEwKLnq?r z6$U2?mU>-a8xg;eNxdO?TzA^|q@la8C`yz>^n|p(hqxu@KOZ6dX{`hLd<5cT_nsoH zZ3;_5%#)*AVb#?xddk+2c#$gS|A40!(PFU{hg?*+7E;l^2kCYqsOYqeCW3`63`Tlg zW&-WjN9Xsw`rsC1;reLR3+-|vzHW!}eaL+6V^UOobbAq(kR!abCp$oyTOW1GV{fr8 zWX(MJZS|p*fV?|o_j~f&>!a@rLGc)5Q#`ra=k@Ai`2*?Vb;wrUCcmRTrpyny_3;@B z*Hk8kf71V zkhUR$ie7!Nu!TYSb@}lZc+t!0AHQt!>VrFJf-`r*F5>{^^uQTaO04)AeH8K=?-jP;{Rb%z53Ymq^b`hCP4a>hbUAZ+Ysp12TP)$J_f&p zUnHp_F2gI_Ki<8SB53poq^F3WqE{a*Y++E|BjsFB7`(Hfbl1yRzXyN!r*3wRkPcp| z@k%2M((Y}u>Tt``U;EnvP?LAkiqhsJ=$t+sXy)pi{?1}q+s9Sf_s-(We*B^-gWLVX zTvTvJo%4k(7kj)PuJo8M<(Jdactn$U9Y7~qEzd;V>j==g!xPJ7jg9FdL6(xw48ec= zZn=Zt4(f(>O$ybk{4gZa7G*C!kuI_*wFebV4V1-R=9)f1kFMAuT^w44Pa%O&clB^duU7M- z!qm3d;}02o@!Z0-#{fGDK8e&p@Vt(mW@nLn{=8Lp(bgBI&P`wf3)WPKe z?VhqYqo~60hMB}Zba2Z3rWOf*pot&V z#-<@NlE>n$JXTmdLM=F73b&`+1McxgCY9Au`UlcdDgw|)9i>l018*~=_p=RkMrd~$ zG71|)|D$s0bxn}kgDL)LVC>rl4yL4?pDe^CWCP7zui6cOB$?soJrUw?N}qw52ry;5 zxd$rC)mieUOpF*b!Pc4Zw%%H8U`-Hx8a$<-ndW6cx2e5hQ)WeU$+n@go{f~E&!%S- zva*?h@^X6{2rsHZ6o~5)s?oM(Pey7kzxw6tbf^tPrwuM4iz# z(&r$3qEGmFg&b(kErc8tQ5`RPvlt>AWCV_h8u$WE#K&bA@#cKw2~=f~k;sw&Sw-X| zGN&M`iW-T`3dm}raU#0O|ZC2jA+nG;9pc{eBWg9xzy+a zjOBx}nTR*(jDch+F!|z~F`Dck?EIKx{sQ|HSqe-PudtNIYbY!hi&^U-co*@IW2_{u zI$3(gRCImMET~5c*jtrGV}?IeC-)3P`3({cFP%CT%`yqX@5f@8bxKN+g3WIBC&4x z#a_9;l>I3YUgT2vGQigJ@aLJ2E5K`*K81Kw+lrE3D6id05JcZY;131s6N7=HYGPxs z@yGbiT@__L?I13LcZ#wv6trpZmQphYn*T#l*3`ZlWKXatN~O6AS{HBE{NEI1BW>VY z_RFwZVx%&ZfaH~cvy*T~QNF3wKn}`kf8b?YqH7YERw$PY9Mw51N#vj{*ts;cB7Yce zE}KI^8xC(8HRu1&xs25Uf17TDQJO2Db@X=4|4lAawBS+8Z7|BvRTzmu673}XTP`~x z2U7ds!z4j;n83w_a>+npvYV~cd*jIQRJmG9--rrs)fTOvcmAlpic=$a7m>-IoK0S^ zVelr8k#Cdb{Tc>ub#Z8-r6_`}C#ca7 zVaEGpBXG4yE?J9S=b$Vah=yShS%IKU6boF(7=@4$fnq>|C=+P&|Vahk9d{y6;zXI9ZLh}9PDE}aN7tSLIBPr`4 z+v3UhYt37W?Q5XRs;bq^FI97Z0yh10*WA z+na9;Kj=03NTe{kVs#2y`(u4&k^Mn->yP)rvRg;h z-;dvL^*^4+_fFX#M9X@g;#X;M*`Gz67dT642JF5D=W7h0)*PNt7t3dVo-*jW7|{tU z3b_vQO~kZTVqTP<{YA>+)&X052%@hF#5~_7dwJke49(i(A$b3G!6)yh=~(LAuH?2S^mP#!a)7!w{T)y1IUJWa`h8G8?*XQ(teMq z3DTq~uLUX9(Ms;PjAIf9`R9FTe+@04fr%GsrVTN6R{wqu#W6VH^WIL?yaV}$J1{p| z0P}!9uo!!#i72xDkRQJT!_g!Ap@gTF1k|mO@-pQ5UN5e6L`Yqcqku#F5pD3vZ4iL+ z9;mBIm4__(*v4p){cu99X|cA+d?4?3(W2y|A4Z7mp$S<`fc1>(W;&~%0+ z?6}*}eiEW*3&bb!Nk;bYgohFmZ0*GmEiVv%hJ*97M^W-zd`UBirBvJ78x_C+`$II;727MOlIAdA#>Q@H z7%RG?^T?@?&u}rKL8oQ)hw2k={@=Gp853It&yK$6BN$2p7YT)l;ITrp=yyrW+Awo zD{?GHeIP~l)Y!eR=(go1khdkKQ0wi9o3gT>jqN-j!p01O{9zX(N-pSzLGL;LKR8rc zHQXr>JzpR`-xm3s<_~rA+2Xe#T3I0O&;r`i6Mwnr6Ra?~3!={o#6#Plc|ISr1E-sD ze3Cyw^lO2bCs$_A@ORy2A6hScpJO=$=hWUO1LH*Y3;wCaaOD~Lg)9zH8Bd(U_inOh z`s04YVYKxS+?XO&D>(~4Mz4O+KjH|=tt*22xgw{|?=xZfrI_iv6YO+72Kf|XRJk#! zq9i}9&VDt}Iz84N;1)u@!n0$K45Q1Vhb;9!j}!7$3U@+&z_Vjx-spr9T%9oCyitaz#5ut;?h8C5!4ZWrq;aJjtg!X#_(GOfMSDEO#o&1|))Y_{ z5BAPwm_^SdYw(mYi{}7aA$TS;Yp`N0QWh6AxvBtI{w8~*$uNV>+EQz0e$a1Ce*qpT zlazVwB`gVt6Y}FL(4c2L0oFWA>NyI=&B6+bthJfcZhFJ7;o1Ljc;-*90=EvhTvFEa zv*D34-vDKNMgwE#;F*AI?n9s~dgfPDJI9C?%>{LZxIM&CU^Sis2nTf|?jQu$z*Wa}K0Hz;skOR& zI6>LU@u4#rViT~zS$ptE5bS_2lV$MJAz|!JL<|iJJ$PU`K3NTp+a1QMu8Ycru}4v) z2z1I;?l+!Me1jpx%zXoi+N)U9gjIC`(#-fIG2?9Bcw)M>YjZQx@0YSx$R9**zFV+*8d`xR2Tie z6w#pUZ!*d}jMp>BmHk8NQy#z%{?Eh295`PPBD+t9O7#TbiqxwN0bn(Rn_Yn2_X5Q` z0`Rx=$HS5u4vzqEilAbi6&v)A^f$%wQ-S^_0CER}Mj-0+8wX3e7ArCDBSV7$G3gmh zj>+V%!`4yRT3SLge+J&S!JMnz-*31mdMpM<*l2x54G=lAcR;sl3&?@X%?76K06hNr z%9^@=;}IMSK(1`EuAi-i7eOI@63(|35>ZZxQgppNL~{`QrYo|~-FQJ$fK*+-*-MDc z5bpEAlZMRk3T zfmbmg%W>t}0Z^g}m+56o>hW1s?Km1CwDldBavg!Gs3&j3>l_@J2SWZ3F-PHvD&G%+ zxSFny8Doo|M(8w8T#hf8l+Dxq!5;C%bL(^s7KK#eg`tTAp<5ogK~={ zY>~}X0*6WR%-y@312}K&i=p@;0cZTRYFfmhP$gK3T zQ0VjE`mpe4$P)e+0N9`p=m$}$XqEcz@0BGmJ7GG2zV7Q3S6XqAxP~71#_O-9h@!=d zL`57!HIONusfY1hs@w?a2XH=098ppI%2bFBA^00tWcQ(Qr+!Hj#f!yoD8>&D+Iz6{ z)Ee9(=fa#>%zOm_22Gk3>Virj#aB6uG*DIPcxP%ZS&N=Y*5J*FCf_49_ztPf$7pltn=sL~EK<2_Hkaf;oX%e)zf)A36Sz98V~Yrp z-#O)aK#1ncI>d_nE~)L}&_($0n18STT4j5U`wQ&;0q5%qC9MNIQI^k+`ThLmN7^gI zn6L2aGhAT^7n=El{Hu4_R?0(M^A5E^d(CAGJ&>an?9m)w0H}l8(oPuf|;Nx2lEkr?~N7v zAV20|#uS*?rQbk1JO|NLPyCn?KXybH`Fs7%w#A6(uW-CY4j4P1dsO1;= zXZ)>e*(LZQB(n>omnJ}ZJ@JV;I9eSQxCW99p0o-d+4KD}W?&opQF}i`M+?M#zmF05 zri{6XQ~%ice}m{sfp}6r#9qzD3^n%N`big zC}=m3G1@N!D8Gx>d`{}r4!?}ycRIJ@ap@rRMO!7_GM)hJOW7Efdlm8V!$=v=L2 zYbo+aOaH17_CsPLS7zs17_2LcJ=COUP|akR!Q^j{^v#wr7yxi8nlS6oo6{Ntz$6Mj zVUO>%86GLKKPY1^1lB8CFba^h=zXZ|T?FxKEg{}ay(FwPt=~g5{SPRz=8sS@zM^vK zHh}3FzmR2W%pzp}B)bxnMb^4N?>fCL_-x(U4bSYh1Gw->4927^--qx>naQAx8W30) zLFJOo{eec8b@NyZJ`wEI_K#Sq%j#XkyeyfRMhcN?| zeO-&3*E^(k5z?`G#ychLU@tCTBcjRz}bs31fy(h14-Tv9Pme~D0@hY ze7{1vGBdQmqMC@czfYm#3D?`>fe*i&!XM&}h6y%SsiXhImnwHA3D2NvxqWOLwW zxKK-tLIs8gEO`##hOu$X;!ErB9aK>ndGfWe;Ex$sp=>LteXM7s0-TGi@rW%~GVJop z5m;uG*&kUZ6>A<03{I==vrWqsmBO;Je-^BFH-ecWEUQNIa07hu_*WQQHO2Y6KirJ6 z+}Ht-C3a8SnE|dw>~L^a_v7~wSyLf{-H*o-nWwm--G7Ortd`V{cNIH;7OZk5m;gq zEdwWPqE+CmO|%aD%O=_cQd3lR+6HRdM7uywn`j>xZ4(^=vp|@9DcBr|8A|=i9)H@| zZOFjy{z#?404wPTs*J1|3CbjEuKf~WiXHtGaJj_wIS#=y!5o}g|PsplwVn6(vNF2l_I6ue2n$&&~poBJIoi=O!*r5{oH z8`)dGf;~t!@>@VooQB6R>#lF0MzBRMcjH-rSN#s~O@cEoK``hV1PrsrfwD-M3^TI6 z1LW2fNdJImCHx8MovV=g&O=(C(kY(HQQDN5yh=RXjf zqJW-7&+K&(EImtkS3#M}nIN5Mxo;A@)|25KgRV9FCOkzk85ScqCos7On1Z>8HcR*QWtzYR~qxX*vL9`FJ zEfTm!z~z#%`f2b;nWI1%_t8KbU5Z??xs5`1T|$WqXX z`3+!GSnag|-P?pM23Si$S!B)E=#e$^QxT@vj-ZTcz?tzuQ1wWaCe@6TN$MV2If^$& za>-isOtR*2c*aml&!$64)}m+r2G*EL!L1??khSQUz6=N!QBW!j0a=TlIT)<5g#uFM zm7-wxf;F3GfjUCL^PnuU<|KM#%?c$Err4^WjDJz%JgLYZK}D7Vl}PFm!$P2}S4tyZ zvKBp)toa%|qb6~B8Bh(0i_QU#tVPdk1=i?B0V#8HIk1Dl=H88YBlmIYPJw5T+Aldh z&IYBuor;mkQsSc(pz=Bbt;zJRSA>0rS<1Tw)@oH5rb!t)0m&t0-h(jX2sKv2mi0&# zs4>h^-lJfx+-mSXCv_a2$uJ}GCm0}Q)`rwb25U8|4qdVqJ@b3!p#pKFEai1755WPZ zv?&B;e`px(2q9%Duhh?gw8@2FFa@M6dgezp5%xI3tiCl6HjEy_`X>LAA+lt$`UJD@ z#!eiNLpyKGKb4aG%vKU|lxnhNRfUIDMF7Q?(uy@2RbA(SBk#iidrlSb1p z^%s}X{#TXJk}bmEViYI4S5RE6GOBfN@KXk4f#`QtgxA{<8K-3a?jK`Mv$%{`dNJL7 z_mE3aT&y^(*7(I`lJN`nLo55kn8>?T=YHsvGu#hdG?M$Fe=XpC=mdmB1V{G3erWJd z6j)SnRf|lV=31t0SVRZ=4-AW#;Oc+EA~yI3=s+-cdsxH;hqc4GkHKf_XNrX2LzPfu z!E;42@vPtOy|74f;xB;{UGab$-0(*j^1JcnYGSZAwug*hJiabX3jVz&jJ0hOY>8RH z@f9;ga`3P8ut*6GxSAn?!OmFPqy<~wl_^5Oy-8tFB)BnzEuY}CA7eQb)UIWSqQN#7 zP{G0dNLR7o;fi5VB6u9uN(P($kReJ1SIrHJ(!p7OW{5Ju8QEcx6THr zcmQdr5S)O;Ri$7Q@?AMN=4@D03HnZDh-$%6DEV5!QyasgUa)qPOwk}X7FF6X_%`Bg z6r7itDH;by7R?mRf~(7hMf2eD&0*0Z*ko#0v=08(DJ&z!Ir6a3&xh8P>H zg*D>1;9~gW@w)E-G>;PUuwR@-qwNc`CFBu<3wP1|cdRr^$fJtG9FTzCkp$Eftt_Os zGV!RChd#+5s|P5Hta%STvgXY?2ve+H7r0u)O|1vP^YD!3U`?_XS@V$wpy-*8!ZQXE z9CsJO$XcyP-3!nBs3D|JQM#%z*mdxXmuZTuF`oj4nMIm_T}hUdsZ(t$*$+TjWX+0% z9AH?Td<`w!UxO#!Lh0v^Mxh14b3qL-W69^k~T0Oymjz zpVK3i%kpc5#j02dp_-uMZT#rYd0eBkROKH5R!%1* zrf+8?Ch#lRrDQ8Sh80sfSo0iHS(1Wd{UP8-?FP@8G|3wEC}5bWzXXb&d4ht@6g)Tp zSt4t#Ahn5JeLn;(;hA3!1a1OwxumR#_roJ)&ID!5rhx|rp*YCq_5@|oGxt($1El85 z`2644LEIMND6nQe2nf#wFutas$wLU+La+Q-Kq#>4fwD-M3^U|;q+lf>^QrrH4=fn} z=!5KsATaq^y}`2$tW%&Y9^zp!%p_&-JO=aZ0ce~!2yaC(^eTD-5Uwf?SAvZPZ!o~x zQXC#x_4DVmE(UK6{ul!c1I(?lpk5}mo5}1u4jw7ijOn9gON_Y zNRI4|td7u1xj-_|I18ltaBEPPsYA+4Z39;O4OC`Zc>G}AFvyl|2alh;82nD&B4w_e zfHJN~>6CM*i#$*&iS0qCBr^U=P~>awi2oTxZ8fR^JOhnE)a=(D)Cf=(DRURuNfdn1 z0Up0*H)fJO-Vq+Z>^AtFxJ63EwH=&_3vb?^!N_DVz`UQGcMqxET~P6<@YLXb!A1L> z{$Id$H>W_n4m_mUj|${IuOS$O8i$uKa2g6mJh9zA0cSks5$&RkFPGbw!-IE$=# zi;yJ@``{Ubku^yfn;16oX|O*(3-(j8`w;l9NK0W5~)(lf~#{4U+(afSwuN3_0!QR_E&CeCZa z{C^2y(?b|v$eN^#QV3J$h?qr|AO+RInxo$WRi9vnS-&0w^$0ef%)jq~pTaDT`kgn>?k&;#rI4$$Q~3%;4v@ zCcm^a_yuMzDT|-IT0DBtBxUf6P?I138T=?Pmz2dXF)bd#XOc4bk)p*TfUTXcA&iv4 zGi~ihG9G&}8>Lbn|2OLXz_K`z4$|ajw+0VD%q3+qWd;vhH2Gnd!2Lq-XFrI_qxys%Y_NNt2YxFRYC<6sU6GN7e?9 zYOz>AW(uU%FZ3=UYa^H3kJpG-)7u2k{(Jj}=b0zr}_oz7{<`F)Xs>#Lx&l zi7@CF%G6;=hvn%Gc%qVLWq^ibu0pVvJN+XOyG9oCP!i5#kUdhlyZk^(Hp1xaL&r>R ze4FZ$hH?m0wORX*plAxF9h_{4IH$^a*v$^hk*Vtdp>xv0Uoo0|dL%=v?5c8en4Tfaj=3p4Ac;p`gQjmAW^c^Ew0YAe<_X%Bb2BBOVdi14^nF zsLjZJ7)2>I7o&3+qe(Sffo?JpUifH#d_9M!%DD($;@YTFgvs1MdF)Clu4aVA7RYwG z^6?-slrl%drgjB(hA z7B$BU@yGzX74LEZsHN%X4`t=MO7SN*Tq{j|1YvQR{OEb?d&oZV-vLg<-v18mj+4d8$sX~2irLWL zJ!pYJa}`>VK}mQcs8{Yv60v_{c!yJM_9`SId>o>bZw*lj!F39YN}a?TObhmvQ9q+? zm9JxKX2NS)8$h(4>=rGyu13hqcIHPhSmj%JBLUDDhHYt(Q)TU#3|#3}OBK{SVpTE~ zRt;!onN>(DCE+TdYTu6;7|a)NDy<7aB&h^N$kHlB#m;X|5g&gb13%zDt^E#2K@!ju z!X060TWMTwcO6#fIGNFs2#G3iBAJ8r z{}C1FMbyf``^PgB>ey{4(cH_1_St#1tC!!!R1{M2XIUPcrG>=7M|E1$YD6$0?a+PgCctZxu_Mq)9}KX_u}2h zYpG&5P>;Gu71Q_fMx9KtZKh^!L*iNtd@(Gxy=F5D0n`{OEPf=nOjc}VU}}3j^wgAC zRj3~kpr*DauVVkPd=XWozc7?P>S!%6u-om4+ghT6UIbN_86cLWn)t8(2CR??|3e20G8WH)w|-(FxIJ1xaXg0c~+k;8Cw>)WuX zC>O~DCT=061J6P_VwX#KEWpwA3I1Hh(fDS9RhACR2hiUu%00H=uqS9C%VRL!D%Hqx zg~6&{d5J{N3*HQiO0tnEGvgm1lxKIk^{D8na^*A>nhdG&x-JpQ1`!2Q3aaJX9Kwnw z63+SL{{IgBB7xA1#D~&s==1*$#Xia7Xke6tp9FOn4-(74Y==_~^d%7X5cGYP>hMRj z5f9^c`}pZXd<~gB=c#6~MbDTa#922`gx`e07xHjw5rTX-3mFt!_4}|j8b+9{uX6b% zRzo7Z8%p=a;nZCS>lIeAJJeC_E(nRghuW%MKF|+gny)NN#<4nEeA@#P);OsO@(F@e zL3$IP*rxBf5f&fHoxOy31@aYcELG5!(|Y#oE25(Gw0F>_MDnoB_=4#a0CDy)C275R zl1OTv3FHux4S04)+Wk1kUsh8mh$LQu*$dFnjayEZ3+%3zsodzQX0(hJQSZuF70HJ( zr8nMx1-eXO4UxET6Fz`Ikk-NtkHEq?_S7W%+yW6MUK~ml-SEFRoKCbzG~UMtFrc(a z@Ki0{z;j0-Jz`rd4vClWe-4~Zv`Bnn173gyrEP|%^e)}5M{E&aNbJM^gK#?0_?@B) zUjGH9U52Oh#$o+mVvGpYtTX|X2ov0(Hg2lJi?lpcMJHT80}t;_zK&-F1}2Nf_->;T zDCfj3jiDl$$F<NJ*NyiMaF2#4ZR4*u1LP5#Mw`F>qI#JT1m zp0*D+GQ@Vc4l~c=K9(Pg@am2FjSW#8u0iMwet3z}Mc0?!#?>{KGuWJ0L$DmK>*6y} zBJzp~I|hC)!!F>p*2q6qSbP&h_~5#BZ35lDQ`qS{fUm=_I-PLQ$luuvdl&p_xCZSJ z**RQjUF`u}KoFTG)j6qoP4K)Q8M2vA0ow)__0y^d(eiyeUpU_hioiE&FY#*lWr(8l zfq@fIOBzJrTqGMP#TWuZveBaiu7fBDP>KR>#cg9QP#04OOqZoL5_lS-Y=BC_>4(9{ zz3_6uRa2@(d+VNRgqTa!A~O3YsOmK!k`>@J0kRR%k<$^an{ zT);X&;U1+l@g3cR`U+9D8nRTo4V9h;tS=OLE2T{Ln*PIx*sSj-W!#xVf(!yHvUg(p9N zcLwm2aPglE^LZLlP$Rfdrs%&QSU&+z9)ef1sUgb2rJi+cFU4Rt3sxg!N9|D|QeSWi zfZ?m{a6Lvyk(#i{ZdVlSE>Or=;)FL^jn*w9d#{TTH@tMa6xTrfi;R)woA{8~rvQ5# z>39@QjsY_r#B*dG05cE7Yj6qCPHLXZj#Vj~0KbFwIQ(|n2-u5aLtgLI*(w&3AxlkR z6l}=vz{ql1WkcQ!;(an~(EC8_fx{g>Xat)a6Vjtpa+%^J8Qx2CY&gfE@D(kv;hY0; zMp(q<|y@Vyh3m(uMmpK z#vf6sJzzDUP@PIqoDf~8Pi$l17n8*oMgsUJM6Cd74ktMc4g}E`t~g2xXNK>bCn$0yx1#ZhGfG#{fWjxIAmOotPGCSbbL{-j5lu7%YyN+o1I!1JihgscSd z4xCCu?YWLNoBwDwE}ZG$$C+yQi!YB7YT#Kv!0ZKZB3N4lZ-ar&wAdKT*B}m)sSV~& z5P!g>wsbVPg!%{hU<_=y9oTRah7^)|5=?qHT82aBB(Dcu!^;Sfzos?7w4_GKq~?Z5 zgcDh#fP2luxs+GUzg8bfoykCD0iQ{o6t?xZJRLu?bTPb~I5zJpz*K-!&AT0lR!WI& zW1?3Mr>S(l@j)uFISd762yvOL4HxGVzbjmERRK>zJ_$}$z)K)z!l?@Ivk^@8jJs6f zMxYwNA}B1N1vY@SAlAU)Zy4{|>W>+IC_a?pAC^_>PtN->S{KWuJMqhoKS?#`AIRXG zFFRy$mT|SDM|tIU(0UJM)g<#F;@Zym)JQ(oiAjh8%8oPgV9pupuxlLv{tKnUGN0h- z6i|-Np->qlRF(fJ;J<-W<$n>x1sX_U`9JF!DE&Rk|48e0RATvy7KXSsb?;71t$VB0$BFAW`Xi3V zKZ#-6Q90ECF6x-hchWECy&ZddeX0s{VbW9ZDsYQ63U*WlK8DncXNt1AqiV`{sV<+irKSv#Qpt-=$fm0Ru4v6K-0DE+G&wxvL3Ef^Z zjI62Ny%qS)N{7RK7f;8fJe^NUjinC9|9!ykfm2h;Nf5`$a6b4I#91<&7jA&~8&1Sj zMy229n3f)8cOSHqopoewAYxi#a)M(m_CqbckN7@Sh9+h{qi4Dg3O8DD5Eo(b!zaDyKnFhE51Pv>2IEx|Wo*dx8iA}o(r_dNoBAY6xT zxJ)gwe-~b0_Zj#daB8%4L0OfDzx{*=YUvEovJ zG2v9j<$|c9lsH7BcuL!pQq_G_;@Y!4Fl`i$3%p7mj_<%mK2+l}aU2RB0A`TFv7_DX z;eH`*M0V*o;Mmc|0W$_pb+oA@0#grM?Z|QaClDegB;#`Y_Svow&x zhn2^@Sfe;DOssK>N_Xpx#|D{?hZ(b$2Cg436Ru~Yby zr&vHaibLv;r6S8C1f?LHN?{I&(r|XUBzj#d$P_-6y^2aKmpou
  • 4`U+$$M8#2-8)P~Pw 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
      1fIFX_TyV)Q&@3T49 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

      $$66{ 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сxys6ZIi16JTpS!GhGWlU8~_u6BnuWEW~_a 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 z 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


      f^fZDW3 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 NBp{;5lj- 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 z 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

      6UQ{ECYM!c*^V%>0ItG=#AuB(|-BcImX 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 ILGrfof9_EaYXATM literal 0 HcmV?d00001 diff --git a/pdns/dnsdistdist/m4/pdns_enable_fuzz_targets.m4 b/pdns/dnsdistdist/m4/pdns_enable_fuzz_targets.m4 new file mode 120000 index 000000000000..7bec31c4345f --- /dev/null +++ b/pdns/dnsdistdist/m4/pdns_enable_fuzz_targets.m4 @@ -0,0 +1 @@ +../../../m4/pdns_enable_fuzz_targets.m4 \ No newline at end of file diff --git a/pdns/dnsdistdist/standalone_fuzz_target_runner.cc b/pdns/dnsdistdist/standalone_fuzz_target_runner.cc new file mode 120000 index 000000000000..61ca1e384c71 --- /dev/null +++ b/pdns/dnsdistdist/standalone_fuzz_target_runner.cc @@ -0,0 +1 @@ +../standalone_fuzz_target_runner.cc \ No newline at end of file diff --git a/tasks.py b/tasks.py index e78e0a55212e..0b326ef26c46 100644 --- a/tasks.py +++ b/tasks.py @@ -510,6 +510,7 @@ def ci_dnsdist_configure(c, features): -DDISABLE_FALSE_SHARING_PADDING \ -DDISABLE_NPN' unittests = ' --enable-unit-tests' if os.getenv('UNIT_TESTS') == 'yes' else '' + fuzztargets = '--enable-fuzz-targets' if os.getenv('FUZZING_TARGETS') == 'yes' else '' sanitizers = ' '.join('--enable-'+x for x in os.getenv('SANITIZERS').split('+')) if os.getenv('SANITIZERS') != '' else '' cflags = '-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int' cxxflags = cflags + ' -Wp,-D_GLIBCXX_ASSERTIONS ' + additional_flags @@ -524,7 +525,7 @@ def ci_dnsdist_configure(c, features): --enable-fortify-source=auto \ --enable-auto-var-init=pattern \ --enable-lto=thin \ - --prefix=/opt/dnsdist %s %s %s''' % (cflags, cxxflags, features_set, sanitizers, unittests), warn=True) + --prefix=/opt/dnsdist %s %s %s %s''' % (cflags, cxxflags, features_set, sanitizers, unittests, fuzztargets), warn=True) if res.exited != 0: c.run('cat config.log') raise UnexpectedExit(res) From c68240b14959e5660abef699320233710752013a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 16 Aug 2023 16:44:37 +0200 Subject: [PATCH 559/909] Format fuzzing targets --- .not-formatted | 5 ----- pdns/dnsdistdist/fuzz_dnsdistcache.cc | 9 +++++---- pdns/fuzz_moadnsparser.cc | 11 ++++++----- pdns/fuzz_packetcache.cc | 15 ++++++++------- pdns/fuzz_proxyprotocol.cc | 9 +++++---- pdns/fuzz_zoneparsertng.cc | 7 ++++--- 6 files changed, 28 insertions(+), 28 deletions(-) diff --git a/.not-formatted b/.not-formatted index e48e5f4affe6..c4d86e3d2964 100644 --- a/.not-formatted +++ b/.not-formatted @@ -149,11 +149,6 @@ ./pdns/ednssubnet.hh ./pdns/fstrm_logger.cc ./pdns/fstrm_logger.hh -./pdns/fuzz_dnsdistcache.cc -./pdns/fuzz_moadnsparser.cc -./pdns/fuzz_packetcache.cc -./pdns/fuzz_proxyprotocol.cc -./pdns/fuzz_zoneparsertng.cc ./pdns/gettime.cc ./pdns/gettime.hh ./pdns/histog.hh diff --git a/pdns/dnsdistdist/fuzz_dnsdistcache.cc b/pdns/dnsdistdist/fuzz_dnsdistcache.cc index c224449533e0..6c10920d4a9a 100644 --- a/pdns/dnsdistdist/fuzz_dnsdistcache.cc +++ b/pdns/dnsdistdist/fuzz_dnsdistcache.cc @@ -24,7 +24,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ if (size > std::numeric_limits::max()) { return 0; @@ -44,16 +45,16 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { uint16_t qtype; uint16_t qclass; unsigned int consumed; - PacketBuffer vect(data, data+size); + PacketBuffer vect(data, data + size); const DNSName qname(reinterpret_cast(data), size, sizeof(dnsheader), false, &qtype, &qclass, &consumed); pcSkipCookies.getKey(qname.getStorage(), consumed, vect, false); pcHashCookies.getKey(qname.getStorage(), consumed, vect, false); boost::optional subnet; DNSDistPacketCache::getClientSubnet(vect, consumed, subnet); } - catch(const std::exception& e) { + catch (const std::exception& e) { } - catch(const PDNSException& e) { + catch (const PDNSException& e) { } return 0; diff --git a/pdns/fuzz_moadnsparser.cc b/pdns/fuzz_moadnsparser.cc index 2605ea82047e..afb3bdea4598 100644 --- a/pdns/fuzz_moadnsparser.cc +++ b/pdns/fuzz_moadnsparser.cc @@ -33,7 +33,8 @@ static void init() extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ static bool initialized = false; if (!initialized) { @@ -48,17 +49,17 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { try { MOADNSParser moaQuery(true, reinterpret_cast(data), size); } - catch(const std::exception& e) { + catch (const std::exception& e) { } - catch(const PDNSException& e) { + catch (const PDNSException& e) { } try { MOADNSParser moaAnswer(false, reinterpret_cast(data), size); } - catch(const std::exception& e) { + catch (const std::exception& e) { } - catch(const PDNSException& e) { + catch (const PDNSException& e) { } return 0; diff --git a/pdns/fuzz_packetcache.cc b/pdns/fuzz_packetcache.cc index 0c982d0e72ac..d607586d53b3 100644 --- a/pdns/fuzz_packetcache.cc +++ b/pdns/fuzz_packetcache.cc @@ -27,7 +27,8 @@ StatBag S; extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ if (size > std::numeric_limits::max() || size < sizeof(dnsheader)) { return 0; @@ -37,28 +38,28 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { /* auth's version */ try { - static const std::unordered_set optionsToIgnore{ EDNSOptionCode::COOKIE }; + static const std::unordered_set optionsToIgnore{EDNSOptionCode::COOKIE}; PacketCache::canHashPacket(input, optionsToIgnore); DNSName qname(input.data(), input.size(), sizeof(dnsheader), false); PacketCache::queryMatches(input, input, qname, optionsToIgnore); } - catch(const std::exception& e) { + catch (const std::exception& e) { } - catch(const PDNSException& e) { + catch (const PDNSException& e) { } /* recursor's version */ try { - static const std::unordered_set optionsToIgnore{ EDNSOptionCode::COOKIE, EDNSOptionCode::ECS }; + static const std::unordered_set optionsToIgnore{EDNSOptionCode::COOKIE, EDNSOptionCode::ECS}; PacketCache::canHashPacket(input, optionsToIgnore); DNSName qname(input.data(), input.size(), sizeof(dnsheader), false); PacketCache::queryMatches(input, input, qname, optionsToIgnore); } - catch(const std::exception& e) { + catch (const std::exception& e) { } - catch(const PDNSException& e) { + catch (const PDNSException& e) { } return 0; diff --git a/pdns/fuzz_proxyprotocol.cc b/pdns/fuzz_proxyprotocol.cc index 25885c8883d0..f9ec613ef33d 100644 --- a/pdns/fuzz_proxyprotocol.cc +++ b/pdns/fuzz_proxyprotocol.cc @@ -24,20 +24,21 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ std::vector values; ComboAddress source; ComboAddress destination; bool proxy = false; - bool tcp = false; + bool tcp = false; try { parseProxyHeader(std::string(reinterpret_cast(data), size), proxy, source, destination, tcp, values); } - catch(const std::exception& e) { + catch (const std::exception& e) { } - catch(const PDNSException& e) { + catch (const PDNSException& e) { } return 0; diff --git a/pdns/fuzz_zoneparsertng.cc b/pdns/fuzz_zoneparsertng.cc index 98e0d5ce383c..03c4ca55d092 100644 --- a/pdns/fuzz_zoneparsertng.cc +++ b/pdns/fuzz_zoneparsertng.cc @@ -35,7 +35,8 @@ static void init() extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size); -extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { +extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) +{ static bool initialized = false; if (!initialized) { @@ -56,9 +57,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { while (zpt.get(drr)) { } } - catch(const std::exception& e) { + catch (const std::exception& e) { } - catch(const PDNSException& e) { + catch (const PDNSException& e) { } return 0; From 2b7797eda703e3b8073f4c0c73b4c66ff53782fb Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Wed, 16 Aug 2023 17:28:23 +0200 Subject: [PATCH 560/909] dnsdist: make query channel receiving part blocking to avoid unnecessary CPU consumption --- pdns/dnsdistdist/doh.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index c8931c5cdb13..2a24dabebca5 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -175,7 +175,7 @@ struct DOHServerConfig { #ifndef USE_SINGLE_ACCEPTOR_THREAD { - auto [sender, receiver] = pdns::channel::createObjectQueue(true, true, internalPipeBufferSize); + auto [sender, receiver] = pdns::channel::createObjectQueue(true, false, internalPipeBufferSize); d_querySender = std::move(sender); d_queryReceiver = std::move(receiver); } From 8830b5e669e75f564a9332dd7d493da2b3890670 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Wed, 16 Aug 2023 16:32:22 +0200 Subject: [PATCH 561/909] dnsdist: remove unused variables warnings --- pdns/dnsdistdist/dnsdist-lua-ffi.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index 33e13b534fb7..20c866931a84 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -1614,7 +1614,7 @@ bool dnsdist_ffi_metric_declare(const char* name, size_t nameLen, const char* ty void dnsdist_ffi_metric_inc(const char* metricName, size_t metricNameLen) { auto result = dnsdist::metrics::incrementCustomCounter(std::string_view(metricName, metricNameLen), 1U); - if (const auto* errorStr = std::get_if(&result)) { + if (std::get_if(&result) != nullptr) { return; } } @@ -1622,7 +1622,7 @@ void dnsdist_ffi_metric_inc(const char* metricName, size_t metricNameLen) void dnsdist_ffi_metric_inc_by(const char* metricName, size_t metricNameLen, uint64_t value) { auto result = dnsdist::metrics::incrementCustomCounter(std::string_view(metricName, metricNameLen), value); - if (const auto* errorStr = std::get_if(&result)) { + if (std::get_if(&result) != nullptr) { return; } } @@ -1630,7 +1630,7 @@ void dnsdist_ffi_metric_inc_by(const char* metricName, size_t metricNameLen, uin void dnsdist_ffi_metric_dec(const char* metricName, size_t metricNameLen) { auto result = dnsdist::metrics::decrementCustomCounter(std::string_view(metricName, metricNameLen), 1U); - if (const auto* errorStr = std::get_if(&result)) { + if (std::get_if(&result) != nullptr) { return; } } @@ -1638,7 +1638,7 @@ void dnsdist_ffi_metric_dec(const char* metricName, size_t metricNameLen) void dnsdist_ffi_metric_set(const char* metricName, size_t metricNameLen, double value) { auto result = dnsdist::metrics::setCustomGauge(std::string_view(metricName, metricNameLen), value); - if (const auto* errorStr = std::get_if(&result)) { + if (std::get_if(&result) != nullptr) { return; } } @@ -1646,7 +1646,7 @@ void dnsdist_ffi_metric_set(const char* metricName, size_t metricNameLen, double double dnsdist_ffi_metric_get(const char* metricName, size_t metricNameLen, bool isCounter) { auto result = dnsdist::metrics::getCustomMetric(std::string_view(metricName, metricNameLen)); - if (const auto* errorStr = std::get_if(&result)) { + if (std::get_if(&result) != nullptr) { return 0.; } return std::get(result); From 63a441709d5a2f784d8109e2dfafa923f3d16d26 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Wed, 16 Aug 2023 17:20:21 +0200 Subject: [PATCH 562/909] dnsdsit: reset IncomingTCPConnectionState's buffer with clear() instead of resize() --- pdns/dnsdist-tcp.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 7b99f6be7d1e..2a1d7b80eebb 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -252,7 +252,7 @@ bool IncomingTCPConnectionState::canAcceptNewQueries(const struct timeval& now) void IncomingTCPConnectionState::resetForNewQuery() { - d_buffer.resize(sizeof(uint16_t)); + d_buffer.clear(); d_currentPos = 0; d_querySize = 0; d_state = State::waitingForQuery; @@ -875,6 +875,7 @@ void IncomingTCPConnectionState::handleIO(std::shared_ptrd_lastIOBlocked && (state->d_state == IncomingTCPConnectionState::State::waitingForQuery || state->d_state == IncomingTCPConnectionState::State::readingQuerySize)) { DEBUGLOG("reading query size"); + state->d_buffer.resize(sizeof(uint16_t)); iostate = state->d_handler.tryRead(state->d_buffer, state->d_currentPos, sizeof(uint16_t)); if (state->d_currentPos > 0) { /* if we got at least one byte, we can't go around sending responses */ From 3692220de3633434cb88556132cbb77255440ce3 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 17 Aug 2023 11:19:15 +0200 Subject: [PATCH 563/909] dnsdist: Properly record self-answered UDP responses with recvmmsg Responses sent directly from dnsdist, without reaching out to a backend (self-generated and cache hits answers, mostly) where not properly accounted for in frontend metrics, ring buffer entries and latency computation when recvmmsg/sendmmsg support was enabled via `setUDPMultipleMessagesVectorSize()`. --- pdns/dnsdist.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 62fef05a2e3c..4f27e84043b5 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -1688,6 +1688,7 @@ static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct if (dq.ids.delayMsec == 0 && responsesVect != nullptr) { queueResponse(cs, query, dest, remote, responsesVect[*queuedResponses], respIOV, respCBuf); (*queuedResponses)++; + handleResponseSent(dq.ids.qname, dq.ids.qtype, 0., remote, ComboAddress(), query.size(), *dh, dnsdist::Protocol::DoUDP, dnsdist::Protocol::DoUDP, false); return; } #endif /* defined(HAVE_RECVMMSG) && defined(HAVE_SENDMMSG) && defined(MSG_WAITFORONE) */ From 84d2423481cff98765c482964d11ef828a2774d2 Mon Sep 17 00:00:00 2001 From: Andreas Jakum Date: Thu, 17 Aug 2023 15:24:05 +0200 Subject: [PATCH 564/909] Fix a few typos. --- pdns/recursordist/rec-lua-conf.cc | 12 ++++++------ pdns/remote_logger.cc | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pdns/recursordist/rec-lua-conf.cc b/pdns/recursordist/rec-lua-conf.cc index 4c471d2481bd..c53c95829a6a 100644 --- a/pdns/recursordist/rec-lua-conf.cc +++ b/pdns/recursordist/rec-lua-conf.cc @@ -365,12 +365,12 @@ static void rpzPrimary(LuaConfigItems& lci, luaConfigDelayedThreads& delayedThre } catch (const PDNSException& e) { SLOG(g_log << Logger::Warning << "Unable to pre-load RPZ zone " << zoneName << " from seed file '" << seedFile << "': " << e.reason << endl, - log->error(Logr::Warning, e.reason, "Exception while pre-loadin RPZ zone", "exception", Logging::Loggable("PDNSException"))); + log->error(Logr::Warning, e.reason, "Exception while pre-loading RPZ zone", "exception", Logging::Loggable("PDNSException"))); zone->clear(); } catch (const std::exception& e) { SLOG(g_log << Logger::Warning << "Unable to pre-load RPZ zone " << zoneName << " from seed file '" << seedFile << "': " << e.what() << endl, - log->error(Logr::Warning, e.what(), "Exception while pre-loadin RPZ zone", "exception", Logging::Loggable("std::exception"))); + log->error(Logr::Warning, e.what(), "Exception while pre-loading RPZ zone", "exception", Logging::Loggable("std::exception"))); zone->clear(); } } @@ -690,11 +690,11 @@ void loadRecursorLuaConfig(const std::string& fname, luaConfigDelayedThreads& de } catch (std::exception& e) { SLOG(g_log << Logger::Error << "Error while adding protobuf logger: " << e.what() << endl, - lci.d_slog->error(Logr::Error, e.what(), "Exception while adding protobuf logger", "exception", Logging::Loggable("std::exception"))); + lci.d_slog->error(Logr::Error, e.what(), "Exception while adding protobuf logger", "exception", Logging::Loggable("std::exception"))); } catch (PDNSException& e) { SLOG(g_log << Logger::Error << "Error while adding protobuf logger: " << e.reason << endl, - lci.d_slog->error(Logr::Error, e.reason, "Exception while adding protobuf logger", "exception", Logging::Loggable("PDNSException"))); + lci.d_slog->error(Logr::Error, e.reason, "Exception while adding protobuf logger", "exception", Logging::Loggable("PDNSException"))); } } else { @@ -907,12 +907,12 @@ void startLuaConfigDelayedThreads(const luaConfigDelayedThreads& delayedThreads, } catch (const std::exception& e) { SLOG(g_log << Logger::Error << "Problem starting RPZIXFRTracker thread: " << e.what() << endl, - g_slog->withName("rpz")->error(Logr::Error, e.what(), "Exception startng RPZIXFRTracker thread", "exception", Logging::Loggable("std::exception"))); + g_slog->withName("rpz")->error(Logr::Error, e.what(), "Exception starting RPZIXFRTracker thread", "exception", Logging::Loggable("std::exception"))); exit(1); } catch (const PDNSException& e) { SLOG(g_log << Logger::Error << "Problem starting RPZIXFRTracker thread: " << e.reason << endl, - g_slog->withName("rpz")->error(Logr::Error, e.reason, "Exception startng RPZIXFRTracker thread", "exception", Logging::Loggable("PDNSException"))); + g_slog->withName("rpz")->error(Logr::Error, e.reason, "Exception starting RPZIXFRTracker thread", "exception", Logging::Loggable("PDNSException"))); exit(1); } } diff --git a/pdns/remote_logger.cc b/pdns/remote_logger.cc index 94a8a94a8b26..d07a5aaf0013 100644 --- a/pdns/remote_logger.cc +++ b/pdns/remote_logger.cc @@ -134,7 +134,7 @@ bool RemoteLogger::reconnect() catch (const std::exception& e) { #ifdef WE_ARE_RECURSOR SLOG(g_log<withName("protobuf")->error(Logr::Error, e.what(), "Exception while connection to remote logger", "address", Logging::Loggable(d_remote))); + g_slog->withName("protobuf")->error(Logr::Error, e.what(), "Exception while connecting to remote logger", "address", Logging::Loggable(d_remote))); #else warnlog("Error connecting to remote logger %s: %s", d_remote.toStringWithPort(), e.what()); #endif From 893078c84cf2033058ac30497b2874242fe25aa9 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 17 Aug 2023 16:59:37 +0200 Subject: [PATCH 565/909] Cleanup convert-yaml-to-json.py --- pdns/convert-yaml-to-json.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/pdns/convert-yaml-to-json.py b/pdns/convert-yaml-to-json.py index ca33e9f30df7..7a5dba239293 100644 --- a/pdns/convert-yaml-to-json.py +++ b/pdns/convert-yaml-to-json.py @@ -1,5 +1,14 @@ -import sys, json, yaml +"""Convert a YAML file to JSON.""" -with open(sys.argv[1], mode='r', encoding='utf-8') as f_in: - with open(sys.argv[2], mode='w', encoding='utf-8') as f_out: - json.dump(yaml.safe_load(f_in.read()), f_out, indent=2, separators=(',', ': ')) +import json +import sys + +import yaml + +yaml_filename = sys.argv[1] +json_filename = sys.argv[2] + +with open(yaml_filename, mode="r", encoding="utf-8") as f_in: + with open(json_filename, mode="w", encoding="utf-8") as f_out: + contents = yaml.safe_load(f_in.read()) + json.dump(contents, f_out, indent=2, separators=(",", ": ")) From 630eb526b49d26e1111c80eacc34a8e2494b22ca Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 7 Jul 2023 18:17:13 +0200 Subject: [PATCH 566/909] dnsdist: Update the regression tests for parallel testing --- regression-tests.dnsdist/dnsdisttests.py | 44 +++++++++---- regression-tests.dnsdist/requirements.txt | 3 +- regression-tests.dnsdist/runtests | 6 +- regression-tests.dnsdist/test_API.py | 4 +- regression-tests.dnsdist/test_AXFR.py | 8 +-- regression-tests.dnsdist/test_Advanced.py | 8 +-- regression-tests.dnsdist/test_Async.py | 12 ++-- .../test_BackendDiscovery.py | 47 ++++++------- regression-tests.dnsdist/test_BrokenAnswer.py | 8 +-- regression-tests.dnsdist/test_Caching.py | 4 +- regression-tests.dnsdist/test_Carbon.py | 16 ++--- regression-tests.dnsdist/test_DNSCrypt.py | 19 +++--- regression-tests.dnsdist/test_DOH.py | 35 +++++----- regression-tests.dnsdist/test_Dnstap.py | 12 ++-- regression-tests.dnsdist/test_DynBlocks.py | 4 +- regression-tests.dnsdist/test_HealthChecks.py | 30 ++++----- regression-tests.dnsdist/test_Metrics.py | 8 +-- regression-tests.dnsdist/test_OCSP.py | 22 +++---- regression-tests.dnsdist/test_OOOR.py | 14 ++-- regression-tests.dnsdist/test_OutgoingDOH.py | 48 +++++++------- regression-tests.dnsdist/test_OutgoingTLS.py | 30 ++++----- regression-tests.dnsdist/test_Prometheus.py | 4 +- regression-tests.dnsdist/test_Protobuf.py | 14 ++-- .../test_ProxyProtocol.py | 10 +-- regression-tests.dnsdist/test_RestartQuery.py | 16 ++--- regression-tests.dnsdist/test_Routing.py | 66 +++++++++---------- regression-tests.dnsdist/test_TCPFastOpen.py | 10 +-- regression-tests.dnsdist/test_TCPLimits.py | 6 +- regression-tests.dnsdist/test_TCPShort.py | 10 +-- regression-tests.dnsdist/test_TLS.py | 20 +++--- .../test_TLSSessionResumption.py | 10 +-- regression-tests.dnsdist/test_TeeAction.py | 10 +-- regression-tests.dnsdist/test_Trailing.py | 8 +-- 33 files changed, 295 insertions(+), 271 deletions(-) diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 1cd53af708bd..579a63df61a0 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -42,6 +42,23 @@ except NameError: pass +def getWorkerID(): + if not 'PYTEST_XDIST_WORKER' in os.environ: + return 0 + workerName = os.environ['PYTEST_XDIST_WORKER'] + return int(workerName[2:]) + +workerPorts = {} + +def pickAvailablePort(): + global workerPorts + workerID = getWorkerID() + if workerID in workerPorts: + port = workerPorts[workerID] + 1 + else: + port = 11000 + (workerID * 1000) + workerPorts[workerID] = port + return port class DNSDistTest(AssertEqualDNSMessageMixin, unittest.TestCase): """ @@ -52,9 +69,7 @@ class DNSDistTest(AssertEqualDNSMessageMixin, unittest.TestCase): from dnsdist on a separate queue, allowing the tests to check that the queries sent from dnsdist were as expected. """ - _dnsDistPort = 5340 _dnsDistListeningAddr = "127.0.0.1" - _testServerPort = 5350 _toResponderQueue = Queue() _fromResponderQueue = Queue() _queueTimeout = 1 @@ -64,7 +79,6 @@ class DNSDistTest(AssertEqualDNSMessageMixin, unittest.TestCase): """ _config_params = ['_testServerPort'] _acl = ['127.0.0.1/32'] - _consolePort = 5199 _consoleKey = None _healthCheckName = 'a.root-servers.net.' _healthCheckCounter = 0 @@ -78,6 +92,9 @@ class DNSDistTest(AssertEqualDNSMessageMixin, unittest.TestCase): _UDPResponder = None _TCPResponder = None _extraStartupSleep = 0 + _dnsDistPort = pickAvailablePort() + _consolePort = pickAvailablePort() + _testServerPort = pickAvailablePort() @classmethod def waitForTCPSocket(cls, ipaddress, port): @@ -97,23 +114,28 @@ def waitForTCPSocket(cls, ipaddress, port): @classmethod def startResponders(cls): print("Launching responders..") + cls._testServerPort = pickAvailablePort() cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() cls.waitForTCPSocket("127.0.0.1", cls._testServerPort); @classmethod def startDNSDist(cls): + cls._dnsDistPort = pickAvailablePort() + cls._consolePort = pickAvailablePort() + print("Launching dnsdist..") confFile = os.path.join('configs', 'dnsdist_%s.conf' % (cls.__name__)) params = tuple([getattr(cls, param) for param in cls._config_params]) print(params) with open(confFile, 'w') as conf: conf.write("-- Autogenerated by dnsdisttests.py\n") + conf.write(f"-- dnsdist will listen on {cls._dnsDistPort}") conf.write(cls._config_template % params) conf.write("setSecurityPollSuffix('')") @@ -141,7 +163,7 @@ def startDNSDist(cls): else: expectedOutput = ('Configuration \'%s\' OK!\n' % (confFile)).encode() if not cls._verboseMode and output != expectedOutput: - raise AssertionError('dnsdist --check-config failed: %s' % output) + raise AssertionError('dnsdist --check-config failed: %s (expected %s)' % (output, expectedOutput)) logFile = os.path.join('configs', 'dnsdist_%s.log' % (cls.__name__)) with open(logFile, 'w') as fdLog: @@ -209,10 +231,10 @@ def tearDownClass(cls): @classmethod def _ResponderIncrementCounter(cls): - if threading.currentThread().name in cls._responsesCounter: - cls._responsesCounter[threading.currentThread().name] += 1 + if threading.current_thread().name in cls._responsesCounter: + cls._responsesCounter[threading.current_thread().name] += 1 else: - cls._responsesCounter[threading.currentThread().name] = 1 + cls._responsesCounter[threading.current_thread().name] = 1 @classmethod def _getResponse(cls, request, fromQueue, toQueue, synthesize=None): @@ -401,7 +423,7 @@ def TCPResponder(cls, port, fromQueue, toQueue, trailingDataResponse=False, mult thread = threading.Thread(name='TCP Connection Handler', target=cls.handleTCPConnection, args=[conn, fromQueue, toQueue, trailingDataResponse, multipleResponses, callback, partialWrite]) - thread.setDaemon(True) + thread.daemon = True thread.start() else: cls.handleTCPConnection(conn, fromQueue, toQueue, trailingDataResponse, multipleResponses, callback, partialWrite) @@ -545,7 +567,7 @@ def DOHResponder(cls, port, fromQueue, toQueue, trailingDataResponse=False, mult thread = threading.Thread(name='DoH Connection Handler', target=cls.handleDoHConnection, args=[config, conn, fromQueue, toQueue, trailingDataResponse, multipleResponses, callback, tlsContext, useProxyProtocol]) - thread.setDaemon(True) + thread.daemon = True thread.start() sock.close() diff --git a/regression-tests.dnsdist/requirements.txt b/regression-tests.dnsdist/requirements.txt index edfdb669ed32..3bc85702d228 100644 --- a/regression-tests.dnsdist/requirements.txt +++ b/regression-tests.dnsdist/requirements.txt @@ -1,5 +1,6 @@ dnspython>=2.2.0 -nose>=1.3.7 +pytest +pytest-xdist libnacl>=1.4.3,<1.7 requests>=2.1.0 protobuf>=3.0 diff --git a/regression-tests.dnsdist/runtests b/regression-tests.dnsdist/runtests index 36e0d50dcdd9..23e6e54e3354 100755 --- a/regression-tests.dnsdist/runtests +++ b/regression-tests.dnsdist/runtests @@ -45,15 +45,15 @@ make certs out=$(mktemp) set -o pipefail -if ! nosetests --with-xunit $@ 2>&1 | tee "${out}" ; then +if ! pytest --junitxml=pytest.xml --dist=loadfile -n auto $@ 2>&1 | tee "${out}" ; then for log in configs/*.log; do echo "=== ${log} ===" cat "${log}" echo done - echo "=== nosetests log ===" + echo "=== pytest log ===" cat "${out}" - echo "=== end of nosetests log ===" + echo "=== end of pytest log ===" false fi rm -f "${out}" diff --git a/regression-tests.dnsdist/test_API.py b/regression-tests.dnsdist/test_API.py index 54e0f94177f3..c89322569dc8 100644 --- a/regression-tests.dnsdist/test_API.py +++ b/regression-tests.dnsdist/test_API.py @@ -6,12 +6,12 @@ import requests import socket import time -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class APITestsBase(DNSDistTest): __test__ = False _webTimeout = 5.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerBasicAuthPassword = 'secret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' _webServerAPIKey = 'apisecret' diff --git a/regression-tests.dnsdist/test_AXFR.py b/regression-tests.dnsdist/test_AXFR.py index b1f3910788c2..2788c79044d3 100644 --- a/regression-tests.dnsdist/test_AXFR.py +++ b/regression-tests.dnsdist/test_AXFR.py @@ -2,7 +2,7 @@ import threading import time import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class TestAXFR(DNSDistTest): @@ -10,7 +10,7 @@ class TestAXFR(DNSDistTest): # because, contrary to the other ones, its # TCP responder allows multiple responses and we don't want # to mix things up. - _testServerPort = 5370 + _testServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%s"} """ @@ -21,10 +21,10 @@ def startResponders(cls): print("Launching responders..") cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, True, None, None, True]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() def setUp(self): diff --git a/regression-tests.dnsdist/test_Advanced.py b/regression-tests.dnsdist/test_Advanced.py index 530bf0190af7..5a0443ac8731 100644 --- a/regression-tests.dnsdist/test_Advanced.py +++ b/regression-tests.dnsdist/test_Advanced.py @@ -349,7 +349,7 @@ def testAdvancedGetLocalAddressOnAnyBind(self): query = query.to_wire() sock.send(query) (data, remote) = sock.recvfrom(4096) - self.assertEquals(remote[0], '127.0.0.2') + self.assertEqual(remote[0], '127.0.0.2') except socket.timeout: data = None @@ -383,7 +383,7 @@ def testAdvancedCheckSourceAddrOnAnyBind(self): data = query.to_wire() sock.send(data) (data, remote) = sock.recvfrom(4096) - self.assertEquals(remote[0], '127.0.0.2') + self.assertEqual(remote[0], '127.0.0.2') except socket.timeout: data = None @@ -406,7 +406,7 @@ def testAdvancedCheckSourceAddrOnAnyBind(self): data = query.to_wire() sock.send(data) (data, remote) = sock.recvfrom(4096) - self.assertEquals(remote[0], '::1') + self.assertEqual(remote[0], '::1') except socket.timeout: data = None @@ -454,7 +454,7 @@ def testAdvancedCheckSourceAddrOnNonDefaultLoopbackBind(self): data = query.to_wire() sock.send(data) (data, remote) = sock.recvfrom(4096) - self.assertEquals(remote[0], '127.0.1.19') + self.assertEqual(remote[0], '127.0.1.19') except socket.timeout: data = None diff --git a/regression-tests.dnsdist/test_Async.py b/regression-tests.dnsdist/test_Async.py index 1a982e3ab127..efda4f4cc731 100644 --- a/regression-tests.dnsdist/test_Async.py +++ b/regression-tests.dnsdist/test_Async.py @@ -5,7 +5,7 @@ import threading import unittest import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort def AsyncResponder(listenPath, responsePath): # Make sure the socket does not already exist @@ -81,7 +81,7 @@ def AsyncResponder(listenPath, responsePath): asyncResponderSocketPath = '/tmp/async-responder.sock' dnsdistSocketPath = '/tmp/dnsdist.sock' asyncResponder = threading.Thread(name='Asynchronous Responder', target=AsyncResponder, args=[asyncResponderSocketPath, dnsdistSocketPath]) -asyncResponder.setDaemon(True) +asyncResponder.daemon = True asyncResponder.start() class AsyncTests(object): @@ -439,8 +439,8 @@ class TestAsyncFFI(DNSDistTest, AsyncTests): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 - _dohServerPort = 8443 + _tlsServerPort = pickAvailablePort() + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ @@ -549,8 +549,8 @@ class TestAsyncLua(DNSDistTest, AsyncTests): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 - _dohServerPort = 8443 + _tlsServerPort = pickAvailablePort() + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ diff --git a/regression-tests.dnsdist/test_BackendDiscovery.py b/regression-tests.dnsdist/test_BackendDiscovery.py index 0521523ae1f8..c4178d94c415 100644 --- a/regression-tests.dnsdist/test_BackendDiscovery.py +++ b/regression-tests.dnsdist/test_BackendDiscovery.py @@ -8,6 +8,7 @@ from dnsdisttests import DNSDistTest class TestBackendDiscovery(DNSDistTest): + # these ports are hardcoded for now, sorry about that! _noSVCBackendPort = 10600 _svcNoUpgradeBackendPort = 10601 _svcUpgradeDoTBackendPort = 10602 @@ -261,90 +262,90 @@ def startResponders(cls): tlsContext.load_cert_chain('server.chain', 'server.key') TCPNoSVCResponder = threading.Thread(name='TCP no SVC Responder', target=cls.TCPResponder, args=[cls._noSVCBackendPort, cls._toResponderQueue, cls._fromResponderQueue, True, False, cls.NoSVCCallback]) - TCPNoSVCResponder.setDaemon(True) + TCPNoSVCResponder.daemon = True TCPNoSVCResponder.start() TCPNoUpgradeResponder = threading.Thread(name='TCP no upgrade Responder', target=cls.TCPResponder, args=[cls._svcNoUpgradeBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.NoUpgradePathCallback]) - TCPNoUpgradeResponder.setDaemon(True) + TCPNoUpgradeResponder.daemon = True TCPNoUpgradeResponder.start() # this one is special, does partial writes! TCPUpgradeToDoTResponder = threading.Thread(name='TCP upgrade to DoT Responder', target=cls.TCPResponder, args=[cls._svcUpgradeDoTBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.UpgradeDoTCallback, None, False, '127.0.0.1', True]) - TCPUpgradeToDoTResponder.setDaemon(True) + TCPUpgradeToDoTResponder.daemon = True TCPUpgradeToDoTResponder.start() # and the corresponding DoT responder UpgradedDoTResponder = threading.Thread(name='DoT upgraded Responder', target=cls.TCPResponder, args=[10652, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - UpgradedDoTResponder.setDaemon(True) + UpgradedDoTResponder.daemon = True UpgradedDoTResponder.start() TCPUpgradeToDoHResponder = threading.Thread(name='TCP upgrade to DoH Responder', target=cls.TCPResponder, args=[cls._svcUpgradeDoHBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.UpgradeDoHCallback]) - TCPUpgradeToDoHResponder.setDaemon(True) + TCPUpgradeToDoHResponder.daemon = True TCPUpgradeToDoHResponder.start() # and the corresponding DoH responder UpgradedDOHResponder = threading.Thread(name='DOH Responder', target=cls.DOHResponder, args=[10653, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - UpgradedDOHResponder.setDaemon(True) + UpgradedDOHResponder.daemon = True UpgradedDOHResponder.start() TCPUpgradeToDoTDifferentAddrResponder = threading.Thread(name='TCP upgrade to DoT different addr 1 Responder', target=cls.TCPResponder, args=[cls._svcUpgradeDoTBackendDifferentAddrPort1, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.UpgradeDoTDifferentAddr1Callback]) - TCPUpgradeToDoTDifferentAddrResponder.setDaemon(True) + TCPUpgradeToDoTDifferentAddrResponder.daemon = True TCPUpgradeToDoTDifferentAddrResponder.start() # and the corresponding DoT responder UpgradedDoTResponder = threading.Thread(name='DoT upgraded different addr 1 Responder', target=cls.TCPResponder, args=[10654, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext, False, '127.0.0.2']) - UpgradedDoTResponder.setDaemon(True) + UpgradedDoTResponder.daemon = True UpgradedDoTResponder.start() TCPUpgradeToDoTDifferentAddrResponder = threading.Thread(name='TCP upgrade to DoT different addr 2 Responder', target=cls.TCPResponder, args=[cls._svcUpgradeDoTBackendDifferentAddrPort2, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.UpgradeDoTDifferentAddr2Callback, None, False, '127.0.0.2']) - TCPUpgradeToDoTDifferentAddrResponder.setDaemon(True) + TCPUpgradeToDoTDifferentAddrResponder.daemon = True TCPUpgradeToDoTDifferentAddrResponder.start() # and the corresponding DoT responder UpgradedDoTResponder = threading.Thread(name='DoT upgraded different addr 2 Responder', target=cls.TCPResponder, args=[10655, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext, False]) - UpgradedDoTResponder.setDaemon(True) + UpgradedDoTResponder.daemon = True UpgradedDoTResponder.start() TCPUpgradeToUnreachableDoTResponder = threading.Thread(name='TCP upgrade to unreachable DoT Responder', target=cls.TCPResponder, args=[cls._svcUpgradeDoTUnreachableBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.UpgradeDoTUnreachableCallback]) - TCPUpgradeToUnreachableDoTResponder.setDaemon(True) + TCPUpgradeToUnreachableDoTResponder.daemon = True TCPUpgradeToUnreachableDoTResponder.start() # and NO corresponding DoT responder # this is not a mistake! BrokenResponseResponder = threading.Thread(name='Broken response Responder', target=cls.TCPResponder, args=[cls._svcBrokenDNSResponseBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.BrokenResponseCallback]) - BrokenResponseResponder.setDaemon(True) + BrokenResponseResponder.daemon = True BrokenResponseResponder.start() DOHMissingPathResponder = threading.Thread(name='DoH missing path Responder', target=cls.TCPResponder, args=[cls._svcUpgradeDoHBackendWithoutPathPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.UpgradeDoHMissingPathCallback]) - DOHMissingPathResponder.setDaemon(True) + DOHMissingPathResponder.daemon = True DOHMissingPathResponder.start() EOFResponder = threading.Thread(name='EOF Responder', target=cls.TCPResponder, args=[cls._eofBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.EOFCallback]) - EOFResponder.setDaemon(True) + EOFResponder.daemon = True EOFResponder.start() ServFailResponder = threading.Thread(name='ServFail Responder', target=cls.TCPResponder, args=[cls._servfailBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.ServFailCallback]) - ServFailResponder.setDaemon(True) + ServFailResponder.daemon = True ServFailResponder.start() WrongNameResponder = threading.Thread(name='Wrong Name Responder', target=cls.TCPResponder, args=[cls._wrongNameBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.WrongNameCallback]) - WrongNameResponder.setDaemon(True) + WrongNameResponder.daemon = True WrongNameResponder.start() WrongIDResponder = threading.Thread(name='Wrong ID Responder', target=cls.TCPResponder, args=[cls._wrongIDBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.WrongIDCallback]) - WrongIDResponder.setDaemon(True) + WrongIDResponder.daemon = True WrongIDResponder.start() TooManyQuestionsResponder = threading.Thread(name='Too many questions Responder', target=cls.TCPResponder, args=[cls._tooManyQuestionsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.TooManyQuestionsCallback]) - TooManyQuestionsResponder.setDaemon(True) + TooManyQuestionsResponder.daemon = True TooManyQuestionsResponder.start() badQNameResponder = threading.Thread(name='Bad QName Responder', target=cls.TCPResponder, args=[cls._badQNameBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.BadQNameCallback]) - badQNameResponder.setDaemon(True) + badQNameResponder.daemon = True badQNameResponder.start() TCPUpgradeToDoTNoPortResponder = threading.Thread(name='TCP upgrade to DoT (no port) Responder', target=cls.TCPResponder, args=[cls._svcUpgradeDoTNoPortBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.UpgradeDoTNoPortCallback]) - TCPUpgradeToDoTNoPortResponder.setDaemon(True) + TCPUpgradeToDoTNoPortResponder.daemon = True TCPUpgradeToDoTNoPortResponder.start() TCPUpgradeToDoHNoPortResponder = threading.Thread(name='TCP upgrade to DoH (no port) Responder', target=cls.TCPResponder, args=[cls._svcUpgradeDoHNoPortBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.UpgradeDoHNoPortCallback]) - TCPUpgradeToDoHNoPortResponder.setDaemon(True) + TCPUpgradeToDoHNoPortResponder.daemon = True TCPUpgradeToDoHNoPortResponder.start() @@ -362,9 +363,9 @@ def checkBackendsUpgraded(self): # in this particular case, the upgraded backend # does not replace the existing one and thus # the health-check is forced to auto (or lazy auto) - self.assertEquals(tokens[2], 'up') + self.assertEqual(tokens[2], 'up') else: - self.assertEquals(tokens[2], 'UP') + self.assertEqual(tokens[2], 'UP') pool = '' if len(tokens) == 14: pool = tokens[13] diff --git a/regression-tests.dnsdist/test_BrokenAnswer.py b/regression-tests.dnsdist/test_BrokenAnswer.py index 78bd713358be..6fad94c51035 100644 --- a/regression-tests.dnsdist/test_BrokenAnswer.py +++ b/regression-tests.dnsdist/test_BrokenAnswer.py @@ -2,7 +2,7 @@ import threading import clientsubnetoption import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort def responseCallback(request): if len(request.question) != 1: @@ -33,7 +33,7 @@ class TestBrokenAnswerECS(DNSDistTest): # this test suite uses a different responder port # because, contrary to the other ones, its # responders send raw, broken data - _testServerPort = 5400 + _testServerPort = pickAvailablePort() _config_template = """ setECSSourcePrefixV4(32) newServer{address="127.0.0.1:%s", useClientSubnet=true} @@ -44,12 +44,12 @@ def startResponders(cls): # Returns broken data for non-healthcheck queries cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, responseCallback]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() # Returns broken data for non-healthcheck queries cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, responseCallback]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() def testUDPWithInvalidAnswer(self): diff --git a/regression-tests.dnsdist/test_Caching.py b/regression-tests.dnsdist/test_Caching.py index 5c95ef36c9cb..d7539836e8d5 100644 --- a/regression-tests.dnsdist/test_Caching.py +++ b/regression-tests.dnsdist/test_Caching.py @@ -5,7 +5,7 @@ import clientsubnetoption import cookiesoption import requests -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class TestCaching(DNSDistTest): @@ -2785,7 +2785,7 @@ def testCachingBackendSetRD(self): class TestAPICache(DNSDistTest): _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerBasicAuthPassword = 'secret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' _webServerAPIKey = 'apisecret' diff --git a/regression-tests.dnsdist/test_Carbon.py b/regression-tests.dnsdist/test_Carbon.py index 4d26c54a3c0d..d697fc8a1279 100644 --- a/regression-tests.dnsdist/test_Carbon.py +++ b/regression-tests.dnsdist/test_Carbon.py @@ -3,13 +3,13 @@ import socket import sys import time -from dnsdisttests import DNSDistTest, Queue +from dnsdisttests import DNSDistTest, Queue, pickAvailablePort class TestCarbon(DNSDistTest): - _carbonServer1Port = 8000 + _carbonServer1Port = pickAvailablePort() _carbonServer1Name = "carbonname1" - _carbonServer2Port = 8001 + _carbonServer2Port = pickAvailablePort() _carbonServer2Name = "carbonname2" _carbonQueue1 = Queue() _carbonQueue2 = Queue() @@ -53,10 +53,10 @@ def CarbonResponder(cls, port): cls._carbonQueue1.put(lines, True, timeout=2.0) else: cls._carbonQueue2.put(lines, True, timeout=2.0) - if threading.currentThread().name in cls._carbonCounters: - cls._carbonCounters[threading.currentThread().name] += 1 + if threading.current_thread().name in cls._carbonCounters: + cls._carbonCounters[threading.current_thread().name] += 1 else: - cls._carbonCounters[threading.currentThread().name] = 1 + cls._carbonCounters[threading.current_thread().name] = 1 conn.close() sock.close() @@ -64,11 +64,11 @@ def CarbonResponder(cls, port): @classmethod def startResponders(cls): cls._CarbonResponder1 = threading.Thread(name='Carbon Responder 1', target=cls.CarbonResponder, args=[cls._carbonServer1Port]) - cls._CarbonResponder1.setDaemon(True) + cls._CarbonResponder1.daemon = True cls._CarbonResponder1.start() cls._CarbonResponder2 = threading.Thread(name='Carbon Responder 2', target=cls.CarbonResponder, args=[cls._carbonServer2Port]) - cls._CarbonResponder2.setDaemon(True) + cls._CarbonResponder2.daemon = True cls._CarbonResponder2.start() def isfloat(self, num): diff --git a/regression-tests.dnsdist/test_DNSCrypt.py b/regression-tests.dnsdist/test_DNSCrypt.py index c67b983558c7..6f8df586ec3d 100644 --- a/regression-tests.dnsdist/test_DNSCrypt.py +++ b/regression-tests.dnsdist/test_DNSCrypt.py @@ -4,7 +4,7 @@ import time import dns import dns.message -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort import dnscrypt class DNSCryptTest(DNSDistTest): @@ -15,8 +15,7 @@ class DNSCryptTest(DNSDistTest): Be careful to change the _providerFingerprint below if you want to regenerate the keys. """ - _dnsDistPort = 5340 - _dnsDistPortDNSCrypt = 8443 + _dnsDistPortDNSCrypt = pickAvailablePort() _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') @@ -76,7 +75,7 @@ def testSimpleA(self): """ DNSCrypt: encrypted A query """ - client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) + client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", self._dnsDistPortDNSCrypt) name = 'a.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) @@ -98,7 +97,7 @@ def testResponseLargerThanPaddedQuery(self): the padding into account) and check that the response is truncated. """ - client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) + client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", self._dnsDistPortDNSCrypt) name = 'smallquerylargeresponse.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'TXT', 'IN', use_edns=True, payload=4096) response = dns.message.make_response(query) @@ -130,7 +129,7 @@ def testCertRotation(self): """ DNSCrypt: certificate rotation """ - client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) + client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", self._dnsDistPortDNSCrypt) client.refreshResolverCertificates() cert = client.getResolverCertificate() @@ -248,7 +247,7 @@ def testProtocolUDP(self): """ DNSCrypt: Test DNSQuestion.Protocol over UDP """ - client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) + client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", self._dnsDistPortDNSCrypt) name = 'udp.protocols.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) @@ -259,7 +258,7 @@ def testProtocolTCP(self): """ DNSCrypt: Test DNSQuestion.Protocol over TCP """ - client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) + client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", self._dnsDistPortDNSCrypt) name = 'tcp.protocols.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) @@ -282,7 +281,7 @@ def testCachedSimpleA(self): DNSCrypt: encrypted A query served from cache """ misses = 0 - client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) + client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", self._dnsDistPortDNSCrypt) name = 'cacheda.dnscrypt.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) @@ -349,7 +348,7 @@ def testCertRotation(self): """ DNSCrypt: automatic certificate rotation """ - client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", 8443) + client = dnscrypt.DNSCryptClient(self._providerName, self._providerFingerprint, "127.0.0.1", self._dnsDistPortDNSCrypt) client.refreshResolverCertificates() cert = client.getResolverCertificate() diff --git a/regression-tests.dnsdist/test_DOH.py b/regression-tests.dnsdist/test_DOH.py index 2dd016fd1b66..5999021f5dd8 100644 --- a/regression-tests.dnsdist/test_DOH.py +++ b/regression-tests.dnsdist/test_DOH.py @@ -7,6 +7,7 @@ import clientsubnetoption from dnsdistdohtests import DNSDistDOHTest +from dnsdisttests import pickAvailablePort import pycurl from io import BytesIO @@ -17,7 +18,7 @@ class TestDOH(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _customResponseHeader1 = 'access-control-allow-origin: *' _customResponseHeader2 = 'user-agent: derp' _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) @@ -527,7 +528,7 @@ class TestDOHSubPaths(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s"} @@ -585,7 +586,7 @@ class TestDOHAddingECS(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s", useClientSubnet=true} @@ -676,7 +677,7 @@ def testDOHExistingECS(self): class TestDOHOverHTTP(DNSDistDOHTest): - _dohServerPort = 8480 + _dohServerPort = pickAvailablePort() _serverName = 'tls.tests.dnsdist.org' _dohBaseURL = ("http://%s:%d/dns-query" % (_serverName, _dohServerPort)) _config_template = """ @@ -684,9 +685,9 @@ class TestDOHOverHTTP(DNSDistDOHTest): addDOHLocal("127.0.0.1:%s") """ _config_params = ['_testServerPort', '_dohServerPort'] - _checkConfigExpectedOutput = b"""No certificate provided for DoH endpoint 127.0.0.1:8480, running in DNS over HTTP mode instead of DNS over HTTPS + _checkConfigExpectedOutput = b"""No certificate provided for DoH endpoint 127.0.0.1:%d, running in DNS over HTTP mode instead of DNS over HTTPS Configuration 'configs/dnsdist_TestDOHOverHTTP.conf' OK! -""" +""" % (_dohServerPort) def testDOHSimple(self): """ @@ -745,7 +746,7 @@ class TestDOHWithCache(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/dns-query" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s"} @@ -954,7 +955,7 @@ class TestDOHWithoutCacheControl(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s"} @@ -995,7 +996,7 @@ class TestDOHFFI(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _customResponseHeader1 = 'access-control-allow-origin: *' _customResponseHeader2 = 'user-agent: derp' _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) @@ -1057,7 +1058,7 @@ class TestDOHForwardedFor(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s"} @@ -1123,7 +1124,7 @@ class TestDOHForwardedForNoTrusted(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s"} @@ -1159,14 +1160,14 @@ class TestDOHFrontendLimits(DNSDistDOHTest): # this test suite uses a different responder port # because it uses a different health check configuration - _testServerPort = 5395 + _testServerPort = pickAvailablePort() _answerUnexpected = True _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _skipListeningOnCL = True @@ -1227,7 +1228,7 @@ class TestProtocols(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _customResponseHeader1 = 'access-control-allow-origin: *' _customResponseHeader2 = 'user-agent: derp' _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) @@ -1268,7 +1269,7 @@ class TestDOHWithPKCS12Cert(DNSDistDOHTest): _pkcs12Password = 'passw0rd' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s"} @@ -1305,7 +1306,7 @@ class TestDOHForwardedToTCPOnly(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s", tcpOnly=true} @@ -1338,7 +1339,7 @@ def testDOHTCPOnly(self): class TestDOHLimits(DNSDistDOHTest): _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _serverKey = 'server.key' _serverCert = 'server.chain' diff --git a/regression-tests.dnsdist/test_Dnstap.py b/regression-tests.dnsdist/test_Dnstap.py index 18c39ca0fbbd..1b699f152757 100644 --- a/regression-tests.dnsdist/test_Dnstap.py +++ b/regression-tests.dnsdist/test_Dnstap.py @@ -5,7 +5,7 @@ import struct import sys import time -from dnsdisttests import DNSDistTest, Queue +from dnsdisttests import DNSDistTest, Queue, pickAvailablePort import dns import dnstap_pb2 @@ -78,7 +78,7 @@ def checkDnstapResponse(testinstance, dnstap, protocol, response, initiator='127 class TestDnstapOverRemoteLogger(DNSDistTest): - _remoteLoggerServerPort = 4243 + _remoteLoggerServerPort = pickAvailablePort() _remoteLoggerQueue = Queue() _remoteLoggerCounter = 0 _config_params = ['_testServerPort', '_remoteLoggerServerPort'] @@ -151,7 +151,7 @@ def startResponders(cls): DNSDistTest.startResponders() cls._remoteLoggerListener = threading.Thread(name='RemoteLogger Listener', target=cls.RemoteLoggerListener, args=[cls._remoteLoggerServerPort]) - cls._remoteLoggerListener.setDaemon(True) + cls._remoteLoggerListener.daemon = True cls._remoteLoggerListener.start() def getFirstDnstap(self): @@ -384,7 +384,7 @@ def startResponders(cls): DNSDistTest.startResponders() cls._fstrmLoggerListener = threading.Thread(name='FrameStreamUnixListener', target=cls.FrameStreamUnixListener, args=[cls._fstrmLoggerAddress]) - cls._fstrmLoggerListener.setDaemon(True) + cls._fstrmLoggerListener.daemon = True cls._fstrmLoggerListener.start() def getFirstDnstap(self): @@ -433,7 +433,7 @@ def testDnstapOverFrameStreamUnix(self): class TestDnstapOverFrameStreamTcpLogger(DNSDistTest): - _fstrmLoggerPort = 4000 + _fstrmLoggerPort = pickAvailablePort() _fstrmLoggerQueue = Queue() _fstrmLoggerCounter = 0 _config_params = ['_testServerPort', '_fstrmLoggerPort'] @@ -466,7 +466,7 @@ def startResponders(cls): DNSDistTest.startResponders() cls._fstrmLoggerListener = threading.Thread(name='FrameStreamUnixListener', target=cls.FrameStreamUnixListener, args=[cls._fstrmLoggerPort]) - cls._fstrmLoggerListener.setDaemon(True) + cls._fstrmLoggerListener.daemon = True cls._fstrmLoggerListener.start() def getFirstDnstap(self): diff --git a/regression-tests.dnsdist/test_DynBlocks.py b/regression-tests.dnsdist/test_DynBlocks.py index 949080e87910..8b9ef6fb6ef3 100644 --- a/regression-tests.dnsdist/test_DynBlocks.py +++ b/regression-tests.dnsdist/test_DynBlocks.py @@ -5,7 +5,7 @@ import socket import time import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort try: range = xrange except NameError: @@ -14,7 +14,7 @@ class DynBlocksTest(DNSDistTest): _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerBasicAuthPassword = 'secret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' _webServerAPIKey = 'apisecret' diff --git a/regression-tests.dnsdist/test_HealthChecks.py b/regression-tests.dnsdist/test_HealthChecks.py index c1ec51b85d64..7a5c6b7e0c06 100644 --- a/regression-tests.dnsdist/test_HealthChecks.py +++ b/regression-tests.dnsdist/test_HealthChecks.py @@ -5,13 +5,13 @@ import threading import time import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class HealthCheckTest(DNSDistTest): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerAPIKey = 'apisecret' _webServerAPIKeyHashed = '$scrypt$ln=10,p=1,r=8$9v8JxDfzQVyTpBkTbkUqYg==$bDQzAOHeK1G9UvTPypNhrX48w974ZXbFPtRKS34+aso=' _config_params = ['_consoleKeyB64', '_consolePort', '_webServerPort', '_webServerAPIKeyHashed', '_testServerPort'] @@ -42,7 +42,7 @@ def getBackendMetric(self, backendID, metricName): class TestDefaultHealthCheck(HealthCheckTest): # this test suite uses a different responder port # because we need fresh counters - _testServerPort = 5380 + _testServerPort = pickAvailablePort() def testDefault(self): """ @@ -90,7 +90,7 @@ def testDefault(self): class TestHealthCheckForcedUP(HealthCheckTest): # this test suite uses a different responder port # because we need fresh counters - _testServerPort = 5381 + _testServerPort = pickAvailablePort() _config_template = """ setKey("%s") @@ -114,7 +114,7 @@ def testForcedUp(self): class TestHealthCheckForcedDown(HealthCheckTest): # this test suite uses a different responder port # because we need fresh counters - _testServerPort = 5382 + _testServerPort = pickAvailablePort() _config_template = """ setKey("%s") @@ -137,7 +137,7 @@ def testForcedDown(self): class TestHealthCheckCustomName(HealthCheckTest): # this test suite uses a different responder port # because it uses a different health check name - _testServerPort = 5383 + _testServerPort = pickAvailablePort() _healthCheckName = 'powerdns.com.' _config_params = ['_consoleKeyB64', '_consolePort', '_webServerPort', '_webServerAPIKeyHashed', '_testServerPort', '_healthCheckName'] @@ -162,7 +162,7 @@ def testAuto(self): class TestHealthCheckCustomNameNoAnswer(HealthCheckTest): # this test suite uses a different responder port # because it uses a different health check configuration - _testServerPort = 5384 + _testServerPort = pickAvailablePort() _answerUnexpected = False _config_template = """ @@ -187,7 +187,7 @@ def testAuto(self): class TestHealthCheckCustomFunction(HealthCheckTest): # this test suite uses a different responder port # because it uses a different health check configuration - _testServerPort = 5385 + _testServerPort = pickAvailablePort() _answerUnexpected = False _healthCheckName = 'powerdns.com.' @@ -221,9 +221,9 @@ def testAuto(self): class TestLazyHealthChecks(HealthCheckTest): _extraStartupSleep = 1 - _do53Port = 10700 - _dotPort = 10701 - _dohPort = 10702 + _do53Port = pickAvailablePort() + _dotPort = pickAvailablePort() + _dohPort = pickAvailablePort() _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') @@ -282,19 +282,19 @@ def startResponders(cls): tlsContext.load_cert_chain('server.chain', 'server.key') Do53Responder = threading.Thread(name='Do53 Lazy Responder', target=cls.UDPResponder, args=[cls._do53Port, cls._toResponderQueue, cls._fromResponderQueue, False, cls.Do53Callback]) - Do53Responder.setDaemon(True) + Do53Responder.daemon = True Do53Responder.start() Do53TCPResponder = threading.Thread(name='Do53 TCP Lazy Responder', target=cls.TCPResponder, args=[cls._do53Port, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.Do53Callback]) - Do53TCPResponder.setDaemon(True) + Do53TCPResponder.daemon = True Do53TCPResponder.start() DoTResponder = threading.Thread(name='DoT Lazy Responder', target=cls.TCPResponder, args=[cls._dotPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.DoTCallback, tlsContext]) - DoTResponder.setDaemon(True) + DoTResponder.daemon = True DoTResponder.start() DoHResponder = threading.Thread(name='DoH Lazy Responder', target=cls.DOHResponder, args=[cls._dohPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.DoHCallback, tlsContext]) - DoHResponder.setDaemon(True) + DoHResponder.daemon = True DoHResponder.start() def testDo53Lazy(self): diff --git a/regression-tests.dnsdist/test_Metrics.py b/regression-tests.dnsdist/test_Metrics.py index 5a70d0d8cefd..3f35554283bb 100644 --- a/regression-tests.dnsdist/test_Metrics.py +++ b/regression-tests.dnsdist/test_Metrics.py @@ -6,7 +6,7 @@ import threading import unittest import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class TestRuleMetrics(DNSDistTest): @@ -27,15 +27,15 @@ class TestRuleMetrics(DNSDistTest): addAction('cache.metrics.tests.powerdns.com', PoolAction('cache')) """ _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerAPIKey = 'apisecret' _webServerAPIKeyHashed = '$scrypt$ln=10,p=1,r=8$9v8JxDfzQVyTpBkTbkUqYg==$bDQzAOHeK1G9UvTPypNhrX48w974ZXbFPtRKS34+aso=' _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 - _dohServerPort = 8443 + _tlsServerPort = pickAvailablePort() + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_params = ['_tlsServerPort', '_serverCert', '_serverKey', '_dohServerPort', '_serverCert', '_serverKey', '_testServerPort', '_webServerPort', '_webServerAPIKeyHashed'] diff --git a/regression-tests.dnsdist/test_OCSP.py b/regression-tests.dnsdist/test_OCSP.py index a8577baea16e..953415082441 100644 --- a/regression-tests.dnsdist/test_OCSP.py +++ b/regression-tests.dnsdist/test_OCSP.py @@ -4,7 +4,7 @@ import os import subprocess import unittest -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class DNSDistOCSPStaplingTest(DNSDistTest): @@ -46,7 +46,7 @@ class TestOCSPStaplingDOH(DNSDistOCSPStaplingTest): _ocspFile = 'server.ocsp' _caCert = 'ca.pem' _caKey = 'ca.key' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%s"} setKey("%s") @@ -101,7 +101,7 @@ class TestBrokenOCSPStaplingDoH(DNSDistOCSPStaplingTest): _caCert = 'ca.pem' # invalid OCSP file! _ocspFile = '/dev/null' - _tlsServerPort = 8443 + _tlsServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%s"} setKey("%s") @@ -128,7 +128,7 @@ class TestOCSPStaplingTLSGnuTLS(DNSDistOCSPStaplingTest): _ocspFile = 'server.ocsp' _caCert = 'ca.pem' _caKey = 'ca.key' - _tlsServerPort = 8443 + _tlsServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%s"} setKey("%s") @@ -146,7 +146,7 @@ def testOCSPStapling(self): """ output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert) self.assertIn('OCSP Response Status: successful (0x0)', output) - self.assertEquals(self.getTLSProvider(), "gnutls") + self.assertEqual(self.getTLSProvider(), "gnutls") serialNumber = self.getOCSPSerial(output) self.assertTrue(serialNumber) @@ -171,7 +171,7 @@ class TestBrokenOCSPStaplingTLSGnuTLS(DNSDistOCSPStaplingTest): _caCert = 'ca.pem' # invalid OCSP file! _ocspFile = '/dev/null' - _tlsServerPort = 8443 + _tlsServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%s"} setKey("%s") @@ -187,7 +187,7 @@ def testBrokenOCSPStapling(self): """ output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert) self.assertNotIn('OCSP Response Status: successful (0x0)', output) - self.assertEquals(self.getTLSProvider(), "gnutls") + self.assertEqual(self.getTLSProvider(), "gnutls") class TestOCSPStaplingTLSOpenSSL(DNSDistOCSPStaplingTest): @@ -199,7 +199,7 @@ class TestOCSPStaplingTLSOpenSSL(DNSDistOCSPStaplingTest): _ocspFile = 'server.ocsp' _caCert = 'ca.pem' _caKey = 'ca.key' - _tlsServerPort = 8443 + _tlsServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%s"} setKey("%s") @@ -217,7 +217,7 @@ def testOCSPStapling(self): """ output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert) self.assertIn('OCSP Response Status: successful (0x0)', output) - self.assertEquals(self.getTLSProvider(), "openssl") + self.assertEqual(self.getTLSProvider(), "openssl") serialNumber = self.getOCSPSerial(output) self.assertTrue(serialNumber) @@ -242,7 +242,7 @@ class TestBrokenOCSPStaplingTLSOpenSSL(DNSDistOCSPStaplingTest): _caCert = 'ca.pem' # invalid OCSP file! _ocspFile = '/dev/null' - _tlsServerPort = 8443 + _tlsServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%s"} setKey("%s") @@ -258,4 +258,4 @@ def testBrokenOCSPStapling(self): """ output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert) self.assertNotIn('OCSP Response Status: successful (0x0)', output) - self.assertEquals(self.getTLSProvider(), "openssl") + self.assertEqual(self.getTLSProvider(), "openssl") diff --git a/regression-tests.dnsdist/test_OOOR.py b/regression-tests.dnsdist/test_OOOR.py index a7364b9daf6e..aa9b76af78f3 100644 --- a/regression-tests.dnsdist/test_OOOR.py +++ b/regression-tests.dnsdist/test_OOOR.py @@ -4,7 +4,7 @@ import struct import time import threading -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class OOORTCPResponder(object): @@ -62,7 +62,7 @@ def __init__(self, port): thread = threading.Thread(name='Connection Handler', target=self.handleConnection, args=[conn]) - thread.setDaemon(True) + thread.daemon = True thread.start() sock.close() @@ -132,20 +132,20 @@ def __init__(self, port): thread = threading.Thread(name='Connection Handler', target=self.handleConnection, args=[conn]) - thread.setDaemon(True) + thread.daemon = True thread.start() sock.close() -OOORResponderPort = 5371 +OOORResponderPort = pickAvailablePort() ooorTCPResponder = threading.Thread(name='TCP Responder', target=OOORTCPResponder, args=[OOORResponderPort]) -ooorTCPResponder.setDaemon(True) +ooorTCPResponder.daemon = True ooorTCPResponder.start() -ReverseOOORResponderPort = 5372 +ReverseOOORResponderPort = pickAvailablePort() ReverseOoorTCPResponder = threading.Thread(name='TCP Responder', target=ReverseOOORTCPResponder, args=[ReverseOOORResponderPort]) -ReverseOoorTCPResponder.setDaemon(True) +ReverseOoorTCPResponder.daemon = True ReverseOoorTCPResponder.start() class TestOOORWithClientNotBackend(DNSDistTest): diff --git a/regression-tests.dnsdist/test_OutgoingDOH.py b/regression-tests.dnsdist/test_OutgoingDOH.py index 55c7ba57ca2f..4f73a5a6b7aa 100644 --- a/regression-tests.dnsdist/test_OutgoingDOH.py +++ b/regression-tests.dnsdist/test_OutgoingDOH.py @@ -7,12 +7,12 @@ import threading import time -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class OutgoingDOHTests(object): _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerBasicAuthPassword = 'secret' _webServerAPIKey = 'apisecret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' @@ -148,7 +148,7 @@ def testZHealthChecks(self): class BrokenOutgoingDOHTests(object): _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerBasicAuthPassword = 'secret' _webServerAPIKey = 'apisecret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' @@ -192,7 +192,7 @@ def testTCP(self): class OutgoingDOHBrokenResponsesTests(object): _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerBasicAuthPassword = 'secret' _webServerAPIKey = 'apisecret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' @@ -263,7 +263,7 @@ def testTCP(self): self.assertEqual(response, receivedResponse) class TestOutgoingDOHOpenSSL(DNSDistTest, OutgoingDOHTests): - _tlsBackendPort = 10543 + _tlsBackendPort = pickAvailablePort() _tlsProvider = 'openssl' _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') @@ -299,11 +299,11 @@ def startResponders(cls): print("Launching DOH responder..") cls._DOHResponder = threading.Thread(name='DOH Responder', target=cls.DOHResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._DOHResponder.setDaemon(True) + cls._DOHResponder.daemon = True cls._DOHResponder.start() class TestOutgoingDOHGnuTLS(DNSDistTest, OutgoingDOHTests): - _tlsBackendPort = 10544 + _tlsBackendPort = pickAvailablePort() _tlsProvider = 'gnutls' _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') @@ -331,11 +331,11 @@ def startResponders(cls): print("Launching DOH responder..") cls._DOHResponder = threading.Thread(name='DOH Responder', target=cls.DOHResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._DOHResponder.setDaemon(True) + cls._DOHResponder.daemon = True cls._DOHResponder.start() class TestOutgoingDOHOpenSSLWrongCertName(DNSDistTest, BrokenOutgoingDOHTests): - _tlsBackendPort = 10545 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] _config_template = """ setMaxTCPClientThreads(1) @@ -351,11 +351,11 @@ def startResponders(cls): print("Launching DOH responder..") cls._DOHResponder = threading.Thread(name='DOH Responder', target=cls.DOHResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._DOHResponder.setDaemon(True) + cls._DOHResponder.daemon = True cls._DOHResponder.start() class TestOutgoingDOHGnuTLSWrongCertName(DNSDistTest, BrokenOutgoingDOHTests): - _tlsBackendPort = 10546 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] _config_template = """ setMaxTCPClientThreads(1) @@ -371,11 +371,11 @@ def startResponders(cls): print("Launching DOH responder..") cls._DOHResponder = threading.Thread(name='DOH Responder', target=cls.DOHResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._DOHResponder.setDaemon(True) + cls._DOHResponder.daemon = True cls._DOHResponder.start() class TestOutgoingDOHOpenSSLWrongCertNameButNoCheck(DNSDistTest, OutgoingDOHTests): - _tlsBackendPort = 10547 + _tlsBackendPort = pickAvailablePort() _tlsProvider = 'openssl' _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') @@ -402,11 +402,11 @@ def startResponders(cls): print("Launching DOH responder..") cls._DOHResponder = threading.Thread(name='DOH Responder', target=cls.DOHResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._DOHResponder.setDaemon(True) + cls._DOHResponder.daemon = True cls._DOHResponder.start() class TestOutgoingDOHGnuTLSWrongCertNameButNoCheck(DNSDistTest, OutgoingDOHTests): - _tlsBackendPort = 10548 + _tlsBackendPort = pickAvailablePort() _tlsProvider = 'gnutls' _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') @@ -433,11 +433,11 @@ def startResponders(cls): print("Launching DOH responder..") cls._DOHResponder = threading.Thread(name='DOH Responder', target=cls.DOHResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._DOHResponder.setDaemon(True) + cls._DOHResponder.daemon = True cls._DOHResponder.start() class TestOutgoingDOHBrokenResponsesOpenSSL(DNSDistTest, OutgoingDOHBrokenResponsesTests): - _tlsBackendPort = 10549 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] _config_template = """ setMaxTCPClientThreads(1) @@ -475,11 +475,11 @@ def startResponders(cls): print("Launching DOH responder..") cls._DOHResponder = threading.Thread(name='DOH Responder', target=cls.DOHResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.callback, tlsContext]) - cls._DOHResponder.setDaemon(True) + cls._DOHResponder.daemon = True cls._DOHResponder.start() class TestOutgoingDOHBrokenResponsesGnuTLS(DNSDistTest, OutgoingDOHBrokenResponsesTests): - _tlsBackendPort = 10550 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] _config_template = """ setMaxTCPClientThreads(1) @@ -512,12 +512,12 @@ def startResponders(cls): print("Launching DOH responder..") cls._DOHResponder = threading.Thread(name='DOH Responder', target=cls.DOHResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.callback, tlsContext]) - cls._DOHResponder.setDaemon(True) + cls._DOHResponder.daemon = True cls._DOHResponder.start() class TestOutgoingDOHProxyProtocol(DNSDistTest): - _tlsBackendPort = 10551 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort'] _config_template = """ setMaxTCPClientThreads(1) @@ -533,7 +533,7 @@ def startResponders(cls): print("Launching DOH woth Proxy Protocol responder..") cls._DOHResponder = threading.Thread(name='DOH with Proxy Protocol Responder', target=cls.DOHResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext, True]) - cls._DOHResponder.setDaemon(True) + cls._DOHResponder.daemon = True cls._DOHResponder.start() def testPP(self): @@ -563,7 +563,7 @@ def testPP(self): self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.1', '127.0.0.1', True) class TestOutgoingDOHXForwarded(DNSDistTest): - _tlsBackendPort = 10560 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort'] _config_template = """ setMaxTCPClientThreads(1) @@ -608,7 +608,7 @@ def startResponders(cls): print("Launching DOH responder..") cls._DOHResponder = threading.Thread(name='DOH Responder', target=cls.DOHResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, cls.callback, tlsContext]) - cls._DOHResponder.setDaemon(True) + cls._DOHResponder.daemon = True cls._DOHResponder.start() def testXForwarded(self): diff --git a/regression-tests.dnsdist/test_OutgoingTLS.py b/regression-tests.dnsdist/test_OutgoingTLS.py index 87db8c461f29..0430cfd979be 100644 --- a/regression-tests.dnsdist/test_OutgoingTLS.py +++ b/regression-tests.dnsdist/test_OutgoingTLS.py @@ -5,12 +5,12 @@ import threading import time -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class OutgoingTLSTests(object): _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerBasicAuthPassword = 'secret' _webServerAPIKey = 'apisecret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' @@ -96,7 +96,7 @@ def testTCP(self): class BrokenOutgoingTLSTests(object): _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerBasicAuthPassword = 'secret' _webServerAPIKey = 'apisecret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' @@ -137,7 +137,7 @@ def testTCP(self): self.checkNoResponderHit() class TestOutgoingTLSOpenSSL(DNSDistTest, OutgoingTLSTests): - _tlsBackendPort = 10443 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] _config_template = """ setMaxTCPClientThreads(1) @@ -161,11 +161,11 @@ def startResponders(cls): print("Launching TLS responder..") cls._TLSResponder = threading.Thread(name='TLS Responder', target=cls.TCPResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._TLSResponder.setDaemon(True) + cls._TLSResponder.daemon = True cls._TLSResponder.start() class TestOutgoingTLSGnuTLS(DNSDistTest, OutgoingTLSTests): - _tlsBackendPort = 10444 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] _config_template = """ setMaxTCPClientThreads(1) @@ -182,11 +182,11 @@ def startResponders(cls): print("Launching TLS responder..") cls._TLSResponder = threading.Thread(name='TLS Responder', target=cls.TCPResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._TLSResponder.setDaemon(True) + cls._TLSResponder.daemon = True cls._TLSResponder.start() class TestOutgoingTLSOpenSSLWrongCertName(DNSDistTest, BrokenOutgoingTLSTests): - _tlsBackendPort = 10445 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] _config_template = """ setMaxTCPClientThreads(1) @@ -202,11 +202,11 @@ def startResponders(cls): print("Launching TLS responder..") cls._TLSResponder = threading.Thread(name='TLS Responder', target=cls.TCPResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._TLSResponder.setDaemon(True) + cls._TLSResponder.daemon = True cls._TLSResponder.start() class TestOutgoingTLSGnuTLSWrongCertName(DNSDistTest, BrokenOutgoingTLSTests): - _tlsBackendPort = 10446 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] _config_template = """ setMaxTCPClientThreads(1) @@ -222,11 +222,11 @@ def startResponders(cls): print("Launching TLS responder..") cls._TLSResponder = threading.Thread(name='TLS Responder', target=cls.TCPResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._TLSResponder.setDaemon(True) + cls._TLSResponder.daemon = True cls._TLSResponder.start() class TestOutgoingTLSOpenSSLWrongCertNameButNoCheck(DNSDistTest, OutgoingTLSTests): - _tlsBackendPort = 10447 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] _config_template = """ setMaxTCPClientThreads(1) @@ -242,11 +242,11 @@ def startResponders(cls): print("Launching TLS responder..") cls._TLSResponder = threading.Thread(name='TLS Responder', target=cls.TCPResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._TLSResponder.setDaemon(True) + cls._TLSResponder.daemon = True cls._TLSResponder.start() class TestOutgoingTLSGnuTLSWrongCertNameButNoCheck(DNSDistTest, OutgoingTLSTests): - _tlsBackendPort = 10448 + _tlsBackendPort = pickAvailablePort() _config_params = ['_tlsBackendPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] _config_template = """ setMaxTCPClientThreads(1) @@ -262,5 +262,5 @@ def startResponders(cls): print("Launching TLS responder..") cls._TLSResponder = threading.Thread(name='TLS Responder', target=cls.TCPResponder, args=[cls._tlsBackendPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, None, tlsContext]) - cls._TLSResponder.setDaemon(True) + cls._TLSResponder.daemon = True cls._TLSResponder.start() diff --git a/regression-tests.dnsdist/test_Prometheus.py b/regression-tests.dnsdist/test_Prometheus.py index a868752339d9..cccf04bfb66e 100644 --- a/regression-tests.dnsdist/test_Prometheus.py +++ b/regression-tests.dnsdist/test_Prometheus.py @@ -3,13 +3,13 @@ import requests import subprocess import unittest -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort @unittest.skipIf('SKIP_PROMETHEUS_TESTS' in os.environ, 'Prometheus tests are disabled') class TestPrometheus(DNSDistTest): _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerBasicAuthPassword = 'secret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' _webServerAPIKey = 'apisecret' diff --git a/regression-tests.dnsdist/test_Protobuf.py b/regression-tests.dnsdist/test_Protobuf.py index eee259b04871..e4f0b0232c17 100644 --- a/regression-tests.dnsdist/test_Protobuf.py +++ b/regression-tests.dnsdist/test_Protobuf.py @@ -5,14 +5,14 @@ import struct import sys import time -from dnsdisttests import DNSDistTest, Queue +from dnsdisttests import DNSDistTest, pickAvailablePort, Queue from proxyprotocol import ProxyProtocol import dns import dnsmessage_pb2 class DNSDistProtobufTest(DNSDistTest): - _protobufServerPort = 4242 + _protobufServerPort = pickAvailablePort() _protobufQueue = Queue() _protobufServerID = 'dnsdist-server-1' _protobufCounter = 0 @@ -58,15 +58,15 @@ def ProtobufListener(cls, port): @classmethod def startResponders(cls): cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() cls._protobufListener = threading.Thread(name='Protobuf Listener', target=cls.ProtobufListener, args=[cls._protobufServerPort]) - cls._protobufListener.setDaemon(True) + cls._protobufListener.daemon = True cls._protobufListener.start() def getFirstProtobufMessage(self): @@ -491,8 +491,8 @@ class TestProtobufMetaDOH(DNSDistProtobufTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 - _dohServerPort = 8443 + _tlsServerPort = pickAvailablePort() + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/dns-query" % (_serverName, _dohServerPort)) _config_params = ['_testServerPort', '_protobufServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohServerPort', '_serverCert', '_serverKey'] _config_template = """ diff --git a/regression-tests.dnsdist/test_ProxyProtocol.py b/regression-tests.dnsdist/test_ProxyProtocol.py index 389c00c860ef..1d7aa5c5c900 100644 --- a/regression-tests.dnsdist/test_ProxyProtocol.py +++ b/regression-tests.dnsdist/test_ProxyProtocol.py @@ -8,7 +8,7 @@ import threading import time -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort from proxyprotocol import ProxyProtocol from dnsdistdohtests import DNSDistDOHTest @@ -132,13 +132,13 @@ def ProxyProtocolTCPResponder(port, fromQueue, toQueue): toProxyQueue = Queue() fromProxyQueue = Queue() -proxyResponderPort = 5470 +proxyResponderPort = pickAvailablePort() udpResponder = threading.Thread(name='UDP Proxy Protocol Responder', target=ProxyProtocolUDPResponder, args=[proxyResponderPort, toProxyQueue, fromProxyQueue]) -udpResponder.setDaemon(True) +udpResponder.daemon = True udpResponder.start() tcpResponder = threading.Thread(name='TCP Proxy Protocol Responder', target=ProxyProtocolTCPResponder, args=[proxyResponderPort, toProxyQueue, fromProxyQueue]) -tcpResponder.setDaemon(True) +tcpResponder.daemon = True tcpResponder.start() class ProxyProtocolTest(DNSDistTest): @@ -729,7 +729,7 @@ class TestDOHWithOutgoingProxyProtocol(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/dns-query" % (_serverName, _dohServerPort)) _proxyResponderPort = proxyResponderPort _config_template = """ diff --git a/regression-tests.dnsdist/test_RestartQuery.py b/regression-tests.dnsdist/test_RestartQuery.py index bd077fa3b452..5bc61ff485ba 100644 --- a/regression-tests.dnsdist/test_RestartQuery.py +++ b/regression-tests.dnsdist/test_RestartQuery.py @@ -2,7 +2,7 @@ import threading import clientsubnetoption import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort def servFailResponseCallback(request): response = dns.message.make_response(request) @@ -22,8 +22,8 @@ def normalResponseCallback(request): class TestRestartQuery(DNSDistTest): # this test suite uses different responder ports - _testNormalServerPort = 5420 - _testServfailServerPort = 5421 + _testNormalServerPort = pickAvailablePort() + _testServfailServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%d", pool='restarted'}:setUp() newServer{address="127.0.0.1:%d", pool=''}:setUp() @@ -54,16 +54,16 @@ def startResponders(cls): # servfail cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServfailServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, servFailResponseCallback]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServfailServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, servFailResponseCallback]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() cls._UDPResponderNormal = threading.Thread(name='UDP ResponderNormal', target=cls.UDPResponder, args=[cls._testNormalServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, normalResponseCallback]) - cls._UDPResponderNormal.setDaemon(True) + cls._UDPResponderNormal.daemon = True cls._UDPResponderNormal.start() cls._TCPResponderNormal = threading.Thread(name='TCP ResponderNormal', target=cls.TCPResponder, args=[cls._testNormalServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, False, normalResponseCallback]) - cls._TCPResponderNormal.setDaemon(True) + cls._TCPResponderNormal.daemon = True cls._TCPResponderNormal.start() def testRestartingQuery(self): @@ -84,5 +84,5 @@ def testRestartingQuery(self): sender = getattr(self, method) (_, receivedResponse) = sender(query, response=None, useQueue=False) self.assertTrue(receivedResponse) - self.assertEquals(receivedResponse, expectedResponse) + self.assertEqual(receivedResponse, expectedResponse) diff --git a/regression-tests.dnsdist/test_Routing.py b/regression-tests.dnsdist/test_Routing.py index 9d45803fcabe..17708b1fb277 100644 --- a/regression-tests.dnsdist/test_Routing.py +++ b/regression-tests.dnsdist/test_Routing.py @@ -3,7 +3,7 @@ import threading import time import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class TestRoutingPoolRouting(DNSDistTest): @@ -132,7 +132,7 @@ def testQPSPoolAction(self): class TestRoutingRoundRobinLB(DNSDistTest): - _testServer2Port = 5351 + _testServer2Port = pickAvailablePort() _config_params = ['_testServerPort', '_testServer2Port'] _config_template = """ setServerPolicy(roundrobin) @@ -146,18 +146,18 @@ class TestRoutingRoundRobinLB(DNSDistTest): def startResponders(cls): print("Launching responders..") cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder2.setDaemon(True) + cls._UDPResponder2.daemon = True cls._UDPResponder2.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder2.setDaemon(True) + cls._TCPResponder2.daemon = True cls._TCPResponder2.start() def testRR(self): @@ -198,7 +198,7 @@ def testRR(self): class TestRoutingRoundRobinLBOneDown(DNSDistTest): - _testServer2Port = 5351 + _testServer2Port = pickAvailablePort() _config_params = ['_testServerPort', '_testServer2Port'] _config_template = """ setServerPolicy(roundrobin) @@ -250,7 +250,7 @@ def testRRWithOneDown(self): class TestRoutingRoundRobinLBAllDown(DNSDistTest): - _testServer2Port = 5351 + _testServer2Port = pickAvailablePort() _config_params = ['_testServerPort', '_testServer2Port'] _config_template = """ setServerPolicy(roundrobin) @@ -283,7 +283,7 @@ def testRRWithAllDown(self): class TestRoutingLuaFFIPerThreadRoundRobinLB(DNSDistTest): - _testServer2Port = 5351 + _testServer2Port = pickAvailablePort() _config_params = ['_testServerPort', '_testServer2Port'] _config_template = """ -- otherwise we start too many TCP workers, and as each thread @@ -310,18 +310,18 @@ class TestRoutingLuaFFIPerThreadRoundRobinLB(DNSDistTest): def startResponders(cls): print("Launching responders..") cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder2.setDaemon(True) + cls._UDPResponder2.daemon = True cls._UDPResponder2.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder2.setDaemon(True) + cls._TCPResponder2.daemon = True cls._TCPResponder2.start() def testRR(self): @@ -362,7 +362,7 @@ def testRR(self): class TestRoutingOrder(DNSDistTest): - _testServer2Port = 5351 + _testServer2Port = pickAvailablePort() _config_params = ['_testServerPort', '_testServer2Port'] _config_template = """ setServerPolicy(firstAvailable) @@ -376,18 +376,18 @@ class TestRoutingOrder(DNSDistTest): def startResponders(cls): print("Launching responders..") cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder2.setDaemon(True) + cls._UDPResponder2.daemon = True cls._UDPResponder2.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder2.setDaemon(True) + cls._TCPResponder2.daemon = True cls._TCPResponder2.start() def testOrder(self): @@ -428,7 +428,7 @@ def testOrder(self): class TestFirstAvailableQPSPacketCacheHits(DNSDistTest): _verboseMode = True - _testServer2Port = 5351 + _testServer2Port = pickAvailablePort() _config_params = ['_testServerPort', '_testServer2Port'] _config_template = """ setServerPolicy(firstAvailable) @@ -444,18 +444,18 @@ class TestFirstAvailableQPSPacketCacheHits(DNSDistTest): def startResponders(cls): print("Launching responders..") cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder2.setDaemon(True) + cls._UDPResponder2.daemon = True cls._UDPResponder2.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder2.setDaemon(True) + cls._TCPResponder2.daemon = True cls._TCPResponder2.start() def testOrderQPSCacheHits(self): @@ -577,7 +577,7 @@ def testPolicyPoolNoServer(self): class TestRoutingWRandom(DNSDistTest): - _testServer2Port = 5351 + _testServer2Port = pickAvailablePort() _config_params = ['_testServerPort', '_testServer2Port'] _config_template = """ setServerPolicy(wrandom) @@ -591,18 +591,18 @@ class TestRoutingWRandom(DNSDistTest): def startResponders(cls): print("Launching responders..") cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder2.setDaemon(True) + cls._UDPResponder2.daemon = True cls._UDPResponder2.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder2.setDaemon(True) + cls._TCPResponder2.daemon = True cls._TCPResponder2.start() def testWRandom(self): @@ -648,7 +648,7 @@ def testWRandom(self): class TestRoutingHighValueWRandom(DNSDistTest): - _testServer2Port = 5351 + _testServer2Port = pickAvailablePort() _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_testServer2Port'] @@ -666,18 +666,18 @@ class TestRoutingHighValueWRandom(DNSDistTest): def startResponders(cls): print("Launching responders..") cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._UDPResponder2 = threading.Thread(name='UDP Responder 2', target=cls.UDPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder2.setDaemon(True) + cls._UDPResponder2.daemon = True cls._UDPResponder2.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() cls._TCPResponder2 = threading.Thread(name='TCP Responder 2', target=cls.TCPResponder, args=[cls._testServer2Port, cls._toResponderQueue, cls._fromResponderQueue]) - cls._TCPResponder2.setDaemon(True) + cls._TCPResponder2.daemon = True cls._TCPResponder2.start() def testHighValueWRandom(self): diff --git a/regression-tests.dnsdist/test_TCPFastOpen.py b/regression-tests.dnsdist/test_TCPFastOpen.py index 96900ce68a98..c061ba935b4f 100644 --- a/regression-tests.dnsdist/test_TCPFastOpen.py +++ b/regression-tests.dnsdist/test_TCPFastOpen.py @@ -5,7 +5,7 @@ import requests import socket import struct -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class TestBrokenTCPFastOpen(DNSDistTest): @@ -13,10 +13,10 @@ class TestBrokenTCPFastOpen(DNSDistTest): # because, contrary to the other ones, its # TCP responder will accept a connection, read the # query then just close the connection right away - _testServerPort = 5410 + _testServerPort = pickAvailablePort() _testServerRetries = 5 _webTimeout = 2.0 - _webServerPort = 8083 + _webServerPort = pickAvailablePort() _webServerBasicAuthPassword = 'secret' _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' _webServerAPIKey = 'apisecret' @@ -71,12 +71,12 @@ def startResponders(cls): # Normal responder cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() # Close the connection right after reading the query cls._TCPResponder = threading.Thread(name='Broken TCP Responder', target=cls.BrokenTCPResponder, args=[cls._testServerPort]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() def testTCOFastOpenOnCloseAfterRead(self): diff --git a/regression-tests.dnsdist/test_TCPLimits.py b/regression-tests.dnsdist/test_TCPLimits.py index 5df419e84300..7f24f54ce31f 100644 --- a/regression-tests.dnsdist/test_TCPLimits.py +++ b/regression-tests.dnsdist/test_TCPLimits.py @@ -2,7 +2,7 @@ import struct import time import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort try: range = xrange @@ -13,7 +13,7 @@ class TestTCPLimits(DNSDistTest): # this test suite uses a different responder port # because it uses a different health check configuration - _testServerPort = 5395 + _testServerPort = pickAvailablePort() _answerUnexpected = True _tcpIdleTimeout = 2 @@ -134,7 +134,7 @@ class TestTCPFrontendLimits(DNSDistTest): # this test suite uses a different responder port # because it uses a different health check configuration - _testServerPort = 5395 + _testServerPort = pickAvailablePort() _answerUnexpected = True _skipListeningOnCL = True diff --git a/regression-tests.dnsdist/test_TCPShort.py b/regression-tests.dnsdist/test_TCPShort.py index 7045134bff60..771dedfc1fa3 100644 --- a/regression-tests.dnsdist/test_TCPShort.py +++ b/regression-tests.dnsdist/test_TCPShort.py @@ -4,7 +4,7 @@ import threading import time import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort try: range = xrange @@ -16,12 +16,12 @@ class TestTCPShort(DNSDistTest): # because, contrary to the other ones, its # responders allow trailing data and multiple responses, # and we don't want to mix things up. - _testServerPort = 5361 + _testServerPort = pickAvailablePort() _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 + _tlsServerPort = pickAvailablePort() _tcpSendTimeout = 60 _config_template = """ newServer{address="127.0.0.1:%s"} @@ -35,11 +35,11 @@ def startResponders(cls): print("Launching responders..") cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, True]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, True, True]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() def testTCPShortRead(self): diff --git a/regression-tests.dnsdist/test_TLS.py b/regression-tests.dnsdist/test_TLS.py index cefe7d26c4c2..12db4639453d 100644 --- a/regression-tests.dnsdist/test_TLS.py +++ b/regression-tests.dnsdist/test_TLS.py @@ -6,7 +6,7 @@ import subprocess import time import unittest -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class TLSTests(object): @@ -272,7 +272,7 @@ class TestOpenSSL(DNSDistTest, TLSTests): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 + _tlsServerPort = pickAvailablePort() _config_template = """ setKey("%s") controlSocket("127.0.0.1:%s") @@ -284,7 +284,7 @@ class TestOpenSSL(DNSDistTest, TLSTests): _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey'] def testProvider(self): - self.assertEquals(self.getTLSProvider(), "openssl") + self.assertEqual(self.getTLSProvider(), "openssl") class TestGnuTLS(DNSDistTest, TLSTests): @@ -294,7 +294,7 @@ class TestGnuTLS(DNSDistTest, TLSTests): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 + _tlsServerPort = pickAvailablePort() _config_template = """ setKey("%s") controlSocket("127.0.0.1:%s") @@ -306,14 +306,14 @@ class TestGnuTLS(DNSDistTest, TLSTests): _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey'] def testProvider(self): - self.assertEquals(self.getTLSProvider(), "gnutls") + self.assertEqual(self.getTLSProvider(), "gnutls") class TestDOTWithCache(DNSDistTest): _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 + _tlsServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%s"} @@ -376,14 +376,14 @@ class TestTLSFrontendLimits(DNSDistTest): # this test suite uses a different responder port # because it uses a different health check configuration - _testServerPort = 5395 + _testServerPort = pickAvailablePort() _answerUnexpected = True _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 + _tlsServerPort = pickAvailablePort() _skipListeningOnCL = True _tcpIdleTimeout = 2 @@ -444,7 +444,7 @@ class TestProtocols(DNSDistTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 + _tlsServerPort = pickAvailablePort() _config_template = """ function checkDOT(dq) @@ -485,7 +485,7 @@ class TestPKCSTLSCertificate(DNSDistTest, TLSTests): _pkcsPassphrase = 'passw0rd' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8453 + _tlsServerPort = pickAvailablePort() _config_template = """ setKey("%s") controlSocket("127.0.0.1:%s") diff --git a/regression-tests.dnsdist/test_TLSSessionResumption.py b/regression-tests.dnsdist/test_TLSSessionResumption.py index 4f9dfd6194c3..0cacf448cf05 100644 --- a/regression-tests.dnsdist/test_TLSSessionResumption.py +++ b/regression-tests.dnsdist/test_TLSSessionResumption.py @@ -7,7 +7,7 @@ import tempfile import time import unittest -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort try: range = xrange except NameError: @@ -65,7 +65,7 @@ class TestNoTLSSessionResumptionDOH(DNSDistTLSSessionResumptionTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _numberOfKeys = 0 _config_template = """ newServer{address="127.0.0.1:%s"} @@ -88,7 +88,7 @@ class TestTLSSessionResumptionDOH(DNSDistTLSSessionResumptionTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 + _dohServerPort = pickAvailablePort() _numberOfKeys = 5 _config_template = """ setKey("%s") @@ -182,7 +182,7 @@ class TestNoTLSSessionResumptionDOT(DNSDistTLSSessionResumptionTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8443 + _tlsServerPort = pickAvailablePort() _numberOfKeys = 0 _config_template = """ newServer{address="127.0.0.1:%s"} @@ -204,7 +204,7 @@ class TestTLSSessionResumptionDOT(DNSDistTLSSessionResumptionTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _tlsServerPort = 8443 + _tlsServerPort = pickAvailablePort() _numberOfKeys = 5 _config_template = """ setKey("%s") diff --git a/regression-tests.dnsdist/test_TeeAction.py b/regression-tests.dnsdist/test_TeeAction.py index 99f506b7b621..373d90f64543 100644 --- a/regression-tests.dnsdist/test_TeeAction.py +++ b/regression-tests.dnsdist/test_TeeAction.py @@ -3,13 +3,13 @@ import threading import clientsubnetoption import dns -from dnsdisttests import DNSDistTest, Queue +from dnsdisttests import DNSDistTest, Queue, pickAvailablePort class TestTeeAction(DNSDistTest): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _teeServerPort = 5390 + _teeServerPort = pickAvailablePort() _toTeeQueue = Queue() _fromTeeQueue = Queue() _config_template = """ @@ -25,15 +25,15 @@ def startResponders(cls): print("Launching responders..") cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, False, True]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() cls._TeeResponder = threading.Thread(name='Tee Responder', target=cls.UDPResponder, args=[cls._teeServerPort, cls._toTeeQueue, cls._fromTeeQueue]) - cls._TeeResponder.setDaemon(True) + cls._TeeResponder.daemon = True cls._TeeResponder.start() def testTeeWithECS(self): diff --git a/regression-tests.dnsdist/test_Trailing.py b/regression-tests.dnsdist/test_Trailing.py index ee44ddba8677..5bb97ff8b8b8 100644 --- a/regression-tests.dnsdist/test_Trailing.py +++ b/regression-tests.dnsdist/test_Trailing.py @@ -1,7 +1,7 @@ #!/usr/bin/env python import threading import dns -from dnsdisttests import DNSDistTest +from dnsdisttests import DNSDistTest, pickAvailablePort class TestTrailingDataToBackend(DNSDistTest): @@ -9,7 +9,7 @@ class TestTrailingDataToBackend(DNSDistTest): # because, contrary to the other ones, its # responders allow trailing data and we don't want # to mix things up. - _testServerPort = 5360 + _testServerPort = pickAvailablePort() _verboseMode = True _config_template = """ newServer{address="127.0.0.1:%s"} @@ -57,12 +57,12 @@ def startResponders(cls): # Respond REFUSED to queries with trailing data. cls._UDPResponder = threading.Thread(name='UDP Responder', target=cls.UDPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, dns.rcode.REFUSED]) - cls._UDPResponder.setDaemon(True) + cls._UDPResponder.daemon = True cls._UDPResponder.start() # Respond REFUSED to queries with trailing data. cls._TCPResponder = threading.Thread(name='TCP Responder', target=cls.TCPResponder, args=[cls._testServerPort, cls._toResponderQueue, cls._fromResponderQueue, dns.rcode.REFUSED]) - cls._TCPResponder.setDaemon(True) + cls._TCPResponder.daemon = True cls._TCPResponder.start() def testTrailingPassthrough(self): From ee34faac7b296c9eebd18f290c76d02f7c706437 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 18 Aug 2023 08:36:19 +0200 Subject: [PATCH 567/909] dnsdist: Fix a deprecation warning in the XPF regression tests --- regression-tests.dnsdist/test_XPF.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/regression-tests.dnsdist/test_XPF.py b/regression-tests.dnsdist/test_XPF.py index 84e1c8e1aa63..934ad50d9475 100644 --- a/regression-tests.dnsdist/test_XPF.py +++ b/regression-tests.dnsdist/test_XPF.py @@ -39,7 +39,7 @@ def testXPF(self): expectedQuery = dns.message.make_query(name, 'A', 'IN') # 0x04 is IPv4, 0x11 (17) is UDP then 127.0.0.1 as source and destination # and finally the ports, zeroed because we have no way to know them beforehand - xpfData = "\# 14 04117f0000017f00000100000000" + xpfData = "\\# 14 04117f0000017f00000100000000" rdata = dns.rdata.from_text(dns.rdataclass.IN, self._xpfCode, xpfData) rrset = dns.rrset.from_rdata(".", 0, rdata) expectedQuery.additional.append(rrset) @@ -58,7 +58,7 @@ def testXPF(self): expectedQuery = dns.message.make_query(name, 'A', 'IN') # 0x04 is IPv4, 0x06 (6) is TCP then 127.0.0.1 as source and destination # and finally the ports, zeroed because we have no way to know them beforehand - xpfData = "\# 14 04067f0000017f00000100000000" + xpfData = "\\# 14 04067f0000017f00000100000000" rdata = dns.rdata.from_text(dns.rdataclass.IN, self._xpfCode, xpfData) rrset = dns.rrset.from_rdata(".", 0, rdata) expectedQuery.additional.append(rrset) From fabe8e3a7a8b80ae16edce3d9ca2aac9dfcdf09c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 18 Aug 2023 08:36:54 +0200 Subject: [PATCH 568/909] dnsdist: Better handling of network events in the regression test responders --- regression-tests.dnsdist/dnsdisttests.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 579a63df61a0..156ba192198f 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -320,7 +320,11 @@ def UDPResponder(cls, port, fromQueue, toQueue, trailingDataResponse=False, call @classmethod def handleTCPConnection(cls, conn, fromQueue, toQueue, trailingDataResponse=False, multipleResponses=False, callback=None, partialWrite=False): ignoreTrailing = trailingDataResponse is True - data = conn.recv(2) + try: + data = conn.recv(2) + except Exception as err: + data = None + print(f'Error while reading query size in TCP responder thread {err=}, {type(err)=}') if not data: conn.close() return @@ -440,6 +444,9 @@ def handleDoHConnection(cls, config, conn, fromQueue, toQueue, trailingDataRespo except ssl.SSLEOFError as e: print("Unexpected EOF: %s" % (e)) return + except Exception as err: + print(f'Unexpected exception in DoH responder thread (connection init) {err=}, {type(err)=}') + return dnsData = {} @@ -470,7 +477,11 @@ def handleDoHConnection(cls, config, conn, fromQueue, toQueue, trailingDataRespo # be careful, HTTP/2 headers and data might be in different recv() results requestHeaders = None while True: - data = conn.recv(65535) + try: + data = conn.recv(65535) + except Exception as err: + data = None + print(f'Unexpected exception in DoH responder thread {err=}, {type(err)=}') if not data: break From f37871dd83b211347b1e68777ee15e2c0d7f9ad7 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 18 Aug 2023 08:37:29 +0200 Subject: [PATCH 569/909] dnsdist: Set verbose for TestAdvancedGetLocalAddressOnAnyBind --- regression-tests.dnsdist/test_Advanced.py | 1 + 1 file changed, 1 insertion(+) diff --git a/regression-tests.dnsdist/test_Advanced.py b/regression-tests.dnsdist/test_Advanced.py index 5a0443ac8731..a30c1318dabe 100644 --- a/regression-tests.dnsdist/test_Advanced.py +++ b/regression-tests.dnsdist/test_Advanced.py @@ -311,6 +311,7 @@ class TestAdvancedGetLocalAddressOnAnyBind(DNSDistTest): _config_params = ['_testServerPort', '_dnsDistPort', '_dnsDistPort'] _acl = ['127.0.0.1/32', '::1/128'] _skipListeningOnCL = True + _verboseMode = True def testAdvancedGetLocalAddressOnAnyBind(self): """ From 239597181eb8f0001d54deb390a77cd326eaba3a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 18 Aug 2023 12:55:10 +0200 Subject: [PATCH 570/909] dnsdist: Use the same UDP timeouts than usual in the 'advanced' tests It makes sense to use a short timeout when we know this is going to fail, but here we actually expect a response, and it seems that the current timeout is sometimes too short when running with TSAN, especially when we have a lot of tests running in parallel. --- regression-tests.dnsdist/test_Advanced.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/regression-tests.dnsdist/test_Advanced.py b/regression-tests.dnsdist/test_Advanced.py index a30c1318dabe..65354bb444b3 100644 --- a/regression-tests.dnsdist/test_Advanced.py +++ b/regression-tests.dnsdist/test_Advanced.py @@ -344,7 +344,7 @@ def testAdvancedGetLocalAddressOnAnyBind(self): 'address-was-127-0-0-2.local-address-any.advanced.tests.powerdns.com.') response.answer.append(rrset) sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.settimeout(1.0) + sock.settimeout(2.0) sock.connect(('127.0.0.2', self._dnsDistPort)) try: query = query.to_wire() @@ -377,7 +377,7 @@ def testAdvancedCheckSourceAddrOnAnyBind(self): # a bit more tricky, UDP-only IPv4 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.settimeout(1.0) + sock.settimeout(2.0) sock.connect(('127.0.0.2', self._dnsDistPort)) self._toResponderQueue.put(response, True, 1.0) try: @@ -400,7 +400,7 @@ def testAdvancedCheckSourceAddrOnAnyBind(self): # a bit more tricky, UDP-only IPv6 sock = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM) - sock.settimeout(1.0) + sock.settimeout(2.0) sock.connect(('::1', self._dnsDistPort)) self._toResponderQueue.put(response, True, 1.0) try: @@ -448,7 +448,7 @@ def testAdvancedCheckSourceAddrOnNonDefaultLoopbackBind(self): # a bit more tricky, UDP-only IPv4 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - sock.settimeout(1.0) + sock.settimeout(2.0) sock.connect(('127.0.1.19', self._dnsDistPort)) self._toResponderQueue.put(response, True, 1.0) try: From c1d76521550a9e72d70436e7f4e6ab2fe1f033fc Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 16 Aug 2023 16:42:26 +0200 Subject: [PATCH 571/909] channel: Make the blocking parameters of the object queue explicit --- pdns/channel.hh | 20 +++++++++++++++----- pdns/delaypipe.cc | 2 +- pdns/distributor.hh | 2 +- pdns/dnsdist-tcp.cc | 6 +++--- pdns/dnsdistdist/dnsdist-nghttp2.cc | 2 +- pdns/dnsdistdist/doh.cc | 4 ++-- pdns/snmp-agent.cc | 2 +- pdns/test-channel.cc | 2 +- 8 files changed, 25 insertions(+), 15 deletions(-) diff --git a/pdns/channel.hh b/pdns/channel.hh index 6947d3b26d4b..2d848fc9eee3 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -43,6 +43,17 @@ namespace pdns { namespace channel { + enum class SenderBlockingMode + { + SenderNonBlocking, + SenderBlocking + }; + enum class ReceiverBlockingMode + { + ReceiverNonBlocking, + ReceiverBlocking + }; + /** * The sender's end of a channel used to pass objects between threads. * @@ -136,7 +147,7 @@ namespace channel * \throw runtime_error if the channel creation failed. */ template > - std::pair, Receiver> createObjectQueue(bool sendNonBlocking = true, bool receiveNonBlocking = true, size_t pipeBufferSize = 0, bool throwOnEOF = true); + std::pair, Receiver> createObjectQueue(SenderBlockingMode senderBlockingMode = SenderBlockingMode::SenderNonBlocking, ReceiverBlockingMode receiverBlockingMode = ReceiverBlockingMode::ReceiverNonBlocking, size_t pipeBufferSize = 0, bool throwOnEOF = true); /** * The notifier's end of a channel used to communicate between threads. @@ -307,7 +318,7 @@ namespace channel } template - std::pair, Receiver> createObjectQueue(bool sendNonBlocking, bool receiveNonBlocking, size_t pipeBufferSize, bool throwOnEOF) + std::pair, Receiver> createObjectQueue(SenderBlockingMode senderBlockingMode, ReceiverBlockingMode receiverBlockingMode, size_t pipeBufferSize, bool throwOnEOF) { int fds[2] = {-1, -1}; if (pipe(fds) < 0) { @@ -316,13 +327,12 @@ namespace channel FDWrapper sender(fds[1]); FDWrapper receiver(fds[0]); - - if (receiveNonBlocking && !setNonBlocking(receiver.getHandle())) { + if (receiverBlockingMode == ReceiverBlockingMode::ReceiverNonBlocking && !setNonBlocking(receiver.getHandle())) { int err = errno; throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); } - if (sendNonBlocking && !setNonBlocking(sender.getHandle())) { + if (senderBlockingMode == SenderBlockingMode::SenderNonBlocking && !setNonBlocking(sender.getHandle())) { int err = errno; throw std::runtime_error("Error making channel pipe non-blocking: " + stringerror(err)); } diff --git a/pdns/delaypipe.cc b/pdns/delaypipe.cc index 645bcf56109f..ada096c1a27f 100644 --- a/pdns/delaypipe.cc +++ b/pdns/delaypipe.cc @@ -28,7 +28,7 @@ template ObjectPipe::ObjectPipe() { - auto [sender, receiver] = pdns::channel::createObjectQueue(false, true, 0, false); + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, 0, false); d_sender = std::move(sender); d_receiver = std::move(receiver); } diff --git a/pdns/distributor.hh b/pdns/distributor.hh index d021cfa0f71f..cdee87b67dc7 100644 --- a/pdns/distributor.hh +++ b/pdns/distributor.hh @@ -165,7 +165,7 @@ templateMultiThreadDistributor(false, false); + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderBlocking, pdns::channel::ReceiverBlockingMode::ReceiverBlocking); d_senders.push_back(std::move(sender)); d_receivers.push_back(std::move(receiver)); } diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 2a1d7b80eebb..14af2564e32c 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -130,11 +130,11 @@ TCPClientCollection::TCPClientCollection(size_t maxThreads, std::vector& tcpAcceptStates) { try { - auto [queryChannelSender, queryChannelReceiver] = pdns::channel::createObjectQueue(true, true, g_tcpInternalPipeBufferSize); + auto [queryChannelSender, queryChannelReceiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, g_tcpInternalPipeBufferSize); - auto [crossProtocolQueryChannelSender, crossProtocolQueryChannelReceiver] = pdns::channel::createObjectQueue(true, true, g_tcpInternalPipeBufferSize); + auto [crossProtocolQueryChannelSender, crossProtocolQueryChannelReceiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, g_tcpInternalPipeBufferSize); - auto [crossProtocolResponseChannelSender, crossProtocolResponseChannelReceiver] = pdns::channel::createObjectQueue(true, true, g_tcpInternalPipeBufferSize); + auto [crossProtocolResponseChannelSender, crossProtocolResponseChannelReceiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, g_tcpInternalPipeBufferSize); vinfolog("Adding TCP Client thread"); diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index fdc3d7a294c2..39e60009e05d 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -1054,7 +1054,7 @@ void DoHClientCollection::addThread() { #ifdef HAVE_NGHTTP2 try { - auto [sender, receiver] = pdns::channel::createObjectQueue(true, true, g_tcpInternalPipeBufferSize); + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, g_tcpInternalPipeBufferSize); vinfolog("Adding DoH Client thread"); std::lock_guard lock(d_mutex); diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 2a24dabebca5..dac28e8ca921 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -175,14 +175,14 @@ struct DOHServerConfig { #ifndef USE_SINGLE_ACCEPTOR_THREAD { - auto [sender, receiver] = pdns::channel::createObjectQueue(true, false, internalPipeBufferSize); + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverBlocking, internalPipeBufferSize); d_querySender = std::move(sender); d_queryReceiver = std::move(receiver); } #endif /* USE_SINGLE_ACCEPTOR_THREAD */ { - auto [sender, receiver] = pdns::channel::createObjectQueue(true, true, internalPipeBufferSize); + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, internalPipeBufferSize); d_responseSender = std::move(sender); d_responseReceiver = std::move(receiver); } diff --git a/pdns/snmp-agent.cc b/pdns/snmp-agent.cc index d13d7d003040..2c9121c279ac 100644 --- a/pdns/snmp-agent.cc +++ b/pdns/snmp-agent.cc @@ -186,7 +186,7 @@ SNMPAgent::SNMPAgent([[maybe_unused]] const std::string& name, [[maybe_unused]] init_snmp(name.c_str()); - auto [sender, receiver] = pdns::channel::createObjectQueue(true, true); + auto [sender, receiver] = pdns::channel::createObjectQueue(); d_sender = std::move(sender); d_receiver = std::move(receiver); #endif /* HAVE_NET_SNMP */ diff --git a/pdns/test-channel.cc b/pdns/test-channel.cc index 9a7e4e037b58..8bd042122e04 100644 --- a/pdns/test-channel.cc +++ b/pdns/test-channel.cc @@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(test_object_queue_throw_on_eof) BOOST_AUTO_TEST_CASE(test_object_queue_do_not_throw_on_eof) { - auto [sender, receiver] = pdns::channel::createObjectQueue(true, true, 0U, false); + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, 0U, false); sender.close(); auto got = receiver.receive(); BOOST_CHECK(got == std::nullopt); From ee773bbc8a7760671d68339772cae44c56f0e24f Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Wed, 16 Aug 2023 14:14:21 +0200 Subject: [PATCH 572/909] Consistency: Use #ifdef instead of #if in iputils.cc --- pdns/iputils.cc | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/pdns/iputils.cc b/pdns/iputils.cc index 31ac2a9773e3..2eda93507caa 100644 --- a/pdns/iputils.cc +++ b/pdns/iputils.cc @@ -28,7 +28,7 @@ #include #include -#if HAVE_GETIFADDRS +#ifdef HAVE_GETIFADDRS #include #endif @@ -540,7 +540,7 @@ void setSocketSendBuffer(int fd, uint32_t size) std::set getListOfNetworkInterfaces() { std::set result; -#if HAVE_GETIFADDRS +#ifdef HAVE_GETIFADDRS struct ifaddrs *ifaddr; if (getifaddrs(&ifaddr) == -1) { return result; @@ -558,11 +558,11 @@ std::set getListOfNetworkInterfaces() return result; } +#ifdef HAVE_GETIFADDRS std::vector getListOfAddressesOfNetworkInterface(const std::string& itf) { std::vector result; -#if HAVE_GETIFADDRS - struct ifaddrs *ifaddr; + struct ifaddrs *ifaddr = nullptr; if (getifaddrs(&ifaddr) == -1) { return result; } @@ -586,11 +586,17 @@ std::vector getListOfAddressesOfNetworkInterface(const std::string } freeifaddrs(ifaddr); -#endif return result; } +#else +std::vector getListOfAddressesOfNetworkInterface(const std::string& /* itf */) +{ + std::vector result; + return result; +} +#endif // HAVE_GETIFADDRS -#if HAVE_GETIFADDRS +#ifdef HAVE_GETIFADDRS static uint8_t convertNetmaskToBits(const uint8_t* mask, socklen_t len) { if (mask == nullptr || len > 16) { @@ -611,11 +617,11 @@ static uint8_t convertNetmaskToBits(const uint8_t* mask, socklen_t len) } #endif /* HAVE_GETIFADDRS */ +#ifdef HAVE_GETIFADDRS std::vector getListOfRangesOfNetworkInterface(const std::string& itf) { std::vector result; -#if HAVE_GETIFADDRS - struct ifaddrs *ifaddr; + struct ifaddrs *ifaddr = nullptr; if (getifaddrs(&ifaddr) == -1) { return result; } @@ -648,6 +654,12 @@ std::vector getListOfRangesOfNetworkInterface(const std::string& itf) } freeifaddrs(ifaddr); -#endif return result; } +#else +std::vector getListOfRangesOfNetworkInterface(const std::string& /* itf */) +{ + std::vector result; + return result; +} +#endif // HAVE_GETIFADDRS From de2fa48768fc71bc851ca39e3ad26872f3478042 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 21 Aug 2023 17:35:30 +0200 Subject: [PATCH 573/909] Coding Guidelines: Apply suggestions from reviews --- CODING_GUIDELINES.md | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/CODING_GUIDELINES.md b/CODING_GUIDELINES.md index 64c2f8b1f11d..63959bb43e25 100644 --- a/CODING_GUIDELINES.md +++ b/CODING_GUIDELINES.md @@ -7,7 +7,7 @@ It does assume that you have already read the contributing document at [CONTRIBU # High-level Guidelines -* Although the codebase does not consistently have them, [docblock](https://www.doxygen.nl/manual/docblocks.html)s on functions and classes are appreciated. +* Although the codebase does not consistently have them, [docblocks](https://www.doxygen.nl/manual/docblocks.html) on functions and classes are appreciated. * Never hesitate to write comments on anything that might not be immediately clear just from reading the code. * When adding whole new things, consider putting them in a `pdns::X` namespace. Look for `namespace pdns` in the codebase for examples. @@ -110,6 +110,7 @@ GoodFileDescriptorWrapper() d_fd = open(...); if (something) { close(d_fd); + d_fd = -1; throw std::runtime_error(...); } ... @@ -149,7 +150,7 @@ Passing one by reference is cheap, however. An important thing to be aware of with shared pointers is that making a new copy or releasing a shared pointer, thus updating its internal reference counter, is atomic and therefore thread-safe. Altering the content of the object pointed to is not, though, and is subject to the usual locking methods. The often misunderstood part is that updating the target of the shared pointer is not thread-safe. -Basically, you can copy the shared pointer from multiple threads at once, and then each thread can assign a new target to its own copy safely, like that: +Basically, you can copy the shared pointer from multiple threads at once, and then each thread can assign a new target to its own copy safely, like this: ```C++ auto ptr = std::make_shared(4); @@ -233,9 +234,7 @@ Calling [`resize()`](https://en.cppreference.com/w/cpp/container/vector/resize) In C++11, move operators make it possible to cheaply get the contents of a container into a different variable if needed. The need to pass a subset of a container without copying it often leads to passing a pointer to an array of chars along with a size. -Introduced in C++14, `views` provide a nice way to borrow the content of a container to pass it to a function, without any copying or dynamic memory allocation. - -The basic `string_view` class provides that feature for a container of chars, but the same feature exists for other types, like `uint8_t`. +Introduced in C++14, `views` provide a nice way to borrow the content of a container to pass it to a function, without any copying or dynamic memory allocation. The basic `string_view` class provides that feature for a container of chars. # Threads and Concurrency @@ -475,6 +474,15 @@ This is hard to avoid in all cases, but some mitigations do help: * Always creating temporary files via the `mkstemp()` function, which guarantees that the file did not exist before and has been created with the right permissions ; * Using operations that are guaranteed to be atomic, like renaming a file on the same filesystem (for example in the same directory). +## `errno` + +`errno` is only guaranteed to be set on failing system calls and not set on succeeding system calls. +A library call may clobber `errno`, even when it succeeds. +Safe practice is: + +* Only look at `errno` on failing system calls or when a library function is documented to set `errno` ; +* Immediately save the value of `errno` in a local variable after a system call for later decision making. + ## Secrets Try very hard not to load sensitive information into memory. @@ -588,7 +596,7 @@ This is especially important when hashing attacker-controlled values, as they ca The first issue can be prevented by comparing the entries and not just the value they hash to. The second one can be avoided by using some sort of secret when computing the hash so that the result cannot be guessed by the attacker. -That can be achieved by using an unpredictable seed for certain hash algorithms, or a secret for some other like `SipHash`. +That can be achieved by using an unpredictable seed for certain hash algorithms, or a secret for some other like [`SipHash`](https://en.wikipedia.org/wiki/SipHash). # Readability Tips @@ -656,7 +664,7 @@ static bool thisOneAsWell() but the unnamed namespace form is now preferred. -For the same reason, global variables that are only accessed from a single file should be marked static as well. +For the same reason, global variables that are only accessed from a single file should be put into an unnamed namespace, or marked static as well. ## Variables @@ -705,19 +713,10 @@ C++-style casts can easily be spotted in a code, which makes it easy to review t It's usually a bad sign, but is sometimes needed to call a function that will not modify the variable but lacks the `const` qualifier ; * `dynamic_cast` can be used to cast a pointer to a derived class or to a base class, while checking that the operation is valid. If the cast object is not valid for the intended type, a `nullptr` value will be returned (or a `bad_cast` exception for references) so the result of the operation should be checked! - Note that the RTTI check needed to verify that the cast object is valid has a non-negligible CPU cost. + Note that the Run-Time Type Information (RTTI) check needed to verify that the cast object is valid has a non-negligible CPU cost. Not checking the return value might lead to remote denial of service by `nullptr`-dereference, as happened with the issue described in this advisory: [2017-08: Crafted CNAME answer can cause a denial of service](https://docs.powerdns.com/recursor/security-advisories/powerdns-advisory-2017-08.html) ; * `static_cast` can perform downcast in place of `dynamic_cast`, with none of the cost associated to the check, but can only be done if the cast is known to be valid. It can also do implicit conversion between types (from `ssize_t` to `size_t`, **after** checking that the value is greater or equal to zero) ; * `reinterpret_cast` is quite dangerous, since it can be used to turn a type into a different one. It cannot be be used to remove a `const` qualifier. When used to reinterpret the content of a buffer it can quickly lead to alignment issues, as described in the [Alignment Issues] section. - -## `errno` - -`errno` is only guaranteed to be set on failing system calls and not set on succeeding system calls. -A library call may clobber `errno`, even when it succeeds. -Safe practice is: - -* Only look at `errno` on failing system calls or when a library function is documented to set `errno` ; -* Immediately save the value of `errno` in a local variable after a system call for later decision making. From df410e5e815bc7c6d2f273c9d39f2bba91f4ab91 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 22 Aug 2023 11:30:29 +0200 Subject: [PATCH 574/909] Auth: Print the list of loaded modules next to the config.h preset --- pdns/version.cc | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pdns/version.cc b/pdns/version.cc index 3575303ca547..7f608572b302 100644 --- a/pdns/version.cc +++ b/pdns/version.cc @@ -24,6 +24,9 @@ #endif #include "logger.hh" #include "version.hh" +#include "dnsbackend.hh" + +#include static ProductType productType; @@ -153,7 +156,9 @@ void showBuildConfiguration() endl; #ifdef PDNS_MODULES // Auth only - g_log< Date: Tue, 22 Aug 2023 16:49:49 +0200 Subject: [PATCH 575/909] Bindlexer whitespace cleanup --- pdns/bindlexer.l | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/bindlexer.l b/pdns/bindlexer.l index 8a5f380d3ba6..85cc0c6ef0e9 100644 --- a/pdns/bindlexer.l +++ b/pdns/bindlexer.l @@ -21,7 +21,7 @@ extern const char *bind_directory; %} -%x comment +%x comment %x incl %x quoted %option stack @@ -106,7 +106,7 @@ include BEGIN(incl); -zone return ZONETOK; +zone return ZONETOK; file return FILETOK; options return OPTIONSTOK; From da3ae59710098b699f2c1618b2a88c7bf7113397 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 23 Aug 2023 11:16:50 +0200 Subject: [PATCH 576/909] Prep for upcoming rec 4.7.6, 4.8.5 and 4.9.1 releases --- docs/secpoll.zone | 5 ++- pdns/recursordist/docs/changelog/4.7.rst | 32 ++++++++++++++ pdns/recursordist/docs/changelog/4.8.rst | 39 +++++++++++++++++ pdns/recursordist/docs/changelog/4.9.rst | 55 +++++++++++++++++++++++- 4 files changed, 129 insertions(+), 2 deletions(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 368d759870e9..a0cecc6af8eb 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023070701 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023082501 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -341,6 +341,7 @@ recursor-4.7.2.security-status 60 IN TXT "3 Upgrade now recursor-4.7.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.7.4.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.7.5.security-status 60 IN TXT "1 OK" +recursor-4.7.6.security-status 60 IN TXT "1 OK" recursor-4.8.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.8.0-beta1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" recursor-4.8.0-beta2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" @@ -350,10 +351,12 @@ recursor-4.8.1.security-status 60 IN TXT "3 Upgrade now recursor-4.8.2.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.8.3.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/recursor/security-advisories/powerdns-advisory-2023-02.html" recursor-4.8.4.security-status 60 IN TXT "1 OK" +recursor-4.8.5.security-status 60 IN TXT "1 OK" recursor-4.9.0-alpha1.security-status 60 IN TXT "2 Unsupported pre-release" recursor-4.9.0-beta1.security-status 60 IN TXT "2 Unsupported pre-release" recursor-4.9.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release" recursor-4.9.0.security-status 60 IN TXT "1 OK" +recursor-4.9.1.security-status 60 IN TXT "1 OK" ; Recursor Debian recursor-3.6.2-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/" diff --git a/pdns/recursordist/docs/changelog/4.7.rst b/pdns/recursordist/docs/changelog/4.7.rst index f30e8f156818..bbe7eb454880 100644 --- a/pdns/recursordist/docs/changelog/4.7.rst +++ b/pdns/recursordist/docs/changelog/4.7.rst @@ -1,6 +1,38 @@ Changelogs for 4.7.X ==================== +.. changelog:: + :version: 4.7.6 + :released: 25th of August 2023 + + .. change:: + :tags: Bug Fixes + :pullreq: 13157 + :tickets: 13105 + + (I)XFR: handle partial read of len prefix. + + .. change:: + :tags: Bug Fixes + :pullreq: 13079 + :tickets: 12892 + + YaHTTP: Prevent integer overflow on very large chunks. + + .. change:: + :tags: Bug Fixes + :pullreq: 13075 + :tickets: 12961 + + Work around Red Hat 8 misfeature in OpenSSL's headers. + + .. change:: + :tags: Bug Fixes + :pullreq: 13058 + :tickets: 13021 + + Fix setting of policy tags for packet cache hits. + .. changelog:: :version: 4.7.5 :released: 29th of March 2023 diff --git a/pdns/recursordist/docs/changelog/4.8.rst b/pdns/recursordist/docs/changelog/4.8.rst index 888633f8d406..a56030368355 100644 --- a/pdns/recursordist/docs/changelog/4.8.rst +++ b/pdns/recursordist/docs/changelog/4.8.rst @@ -1,6 +1,45 @@ Changelogs for 4.8.X ==================== +.. changelog:: + :version: 4.8.5 + :released: 25th of August 2023 + + .. change:: + :tags: Bug Fixes + :pullreq: 13158 + :tickets: 13105 + + (I)XFR: handle partial read of len prefix. + + .. change:: + :tags: Bug Fixes + :pullreq: 13078 + :tickets: 12892 + + YaHTTP: Prevent integer overflow on very large chunks. + + .. change:: + :tags: Bug Fixes + :pullreq: 13077 + :tickets: 12935 + + Stop using the now deprecated ERR_load_CRYPTO_strings() to detect OpenSSL. + + .. change:: + :tags: Bug Fixes + :pullreq: 13076 + :tickets: 12961 + + Work around Red Hat 8 misfeature in OpenSSL's headers. + + .. change:: + :tags: Bug Fixes + :pullreq: 13056 + :tickets: 13021 + + Fix setting of policy tags for packet cache hits. + .. changelog:: :version: 4.8.4 :released: 29th of March 2023 diff --git a/pdns/recursordist/docs/changelog/4.9.rst b/pdns/recursordist/docs/changelog/4.9.rst index 657b809a7b7e..e0c7fc956b38 100644 --- a/pdns/recursordist/docs/changelog/4.9.rst +++ b/pdns/recursordist/docs/changelog/4.9.rst @@ -1,11 +1,64 @@ Changelogs for 4.9.X ==================== +.. changelog:: + :version: 4.9.1 + :released: 25th of August 2023 + + .. change:: + :tags: Bug Fixes + :pullreq: 13163 + :tickets: 13071 + + Fix code producing json. + + .. change:: + :tags: Bug Fixes + :pullreq: 13161 + :tickets: 13106 + + Replace data in the aggressive cache if new data becomes available. + + .. change:: + :tags: Bug Fixes + :pullreq: 13160 + :tickets: 13151 + + Fix a few typos in log messages. + + .. change:: + :tags: Bug Fixes + :pullreq: 13159 + :tickets: 13105 + + (I)XFR: handle partial read of len prefix. + + .. change:: + :tags: Bug Fixes + :pullreq: 13057 + :tickets: 13021 + + Fix setting of policy tags on packet cache hits. + + .. change:: + :tags: Bug Fixes + :pullreq: 12995 + :tickets: 12961 + + Work around Red Hat 8 misfeature OpenSSL's headers. + + .. change:: + :tags: Bug Fixes + :pullreq: 12994 + :tickets: 12935 + + Stop using the now deprecated ERR_load_CRYPTO_strings() to detect OpenSSL. + .. changelog:: :version: 4.9.0 :released: 30th of June 2023 Please review the :doc:`Upgrade Guide <../upgrade>` before upgrading from versions < 4.9.x. - + .. change:: :tags: Bug Fixes :pullreq: 12968 From 607d24f9dfcfd70ebff1c2e0786e7ec3fc1b574c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 23 Aug 2023 13:23:56 +0200 Subject: [PATCH 577/909] Avoid running SNMP tests on the current buildbot setup Since the change from nose to pytest, the SNMP exclusion via the environment var NOSE_EXLUDE does no longer work. --- build-scripts/test-recursor | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/build-scripts/test-recursor b/build-scripts/test-recursor index ac41da9da3f9..b0999567f1dc 100755 --- a/build-scripts/test-recursor +++ b/build-scripts/test-recursor @@ -16,6 +16,11 @@ fi set -x +EXTRA_ARG="" +if [ $PWD = /srv/buildbot-worker/test-rec-debian-buster/build ]; then + EXTRA_ARG=--ignore=test_SNMP.py +fi + cd regression-tests/modules MODULES="" @@ -59,7 +64,8 @@ sleep 3 ./clean.sh cd ../regression-tests.recursor-dnssec -./runtests $@ || EXIT=1 + +./runtests $EXTRA_ARG $@ || EXIT=1 ./printlogs.py || true exit $EXIT From 8c87daac8ed54da6e300e481fd433acf393ad6ce Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 23 Aug 2023 14:40:30 +0200 Subject: [PATCH 578/909] dnsdist: Split the DynBlocks regression tests On my 8 physical CPU cores machine this brings the total time for all regression tests to 107.60s (01:47). --- .../dnsdistDynBlockTests.py | 548 +++++++ regression-tests.dnsdist/test_DynBlocks.py | 1378 ++--------------- .../test_DynBlocksGroup.py | 376 +++++ .../test_DynBlocksRatio.py | 31 + .../test_DynBlocksResponseBytes.py | 55 + .../test_DynBlocksServFail.py | 114 ++ 6 files changed, 1229 insertions(+), 1273 deletions(-) create mode 100644 regression-tests.dnsdist/dnsdistDynBlockTests.py create mode 100644 regression-tests.dnsdist/test_DynBlocksGroup.py create mode 100644 regression-tests.dnsdist/test_DynBlocksRatio.py create mode 100644 regression-tests.dnsdist/test_DynBlocksResponseBytes.py create mode 100644 regression-tests.dnsdist/test_DynBlocksServFail.py diff --git a/regression-tests.dnsdist/dnsdistDynBlockTests.py b/regression-tests.dnsdist/dnsdistDynBlockTests.py new file mode 100644 index 000000000000..ccee6eb7c36b --- /dev/null +++ b/regression-tests.dnsdist/dnsdistDynBlockTests.py @@ -0,0 +1,548 @@ +#!/usr/bin/env python +import time +import requests +import dns +from dnsdisttests import DNSDistTest, pickAvailablePort + +_maintenanceWaitTime = 2 + +def waitForMaintenanceToRun(): + time.sleep(_maintenanceWaitTime) + +class DynBlocksTest(DNSDistTest): + + _webTimeout = 2.0 + _webServerPort = pickAvailablePort() + _webServerBasicAuthPassword = 'secret' + _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' + _webServerAPIKey = 'apisecret' + _webServerAPIKeyHashed = '$scrypt$ln=10,p=1,r=8$9v8JxDfzQVyTpBkTbkUqYg==$bDQzAOHeK1G9UvTPypNhrX48w974ZXbFPtRKS34+aso=' + _dynBlockQPS = 10 + _dynBlockPeriod = 2 + # this needs to be greater than maintenanceWaitTime + _dynBlockDuration = _maintenanceWaitTime + 2 + _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] + + def doTestDynBlockViaAPI(self, ipRange, reason, minSeconds, maxSeconds, minBlocks, maxBlocks): + headers = {'x-api-key': self._webServerAPIKey} + url = 'http://127.0.0.1:' + str(self._webServerPort) + '/jsonstat?command=dynblocklist' + r = requests.get(url, headers=headers, timeout=self._webTimeout) + self.assertTrue(r) + self.assertEqual(r.status_code, 200) + + content = r.json() + self.assertIsNotNone(content) + self.assertIn(ipRange, content) + + values = content[ipRange] + for key in ['reason', 'seconds', 'blocks', 'action']: + self.assertIn(key, values) + + self.assertEqual(values['reason'], reason) + self.assertGreaterEqual(values['seconds'], minSeconds) + self.assertLessEqual(values['seconds'], maxSeconds) + self.assertGreaterEqual(values['blocks'], minBlocks) + self.assertLessEqual(values['blocks'], maxBlocks) + + def doTestQRate(self, name, testViaAPI=True): + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + + allowed = 0 + sent = 0 + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we might be already blocked, but we should have been able to send + # at least self._dynBlockQPS queries + self.assertGreaterEqual(allowed, self._dynBlockQPS) + + if allowed == sent: + waitForMaintenanceToRun() + + # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, None) + + if testViaAPI: + self.doTestDynBlockViaAPI('127.0.0.1/32', 'Exceeded query rate', 1, self._dynBlockDuration, (sent-allowed)+1, (sent-allowed)+1) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + # again, over TCP this time + allowed = 0 + sent = 0 + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we might be already blocked, but we should have been able to send + # at least self._dynBlockQPS queries + self.assertGreaterEqual(allowed, self._dynBlockQPS) + + if allowed == sent: + waitForMaintenanceToRun() + + # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, None) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + def doTestQRateRCode(self, name, rcode): + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + expectedResponse = dns.message.make_response(query) + expectedResponse.set_rcode(rcode) + + allowed = 0 + sent = 0 + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(receivedResponse, response) + allowed = allowed + 1 + else: + self.assertEqual(receivedResponse, expectedResponse) + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we might be already blocked, but we should have been able to send + # at least self._dynBlockQPS queries + self.assertGreaterEqual(allowed, self._dynBlockQPS) + + if allowed == sent: + waitForMaintenanceToRun() + + # we should now be 'rcode' for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, expectedResponse) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + allowed = 0 + sent = 0 + # again, over TCP this time + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(receivedResponse, response) + allowed = allowed + 1 + else: + self.assertEqual(receivedResponse, expectedResponse) + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we might be already blocked, but we should have been able to send + # at least self._dynBlockQPS queries + self.assertGreaterEqual(allowed, self._dynBlockQPS) + + if allowed == sent: + waitForMaintenanceToRun() + + # we should now be 'rcode' for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, expectedResponse) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + def doTestResponseByteRate(self, name, dynBlockBytesPerSecond): + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + response.answer.append(dns.rrset.from_text_list(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + ['192.0.2.1', '192.0.2.2', '192.0.2.3', '192.0.2.4'])) + response.answer.append(dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.AAAA, + '2001:DB8::1')) + + allowed = 0 + sent = 0 + + print(time.time()) + + for _ in range(int(dynBlockBytesPerSecond * 5 / len(response.to_wire()))): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + sent = sent + len(response.to_wire()) + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + allowed = allowed + len(response.to_wire()) + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + # and stop right there, otherwise we might + # wait for so long that the dynblock is gone + # by the time we finished + break + + # we might be already blocked, but we should have been able to send + # at least dynBlockBytesPerSecond bytes + print(allowed) + print(sent) + print(time.time()) + self.assertGreaterEqual(allowed, dynBlockBytesPerSecond) + + print(self.sendConsoleCommand("showDynBlocks()")) + print(self.sendConsoleCommand("grepq(\"\")")) + print(time.time()) + + if allowed == sent: + print("Waiting for the maintenance function to run") + waitForMaintenanceToRun() + + print(self.sendConsoleCommand("showDynBlocks()")) + print(self.sendConsoleCommand("grepq(\"\")")) + print(time.time()) + + # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, None) + + print(self.sendConsoleCommand("showDynBlocks()")) + print(self.sendConsoleCommand("grepq(\"\")")) + print(time.time()) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + print(self.sendConsoleCommand("showDynBlocks()")) + print(self.sendConsoleCommand("grepq(\"\")")) + print(time.time()) + + # this one should succeed + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + # again, over TCP this time + allowed = 0 + sent = 0 + for _ in range(int(dynBlockBytesPerSecond * 5 / len(response.to_wire()))): + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) + sent = sent + len(response.to_wire()) + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + allowed = allowed + len(response.to_wire()) + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + # and stop right there, otherwise we might + # wait for so long that the dynblock is gone + # by the time we finished + break + + # we might be already blocked, but we should have been able to send + # at least dynBlockBytesPerSecond bytes + self.assertGreaterEqual(allowed, dynBlockBytesPerSecond) + + if allowed == sent: + waitForMaintenanceToRun() + + # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, None) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + def doTestRCodeRate(self, name, rcode): + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + expectedResponse = dns.message.make_response(query) + expectedResponse.set_rcode(rcode) + + # start with normal responses + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + waitForMaintenanceToRun() + + # we should NOT be dropped! + (_, receivedResponse) = self.sendUDPQuery(query, response) + self.assertEqual(receivedResponse, response) + + # now with rcode! + sent = 0 + allowed = 0 + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, expectedResponse) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(expectedResponse, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we might be already blocked, but we should have been able to send + # at least self._dynBlockQPS queries + self.assertGreaterEqual(allowed, self._dynBlockQPS) + + if allowed == sent: + waitForMaintenanceToRun() + + # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, None) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + # again, over TCP this time + # start with normal responses + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + waitForMaintenanceToRun() + + # we should NOT be dropped! + (_, receivedResponse) = self.sendUDPQuery(query, response) + self.assertEqual(receivedResponse, response) + + # now with rcode! + sent = 0 + allowed = 0 + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, expectedResponse) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(expectedResponse, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we might be already blocked, but we should have been able to send + # at least self._dynBlockQPS queries + self.assertGreaterEqual(allowed, self._dynBlockQPS) + + if allowed == sent: + waitForMaintenanceToRun() + + # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, None) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + def doTestRCodeRatio(self, name, rcode, noerrorcount, rcodecount): + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + expectedResponse = dns.message.make_response(query) + expectedResponse.set_rcode(rcode) + + # start with normal responses + for _ in range(noerrorcount-1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + waitForMaintenanceToRun() + + # we should NOT be dropped! + (_, receivedResponse) = self.sendUDPQuery(query, response) + self.assertEqual(receivedResponse, response) + + # now with rcode! + sent = 0 + allowed = 0 + for _ in range(rcodecount): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, expectedResponse) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(expectedResponse, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we should have been able to send all our queries since the minimum number of queries is set to noerrorcount + rcodecount + self.assertGreaterEqual(allowed, rcodecount) + + waitForMaintenanceToRun() + + # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, None) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + # again, over TCP this time + # start with normal responses + for _ in range(noerrorcount-1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + waitForMaintenanceToRun() + + # we should NOT be dropped! + (_, receivedResponse) = self.sendUDPQuery(query, response) + self.assertEqual(receivedResponse, response) + + # now with rcode! + sent = 0 + allowed = 0 + for _ in range(rcodecount): + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, expectedResponse) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(expectedResponse, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we should have been able to send all our queries since the minimum number of queries is set to noerrorcount + rcodecount + self.assertGreaterEqual(allowed, rcodecount) + + waitForMaintenanceToRun() + + # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, None) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) diff --git a/regression-tests.dnsdist/test_DynBlocks.py b/regression-tests.dnsdist/test_DynBlocks.py index 8b9ef6fb6ef3..761263882ba1 100644 --- a/regression-tests.dnsdist/test_DynBlocks.py +++ b/regression-tests.dnsdist/test_DynBlocks.py @@ -1,1122 +1,104 @@ #!/usr/bin/env python import base64 -import json -import requests import socket import time import dns -from dnsdisttests import DNSDistTest, pickAvailablePort -try: - range = xrange -except NameError: - pass +from dnsdisttests import DNSDistTest +from dnsdistDynBlockTests import DynBlocksTest, waitForMaintenanceToRun, _maintenanceWaitTime -class DynBlocksTest(DNSDistTest): - - _webTimeout = 2.0 - _webServerPort = pickAvailablePort() - _webServerBasicAuthPassword = 'secret' - _webServerBasicAuthPasswordHashed = '$scrypt$ln=10,p=1,r=8$6DKLnvUYEeXWh3JNOd3iwg==$kSrhdHaRbZ7R74q3lGBqO1xetgxRxhmWzYJ2Qvfm7JM=' - _webServerAPIKey = 'apisecret' - _webServerAPIKeyHashed = '$scrypt$ln=10,p=1,r=8$9v8JxDfzQVyTpBkTbkUqYg==$bDQzAOHeK1G9UvTPypNhrX48w974ZXbFPtRKS34+aso=' - - def doTestDynBlockViaAPI(self, range, reason, minSeconds, maxSeconds, minBlocks, maxBlocks): - headers = {'x-api-key': self._webServerAPIKey} - url = 'http://127.0.0.1:' + str(self._webServerPort) + '/jsonstat?command=dynblocklist' - r = requests.get(url, headers=headers, timeout=self._webTimeout) - self.assertTrue(r) - self.assertEqual(r.status_code, 200) - - content = r.json() - self.assertIsNotNone(content) - self.assertIn(range, content) - - values = content[range] - for key in ['reason', 'seconds', 'blocks', 'action']: - self.assertIn(key, values) - - self.assertEqual(values['reason'], reason) - self.assertGreaterEqual(values['seconds'], minSeconds) - self.assertLessEqual(values['seconds'], maxSeconds) - self.assertGreaterEqual(values['blocks'], minBlocks) - self.assertLessEqual(values['blocks'], maxBlocks) - - def doTestQRate(self, name, testViaAPI=True): - query = dns.message.make_query(name, 'A', 'IN') - response = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - '192.0.2.1') - response.answer.append(rrset) - - allowed = 0 - sent = 0 - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - allowed = allowed + 1 - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we might be already blocked, but we should have been able to send - # at least self._dynBlockQPS queries - self.assertGreaterEqual(allowed, self._dynBlockQPS) - - if allowed == sent: - # wait for the maintenance function to run - time.sleep(2) - - # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, None) - - if testViaAPI: - self.doTestDynBlockViaAPI('127.0.0.1/32', 'Exceeded query rate', self._dynBlockDuration - 4, self._dynBlockDuration, (sent-allowed)+1, (sent-allowed)+1) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - # again, over TCP this time - allowed = 0 - sent = 0 - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - allowed = allowed + 1 - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we might be already blocked, but we should have been able to send - # at least self._dynBlockQPS queries - self.assertGreaterEqual(allowed, self._dynBlockQPS) - - if allowed == sent: - # wait for the maintenance function to run - time.sleep(2) - - # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, None) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - def doTestQRateRCode(self, name, rcode): - query = dns.message.make_query(name, 'A', 'IN') - response = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - '192.0.2.1') - response.answer.append(rrset) - expectedResponse = dns.message.make_response(query) - expectedResponse.set_rcode(rcode) - - allowed = 0 - sent = 0 - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, response) - allowed = allowed + 1 - else: - self.assertEqual(receivedResponse, expectedResponse) - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we might be already blocked, but we should have been able to send - # at least self._dynBlockQPS queries - self.assertGreaterEqual(allowed, self._dynBlockQPS) - - if allowed == sent: - # wait for the maintenance function to run - time.sleep(2) - - # we should now be 'rcode' for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, expectedResponse) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - allowed = 0 - sent = 0 - # again, over TCP this time - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, response) - allowed = allowed + 1 - else: - self.assertEqual(receivedResponse, expectedResponse) - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we might be already blocked, but we should have been able to send - # at least self._dynBlockQPS queries - self.assertGreaterEqual(allowed, self._dynBlockQPS) - - if allowed == sent: - # wait for the maintenance function to run - time.sleep(2) - - # we should now be 'rcode' for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, expectedResponse) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - def doTestResponseByteRate(self, name): - query = dns.message.make_query(name, 'A', 'IN') - response = dns.message.make_response(query) - response.answer.append(dns.rrset.from_text_list(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - ['192.0.2.1', '192.0.2.2', '192.0.2.3', '192.0.2.4'])) - response.answer.append(dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.AAAA, - '2001:DB8::1')) - - allowed = 0 - sent = 0 - - print(time.time()) - - for _ in range(int(self._dynBlockBytesPerSecond * 5 / len(response.to_wire()))): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - sent = sent + len(response.to_wire()) - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - allowed = allowed + len(response.to_wire()) - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - # and stop right there, otherwise we might - # wait for so long that the dynblock is gone - # by the time we finished - break - - # we might be already blocked, but we should have been able to send - # at least self._dynBlockBytesPerSecond bytes - print(allowed) - print(sent) - print(time.time()) - self.assertGreaterEqual(allowed, self._dynBlockBytesPerSecond) - - print(self.sendConsoleCommand("showDynBlocks()")) - print(self.sendConsoleCommand("grepq(\"\")")) - print(time.time()) - - if allowed == sent: - # wait for the maintenance function to run - print("Waiting for the maintenance function to run") - time.sleep(2) - - print(self.sendConsoleCommand("showDynBlocks()")) - print(self.sendConsoleCommand("grepq(\"\")")) - print(time.time()) - - # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, None) - - print(self.sendConsoleCommand("showDynBlocks()")) - print(self.sendConsoleCommand("grepq(\"\")")) - print(time.time()) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - print(self.sendConsoleCommand("showDynBlocks()")) - print(self.sendConsoleCommand("grepq(\"\")")) - print(time.time()) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - # again, over TCP this time - allowed = 0 - sent = 0 - for _ in range(int(self._dynBlockBytesPerSecond * 5 / len(response.to_wire()))): - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - sent = sent + len(response.to_wire()) - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - allowed = allowed + len(response.to_wire()) - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - # and stop right there, otherwise we might - # wait for so long that the dynblock is gone - # by the time we finished - break - - # we might be already blocked, but we should have been able to send - # at least self._dynBlockBytesPerSecond bytes - self.assertGreaterEqual(allowed, self._dynBlockBytesPerSecond) - - if allowed == sent: - # wait for the maintenance function to run - time.sleep(2) - - # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, None) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - def doTestRCodeRate(self, name, rcode): - query = dns.message.make_query(name, 'A', 'IN') - response = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - '192.0.2.1') - response.answer.append(rrset) - expectedResponse = dns.message.make_response(query) - expectedResponse.set_rcode(rcode) - - # start with normal responses - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - # wait for the maintenance function to run - time.sleep(2) - - # we should NOT be dropped! - (_, receivedResponse) = self.sendUDPQuery(query, response) - self.assertEqual(receivedResponse, response) - - # now with rcode! - sent = 0 - allowed = 0 - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, expectedResponse) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(expectedResponse, receivedResponse) - allowed = allowed + 1 - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we might be already blocked, but we should have been able to send - # at least self._dynBlockQPS queries - self.assertGreaterEqual(allowed, self._dynBlockQPS) - - if allowed == sent: - # wait for the maintenance function to run - time.sleep(2) - - # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, None) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - # again, over TCP this time - # start with normal responses - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - # wait for the maintenance function to run - time.sleep(2) - - # we should NOT be dropped! - (_, receivedResponse) = self.sendUDPQuery(query, response) - self.assertEqual(receivedResponse, response) - - # now with rcode! - sent = 0 - allowed = 0 - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, expectedResponse) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(expectedResponse, receivedResponse) - allowed = allowed + 1 - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we might be already blocked, but we should have been able to send - # at least self._dynBlockQPS queries - self.assertGreaterEqual(allowed, self._dynBlockQPS) - - if allowed == sent: - # wait for the maintenance function to run - time.sleep(2) - - # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, None) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - def doTestRCodeRatio(self, name, rcode, noerrorcount, rcodecount): - query = dns.message.make_query(name, 'A', 'IN') - response = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - '192.0.2.1') - response.answer.append(rrset) - expectedResponse = dns.message.make_response(query) - expectedResponse.set_rcode(rcode) - - # start with normal responses - for _ in range(noerrorcount-1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - # wait for the maintenance function to run - time.sleep(2) - - # we should NOT be dropped! - (_, receivedResponse) = self.sendUDPQuery(query, response) - self.assertEqual(receivedResponse, response) - - # now with rcode! - sent = 0 - allowed = 0 - for _ in range(rcodecount): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, expectedResponse) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(expectedResponse, receivedResponse) - allowed = allowed + 1 - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we should have been able to send all our queries since the minimum number of queries is set to noerrorcount + rcodecount - self.assertGreaterEqual(allowed, rcodecount) - - # wait for the maintenance function to run - time.sleep(2) - - # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, None) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - # again, over TCP this time - # start with normal responses - for _ in range(noerrorcount-1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - # wait for the maintenance function to run - time.sleep(2) - - # we should NOT be dropped! - (_, receivedResponse) = self.sendUDPQuery(query, response) - self.assertEqual(receivedResponse, response) - - # now with rcode! - sent = 0 - allowed = 0 - for _ in range(rcodecount): - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, expectedResponse) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(expectedResponse, receivedResponse) - allowed = allowed + 1 - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we should have been able to send all our queries since the minimum number of queries is set to noerrorcount + rcodecount - self.assertGreaterEqual(allowed, rcodecount) - - # wait for the maintenance function to run - time.sleep(2) - - # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendTCPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, None) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - -class TestDynBlockQPS(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_template = """ - function maintenance() - addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d) - end - newServer{address="127.0.0.1:%s"} - webserver("127.0.0.1:%s") - setWebserverConfig({password="%s", apiKey="%s"}) - """ - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] - - def testDynBlocksQRate(self): - """ - Dyn Blocks: QRate - """ - name = 'qrate.dynblocks.tests.powerdns.com.' - self.doTestQRate(name) - -class TestDynBlockGroupQPS(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_template = """ - local dbr = dynBlockRulesGroup() - dbr:setQueryRate(%d, %d, "Exceeded query rate", %d) - - function maintenance() - dbr:apply() - end - newServer{address="127.0.0.1:%s"} - webserver("127.0.0.1:%s") - setWebserverConfig({password="%s", apiKey="%s"}) - """ - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] - - def testDynBlocksQRate(self): - """ - Dyn Blocks (Group): QRate - """ - name = 'qrate.group.dynblocks.tests.powerdns.com.' - self.doTestQRate(name) - - -class TestDynBlockQPSRefused(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - _config_template = """ - function maintenance() - addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d) - end - setDynBlocksAction(DNSAction.Refused) - newServer{address="127.0.0.1:%s"} - """ - - def testDynBlocksQRate(self): - """ - Dyn Blocks: QRate refused - """ - name = 'qraterefused.dynblocks.tests.powerdns.com.' - self.doTestQRateRCode(name, dns.rcode.REFUSED) - -class TestDynBlockGroupQPSRefused(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - _config_template = """ - local dbr = dynBlockRulesGroup() - dbr:setQueryRate(%d, %d, "Exceeded query rate", %d) - - function maintenance() - dbr:apply() - end - setDynBlocksAction(DNSAction.Refused) - newServer{address="127.0.0.1:%s"} - """ - - def testDynBlocksQRate(self): - """ - Dyn Blocks (Group): QRate refused - """ - name = 'qraterefused.group.dynblocks.tests.powerdns.com.' - self.doTestQRateRCode(name, dns.rcode.REFUSED) - -class TestDynBlockQPSActionRefused(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - _config_template = """ - function maintenance() - addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d, DNSAction.Refused) - end - setDynBlocksAction(DNSAction.Drop) - newServer{address="127.0.0.1:%s"} - """ - - def testDynBlocksQRate(self): - """ - Dyn Blocks: QRate refused (action) - """ - name = 'qrateactionrefused.dynblocks.tests.powerdns.com.' - self.doTestQRateRCode(name, dns.rcode.REFUSED) - -class TestDynBlockQPSActionNXD(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - _config_template = """ - function maintenance() - addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d, DNSAction.Nxdomain) - end - setDynBlocksAction(DNSAction.Drop) - newServer{address="127.0.0.1:%s"} - """ - - def testDynBlocksQRate(self): - """ - Dyn Blocks: QRate NXD (action) - """ - name = 'qrateactionnxd.dynblocks.tests.powerdns.com.' - self.doTestQRateRCode(name, dns.rcode.NXDOMAIN) - -class TestDynBlockGroupQPSActionRefused(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - _config_template = """ - local dbr = dynBlockRulesGroup() - dbr:setQueryRate(%d, %d, "Exceeded query rate", %d, DNSAction.Refused) - - function maintenance() - dbr:apply() - end - setDynBlocksAction(DNSAction.Drop) - newServer{address="127.0.0.1:%s"} - """ - - def testDynBlocksQRate(self): - """ - Dyn Blocks (group): QRate refused (action) - """ - name = 'qrateactionrefused.group.dynblocks.tests.powerdns.com.' - self.doTestQRateRCode(name, dns.rcode.REFUSED) - -class TestDynBlockQPSActionTruncated(DNSDistTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - _config_template = """ - function maintenance() - addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d, DNSAction.Truncate) - end - setDynBlocksAction(DNSAction.Drop) - newServer{address="127.0.0.1:%s"} - """ - - def testDynBlocksQRate(self): - """ - Dyn Blocks: QRate truncated (action) - """ - name = 'qrateactiontruncated.dynblocks.tests.powerdns.com.' - query = dns.message.make_query(name, 'A', 'IN') - # dnsdist sets RA = RD for TC responses - query.flags &= ~dns.flags.RD - response = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - '192.0.2.1') - response.answer.append(rrset) - truncatedResponse = dns.message.make_response(query) - truncatedResponse.flags |= dns.flags.TC - - allowed = 0 - sent = 0 - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, response) - allowed = allowed + 1 - else: - self.assertEqual(receivedResponse, truncatedResponse) - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we might be already truncated, but we should have been able to send - # at least self._dynBlockQPS queries - self.assertGreaterEqual(allowed, self._dynBlockQPS) - - if allowed == sent: - # wait for the maintenance function to run - time.sleep(2) - - # we should now be 'truncated' for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, truncatedResponse) - - # check over TCP, which should not be truncated - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, response) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - allowed = 0 - sent = 0 - # again, over TCP this time, we should never get truncated! - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - sent = sent + 1 - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, response) - receivedQuery.id = query.id - allowed = allowed + 1 - - self.assertEqual(allowed, sent) - -class TestDynBlockServFails(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - _config_template = """ - function maintenance() - addDynBlocks(exceedServFails(%d, %d), "Exceeded servfail rate", %d) - end - newServer{address="127.0.0.1:%s"} - """ - - def testDynBlocksServFailRate(self): - """ - Dyn Blocks: Server Failure Rate - """ - name = 'servfailrate.dynblocks.tests.powerdns.com.' - self.doTestRCodeRate(name, dns.rcode.SERVFAIL) - -class TestDynBlockServFailsCached(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - _config_template = """ - pc = newPacketCache(10000, {maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=false}) - getPool(""):setCache(pc) - function maintenance() - addDynBlocks(exceedServFails(%d, %d), "Exceeded servfail rate", %d) - end - newServer{address="127.0.0.1:%s"} - """ - - def testDynBlocksServFailRateCached(self): - """ - Dyn Blocks: Make sure cache hit responses also gets inserted into rings - """ - name = 'servfailrate.dynblocks.tests.powerdns.com.' - rcode = dns.rcode.SERVFAIL - query = dns.message.make_query(name, 'A', 'IN') - response = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - '192.0.2.1') - response.answer.append(rrset) - expectedResponse = dns.message.make_response(query) - expectedResponse.set_rcode(rcode) - - - for method in ("sendUDPQuery", "sendTCPQuery"): - print(method, "()") - sender = getattr(self, method) - - # fill the cache - (receivedQuery, receivedResponse) = sender(query, expectedResponse) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(expectedResponse, receivedResponse) - - # wait for the maintenance function to run - time.sleep(2) - - # we should NOT be dropped! - (_, receivedResponse) = sender(query, response=None) - self.assertEqual(receivedResponse, expectedResponse) - - # now with rcode! - sent = 0 - allowed = 0 - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (_, receivedResponse) = sender(query, expectedResponse) - sent = sent + 1 - self.assertEqual(expectedResponse, receivedResponse) - allowed = allowed + 1 - # we might be already blocked, but we should have been able to send - # at least self._dynBlockQPS queries - self.assertGreaterEqual(allowed, self._dynBlockQPS) - - if allowed == sent: - # wait for the maintenance function to run - time.sleep(2) - - # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = sender(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, None) - - # wait until we are not blocked anymore - time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - - # this one should succeed - (receivedQuery, receivedResponse) = sender(query, response=None) - self.assertEqual(expectedResponse, receivedResponse) - -class TestDynBlockAllowlist(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - _config_template = """ - allowlisted = false - function maintenance() - toBlock = exceedQRate(%d, %d) - for addr, count in pairs(toBlock) do - if tostring(addr) == "127.0.0.1" then - allowlisted = true - toBlock[addr] = nil - end - end - addDynBlocks(toBlock, "Exceeded query rate", %d) - end - - function spoofrule(dq) - if (allowlisted) - then - return DNSAction.Spoof, "192.0.2.42" - else - return DNSAction.None, "" - end - end - addAction("allowlisted-test.dynblocks.tests.powerdns.com.", LuaAction(spoofrule)) - - newServer{address="127.0.0.1:%s"} - """ - - def testAllowlisted(self): - """ - Dyn Blocks: Allowlisted from the dynamic blocks - """ - name = 'allowlisted.dynblocks.tests.powerdns.com.' - query = dns.message.make_query(name, 'A', 'IN') - response = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - '192.0.2.1') - response.answer.append(rrset) - - allowed = 0 - sent = 0 - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - allowed = allowed + 1 - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we should not have been blocked - self.assertEqual(allowed, sent) - - # wait for the maintenance function to run - time.sleep(2) - - # we should still not be blocked - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, receivedResponse) - - # check that we would have been blocked without the allowlisting - name = 'allowlisted-test.dynblocks.tests.powerdns.com.' - query = dns.message.make_query(name, 'A', 'IN') - # dnsdist set RA = RD for spoofed responses - query.flags &= ~dns.flags.RD - expectedResponse = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - '192.0.2.42') - expectedResponse.answer.append(rrset) - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, expectedResponse) - -class TestDynBlockGroupServFails(DynBlocksTest): +class TestDynBlockQPS(DynBlocksTest): - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] _config_template = """ - local dbr = dynBlockRulesGroup() - dbr:setRCodeRate(DNSRCode.SERVFAIL, %d, %d, "Exceeded query rate", %d) - function maintenance() - dbr:apply() + addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d) end - newServer{address="127.0.0.1:%s"} + webserver("127.0.0.1:%s") + setWebserverConfig({password="%s", apiKey="%s"}) """ + _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] - def testDynBlocksServFailRate(self): + def testDynBlocksQRate(self): """ - Dyn Blocks (group): Server Failure Rate + Dyn Blocks: QRate """ - name = 'servfailrate.group.dynblocks.tests.powerdns.com.' - self.doTestRCodeRate(name, dns.rcode.SERVFAIL) + name = 'qrate.dynblocks.tests.powerdns.com.' + self.doTestQRate(name) -class TestDynBlockGroupServFailsRatio(DynBlocksTest): +class TestDynBlockQPSRefused(DynBlocksTest): - # we need this period to be quite long because we request the valid - # queries to be still looked at to reach the 20 queries count! - _dynBlockPeriod = 6 - _dynBlockDuration = 5 - _config_params = ['_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] _config_template = """ - local dbr = dynBlockRulesGroup() - dbr:setRCodeRatio(DNSRCode.SERVFAIL, 0.2, %d, "Exceeded query rate", %d, 20) - function maintenance() - dbr:apply() + addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d) end - + setDynBlocksAction(DNSAction.Refused) newServer{address="127.0.0.1:%s"} """ - def testDynBlocksServFailRatio(self): + def testDynBlocksQRate(self): """ - Dyn Blocks (group): Server Failure Ratio + Dyn Blocks: QRate refused """ - name = 'servfailratio.group.dynblocks.tests.powerdns.com.' - self.doTestRCodeRatio(name, dns.rcode.SERVFAIL, 10, 10) + name = 'qraterefused.dynblocks.tests.powerdns.com.' + self.doTestQRateRCode(name, dns.rcode.REFUSED) -class TestDynBlockResponseBytes(DynBlocksTest): +class TestDynBlockQPSActionRefused(DynBlocksTest): - _dynBlockBytesPerSecond = 200 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _consoleKey = DNSDistTest.generateConsoleKey() - _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _config_params = ['_consoleKeyB64', '_consolePort', '_dynBlockBytesPerSecond', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] _config_template = """ - setKey("%s") - controlSocket("127.0.0.1:%s") function maintenance() - addDynBlocks(exceedRespByterate(%d, %d), "Exceeded response byterate", %d) + addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d, DNSAction.Refused) end + setDynBlocksAction(DNSAction.Drop) newServer{address="127.0.0.1:%s"} """ - def testDynBlocksResponseByteRate(self): + def testDynBlocksQRate(self): """ - Dyn Blocks: Response Byte Rate + Dyn Blocks: QRate refused (action) """ - name = 'responsebyterate.dynblocks.tests.powerdns.com.' - self.doTestResponseByteRate(name) + name = 'qrateactionrefused.dynblocks.tests.powerdns.com.' + self.doTestQRateRCode(name, dns.rcode.REFUSED) -class TestDynBlockGroupResponseBytes(DynBlocksTest): +class TestDynBlockQPSActionNXD(DynBlocksTest): - _dynBlockBytesPerSecond = 200 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _consoleKey = DNSDistTest.generateConsoleKey() - _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _config_params = ['_consoleKeyB64', '_consolePort', '_dynBlockBytesPerSecond', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] _config_template = """ - setKey("%s") - controlSocket("127.0.0.1:%s") - local dbr = dynBlockRulesGroup() - dbr:setResponseByteRate(%d, %d, "Exceeded query rate", %d) - function maintenance() - dbr:apply() + addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d, DNSAction.Nxdomain) end - + setDynBlocksAction(DNSAction.Drop) newServer{address="127.0.0.1:%s"} """ - def testDynBlocksResponseByteRate(self): + def testDynBlocksQRate(self): """ - Dyn Blocks (group) : Response Byte Rate + Dyn Blocks: QRate NXD (action) """ - name = 'responsebyterate.group.dynblocks.tests.powerdns.com.' - self.doTestResponseByteRate(name) + name = 'qrateactionnxd.dynblocks.tests.powerdns.com.' + self.doTestQRateRCode(name, dns.rcode.NXDOMAIN) -class TestDynBlockGroupExcluded(DynBlocksTest): +class TestDynBlockQPSActionTruncated(DNSDistTest): _dynBlockQPS = 10 _dynBlockPeriod = 2 - _dynBlockDuration = 5 + # this needs to be greater than maintenanceWaitTime + _dynBlockDuration = _maintenanceWaitTime + 1 _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] _config_template = """ - local dbr = dynBlockRulesGroup() - dbr:setQueryRate(%d, %d, "Exceeded query rate", %d) - dbr:excludeRange("127.0.0.1/32") - function maintenance() - dbr:apply() + addDynBlocks(exceedQRate(%d, %d), "Exceeded query rate", %d, DNSAction.Truncate) end - + setDynBlocksAction(DNSAction.Drop) newServer{address="127.0.0.1:%s"} """ - def testExcluded(self): + def testDynBlocksQRate(self): """ - Dyn Blocks (group) : Excluded from the dynamic block rules + Dyn Blocks: QRate truncated (action) """ - name = 'excluded.group.dynblocks.tests.powerdns.com.' + name = 'qrateactiontruncated.dynblocks.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') + # dnsdist sets RA = RD for TC responses + query.flags &= ~dns.flags.RD response = dns.message.make_response(query) rrset = dns.rrset.from_text(name, 60, @@ -1124,6 +106,8 @@ def testExcluded(self): dns.rdatatype.A, '192.0.2.1') response.answer.append(rrset) + truncatedResponse = dns.message.make_response(query) + truncatedResponse.flags |= dns.flags.TC allowed = 0 sent = 0 @@ -1133,175 +117,88 @@ def testExcluded(self): if receivedQuery: receivedQuery.id = query.id self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) + self.assertEqual(receivedResponse, response) allowed = allowed + 1 else: + self.assertEqual(receivedResponse, truncatedResponse) # the query has not reached the responder, # let's clear the response queue self.clearToResponderQueue() - # we should not have been blocked - self.assertEqual(allowed, sent) - - # wait for the maintenance function to run - time.sleep(2) - - # we should still not be blocked - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, receivedResponse) - -class TestDynBlockGroupExcludedViaNMG(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - _config_template = """ - local nmg = newNMG() - nmg:addMask("127.0.0.1/32") - - local dbr = dynBlockRulesGroup() - dbr:setQueryRate(%d, %d, "Exceeded query rate", %d) - dbr:excludeRange(nmg) - - function maintenance() - dbr:apply() - end + # we might be already truncated, but we should have been able to send + # at least self._dynBlockQPS queries + self.assertGreaterEqual(allowed, self._dynBlockQPS) - newServer{address="127.0.0.1:%s"} - """ + if allowed == sent: + waitForMaintenanceToRun() - def testExcluded(self): - """ - Dyn Blocks (group) : Excluded (via NMG) from the dynamic block rules - """ - name = 'excluded-nmg.group.dynblocks.tests.powerdns.com.' - query = dns.message.make_query(name, 'A', 'IN') - response = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - '192.0.2.1') - response.answer.append(rrset) + # we should now be 'truncated' for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, truncatedResponse) - allowed = 0 - sent = 0 - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - allowed = allowed + 1 - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() + # check over TCP, which should not be truncated + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) - # we should not have been blocked - self.assertEqual(allowed, sent) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(receivedResponse, response) - # wait for the maintenance function to run - time.sleep(2) + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) - # we should still not be blocked + # this one should succeed (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, receivedResponse) - -class TestDynBlockGroupNoOp(DynBlocksTest): - - _dynBlockQPS = 10 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_template = """ - local dbr = dynBlockRulesGroup() - dbr:setQueryRate(%d, %d, "Exceeded query rate", %d, DNSAction.NoOp) - - function maintenance() - dbr:apply() - end - - newServer{address="127.0.0.1:%s"} - webserver("127.0.0.1:%s") - setWebserverConfig({password="%s", apiKey="%s"}) - """ - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] - - def testNoOp(self): - """ - Dyn Blocks (group) : NoOp - """ - name = 'noop.group.dynblocks.tests.powerdns.com.' - query = dns.message.make_query(name, 'A', 'IN') - response = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 60, - dns.rdataclass.IN, - dns.rdatatype.A, - '192.0.2.1') - response.answer.append(rrset) + self.assertEqual(response, receivedResponse) allowed = 0 sent = 0 + # again, over TCP this time, we should never get truncated! for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + (receivedQuery, receivedResponse) = self.sendTCPQuery(query, response) sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - allowed = allowed + 1 - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(receivedResponse, response) + receivedQuery.id = query.id + allowed = allowed + 1 - # a dynamic rule should have been inserted, but the queries should still go on self.assertEqual(allowed, sent) - # wait for the maintenance function to run - time.sleep(2) - - # the rule should still be present, but the queries pass through anyway - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, receivedResponse) - - # check that the rule has been inserted - self.doTestDynBlockViaAPI('127.0.0.1/32', 'Exceeded query rate', self._dynBlockDuration - 4, self._dynBlockDuration, 0, sent) - -class TestDynBlockGroupWarning(DynBlocksTest): +class TestDynBlockAllowlist(DynBlocksTest): - _dynBlockWarningQPS = 5 - _dynBlockQPS = 20 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 _config_template = """ - local dbr = dynBlockRulesGroup() - dbr:setQueryRate(%d, %d, "Exceeded query rate", %d, DNSAction.Drop, %d) - + allowlisted = false function maintenance() - dbr:apply() + toBlock = exceedQRate(%d, %d) + for addr, count in pairs(toBlock) do + if tostring(addr) == "127.0.0.1" then + allowlisted = true + toBlock[addr] = nil + end + end + addDynBlocks(toBlock, "Exceeded query rate", %d) + end + + function spoofrule(dq) + if (allowlisted) + then + return DNSAction.Spoof, "192.0.2.42" + else + return DNSAction.None, "" + end end + addAction("allowlisted-test.dynblocks.tests.powerdns.com.", LuaAction(spoofrule)) newServer{address="127.0.0.1:%s"} - webserver("127.0.0.1:%s") - setWebserverConfig({password="%s", apiKey="%s"}) """ - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_dynBlockWarningQPS', '_testServerPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] - def testWarning(self): + def testAllowlisted(self): """ - Dyn Blocks (group) : Warning + Dyn Blocks: Allowlisted from the dynamic blocks """ - name = 'warning.group.dynblocks.tests.powerdns.com.' + name = 'allowlisted.dynblocks.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) rrset = dns.rrset.from_text(name, @@ -1313,7 +210,7 @@ def testWarning(self): allowed = 0 sent = 0 - for _ in range((self._dynBlockWarningQPS * self._dynBlockPeriod) + 1): + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) sent = sent + 1 if receivedQuery: @@ -1326,93 +223,28 @@ def testWarning(self): # let's clear the response queue self.clearToResponderQueue() - # a dynamic rule should have been inserted, but the queries should - # still go on because we are still at warning level + # we should not have been blocked self.assertEqual(allowed, sent) - # wait for the maintenance function to run - time.sleep(2) + waitForMaintenanceToRun() - # the rule should still be present, but the queries pass through anyway + # we should still not be blocked (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) self.assertEqual(receivedResponse, receivedResponse) - # check that the rule has been inserted - self.doTestDynBlockViaAPI('127.0.0.1/32', 'Exceeded query rate', self._dynBlockDuration - 4, self._dynBlockDuration, 0, sent) - - self.doTestQRate(name) - -class TestDynBlockGroupPort(DNSDistTest): - - _dynBlockQPS = 20 - _dynBlockPeriod = 2 - _dynBlockDuration = 5 - _config_template = """ - local dbr = dynBlockRulesGroup() - dbr:setQueryRate(%d, %d, "Exceeded query rate", %d, DNSAction.Drop) - -- take the exact port into account - dbr:setMasks(32, 128, 16) - - function maintenance() - dbr:apply() - end - newServer{address="127.0.0.1:%d"} - """ - _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] - - def testPort(self): - """ - Dyn Blocks (group): Exact port matching - """ - name = 'port.group.dynblocks.tests.powerdns.com.' + # check that we would have been blocked without the allowlisting + name = 'allowlisted-test.dynblocks.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') - response = dns.message.make_response(query) + # dnsdist set RA = RD for spoofed responses + query.flags &= ~dns.flags.RD + expectedResponse = dns.message.make_response(query) rrset = dns.rrset.from_text(name, 60, dns.rdataclass.IN, dns.rdatatype.A, - '192.0.2.1') - response.answer.append(rrset) - - allowed = 0 - sent = 0 - for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): - (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) - sent = sent + 1 - if receivedQuery: - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - allowed = allowed + 1 - else: - # the query has not reached the responder, - # let's clear the response queue - self.clearToResponderQueue() - - # we might be already blocked, but we should have been able to send - # at least self._dynBlockQPS queries - self.assertGreaterEqual(allowed, self._dynBlockQPS) - - if allowed == sent: - # wait for the maintenance function to run - time.sleep(2) - - # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + '192.0.2.42') + expectedResponse.answer.append(rrset) (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) - self.assertEqual(receivedResponse, None) - - # use a new socket, so a new port - self._toResponderQueue.put(response, True, 1.0) - newsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) - newsock.settimeout(1.0) - newsock.connect(("127.0.0.1", self._dnsDistPort)) - newsock.send(query.to_wire()) - receivedResponse = newsock.recv(4096) - if receivedResponse: - receivedResponse = dns.message.from_wire(receivedResponse) - receivedQuery = self._fromResponderQueue.get(True, 1.0) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) + self.assertEqual(receivedResponse, expectedResponse) diff --git a/regression-tests.dnsdist/test_DynBlocksGroup.py b/regression-tests.dnsdist/test_DynBlocksGroup.py new file mode 100644 index 000000000000..fc6299805ead --- /dev/null +++ b/regression-tests.dnsdist/test_DynBlocksGroup.py @@ -0,0 +1,376 @@ +#!/usr/bin/env python +import base64 +import socket +import time +import dns +from dnsdisttests import DNSDistTest +from dnsdistDynBlockTests import DynBlocksTest, waitForMaintenanceToRun, _maintenanceWaitTime + +class TestDynBlockGroupQPS(DynBlocksTest): + + _config_template = """ + local dbr = dynBlockRulesGroup() + dbr:setQueryRate(%d, %d, "Exceeded query rate", %d) + + function maintenance() + dbr:apply() + end + newServer{address="127.0.0.1:%s"} + webserver("127.0.0.1:%s") + setWebserverConfig({password="%s", apiKey="%s"}) + """ + _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] + + def testDynBlocksQRate(self): + """ + Dyn Blocks (Group): QRate + """ + name = 'qrate.group.dynblocks.tests.powerdns.com.' + self.doTestQRate(name) + +class TestDynBlockGroupQPSRefused(DynBlocksTest): + + _config_template = """ + local dbr = dynBlockRulesGroup() + dbr:setQueryRate(%d, %d, "Exceeded query rate", %d) + + function maintenance() + dbr:apply() + end + setDynBlocksAction(DNSAction.Refused) + newServer{address="127.0.0.1:%s"} + """ + + def testDynBlocksQRate(self): + """ + Dyn Blocks (Group): QRate refused + """ + name = 'qraterefused.group.dynblocks.tests.powerdns.com.' + self.doTestQRateRCode(name, dns.rcode.REFUSED) + +class TestDynBlockGroupQPSActionRefused(DynBlocksTest): + + _config_template = """ + local dbr = dynBlockRulesGroup() + dbr:setQueryRate(%d, %d, "Exceeded query rate", %d, DNSAction.Refused) + + function maintenance() + dbr:apply() + end + setDynBlocksAction(DNSAction.Drop) + newServer{address="127.0.0.1:%s"} + """ + + def testDynBlocksQRate(self): + """ + Dyn Blocks (group): QRate refused (action) + """ + name = 'qrateactionrefused.group.dynblocks.tests.powerdns.com.' + self.doTestQRateRCode(name, dns.rcode.REFUSED) + +class TestDynBlockGroupExcluded(DynBlocksTest): + + _config_template = """ + local dbr = dynBlockRulesGroup() + dbr:setQueryRate(%d, %d, "Exceeded query rate", %d) + dbr:excludeRange("127.0.0.1/32") + + function maintenance() + dbr:apply() + end + + newServer{address="127.0.0.1:%s"} + """ + + def testExcluded(self): + """ + Dyn Blocks (group) : Excluded from the dynamic block rules + """ + name = 'excluded.group.dynblocks.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + + allowed = 0 + sent = 0 + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we should not have been blocked + self.assertEqual(allowed, sent) + + waitForMaintenanceToRun() + + # we should still not be blocked + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(receivedResponse, receivedResponse) + +class TestDynBlockGroupExcludedViaNMG(DynBlocksTest): + + _config_template = """ + local nmg = newNMG() + nmg:addMask("127.0.0.1/32") + + local dbr = dynBlockRulesGroup() + dbr:setQueryRate(%d, %d, "Exceeded query rate", %d) + dbr:excludeRange(nmg) + + function maintenance() + dbr:apply() + end + + newServer{address="127.0.0.1:%s"} + """ + + def testExcluded(self): + """ + Dyn Blocks (group) : Excluded (via NMG) from the dynamic block rules + """ + name = 'excluded-nmg.group.dynblocks.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + + allowed = 0 + sent = 0 + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we should not have been blocked + self.assertEqual(allowed, sent) + + waitForMaintenanceToRun() + + # we should still not be blocked + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(receivedResponse, receivedResponse) + +class TestDynBlockGroupNoOp(DynBlocksTest): + + _config_template = """ + local dbr = dynBlockRulesGroup() + dbr:setQueryRate(%d, %d, "Exceeded query rate", %d, DNSAction.NoOp) + + function maintenance() + dbr:apply() + end + + newServer{address="127.0.0.1:%s"} + webserver("127.0.0.1:%s") + setWebserverConfig({password="%s", apiKey="%s"}) + """ + _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] + + def testNoOp(self): + """ + Dyn Blocks (group) : NoOp + """ + name = 'noop.group.dynblocks.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + + allowed = 0 + sent = 0 + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # a dynamic rule should have been inserted, but the queries should still go on + self.assertEqual(allowed, sent) + + waitForMaintenanceToRun() + + # the rule should still be present, but the queries pass through anyway + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(receivedResponse, receivedResponse) + + # check that the rule has been inserted + self.doTestDynBlockViaAPI('127.0.0.1/32', 'Exceeded query rate', 1, self._dynBlockDuration, 0, sent) + +class TestDynBlockGroupWarning(DynBlocksTest): + + _dynBlockWarningQPS = 5 + _dynBlockQPS = 20 + _config_template = """ + local dbr = dynBlockRulesGroup() + dbr:setQueryRate(%d, %d, "Exceeded query rate", %d, DNSAction.Drop, %d) + + function maintenance() + dbr:apply() + end + + newServer{address="127.0.0.1:%s"} + webserver("127.0.0.1:%s") + setWebserverConfig({password="%s", apiKey="%s"}) + """ + _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_dynBlockWarningQPS', '_testServerPort', '_webServerPort', '_webServerBasicAuthPasswordHashed', '_webServerAPIKeyHashed'] + + def testWarning(self): + """ + Dyn Blocks (group) : Warning + """ + name = 'warning.group.dynblocks.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + + allowed = 0 + sent = 0 + for _ in range((self._dynBlockWarningQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # a dynamic rule should have been inserted, but the queries should + # still go on because we are still at warning level + self.assertEqual(allowed, sent) + + waitForMaintenanceToRun() + + # the rule should still be present, but the queries pass through anyway + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(receivedResponse, receivedResponse) + + # check that the rule has been inserted + self.doTestDynBlockViaAPI('127.0.0.1/32', 'Exceeded query rate', 1, self._dynBlockDuration, 0, sent) + + self.doTestQRate(name) + +class TestDynBlockGroupPort(DNSDistTest): + + _dynBlockQPS = 20 + _dynBlockPeriod = 2 + # this needs to be greater than maintenanceWaitTime + _dynBlockDuration = _maintenanceWaitTime + 1 + _config_template = """ + local dbr = dynBlockRulesGroup() + dbr:setQueryRate(%d, %d, "Exceeded query rate", %d, DNSAction.Drop) + -- take the exact port into account + dbr:setMasks(32, 128, 16) + + function maintenance() + dbr:apply() + end + newServer{address="127.0.0.1:%d"} + """ + _config_params = ['_dynBlockQPS', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] + + def testPort(self): + """ + Dyn Blocks (group): Exact port matching + """ + name = 'port.group.dynblocks.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + + allowed = 0 + sent = 0 + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + sent = sent + 1 + if receivedQuery: + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + allowed = allowed + 1 + else: + # the query has not reached the responder, + # let's clear the response queue + self.clearToResponderQueue() + + # we might be already blocked, but we should have been able to send + # at least self._dynBlockQPS queries + self.assertGreaterEqual(allowed, self._dynBlockQPS) + + if allowed == sent: + waitForMaintenanceToRun() + + # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, None) + + # use a new socket, so a new port + self._toResponderQueue.put(response, True, 1.0) + newsock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + newsock.settimeout(1.0) + newsock.connect(("127.0.0.1", self._dnsDistPort)) + newsock.send(query.to_wire()) + receivedResponse = newsock.recv(4096) + if receivedResponse: + receivedResponse = dns.message.from_wire(receivedResponse) + receivedQuery = self._fromResponderQueue.get(True, 1.0) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) diff --git a/regression-tests.dnsdist/test_DynBlocksRatio.py b/regression-tests.dnsdist/test_DynBlocksRatio.py new file mode 100644 index 000000000000..9eb8c1169b89 --- /dev/null +++ b/regression-tests.dnsdist/test_DynBlocksRatio.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python +import base64 +import socket +import time +import dns +from dnsdisttests import DNSDistTest +from dnsdistDynBlockTests import DynBlocksTest, waitForMaintenanceToRun, _maintenanceWaitTime + +class TestDynBlockGroupServFailsRatio(DynBlocksTest): + + # we need this period to be quite long because we request the valid + # queries to be still looked at to reach the 20 queries count! + _dynBlockPeriod = 6 + _config_params = ['_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] + _config_template = """ + local dbr = dynBlockRulesGroup() + dbr:setRCodeRatio(DNSRCode.SERVFAIL, 0.2, %d, "Exceeded query rate", %d, 20) + + function maintenance() + dbr:apply() + end + + newServer{address="127.0.0.1:%s"} + """ + + def testDynBlocksServFailRatio(self): + """ + Dyn Blocks (group): Server Failure Ratio + """ + name = 'servfailratio.group.dynblocks.tests.powerdns.com.' + self.doTestRCodeRatio(name, dns.rcode.SERVFAIL, 10, 10) diff --git a/regression-tests.dnsdist/test_DynBlocksResponseBytes.py b/regression-tests.dnsdist/test_DynBlocksResponseBytes.py new file mode 100644 index 000000000000..18cdce565bcb --- /dev/null +++ b/regression-tests.dnsdist/test_DynBlocksResponseBytes.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +import base64 +import socket +import time +import dns +from dnsdisttests import DNSDistTest +from dnsdistDynBlockTests import DynBlocksTest, waitForMaintenanceToRun, _maintenanceWaitTime + +class TestDynBlockResponseBytes(DynBlocksTest): + + _dynBlockBytesPerSecond = 200 + _consoleKey = DNSDistTest.generateConsoleKey() + _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') + _config_params = ['_consoleKeyB64', '_consolePort', '_dynBlockBytesPerSecond', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] + _config_template = """ + setKey("%s") + controlSocket("127.0.0.1:%s") + function maintenance() + addDynBlocks(exceedRespByterate(%d, %d), "Exceeded response byterate", %d) + end + newServer{address="127.0.0.1:%s"} + """ + + def testDynBlocksResponseByteRate(self): + """ + Dyn Blocks: Response Byte Rate + """ + name = 'responsebyterate.dynblocks.tests.powerdns.com.' + self.doTestResponseByteRate(name, self._dynBlockBytesPerSecond) + +class TestDynBlockGroupResponseBytes(DynBlocksTest): + + _dynBlockBytesPerSecond = 200 + _consoleKey = DNSDistTest.generateConsoleKey() + _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') + _config_params = ['_consoleKeyB64', '_consolePort', '_dynBlockBytesPerSecond', '_dynBlockPeriod', '_dynBlockDuration', '_testServerPort'] + _config_template = """ + setKey("%s") + controlSocket("127.0.0.1:%s") + local dbr = dynBlockRulesGroup() + dbr:setResponseByteRate(%d, %d, "Exceeded query rate", %d) + + function maintenance() + dbr:apply() + end + + newServer{address="127.0.0.1:%s"} + """ + + def testDynBlocksResponseByteRate(self): + """ + Dyn Blocks (group) : Response Byte Rate + """ + name = 'responsebyterate.group.dynblocks.tests.powerdns.com.' + self.doTestResponseByteRate(name, self._dynBlockBytesPerSecond) diff --git a/regression-tests.dnsdist/test_DynBlocksServFail.py b/regression-tests.dnsdist/test_DynBlocksServFail.py new file mode 100644 index 000000000000..fa142c8fbd50 --- /dev/null +++ b/regression-tests.dnsdist/test_DynBlocksServFail.py @@ -0,0 +1,114 @@ +#!/usr/bin/env python +import base64 +import socket +import time +import dns +from dnsdisttests import DNSDistTest +from dnsdistDynBlockTests import DynBlocksTest, waitForMaintenanceToRun, _maintenanceWaitTime + +class TestDynBlockServFails(DynBlocksTest): + + _config_template = """ + function maintenance() + addDynBlocks(exceedServFails(%d, %d), "Exceeded servfail rate", %d) + end + newServer{address="127.0.0.1:%s"} + """ + + def testDynBlocksServFailRate(self): + """ + Dyn Blocks: Server Failure Rate + """ + name = 'servfailrate.dynblocks.tests.powerdns.com.' + self.doTestRCodeRate(name, dns.rcode.SERVFAIL) + +class TestDynBlockServFailsCached(DynBlocksTest): + + _config_template = """ + pc = newPacketCache(10000, {maxTTL=86400, minTTL=0, temporaryFailureTTL=60, staleTTL=60, dontAge=false}) + getPool(""):setCache(pc) + function maintenance() + addDynBlocks(exceedServFails(%d, %d), "Exceeded servfail rate", %d) + end + newServer{address="127.0.0.1:%s"} + """ + + def testDynBlocksServFailRateCached(self): + """ + Dyn Blocks: Make sure cache hit responses also gets inserted into rings + """ + name = 'servfailrate.dynblocks.tests.powerdns.com.' + rcode = dns.rcode.SERVFAIL + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 60, + dns.rdataclass.IN, + dns.rdatatype.A, + '192.0.2.1') + response.answer.append(rrset) + expectedResponse = dns.message.make_response(query) + expectedResponse.set_rcode(rcode) + + + for method in ("sendUDPQuery", "sendTCPQuery"): + print(method, "()") + sender = getattr(self, method) + + # fill the cache + (receivedQuery, receivedResponse) = sender(query, expectedResponse) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(expectedResponse, receivedResponse) + + waitForMaintenanceToRun() + + # we should NOT be dropped! + (_, receivedResponse) = sender(query, response=None) + self.assertEqual(receivedResponse, expectedResponse) + + # now with rcode! + sent = 0 + allowed = 0 + for _ in range((self._dynBlockQPS * self._dynBlockPeriod) + 1): + (_, receivedResponse) = sender(query, expectedResponse) + sent = sent + 1 + self.assertEqual(expectedResponse, receivedResponse) + allowed = allowed + 1 + # we might be already blocked, but we should have been able to send + # at least self._dynBlockQPS queries + self.assertGreaterEqual(allowed, self._dynBlockQPS) + + if allowed == sent: + waitForMaintenanceToRun() + + # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod + (_, receivedResponse) = sender(query, response=None, useQueue=False) + self.assertEqual(receivedResponse, None) + + # wait until we are not blocked anymore + time.sleep(self._dynBlockDuration + self._dynBlockPeriod) + + # this one should succeed + (receivedQuery, receivedResponse) = sender(query, response=None) + self.assertEqual(expectedResponse, receivedResponse) + +class TestDynBlockGroupServFails(DynBlocksTest): + + _config_template = """ + local dbr = dynBlockRulesGroup() + dbr:setRCodeRate(DNSRCode.SERVFAIL, %d, %d, "Exceeded query rate", %d) + + function maintenance() + dbr:apply() + end + + newServer{address="127.0.0.1:%s"} + """ + + def testDynBlocksServFailRate(self): + """ + Dyn Blocks (group): Server Failure Rate + """ + name = 'servfailrate.group.dynblocks.tests.powerdns.com.' + self.doTestRCodeRate(name, dns.rcode.SERVFAIL) From b56f05b6d81d64cc11f389e2b08d070c1b912ce7 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 23 Aug 2023 16:46:55 +0200 Subject: [PATCH 579/909] TCPIOHandler: Fix a race when creating the first TLS connections We used to get a index from OpenSSL when the first incoming or outgoing TLS connection was created. That index is later used to store application-related data along the TLS connection, to be able to access it in callbacks called from inside the OpenSSL library. Unfortunately the atomic flag construction used was racy: if a second connection is created while the first one is still getting the index, it could be reading the initial value (-1) instead of the actual index, which might prevent the callback from working properly because they cannot retrieve the necessary data. The good news is that this should not have a serious impact: a TLS session might not be properly resumed while it should have been, leading to a full TLS session negotiation. This commit fixes the race by using a full mutex and only releasing it once the value has been computed. In order to avoid a performance penalty, the index is now computed when a TLS connection _context_ is created, instead of a TLS connection. TLS contexts should be reused for a large number of connections, and mostly created during startup or in the first few seconds of the application. The race was reported by Thread Sanitizer during the `test_TLS.py::TestTLSFrontendLimits::testTCPConnsPerTLSFrontend` regression test as: ``` WARNING: ThreadSanitizer: data race (pid=120466) Read of size 4 at 0x55a12bf3d758 by thread T4: #0 OpenSSLTLSConnection::OpenSSLTLSConnection(int, timeval const&, std::shared_ptr) /work/pdns/pdns/dnsdistdist/tcpiohandler.cc:106 (dnsdist+0x97ece8) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #1 std::__detail::_MakeUniq::__single_object std::make_unique&>(int&, timeval const&, std::shared_ptr&) /usr/include/c++/13.2.1/bits/unique_ptr.h:1070 (dnsdist+0x97eff6) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #2 OpenSSLTLSIOCtx::getConnection(int, timeval const&, long) /work/pdns/pdns/dnsdistdist/tcpiohandler.cc:797 (dnsdist+0x97eff6) #3 TCPIOHandler::TCPIOHandler(int, timeval const&, std::shared_ptr, long) /work/pdns/pdns/dnsdistdist/tcpiohandler.hh:246 (dnsdist+0x88c24f) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #4 IncomingTCPConnectionState::IncomingTCPConnectionState(ConnectionInfo&&, TCPClientThreadData&, timeval const&) /work/pdns/pdns/dnsdistdist/dnsdist-tcp-upstream.hh:29 (dnsdist+0x88c24f) #5 void std::_Construct(IncomingTCPConnectionState*, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/stl_construct.h:119 (dnsdist+0x878b1e) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #6 void std::allocator_traits >::construct(std::allocator&, IncomingTCPConnectionState*, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/alloc_traits.h:660 (dnsdist+0x878b1e) #7 std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace(std::allocator, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/shared_ptr_base.h:604 (dnsdist+0x878b1e) #8 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count, ConnectionInfo, TCPClientThreadData&, timeval&>(IncomingTCPConnectionState*&, std::_Sp_alloc_shared_tag >, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/shared_ptr_base.h:971 (dnsdist+0x878b1e) #9 std::__shared_ptr::__shared_ptr, ConnectionInfo, TCPClientThreadData&, timeval&>(std::_Sp_alloc_shared_tag >, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/shared_ptr_base.h:1712 (dnsdist+0x878b1e) #10 std::shared_ptr::shared_ptr, ConnectionInfo, TCPClientThreadData&, timeval&>(std::_Sp_alloc_shared_tag >, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/shared_ptr.h:464 (dnsdist+0x878b1e) #11 std::shared_ptr::value, IncomingTCPConnectionState>::type> std::make_shared(ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/shared_ptr.h:1010 (dnsdist+0x878b1e) #12 handleIncomingTCPQuery /work/pdns/pdns/dnsdistdist/dnsdist-tcp.cc:1118 (dnsdist+0x878b1e) #13 void std::__invoke_impl(std::__invoke_other, void (*&)(int, boost::any&), int&&, boost::any&) /usr/include/c++/13.2.1/bits/invoke.h:61 (dnsdist+0x32d951) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #14 std::enable_if, void>::type std::__invoke_r(void (*&)(int, boost::any&), int&&, boost::any&) /usr/include/c++/13.2.1/bits/invoke.h:111 (dnsdist+0x32d951) #15 std::_Function_handler::_M_invoke(std::_Any_data const&, int&&, boost::any&) /usr/include/c++/13.2.1/bits/std_function.h:290 (dnsdist+0x32d951) #16 std::function::operator()(int, boost::any&) const /usr/include/c++/13.2.1/bits/std_function.h:591 (dnsdist+0x98fc0f) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #17 EpollFDMultiplexer::run(timeval*, int) /work/pdns/pdns/dnsdistdist/epollmplexer.cc:190 (dnsdist+0x98fc0f) #18 tcpClientThread /work/pdns/pdns/dnsdistdist/dnsdist-tcp.cc:1251 (dnsdist+0x86cb7f) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #19 void std::__invoke_impl >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > >(std::__invoke_other, void (*&&)(pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >&&) /usr/include/c++/13.2.1/bits/invoke.h:61 (dnsdist+0x87aab1) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #20 std::__invoke_result >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > >::type std::__invoke >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > >(void (*&&)(pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >&&) /usr/include/c++/13.2.1/bits/invoke.h:96 (dnsdist+0x87aab1) #21 void std::thread::_Invoker >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > > >::_M_invoke<0ul, 1ul, 2ul, 3ul, 4ul, 5ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul, 4ul, 5ul>) /usr/include/c++/13.2.1/bits/std_thread.h:292 (dnsdist+0x87aab1) #22 std::thread::_Invoker >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > > >::operator()() /usr/include/c++/13.2.1/bits/std_thread.h:299 (dnsdist+0x87aab1) #23 std::thread::_State_impl >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > > > >::_M_run() /usr/include/c++/13.2.1/bits/std_thread.h:244 (dnsdist+0x87aab1) #24 execute_native_thread_routine /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:104 (libstdc++.so.6+0xe1942) (BuildId: 207eb738c5976dd9aac1ae0640fc4de5946b547e) Previous write of size 4 at 0x55a12bf3d758 by thread T3: #0 OpenSSLTLSConnection::OpenSSLTLSConnection(int, timeval const&, std::shared_ptr) /work/pdns/pdns/dnsdistdist/tcpiohandler.cc:88 (dnsdist+0x97ed98) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #1 std::__detail::_MakeUniq::__single_object std::make_unique&>(int&, timeval const&, std::shared_ptr&) /usr/include/c++/13.2.1/bits/unique_ptr.h:1070 (dnsdist+0x97eff6) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #2 OpenSSLTLSIOCtx::getConnection(int, timeval const&, long) /work/pdns/pdns/dnsdistdist/tcpiohandler.cc:797 (dnsdist+0x97eff6) #3 TCPIOHandler::TCPIOHandler(int, timeval const&, std::shared_ptr, long) /work/pdns/pdns/dnsdistdist/tcpiohandler.hh:246 (dnsdist+0x88c24f) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #4 IncomingTCPConnectionState::IncomingTCPConnectionState(ConnectionInfo&&, TCPClientThreadData&, timeval const&) /work/pdns/pdns/dnsdistdist/dnsdist-tcp-upstream.hh:29 (dnsdist+0x88c24f) #5 void std::_Construct(IncomingTCPConnectionState*, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/stl_construct.h:119 (dnsdist+0x878b1e) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #6 void std::allocator_traits >::construct(std::allocator&, IncomingTCPConnectionState*, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/alloc_traits.h:660 (dnsdist+0x878b1e) #7 std::_Sp_counted_ptr_inplace, (__gnu_cxx::_Lock_policy)2>::_Sp_counted_ptr_inplace(std::allocator, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/shared_ptr_base.h:604 (dnsdist+0x878b1e) #8 std::__shared_count<(__gnu_cxx::_Lock_policy)2>::__shared_count, ConnectionInfo, TCPClientThreadData&, timeval&>(IncomingTCPConnectionState*&, std::_Sp_alloc_shared_tag >, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/shared_ptr_base.h:971 (dnsdist+0x878b1e) #9 std::__shared_ptr::__shared_ptr, ConnectionInfo, TCPClientThreadData&, timeval&>(std::_Sp_alloc_shared_tag >, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/shared_ptr_base.h:1712 (dnsdist+0x878b1e) #10 std::shared_ptr::shared_ptr, ConnectionInfo, TCPClientThreadData&, timeval&>(std::_Sp_alloc_shared_tag >, ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/shared_ptr.h:464 (dnsdist+0x878b1e) #11 std::shared_ptr::value, IncomingTCPConnectionState>::type> std::make_shared(ConnectionInfo&&, TCPClientThreadData&, timeval&) /usr/include/c++/13.2.1/bits/shared_ptr.h:1010 (dnsdist+0x878b1e) #12 handleIncomingTCPQuery /work/pdns/pdns/dnsdistdist/dnsdist-tcp.cc:1118 (dnsdist+0x878b1e) #13 void std::__invoke_impl(std::__invoke_other, void (*&)(int, boost::any&), int&&, boost::any&) /usr/include/c++/13.2.1/bits/invoke.h:61 (dnsdist+0x32d951) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #14 std::enable_if, void>::type std::__invoke_r(void (*&)(int, boost::any&), int&&, boost::any&) /usr/include/c++/13.2.1/bits/invoke.h:111 (dnsdist+0x32d951) #15 std::_Function_handler::_M_invoke(std::_Any_data const&, int&&, boost::any&) /usr/include/c++/13.2.1/bits/std_function.h:290 (dnsdist+0x32d951) #16 std::function::operator()(int, boost::any&) const /usr/include/c++/13.2.1/bits/std_function.h:591 (dnsdist+0x98fc0f) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #17 EpollFDMultiplexer::run(timeval*, int) /work/pdns/pdns/dnsdistdist/epollmplexer.cc:190 (dnsdist+0x98fc0f) #18 tcpClientThread /work/pdns/pdns/dnsdistdist/dnsdist-tcp.cc:1251 (dnsdist+0x86cb7f) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #19 void std::__invoke_impl >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > >(std::__invoke_other, void (*&&)(pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >&&) /usr/include/c++/13.2.1/bits/invoke.h:61 (dnsdist+0x87aab1) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #20 std::__invoke_result >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > >::type std::__invoke >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > >(void (*&&)(pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >&&) /usr/include/c++/13.2.1/bits/invoke.h:96 (dnsdist+0x87aab1) #21 void std::thread::_Invoker >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > > >::_M_invoke<0ul, 1ul, 2ul, 3ul, 4ul, 5ul>(std::_Index_tuple<0ul, 1ul, 2ul, 3ul, 4ul, 5ul>) /usr/include/c++/13.2.1/bits/std_thread.h:292 (dnsdist+0x87aab1) #22 std::thread::_Invoker >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > > >::operator()() /usr/include/c++/13.2.1/bits/std_thread.h:299 (dnsdist+0x87aab1) #23 std::thread::_State_impl >&&, pdns::channel::Receiver >&&, pdns::channel::Receiver >&&, pdns::channel::Sender >&&, std::vector >), pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Receiver >, pdns::channel::Sender >, std::vector > > > >::_M_run() /usr/include/c++/13.2.1/bits/std_thread.h:244 (dnsdist+0x87aab1) #24 execute_native_thread_routine /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:104 (libstdc++.so.6+0xe1942) (BuildId: 207eb738c5976dd9aac1ae0640fc4de5946b547e) Location is global 'OpenSSLTLSConnection::s_tlsConnIndex' of size 4 at 0x55a12bf3d758 (dnsdist+0xc49758) Thread T4 'dnsdist/tcpClie' (tid=120471, running) created by main thread at: #0 pthread_create /usr/src/debug/gcc/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:1036 (libtsan.so.2+0x44219) (BuildId: 7e8fcb9ed0a63b98f2293e37c92ac955413efd9e) #1 __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663 (libstdc++.so.6+0xe1a29) (BuildId: 207eb738c5976dd9aac1ae0640fc4de5946b547e) #2 std::thread::_M_start_thread(std::unique_ptr >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:172 (libstdc++.so.6+0xe1a29) #3 TCPClientCollection::addTCPClientThread(std::vector >&) /work/pdns/pdns/dnsdistdist/dnsdist-tcp.cc:149 (dnsdist+0x8685a1) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #4 TCPClientCollection::TCPClientCollection(unsigned long, std::vector >) /work/pdns/pdns/dnsdistdist/dnsdist-tcp.cc:126 (dnsdist+0x868912) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #5 std::__detail::_MakeUniq::__single_object std::make_unique > >(unsigned long&, std::vector >&&) /usr/include/c++/13.2.1/bits/unique_ptr.h:1070 (dnsdist+0x20adef) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #6 main /work/pdns/pdns/dnsdistdist/dnsdist.cc:2865 (dnsdist+0x20adef) Thread T3 'dnsdist/tcpClie' (tid=120470, running) created by main thread at: #0 pthread_create /usr/src/debug/gcc/gcc/libsanitizer/tsan/tsan_interceptors_posix.cpp:1036 (libtsan.so.2+0x44219) (BuildId: 7e8fcb9ed0a63b98f2293e37c92ac955413efd9e) #1 __gthread_create /usr/src/debug/gcc/gcc-build/x86_64-pc-linux-gnu/libstdc++-v3/include/x86_64-pc-linux-gnu/bits/gthr-default.h:663 (libstdc++.so.6+0xe1a29) (BuildId: 207eb738c5976dd9aac1ae0640fc4de5946b547e) #2 std::thread::_M_start_thread(std::unique_ptr >, void (*)()) /usr/src/debug/gcc/gcc/libstdc++-v3/src/c++11/thread.cc:172 (libstdc++.so.6+0xe1a29) #3 TCPClientCollection::addTCPClientThread(std::vector >&) /work/pdns/pdns/dnsdistdist/dnsdist-tcp.cc:149 (dnsdist+0x8685a1) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #4 TCPClientCollection::TCPClientCollection(unsigned long, std::vector >) /work/pdns/pdns/dnsdistdist/dnsdist-tcp.cc:126 (dnsdist+0x868912) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #5 std::__detail::_MakeUniq::__single_object std::make_unique > >(unsigned long&, std::vector >&&) /usr/include/c++/13.2.1/bits/unique_ptr.h:1070 (dnsdist+0x20adef) (BuildId: ad82581368352777fda41d4b4145ba8ec738044c) #6 main /work/pdns/pdns/dnsdistdist/dnsdist.cc:2865 (dnsdist+0x20adef) SUMMARY: ThreadSanitizer: data race /work/pdns/pdns/dnsdistdist/tcpiohandler.cc:106 in OpenSSLTLSConnection::OpenSSLTLSConnection(int, timeval const&, std::shared_ptr) ``` --- pdns/tcpiohandler.cc | 57 +++++++++++++++++++++++++------------------- 1 file changed, 32 insertions(+), 25 deletions(-) diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index 64f330f464a3..d085125553f9 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -83,14 +83,6 @@ class OpenSSLTLSConnection: public TLSConnection { d_socket = socket; - if (!s_initTLSConnIndex.test_and_set()) { - /* not initialized yet */ - s_tlsConnIndex = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); - if (s_tlsConnIndex == -1) { - throw std::runtime_error("Error getting an index for TLS connection data"); - } - } - if (!d_conn) { vinfolog("Error creating TLS object"); if (g_verbose) { @@ -103,7 +95,7 @@ class OpenSSLTLSConnection: public TLSConnection throw std::runtime_error("Error assigning socket"); } - SSL_set_ex_data(d_conn.get(), s_tlsConnIndex, this); + SSL_set_ex_data(d_conn.get(), getConnectionIndex(), this); } /* client-side connection */ @@ -111,14 +103,6 @@ class OpenSSLTLSConnection: public TLSConnection { d_socket = socket; - if (!s_initTLSConnIndex.test_and_set()) { - /* not initialized yet */ - s_tlsConnIndex = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); - if (s_tlsConnIndex == -1) { - throw std::runtime_error("Error getting an index for TLS connection data"); - } - } - if (!d_conn) { vinfolog("Error creating TLS object"); if (g_verbose) { @@ -166,7 +150,7 @@ class OpenSSLTLSConnection: public TLSConnection #endif } - SSL_set_ex_data(d_conn.get(), s_tlsConnIndex, this); + SSL_set_ex_data(d_conn.get(), getConnectionIndex(), this); } std::vector getAsyncFDs() override @@ -579,11 +563,30 @@ class OpenSSLTLSConnection: public TLSConnection d_ktls = true; } - static int s_tlsConnIndex; + static void generateConnectionIndexIfNeeded() + { + auto init = s_initTLSConnIndex.lock(); + if (*init == true) { + return; + } -private: - static std::atomic_flag s_initTLSConnIndex; + /* not initialized yet */ + s_tlsConnIndex = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr); + if (s_tlsConnIndex == -1) { + throw std::runtime_error("Error getting an index for TLS connection data"); + } + + *init = true; + } + + static int getConnectionIndex() + { + return s_tlsConnIndex; + } +private: + static LockGuarded s_initTLSConnIndex; + static int s_tlsConnIndex; std::vector> d_tlsSessions; /* server context */ std::shared_ptr d_feContext; @@ -596,8 +599,8 @@ class OpenSSLTLSConnection: public TLSConnection bool d_ktls{false}; }; -std::atomic_flag OpenSSLTLSConnection::s_initTLSConnIndex = ATOMIC_FLAG_INIT; -int OpenSSLTLSConnection::s_tlsConnIndex = -1; +LockGuarded OpenSSLTLSConnection::s_initTLSConnIndex{false}; +int OpenSSLTLSConnection::s_tlsConnIndex{-1}; class OpenSSLTLSIOCtx: public TLSCtx { @@ -605,6 +608,8 @@ class OpenSSLTLSIOCtx: public TLSCtx /* server side context */ OpenSSLTLSIOCtx(TLSFrontend& fe): d_feContext(std::make_shared(fe.d_addr, fe.d_tlsConfig)) { + OpenSSLTLSConnection::generateConnectionIndexIfNeeded(); + d_ticketsKeyRotationDelay = fe.d_tlsConfig.d_ticketsKeyRotationDelay; if (fe.d_tlsConfig.d_enableTickets && fe.d_tlsConfig.d_numberOfTicketsKeys > 0) { @@ -674,6 +679,8 @@ class OpenSSLTLSIOCtx: public TLSCtx registerOpenSSLUser(); + OpenSSLTLSConnection::generateConnectionIndexIfNeeded(); + #ifdef HAVE_TLS_CLIENT_METHOD d_tlsCtx = std::shared_ptr(SSL_CTX_new(TLS_client_method()), SSL_CTX_free); #else @@ -753,7 +760,7 @@ class OpenSSLTLSIOCtx: public TLSCtx int ret = libssl_ticket_key_callback(s, ctx->d_ticketKeys, keyName, iv, ectx, hctx, enc); if (enc == 0) { if (ret == 0 || ret == 2) { - auto* conn = reinterpret_cast(SSL_get_ex_data(s, OpenSSLTLSConnection::s_tlsConnIndex)); + auto* conn = reinterpret_cast(SSL_get_ex_data(s, OpenSSLTLSConnection::getConnectionIndex())); if (conn != nullptr) { if (ret == 0) { conn->setUnknownTicketKey(); @@ -781,7 +788,7 @@ class OpenSSLTLSIOCtx: public TLSCtx static int newTicketFromServerCb(SSL* ssl, SSL_SESSION* session) { - OpenSSLTLSConnection* conn = reinterpret_cast(SSL_get_ex_data(ssl, OpenSSLTLSConnection::s_tlsConnIndex)); + OpenSSLTLSConnection* conn = reinterpret_cast(SSL_get_ex_data(ssl, OpenSSLTLSConnection::getConnectionIndex())); if (session == nullptr || conn == nullptr) { return 0; } From d5d26f840ba41b23e2f4c0ba2c359197ff7cd900 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 23 Aug 2023 17:00:17 +0200 Subject: [PATCH 580/909] Change the default for building with net-snmp from `auto` to `no` We have had a fair amount of issues with `net-snmp` adding unexpected and unwanted values to both `CXXFLAGS` and `LDFLAGS`, and it was just reported to also define `HAVE_LIBSSL` is in public header, which messes up our own feature detection. Therefore it is likely better for everyone to prevent net-snmp from being enabled without the user intending it. For our own packages we explicitly enable net-snmp when supported, and this commit also enables it in our CI for dnsdist (it was already done for the recursor) so it should not have any impact. --- m4/pdns_with_net_snmp.m4 | 4 ++-- tasks.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/m4/pdns_with_net_snmp.m4 b/m4/pdns_with_net_snmp.m4 index 08ce13987a2f..19102b6cf19f 100644 --- a/m4/pdns_with_net_snmp.m4 +++ b/m4/pdns_with_net_snmp.m4 @@ -1,9 +1,9 @@ AC_DEFUN([PDNS_WITH_NET_SNMP], [ AC_MSG_CHECKING([if we need to link in Net SNMP]) AC_ARG_WITH([net-snmp], - AS_HELP_STRING([--with-net-snmp],[enable net snmp support @<:@default=auto@:>@]), + AS_HELP_STRING([--with-net-snmp],[enable net snmp support @<:@default=no@:>@]), [with_net_snmp=$withval], - [with_net_snmp=auto], + [with_net_snmp=no], ) AC_MSG_RESULT([$with_net_snmp]) diff --git a/tasks.py b/tasks.py index e78e0a55212e..6115bd4ed5b7 100644 --- a/tasks.py +++ b/tasks.py @@ -462,6 +462,7 @@ def ci_dnsdist_configure(c, features): --with-libsodium \ --with-lua=luajit \ --with-libcap \ + --with-net-snmp \ --with-nghttp2 \ --with-re2 ' else: From bbf76a06de324da40302d51850c7c475e465cb3a Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 25 Aug 2023 14:08:36 +0200 Subject: [PATCH 581/909] Include cstdint in mtasker_ucontext.cc, noted by @zeha --- pdns/recursordist/mtasker_ucontext.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/mtasker_ucontext.cc b/pdns/recursordist/mtasker_ucontext.cc index 2d0825921cd9..9fcb3daaa0d6 100644 --- a/pdns/recursordist/mtasker_ucontext.cc +++ b/pdns/recursordist/mtasker_ucontext.cc @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include #include #ifdef PDNS_USE_VALGRIND From 643c14a69b993e85639c80c794b1d371b89644b6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 25 Aug 2023 15:00:37 +0200 Subject: [PATCH 582/909] Declare ssh_compat_getentropy in the right spot. Avoiding a redundant and/or missing declaration (depending HAVE_* defines) --- ext/arc4random/arc4random.c | 1 - ext/arc4random/includes.h | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/arc4random/arc4random.c b/ext/arc4random/arc4random.c index afcaa64720e2..56ebd811e867 100644 --- a/ext/arc4random/arc4random.c +++ b/ext/arc4random/arc4random.c @@ -48,7 +48,6 @@ * will call a native getentropy if available then fall back as required. * We use a different name so that OpenSSL cannot call the wrong getentropy. */ -int _ssh_compat_getentropy(void *, size_t); #ifdef getentropy # undef getentropy #endif diff --git a/ext/arc4random/includes.h b/ext/arc4random/includes.h index 5ef06b816bf2..f5bedfa183fb 100644 --- a/ext/arc4random/includes.h +++ b/ext/arc4random/includes.h @@ -24,4 +24,6 @@ uint32_t arc4random_uniform(uint32_t upper_bound); void explicit_bzero(void *, size_t len); #endif +int _ssh_compat_getentropy(void *, size_t); + #define DEF_WEAK(x) From fda6bdcb652af753fb9193c4a531a1f1eb31891e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 28 Aug 2023 12:33:21 +0200 Subject: [PATCH 583/909] dnsdist: Add missing 'sys' import in the Async regression test As noticed by Charles-Henri (thanks!). --- regression-tests.dnsdist/test_Async.py | 1 + 1 file changed, 1 insertion(+) diff --git a/regression-tests.dnsdist/test_Async.py b/regression-tests.dnsdist/test_Async.py index efda4f4cc731..8be405df6dde 100644 --- a/regression-tests.dnsdist/test_Async.py +++ b/regression-tests.dnsdist/test_Async.py @@ -2,6 +2,7 @@ import os import socket +import sys import threading import unittest import dns From 924dd14a0e25ff7ef3e27df98f93029a247251d4 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 1 May 2022 21:03:42 +0300 Subject: [PATCH 584/909] geoipbackend: Move global custom mapping and format to object Simplifies following change --- modules/geoipbackend/geoipbackend.cc | 12 +++++------- modules/geoipbackend/geoipbackend.hh | 2 ++ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/geoipbackend/geoipbackend.cc b/modules/geoipbackend/geoipbackend.cc index 4ca8ed0a4766..232b2d517bb1 100644 --- a/modules/geoipbackend/geoipbackend.cc +++ b/modules/geoipbackend/geoipbackend.cc @@ -149,15 +149,13 @@ void GeoIPBackend::initialize() // Global lookup formats and mapping will be used // if none defined at the domain level. - vector global_mapping_lookup_formats; - map global_custom_mapping; if (YAML::Node formats = config["mapping_lookup_formats"]) { - global_mapping_lookup_formats = formats.as>(); - if (!validateMappingLookupFormats(global_mapping_lookup_formats)) + d_global_mapping_lookup_formats = formats.as>(); + if (!validateMappingLookupFormats(d_global_mapping_lookup_formats)) throw PDNSException(string("%mp is not allowed in mapping lookup")); } if (YAML::Node mapping = config["custom_mapping"]) { - global_custom_mapping = mapping.as>(); + d_global_custom_mapping = mapping.as>(); } for (YAML::const_iterator _domain = config["domains"].begin(); _domain != config["domains"].end(); _domain++) { @@ -275,13 +273,13 @@ void GeoIPBackend::initialize() dom.mapping_lookup_formats = mapping_lookup_formats; } else { - dom.mapping_lookup_formats = global_mapping_lookup_formats; + dom.mapping_lookup_formats = d_global_mapping_lookup_formats; } if (YAML::Node mapping = domain["custom_mapping"]) { dom.custom_mapping = mapping.as>(); } else { - dom.custom_mapping = global_custom_mapping; + dom.custom_mapping = d_global_custom_mapping; } dom.services[srvName].netmask4 = netmask4; diff --git a/modules/geoipbackend/geoipbackend.hh b/modules/geoipbackend/geoipbackend.hh index e036ab4f1e20..d4138383b1b1 100644 --- a/modules/geoipbackend/geoipbackend.hh +++ b/modules/geoipbackend/geoipbackend.hh @@ -79,4 +79,6 @@ private: bool lookup_static(const GeoIPDomain& dom, const DNSName& search, const QType& qtype, const DNSName& qdomain, const Netmask& addr, GeoIPNetmask& gl); vector d_result; vector d_files; + std::vector d_global_mapping_lookup_formats; + std::map d_global_custom_mapping; }; From 4287cb762b1d3603047d60e3d0918e7cf09ddd00 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 1 May 2022 20:50:59 +0300 Subject: [PATCH 585/909] geoipbackend: Move domain loading to separate function Simplifies next change --- modules/geoipbackend/geoipbackend.cc | 88 +++++++++++++++------------- modules/geoipbackend/geoipbackend.hh | 6 ++ 2 files changed, 52 insertions(+), 42 deletions(-) diff --git a/modules/geoipbackend/geoipbackend.cc b/modules/geoipbackend/geoipbackend.cc index 232b2d517bb1..1ff316cd686d 100644 --- a/modules/geoipbackend/geoipbackend.cc +++ b/modules/geoipbackend/geoipbackend.cc @@ -120,48 +120,8 @@ static bool validateMappingLookupFormats(const vector& formats) return true; } -void GeoIPBackend::initialize() +bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDomain& dom) { - YAML::Node config; - vector tmp_domains; - - s_geoip_files.clear(); // reset pointers - - if (getArg("database-files").empty() == false) { - vector files; - stringtok(files, getArg("database-files"), " ,\t\r\n"); - for (auto const& file : files) { - s_geoip_files.push_back(GeoIPInterface::makeInterface(file)); - } - } - - if (s_geoip_files.empty()) - g_log << Logger::Warning << "No GeoIP database files loaded!" << endl; - - if (!getArg("zones-file").empty()) { - try { - config = YAML::LoadFile(getArg("zones-file")); - } - catch (YAML::Exception& ex) { - throw PDNSException(string("Cannot read config file ") + ex.msg); - } - } - - // Global lookup formats and mapping will be used - // if none defined at the domain level. - if (YAML::Node formats = config["mapping_lookup_formats"]) { - d_global_mapping_lookup_formats = formats.as>(); - if (!validateMappingLookupFormats(d_global_mapping_lookup_formats)) - throw PDNSException(string("%mp is not allowed in mapping lookup")); - } - if (YAML::Node mapping = config["custom_mapping"]) { - d_global_custom_mapping = mapping.as>(); - } - - for (YAML::const_iterator _domain = config["domains"].begin(); _domain != config["domains"].end(); _domain++) { - const auto& domain = *_domain; - GeoIPDomain dom; - dom.id = tmp_domains.size(); dom.domain = DNSName(domain["domain"].as()); dom.ttl = domain["ttl"].as(); @@ -360,8 +320,52 @@ void GeoIPBackend::initialize() } } } + return true; +} - tmp_domains.push_back(std::move(dom)); +void GeoIPBackend::initialize() +{ + YAML::Node config; + vector tmp_domains; + + s_geoip_files.clear(); // reset pointers + + if (getArg("database-files").empty() == false) { + vector files; + stringtok(files, getArg("database-files"), " ,\t\r\n"); + for (auto const& file : files) { + s_geoip_files.push_back(GeoIPInterface::makeInterface(file)); + } + } + + if (s_geoip_files.empty()) + g_log << Logger::Warning << "No GeoIP database files loaded!" << endl; + + if (!getArg("zones-file").empty()) { + try { + config = YAML::LoadFile(getArg("zones-file")); + } + catch (YAML::Exception& ex) { + throw PDNSException(string("Cannot read config file ") + ex.msg); + } + } + + // Global lookup formats and mapping will be used + // if none defined at the domain level. + if (YAML::Node formats = config["mapping_lookup_formats"]) { + d_global_mapping_lookup_formats = formats.as>(); + if (!validateMappingLookupFormats(d_global_mapping_lookup_formats)) + throw PDNSException(string("%mp is not allowed in mapping lookup")); + } + if (YAML::Node mapping = config["custom_mapping"]) { + d_global_custom_mapping = mapping.as>(); + } + + for (YAML::const_iterator _domain = config["domains"].begin(); _domain != config["domains"].end(); _domain++) { + GeoIPDomain dom; + auto id = tmp_domains.size(); + if (loadDomain(*_domain, id, dom)) + tmp_domains.push_back(std::move(dom)); } s_domains.clear(); diff --git a/modules/geoipbackend/geoipbackend.hh b/modules/geoipbackend/geoipbackend.hh index d4138383b1b1..949481dfd2af 100644 --- a/modules/geoipbackend/geoipbackend.hh +++ b/modules/geoipbackend/geoipbackend.hh @@ -36,6 +36,11 @@ class GeoIPInterface; +namespace YAML +{ +class Node; +}; + struct GeoIPDomain; struct GeoIPNetmask @@ -77,6 +82,7 @@ private: bool d_dnssec; bool hasDNSSECkey(const DNSName& name); bool lookup_static(const GeoIPDomain& dom, const DNSName& search, const QType& qtype, const DNSName& qdomain, const Netmask& addr, GeoIPNetmask& gl); + bool loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDomain& dom); vector d_result; vector d_files; std::vector d_global_mapping_lookup_formats; From 2300566fc69396d67c71781606eac89795a5c1e9 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 1 May 2022 21:17:59 +0300 Subject: [PATCH 586/909] geoipbackend: Emit error and discard errorneus zones instead of failing completely --- modules/geoipbackend/geoipbackend.cc | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/geoipbackend/geoipbackend.cc b/modules/geoipbackend/geoipbackend.cc index 1ff316cd686d..de939804fee3 100644 --- a/modules/geoipbackend/geoipbackend.cc +++ b/modules/geoipbackend/geoipbackend.cc @@ -122,6 +122,7 @@ static bool validateMappingLookupFormats(const vector& formats) bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDomain& dom) { + try { dom.domain = DNSName(domain["domain"].as()); dom.ttl = domain["ttl"].as(); @@ -320,6 +321,15 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo } } } + } + catch (std::exception& ex) { + g_log << Logger::Error << ex.what() << endl; + return false; + } + catch (PDNSException& ex) { + g_log << Logger::Error << ex.reason << endl; + return false; + } return true; } From 9969d936f355e938555fba0fd60b6f6eb6470821 Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 1 May 2022 21:36:25 +0300 Subject: [PATCH 587/909] geoipbackend: Add zones_dir key for geoipbackend file Allows loading zones from a directory. Based on code by mason-chase --- configure.ac | 5 +++++ m4/ax_cxx_fs.m4 | 31 ++++++++++++++++++++++++++++ modules/geoipbackend/geoipbackend.cc | 26 +++++++++++++++++++++++ modules/geoipbackend/geoipbackend.hh | 1 + 4 files changed, 63 insertions(+) create mode 100644 m4/ax_cxx_fs.m4 diff --git a/configure.ac b/configure.ac index 66480b71aa39..8f6fde4604a1 100644 --- a/configure.ac +++ b/configure.ac @@ -40,6 +40,7 @@ LT_INIT([disable-static dlopen]) PDNS_CHECK_OS PTHREAD_SET_NAME AC_FUNC_STRERROR_R +AX_CXX_CXXFS PDNS_WITH_LUA([mandatory]) PDNS_CHECK_LUA_HPP @@ -308,6 +309,10 @@ LDFLAGS="$RELRO_LDFLAGS $LDFLAGS" CFLAGS="$PIE_CFLAGS $CFLAGS" CXXFLAGS="$PIE_CFLAGS $CXXFLAGS" PROGRAM_LDFLAGS="$PIE_LDFLAGS $PROGRAM_LDFLAGS" +AS_IF([test "$ax_cxx_cv_filesystem_lib" != "none"], + [PROGRAM_LDFLAGS="$PROGRAM_LDFLAGS -l$ax_cxx_cv_filesystem_lib"], + [] +) AC_SUBST([PROGRAM_LDFLAGS]) PDNS_ENABLE_COVERAGE diff --git a/m4/ax_cxx_fs.m4 b/m4/ax_cxx_fs.m4 new file mode 100644 index 000000000000..fca0d0576474 --- /dev/null +++ b/m4/ax_cxx_fs.m4 @@ -0,0 +1,31 @@ +AC_DEFUN([AX_CXX_CXXFS], [ + AC_LANG_PUSH([C++]) + old_LIBS="$LIBS" + dnl * Test first if it can be used without anything, then -lstdc++fs and -lc++fs + AC_CACHE_CHECK([for library with std::filesystem], [ax_cxx_cv_filesystem_lib], [ + ax_cxx_cv_filesystem_lib=none + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[#include + #include ]], + [[std::filesystem::path path("."); + std::filesystem::status(path);]])], + [], [ + LIBS="$LIBS -lstdc++fs" + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[#include + #include ]], + [[std::filesystem::path path("."); + std::filesystem::status(path);]])], + [ax_cxx_cv_filesystem_lib=stdc++fs], [ + LIBS="$old_LIBS -lc++fs" + AC_LINK_IFELSE([AC_LANG_PROGRAM( + [[#include + #include ]], + [[std::filesystem::path path("."); + std::filesystem::status(path);]])], + [ax_cxx_cv_filesystem_lib=c++fs], [AC_MSG_ERROR([Cannot find std::filesystem library])]) + ])]) + LIBS="$old_LIBS" + ]) + AC_LANG_POP() +]) diff --git a/modules/geoipbackend/geoipbackend.cc b/modules/geoipbackend/geoipbackend.cc index de939804fee3..ada8093b41a7 100644 --- a/modules/geoipbackend/geoipbackend.cc +++ b/modules/geoipbackend/geoipbackend.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include ReadWriteLock GeoIPBackend::s_state_lock; @@ -333,6 +334,28 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo return true; } +void GeoIPBackend::loadDomainsFromDirectory(const std::string& dir, vector& domains) +{ + vector paths; + for (const std::filesystem::path& p : std::filesystem::directory_iterator(std::filesystem::path(dir))) + if (std::filesystem::is_regular_file(p) && p.has_extension() && (p.extension() == ".yaml" || p.extension() == ".yml")) + paths.push_back(p); + std::sort(paths.begin(), paths.end()); + for (const auto& p : paths) { + try { + GeoIPDomain dom; + const auto& zoneRoot = YAML::LoadFile(p.string()); + // expect zone key + const auto& zone = zoneRoot["zone"]; + if (loadDomain(zone, domains.size(), dom)) + domains.push_back(dom); + } + catch (std::exception& ex) { + g_log << Logger::Warning << "Cannot load zone from " << p << ": " << ex.what() << endl; + } + } +} + void GeoIPBackend::initialize() { YAML::Node config; @@ -378,6 +401,9 @@ void GeoIPBackend::initialize() tmp_domains.push_back(std::move(dom)); } + if (YAML::Node domain_dir = config["zones_dir"]) + loadDomainsFromDirectory(domain_dir.as(), tmp_domains); + s_domains.clear(); std::swap(s_domains, tmp_domains); diff --git a/modules/geoipbackend/geoipbackend.hh b/modules/geoipbackend/geoipbackend.hh index 949481dfd2af..c7e988a2f8ec 100644 --- a/modules/geoipbackend/geoipbackend.hh +++ b/modules/geoipbackend/geoipbackend.hh @@ -83,6 +83,7 @@ private: bool hasDNSSECkey(const DNSName& name); bool lookup_static(const GeoIPDomain& dom, const DNSName& search, const QType& qtype, const DNSName& qdomain, const Netmask& addr, GeoIPNetmask& gl); bool loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDomain& dom); + void loadDomainsFromDirectory(const std::string& dir, vector& domains); vector d_result; vector d_files; std::vector d_global_mapping_lookup_formats; From 16e0a190bcbafebbf4c91c42700da4892acfaa3c Mon Sep 17 00:00:00 2001 From: Aki Tuomi Date: Sun, 1 May 2022 21:48:29 +0300 Subject: [PATCH 588/909] geoipbackend: Move geo2.example.com to separate file Tests the new feature of loading zones from dir. --- regression-tests/backends/geoip-master | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/regression-tests/backends/geoip-master b/regression-tests/backends/geoip-master index a88db8f2d1e0..201892932407 100644 --- a/regression-tests/backends/geoip-master +++ b/regression-tests/backends/geoip-master @@ -76,6 +76,26 @@ domains: mapping_lookup_formats: ['%cn'] custom_mapping: $geoipregion: earth +EOF + if ! [ -d $testsdir/geozones ]; then + mkdir $testsdir/geozones + fi + cat > $testsdir/geozones/geo2.yaml < $testsdir/region-a-resolution/expected_result < Date: Sun, 1 May 2022 21:50:05 +0300 Subject: [PATCH 589/909] geoipbackend: Document loading zones from directory. --- docs/backends/geoip.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/backends/geoip.rst b/docs/backends/geoip.rst index 4c04a818dfdd..8dccea036c36 100644 --- a/docs/backends/geoip.rst +++ b/docs/backends/geoip.rst @@ -164,6 +164,7 @@ Keys explained format (e.g. %cc). :custom_mapping: Defines the mapping between the lookup format and a custom value to replace ``%mp`` placeholder. +:zones_dir: Directory to load zones from. Each file must contain exactly one ``zone:`` object, formatted like individual domains in the example configuration above. :mapping_lookup_formats: Same as per domain, but used as default value if not defined at the domain level. :custom_mapping: Same as per domain, but used as default value if not defined at the domain level. From 99c370a2c30ae7152791d852fb7b37280ac35b22 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 28 Aug 2023 15:52:38 +0200 Subject: [PATCH 590/909] Fix the generation of packages JSON list for provenance --- builder-support/dockerfiles/Dockerfile.rpmbuild | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/builder-support/dockerfiles/Dockerfile.rpmbuild b/builder-support/dockerfiles/Dockerfile.rpmbuild index c18859c2609c..d98a6826c63d 100644 --- a/builder-support/dockerfiles/Dockerfile.rpmbuild +++ b/builder-support/dockerfiles/Dockerfile.rpmbuild @@ -59,10 +59,10 @@ RUN touch /var/lib/rpm/* && if $(grep -q 'release 7' /etc/redhat-release); then @ENDIF # Generate provenance -@IF [ ${BUILDER_TARGET} = el-7 || ${BUILDER_TARGET} = centos-7 ] +@IF [ "${BUILDER_TARGET}" = "el-7" -o "${BUILDER_TARGET}" = "centos-7" ] @EVAL RUN python builder/helpers/generate-yum-provenance.py /dist/packages-${BUILDER_TARGET}.json || python3 builder/helpers/generate-yum-provenance.py /dist/packages-${BUILDER_TARGET}.json @ENDIF -@IF [ ${BUILDER_TARGET} != el-7 && ${BUILDET_TARGET} != centos-7 ] +@IF [ "${BUILDER_TARGET}" != "el-7" -a "${BUILDER_TARGET}" != "centos-7" ] @EVAL RUN python builder/helpers/generate-dnf-provenance.py /dist/packages-${BUILDER_TARGET}.json || python3 builder/helpers/generate-dnf-provenance.py /dist/packages-${BUILDER_TARGET}.json @ENDIF From 00feba47c530579440085ba16248adcf4c2cc71f Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 28 Aug 2023 15:54:18 +0200 Subject: [PATCH 591/909] build-packages: Fix 'check if hashes were created for all requested targets' If the 'inputs.os' list ends with a newline the check fails. --- .github/workflows/build-packages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index 12bedec6cb98..1b45d241168e 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -14,7 +14,7 @@ on: type: string # please remember to update the pkghashes below when you # update this list, as well as the one in builder-dispatch.yml - default: > + default: >- el-7 el-8 el-9 From bd5a0bc629d6445be7a77e1c28539702f5cf2585 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 28 Aug 2023 16:12:01 +0200 Subject: [PATCH 592/909] dnsdist: Also test metrics with recvmmsg support enabled We have seen in https://github.com/PowerDNS/pdns/issues/13148 that we can easily break frontend metrics when `recvmmsg`/`sendmmsg` support is enabled via `setUDPMultipleMessagesVectorSize()`, so let's test the metrics in that case explicitly so we do not break them again in the future. --- regression-tests.dnsdist/test_Metrics.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/regression-tests.dnsdist/test_Metrics.py b/regression-tests.dnsdist/test_Metrics.py index cac87f3d912f..bc7faf6c68c4 100644 --- a/regression-tests.dnsdist/test_Metrics.py +++ b/regression-tests.dnsdist/test_Metrics.py @@ -8,7 +8,7 @@ import dns from dnsdisttests import DNSDistTest, pickAvailablePort -class TestRuleMetrics(DNSDistTest): +class RuleMetricsTest(object): _config_template = """ addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="openssl" }) @@ -176,3 +176,12 @@ def testServFailMetrics(self): self.assertEqual(self.getMetric('frontend-servfail'), frontendBefore + 2) self.assertEqual(self.getMetric('servfail-responses'), servfailBefore + 1) self.assertEqual(self.getMetric('rule-servfail'), ruleBefore) + +class TestRuleMetricsDefault(RuleMetricsTest, DNSDistTest): + None + +class TestRuleMetricsRecvmmsg(RuleMetricsTest, DNSDistTest): + # test the metrics with recvmmsg/sendmmsg support enabled as well + _config_template = RuleMetricsTest._config_template + """ + setUDPMultipleMessagesVectorSize(10) + """ From a95b4e221cac646ec5b5ccbc84390726b9ebc241 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 28 Aug 2023 16:19:05 +0200 Subject: [PATCH 593/909] rec: fix call of empty() in Protobuf regression test, nice speedup --- regression-tests.recursor-dnssec/test_Protobuf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests.recursor-dnssec/test_Protobuf.py b/regression-tests.recursor-dnssec/test_Protobuf.py index 347c918832a3..953a9ce20ead 100644 --- a/regression-tests.recursor-dnssec/test_Protobuf.py +++ b/regression-tests.recursor-dnssec/test_Protobuf.py @@ -99,7 +99,7 @@ def getFirstProtobufMessage(self, retries=1, waitTime=1): #print(param.port) failed = 0 - while param.queue.empty: + while param.queue.empty(): #print(failed) #print(retries) if failed >= retries: From aeb6856754f2969bb38be588e7c790091242aef4 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 22 Aug 2023 16:50:00 +0200 Subject: [PATCH 594/909] Use the C++ header file generated by bison instead of opting for a C header file --- modules/bindbackend/Makefile.am | 4 ---- pdns/Makefile.am | 10 +++------- pdns/bindlexer.l | 2 +- 3 files changed, 4 insertions(+), 12 deletions(-) diff --git a/modules/bindbackend/Makefile.am b/modules/bindbackend/Makefile.am index 58663f50b900..7906e2078cb9 100644 --- a/modules/bindbackend/Makefile.am +++ b/modules/bindbackend/Makefile.am @@ -19,7 +19,3 @@ libbindbackend_la_SOURCES = \ binddnssec.cc libbindbackend_la_LDFLAGS = -module -avoid-version - -# for bindparser.h/hh -.hh.h: - cp $< $@ diff --git a/pdns/Makefile.am b/pdns/Makefile.am index 43a464f8ab96..7b4436ef57fa 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -55,7 +55,7 @@ EXTRA_DIST = \ dnsmessage.proto \ mtasker.cc \ inflighter.cc \ - bindparser.h \ + bindparser.hh \ named.conf.parsertest \ pdns.service.in \ ixfrdist.service.in \ @@ -71,7 +71,7 @@ EXTRA_DIST = \ BUILT_SOURCES = \ bind-dnssec.schema.sqlite3.sql.h \ - bindparser.h \ + bindparser.hh \ dnslabeltext.cc \ apidocfiles.h @@ -1676,11 +1676,7 @@ dnslabeltext.cc: dnslabeltext.rl bind-dnssec.schema.sqlite3.sql.h: bind-dnssec.schema.sqlite3.sql ( echo '#pragma once'; echo 'static char sqlCreate[] __attribute__((unused))=' ; sed 's/$$/"/g' $< | sed 's/^/"/g' ; echo ';' ) > $@ -# for bindparser.h/hh -.hh.h: - cp $< $@ - -bindlexer.$(OBJEXT): bindparser.h +bindlexer.$(OBJEXT): bindparser.hh pdns_recursor rec_control: @echo "Please build the recursor from the recursordist/ dir" diff --git a/pdns/bindlexer.l b/pdns/bindlexer.l index 85cc0c6ef0e9..65dfc4da02ca 100644 --- a/pdns/bindlexer.l +++ b/pdns/bindlexer.l @@ -7,7 +7,7 @@ #define YY_NO_INPUT 1 #define YYSTYPE char * -#include "bindparser.h" +#include "bindparser.hh" int linenumber; #define MAX_INCLUDE_DEPTH 10 From 212f3bb3e09ae02a57dfa6e549719a251f3fa772 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 29 Aug 2023 11:48:57 +0200 Subject: [PATCH 595/909] builder-dispatch: Remove the newline at the end of the os list --- .github/workflows/builder-dispatch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/builder-dispatch.yml b/.github/workflows/builder-dispatch.yml index 30cab32c47f7..0e680324b41c 100644 --- a/.github/workflows/builder-dispatch.yml +++ b/.github/workflows/builder-dispatch.yml @@ -15,7 +15,7 @@ on: description: OSes to build for, space separated type: string # please remember to update build-packages.yml as well - default: > + default: >- el-7 el-8 el-9 From e8cf6180d206c6d46f3f8d7f0558a24967d19b0e Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 29 Aug 2023 11:28:33 +0200 Subject: [PATCH 596/909] rec: fix a few unused argument warnings (depening on features enabled) Additionally, handle a few clang-tidy warnings --- pdns/recursordist/lwres.cc | 45 +++++++++++++++--------------- pdns/recursordist/lwres.hh | 2 +- pdns/recursordist/pdns_recursor.cc | 2 +- pdns/recursordist/rec-protozero.cc | 2 +- pdns/recursordist/syncres.cc | 14 +++++----- pdns/recursordist/syncres.hh | 2 +- 6 files changed, 34 insertions(+), 33 deletions(-) diff --git a/pdns/recursordist/lwres.cc b/pdns/recursordist/lwres.cc index f6c6fa2479c9..d02e51eb54e3 100644 --- a/pdns/recursordist/lwres.cc +++ b/pdns/recursordist/lwres.cc @@ -385,7 +385,8 @@ static void addPadding(const DNSPacketWriter& pw, size_t bufsize, DNSPacketWrite /** lwr is only filled out in case 1 was returned, and even when returning 1 for 'success', lwr might contain DNS errors Never throws! */ -static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, boost::optional context, const std::shared_ptr>>& outgoingLoggers, const std::shared_ptr>>& fstrmLoggers, const std::set& exportTypes, LWResult* lwr, bool* chained, TCPOutConnectionManager::Connection& connection) +// NOLINTNEXTLINE(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 +static LWResult::Result asyncresolve(const ComboAddress& address, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional& srcmask, const boost::optional& context, const std::shared_ptr>>& outgoingLoggers, [[maybe_unused]] const std::shared_ptr>>& fstrmLoggers, const std::set& exportTypes, LWResult* lwr, bool* chained, TCPOutConnectionManager::Connection& connection) { size_t len; size_t bufsize = g_outgoingEDNSBufsize; @@ -395,7 +396,7 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma // string mapped0x20=dns0x20(domain); uint16_t qid = dns_random_uint16(); DNSPacketWriter pw(vpacket, domain, type); - bool dnsOverTLS = SyncRes::s_dot_to_port_853 && ip.getPort() == 853; + bool dnsOverTLS = SyncRes::s_dot_to_port_853 && address.getPort() == 853; pw.getHeader()->rd = sendRDQuery; pw.getHeader()->id = qid; @@ -446,7 +447,7 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma if (outgoingLoggers) { uuid = getUniqueID(); - logOutgoingQuery(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, vpacket.size(), srcmask); + logOutgoingQuery(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, address, domain, type, qid, doTCP, dnsOverTLS, vpacket.size(), srcmask); } srcmask = boost::none; // this is also our return value, even if EDNS0Level == 0 @@ -467,11 +468,11 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma if (!doTCP) { int queryfd; - if (ip.sin4.sin_family == AF_INET6) { + if (address.sin4.sin_family == AF_INET6) { t_Counters.at(rec::Counter::ipv6queries)++; } - ret = asendto((const char*)&*vpacket.begin(), vpacket.size(), 0, ip, qid, domain, type, weWantEDNSSubnet, &queryfd); + ret = asendto(vpacket.data(), vpacket.size(), 0, address, qid, domain, type, weWantEDNSSubnet, &queryfd); if (ret != LWResult::Result::Success) { return ret; @@ -484,18 +485,18 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma #ifdef HAVE_FSTRM if (!*chained) { if (fstrmQEnabled || fstrmREnabled) { - localip.sin4.sin_family = ip.sin4.sin_family; - socklen_t slen = ip.getSocklen(); + localip.sin4.sin_family = address.sin4.sin_family; + socklen_t slen = address.getSocklen(); (void)getsockname(queryfd, reinterpret_cast(&localip), &slen); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast)) } if (fstrmQEnabled) { - logFstreamQuery(fstrmLoggers, queryTime, localip, ip, DnstapMessage::ProtocolType::DoUDP, context ? context->d_auth : boost::none, vpacket); + logFstreamQuery(fstrmLoggers, queryTime, localip, address, DnstapMessage::ProtocolType::DoUDP, context ? context->d_auth : boost::none, vpacket); } } #endif /* HAVE_FSTRM */ // sleep until we see an answer to this, interface to mtasker - ret = arecvfrom(buf, 0, ip, len, qid, domain, type, queryfd, *now); + ret = arecvfrom(buf, 0, address, len, qid, domain, type, queryfd, *now); } else { bool isNew; @@ -510,11 +511,11 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma if (context && !context->d_nsName.empty()) { nsName = context->d_nsName.toStringNoDot(); } - isNew = tcpconnect(ip, connection, dnsOverTLS, nsName); - ret = tcpsendrecv(ip, connection, localip, vpacket, len, buf); + isNew = tcpconnect(address, connection, dnsOverTLS, nsName); + ret = tcpsendrecv(address, connection, localip, vpacket, len, buf); #ifdef HAVE_FSTRM if (fstrmQEnabled) { - logFstreamQuery(fstrmLoggers, queryTime, localip, ip, !dnsOverTLS ? DnstapMessage::ProtocolType::DoTCP : DnstapMessage::ProtocolType::DoT, context ? context->d_auth : boost::none, vpacket); + logFstreamQuery(fstrmLoggers, queryTime, localip, address, !dnsOverTLS ? DnstapMessage::ProtocolType::DoTCP : DnstapMessage::ProtocolType::DoT, context ? context->d_auth : boost::none, vpacket); } #endif /* HAVE_FSTRM */ if (ret == LWResult::Result::Success) { @@ -536,7 +537,7 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma if (ret != LWResult::Result::Success) { // includes 'timeout' if (outgoingLoggers) { - logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, 0, -1, {}, queryTime, exportTypes); + logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, address, domain, type, qid, doTCP, dnsOverTLS, srcmask, 0, -1, {}, queryTime, exportTypes); } return ret; } @@ -549,7 +550,7 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma if (dnsOverTLS) { protocol = DnstapMessage::ProtocolType::DoT; } - logFstreamResponse(fstrmLoggers, localip, ip, protocol, context ? context->d_auth : boost::none, buf, queryTime, *now); + logFstreamResponse(fstrmLoggers, localip, address, protocol, context ? context->d_auth : boost::none, buf, queryTime, *now); } #endif /* HAVE_FSTRM */ @@ -563,7 +564,7 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma if (mdp.d_header.rcode == RCode::FormErr && mdp.d_qname.empty() && mdp.d_qtype == 0 && mdp.d_qclass == 0) { if (outgoingLoggers) { - logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes); + logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, address, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes); } lwr->d_validpacket = true; return LWResult::Result::Success; // this is "success", the error is set in lwr->d_rcode @@ -571,9 +572,9 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma if (domain != mdp.d_qname) { if (!mdp.d_qname.empty() && domain.toString().find((char)0) == string::npos /* ugly */) { // embedded nulls are too noisy, plus empty domains are too - SLOG(g_log << Logger::Notice << "Packet purporting to come from remote server " << ip.toString() << " contained wrong answer: '" << domain << "' != '" << mdp.d_qname << "'" << endl, + SLOG(g_log << Logger::Notice << "Packet purporting to come from remote server " << address.toString() << " contained wrong answer: '" << domain << "' != '" << mdp.d_qname << "'" << endl, g_slogout->info(Logr::Notice, "Packet purporting to come from remote server contained wrong answer", - "server", Logging::Loggable(ip), + "server", Logging::Loggable(address), "qname", Logging::Loggable(domain), "onwire", Logging::Loggable(mdp.d_qname))); } @@ -610,7 +611,7 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma } if (outgoingLoggers) { - logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes); + logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, address, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes); } lwr->d_validpacket = true; @@ -618,8 +619,8 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma } catch (const std::exception& mde) { if (::arg().mustDo("log-common-errors")) { - SLOG(g_log << Logger::Notice << "Unable to parse packet from remote server " << ip.toString() << ": " << mde.what() << endl, - g_slogout->error(Logr::Notice, mde.what(), "Unable to parse packet from remote server", "server", Logging::Loggable(ip), + SLOG(g_log << Logger::Notice << "Unable to parse packet from remote server " << address.toString() << ": " << mde.what() << endl, + g_slogout->error(Logr::Notice, mde.what(), "Unable to parse packet from remote server", "server", Logging::Loggable(address), "exception", Logging::Loggable("std::exception"))); } @@ -628,14 +629,14 @@ static LWResult::Result asyncresolve(const ComboAddress& ip, const DNSName& doma t_Counters.at(rec::Counter::serverParseError)++; if (outgoingLoggers) { - logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, ip, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes); + logIncomingResponse(outgoingLoggers, context ? context->d_initialRequestId : boost::none, uuid, address, domain, type, qid, doTCP, dnsOverTLS, srcmask, len, lwr->d_rcode, lwr->d_records, queryTime, exportTypes); } return LWResult::Result::Success; // success - oddly enough } catch (...) { SLOG(g_log << Logger::Notice << "Unknown error parsing packet from remote server" << endl, - g_slogout->info(Logr::Notice, "Unknown error parsing packet from remote server", "server", Logging::Loggable(ip))); + g_slogout->info(Logr::Notice, "Unknown error parsing packet from remote server", "server", Logging::Loggable(address))); } t_Counters.at(rec::Counter::serverParseError)++; diff --git a/pdns/recursordist/lwres.hh b/pdns/recursordist/lwres.hh index 688c86cb009f..07a0185a4d3f 100644 --- a/pdns/recursordist/lwres.hh +++ b/pdns/recursordist/lwres.hh @@ -83,7 +83,7 @@ public: bool d_haveEDNS{false}; }; -LWResult::Result asendto(const char* data, size_t len, int flags, const ComboAddress& toAddress, uint16_t qid, +LWResult::Result asendto(const void* data, size_t len, int flags, const ComboAddress& toAddress, uint16_t qid, const DNSName& domain, uint16_t qtype, bool ecs, int* fileDesc); LWResult::Result arecvfrom(PacketBuffer& packet, int flags, const ComboAddress& fromAddr, size_t& len, uint16_t qid, const DNSName& domain, uint16_t qtype, int fileDesc, const struct timeval& now); diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 172ccf7caad1..e6ef3bae63c2 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -263,7 +263,7 @@ static void handleUDPServerResponse(int fileDesc, FDMultiplexer::funcparam_t& va thread_local std::unique_ptr t_udpclientsocks; /* these two functions are used by LWRes */ -LWResult::Result asendto(const char* data, size_t len, int /* flags */, +LWResult::Result asendto(const void* data, size_t len, int /* flags */, const ComboAddress& toAddress, uint16_t qid, const DNSName& domain, uint16_t qtype, bool ecs, int* fileDesc) { diff --git a/pdns/recursordist/rec-protozero.cc b/pdns/recursordist/rec-protozero.cc index e7ef18eb927e..bcc870c4eca0 100644 --- a/pdns/recursordist/rec-protozero.cc +++ b/pdns/recursordist/rec-protozero.cc @@ -24,7 +24,7 @@ #include "rec-protozero.hh" #include -void pdns::ProtoZero::RecMessage::addRR(const DNSRecord& record, const std::set& exportTypes, bool udr) +void pdns::ProtoZero::RecMessage::addRR(const DNSRecord& record, const std::set& exportTypes, [[maybe_unused]] bool udr) { if (record.d_place != DNSResourceRecord::ANSWER || record.d_class != QClass::IN) { return; diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index e0447a52cffe..d6825567e775 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1470,7 +1470,7 @@ uint64_t SyncRes::doDumpDoTProbeMap(int fd) For now this means we can't be clever, but will turn off DNSSEC if you reply with FormError or gibberish. */ -LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsMANDATORY, const DNSName& domain, const DNSName& auth, int type, bool doTCP, bool sendRDQuery, struct timeval* now, boost::optional& srcmask, LWResult* res, bool* chained, const DNSName& nsName) const +LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& address, bool ednsMANDATORY, const DNSName& domain, [[maybe_unused]] const DNSName& auth, int type, bool doTCP, bool sendRDQuery, struct timeval* now, boost::optional& srcmask, LWResult* res, bool* chained, const DNSName& nsName) const { /* what is your QUEST? the goal is to get as many remotes as possible on the best level of EDNS support @@ -1493,7 +1493,7 @@ LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsM SyncRes::EDNSStatus::EDNSMode mode = EDNSStatus::EDNSOK; { auto lock = s_ednsstatus.lock(); - auto ednsstatus = lock->find(ip); // does this include port? YES + auto ednsstatus = lock->find(address); // does this include port? YES if (ednsstatus != lock->end()) { if (ednsstatus->ttd && ednsstatus->ttd < d_now.tv_sec) { lock->erase(ednsstatus); @@ -1531,10 +1531,10 @@ LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsM } if (d_asyncResolve) { - ret = d_asyncResolve(ip, sendQname, type, doTCP, sendRDQuery, EDNSLevel, now, srcmask, ctx, res, chained); + ret = d_asyncResolve(address, sendQname, type, doTCP, sendRDQuery, EDNSLevel, now, srcmask, ctx, res, chained); } else { - ret = asyncresolve(ip, sendQname, type, doTCP, sendRDQuery, EDNSLevel, now, srcmask, ctx, d_outgoingProtobufServers, d_frameStreamServers, luaconfsLocal->outgoingProtobufExportConfig.exportTypes, res, chained); + ret = asyncresolve(address, sendQname, type, doTCP, sendRDQuery, EDNSLevel, now, srcmask, ctx, d_outgoingProtobufServers, d_frameStreamServers, luaconfsLocal->outgoingProtobufExportConfig.exportTypes, res, chained); } if (ret == LWResult::Result::PermanentError || ret == LWResult::Result::OSLimitError || ret == LWResult::Result::Spoofed) { @@ -1554,20 +1554,20 @@ LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsM // Determine new mode if (res->d_validpacket && !res->d_haveEDNS && res->d_rcode == RCode::FormErr) { mode = EDNSStatus::NOEDNS; - auto ednsstatus = lock->insert(ip).first; + auto ednsstatus = lock->insert(address).first; auto& ind = lock->get(); lock->setMode(ind, ednsstatus, mode, d_now.tv_sec); // This is the only path that re-iterates the loop continue; } else if (!res->d_haveEDNS) { - auto ednsstatus = lock->insert(ip).first; + auto ednsstatus = lock->insert(address).first; auto& ind = lock->get(); lock->setMode(ind, ednsstatus, EDNSStatus::EDNSIGNORANT, d_now.tv_sec); } else { // New status is EDNSOK - lock->erase(ip); + lock->erase(address); } } diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index d946577ab06a..9e8b622e20b1 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -652,7 +652,7 @@ private: bool doSpecialNamesResolve(const DNSName& qname, QType qtype, const QClass qclass, vector& ret); - LWResult::Result asyncresolveWrapper(const ComboAddress& ip, bool ednsMANDATORY, const DNSName& domain, const DNSName& auth, int type, bool doTCP, bool sendRDQuery, struct timeval* now, boost::optional& srcmask, LWResult* res, bool* chained, const DNSName& nsName) const; + LWResult::Result asyncresolveWrapper(const ComboAddress& address, bool ednsMANDATORY, const DNSName& domain, const DNSName& auth, int type, bool doTCP, bool sendRDQuery, struct timeval* now, boost::optional& srcmask, LWResult* res, bool* chained, const DNSName& nsName) const; boost::optional getEDNSSubnetMask(const DNSName& dn, const ComboAddress& rem); From 0a3556f74589c5cf2d265bddcfd6a946d747acfe Mon Sep 17 00:00:00 2001 From: Andreas Jakum Date: Tue, 29 Aug 2023 15:07:31 +0200 Subject: [PATCH 597/909] Englishify missing GSS-TSIG feature error message. --- pdns/tkey.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/tkey.cc b/pdns/tkey.cc index 0fabcd2f9a82..23214af3cd1b 100644 --- a/pdns/tkey.cc +++ b/pdns/tkey.cc @@ -71,7 +71,7 @@ void PacketHandler::tkeyHandler(const DNSPacket& p, std::unique_ptr& #ifdef ENABLE_GSS_TSIG g_log< Date: Wed, 30 Aug 2023 15:55:01 +0200 Subject: [PATCH 598/909] dnsdist: Reduce the UDP wait time for blocked queries in the tests We know that we are not going to get a response, and waiting for too long increases the risk that the dynamic block is no longer present and/or has expired (validity of 0s) in the subsequent API check. --- regression-tests.dnsdist/dnsdistDynBlockTests.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/regression-tests.dnsdist/dnsdistDynBlockTests.py b/regression-tests.dnsdist/dnsdistDynBlockTests.py index ccee6eb7c36b..67f986b585e1 100644 --- a/regression-tests.dnsdist/dnsdistDynBlockTests.py +++ b/regression-tests.dnsdist/dnsdistDynBlockTests.py @@ -77,7 +77,7 @@ def doTestQRate(self, name, testViaAPI=True): waitForMaintenanceToRun() # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False, timeout=1) self.assertEqual(receivedResponse, None) if testViaAPI: @@ -269,7 +269,7 @@ def doTestResponseByteRate(self, name, dynBlockBytesPerSecond): print(time.time()) # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False, timeout=1) self.assertEqual(receivedResponse, None) print(self.sendConsoleCommand("showDynBlocks()")) @@ -378,7 +378,7 @@ def doTestRCodeRate(self, name, rcode): waitForMaintenanceToRun() # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False, timeout=1) self.assertEqual(receivedResponse, None) # wait until we are not blocked anymore @@ -487,7 +487,7 @@ def doTestRCodeRatio(self, name, rcode, noerrorcount, rcodecount): waitForMaintenanceToRun() # we should now be dropped for up to self._dynBlockDuration + self._dynBlockPeriod - (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False) + (_, receivedResponse) = self.sendUDPQuery(query, response=None, useQueue=False, timeout=1) self.assertEqual(receivedResponse, None) # wait until we are not blocked anymore From 25d7b8d00e10b897c215eb1cff14a322971def15 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 31 Aug 2023 11:40:46 +0200 Subject: [PATCH 599/909] =?UTF-8?q?arc4random:=20Fix=20'redundant=20redecl?= =?UTF-8?q?aration=E2=80=99=20warnings?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If `arc4random.hh` is included before `config.h`, the `HAVE_*` defines are not yet available and thus we include the definition of the following functions even though they might be available in the standard headers: - `arc4random` - `arc4random_buf` - `arc4random_uniform` - `explicit_bzero` Yielding warnings: ``` In file included from dns_random.hh:27, from tsigutils.cc:25: ../ext/arc4random/arc4random.hh:9:12: warning: redundant redeclaration of ‘uint32_t arc4random()’ in same scope [-Wredundant-decls] 9 | uint32_t arc4random(void); | ^~~~~~~~~~ In file included from /usr/include/c++/13.2.1/cstdlib:79, from /usr/include/c++/13.2.1/ext/string_conversions.h:43, from /usr/include/c++/13.2.1/bits/basic_string.h:4097, from /usr/include/c++/13.2.1/string:54, from dnsname.hh:26, from tsigutils.cc:23: /usr/include/stdlib.h:657:19: note: previous declaration of ‘__uint32_t arc4random()’ 657 | extern __uint32_t arc4random (void) | ^~~~~~~~~~ ../ext/arc4random/arc4random.hh:12:8: warning: redundant redeclaration of ‘void arc4random_buf(void*, size_t)’ in same scope [-Wredundant-decls] 12 | void arc4random_buf(void* buf, size_t nbytes); | ^~~~~~~~~~~~~~ /usr/include/stdlib.h:661:13: note: previous declaration of ‘void arc4random_buf(void*, size_t)’ 661 | extern void arc4random_buf (void *__buf, size_t __size) | ^~~~~~~~~~~~~~ ../ext/arc4random/arc4random.hh:15:12: warning: redundant redeclaration of ‘uint32_t arc4random_uniform(uint32_t)’ in same scope [-Wredundant-decls] 15 | uint32_t arc4random_uniform(uint32_t upper_bound); | ^~~~~~~~~~~~~~~~~~ /usr/include/stdlib.h:666:19: note: previous declaration of ‘__uint32_t arc4random_uniform(__uint32_t)’ 666 | extern __uint32_t arc4random_uniform (__uint32_t __upper_bound) | ^~~~~~~~~~~~~~~~~~ ../ext/arc4random/arc4random.hh:18:8: warning: redundant redeclaration of ‘void explicit_bzero(void*, size_t)’ in same scope [-Wredundant-decls] 18 | void explicit_bzero(void*, size_t len); ``` --- ext/arc4random/arc4random.hh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ext/arc4random/arc4random.hh b/ext/arc4random/arc4random.hh index cff8dd031ecd..6e01712a4f90 100644 --- a/ext/arc4random/arc4random.hh +++ b/ext/arc4random/arc4random.hh @@ -1,8 +1,9 @@ #pragma once - #include #include +#include "config.h" + extern "C" { #ifndef HAVE_ARC4RANDOM From 0b0882f5d6457a0fae0d2acbb1085fab027b43b0 Mon Sep 17 00:00:00 2001 From: Rosen Penev Date: Fri, 1 Sep 2023 08:41:48 +0000 Subject: [PATCH 600/909] remove make_tuple and make_pair Not needed Signed-off-by: Rosen Penev --- modules/lmdbbackend/lmdbbackend.cc | 10 +++++----- pdns/bpf-filter.cc | 4 ++-- pdns/channel.hh | 2 +- pdns/dnsdist-dynbpf.cc | 2 +- pdns/dnsdist-lua.cc | 6 +++--- pdns/dnsdistdist/dnsdist-lbpolicies.cc | 4 ++-- pdns/gss_context.cc | 4 ++-- pdns/libssl.cc | 2 +- pdns/lua-auth4.cc | 2 +- pdns/lua-record.cc | 4 ++-- pdns/pdnsutil.cc | 4 ++-- pdns/recursordist/rec-lua-conf.cc | 2 +- pdns/recursordist/rec-zonetocache.cc | 6 +++--- pdns/recursordist/rec_channel_rec.cc | 10 +++++----- pdns/recursordist/recursor_cache.cc | 8 ++++---- pdns/recursordist/syncres.cc | 14 +++++++------- pdns/shuffle.cc | 2 +- pdns/signingpipe.cc | 4 ++-- pdns/slavecommunicator.cc | 4 ++-- pdns/statbag.hh | 2 +- pdns/test-ueberbackend_cc.cc | 10 +++++----- pdns/validate.cc | 2 +- 22 files changed, 54 insertions(+), 54 deletions(-) diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 11168f326677..9b600f137064 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -88,7 +88,7 @@ std::pair LMDBBackend::getSchemaVersionAndShards(std::string if ((rc = mdb_env_open(env, filename.c_str(), MDB_NOSUBDIR | MDB_RDONLY, 0600)) != 0) { if (rc == ENOENT) { // we don't have a database yet! report schema 0, with 0 shards - return std::make_pair(0, 0); + return {0u, 0u}; } mdb_env_close(env); throw std::runtime_error("mdb_env_open failed"); @@ -109,7 +109,7 @@ std::pair LMDBBackend::getSchemaVersionAndShards(std::string // we pretend this means 5 mdb_txn_abort(txn); mdb_env_close(env); - return std::make_pair(5, 0); + return {5u, 0u}; } mdb_txn_abort(txn); mdb_env_close(env); @@ -127,7 +127,7 @@ std::pair LMDBBackend::getSchemaVersionAndShards(std::string // we pretend this means 5 mdb_txn_abort(txn); mdb_env_close(env); - return std::make_pair(5, 0); + return {5u, 0u}; } throw std::runtime_error("mdb_get pdns.schemaversion failed"); @@ -183,7 +183,7 @@ std::pair LMDBBackend::getSchemaVersionAndShards(std::string mdb_txn_abort(txn); mdb_env_close(env); - return std::make_pair(schemaversion, shards); + return {schemaversion, shards}; } namespace @@ -1702,7 +1702,7 @@ void LMDBBackend::getAllDomainsFiltered(vector* domains, const std:: di.id = iter.getID(); di.backend = this; - if (!zonemap.insert(std::make_pair(di.zone, di)).second) { + if (!zonemap.emplace(di.zone, di).second) { dups.insert(di.zone); } } diff --git a/pdns/bpf-filter.cc b/pdns/bpf-filter.cc index bb0c58e01d9c..ec6bd05c5528 100644 --- a/pdns/bpf-filter.cc +++ b/pdns/bpf-filter.cc @@ -832,7 +832,7 @@ std::vector > BPFFilter::getQNameStats() while (res == 0) { if (bpf_lookup_elem(map.d_fd.getHandle(), &nextKey, &value) == 0) { nextKey.qname[sizeof(nextKey.qname) - 1 ] = '\0'; - result.push_back(std::make_tuple(DNSName(reinterpret_cast(nextKey.qname), sizeof(nextKey.qname), 0, false), value.qtype, value.counter)); + result.emplace_back(DNSName(reinterpret_cast(nextKey.qname), sizeof(nextKey.qname), 0, false), value.qtype, value.counter); } res = bpf_get_next_key(map.d_fd.getHandle(), &nextKey, &nextKey); @@ -853,7 +853,7 @@ std::vector > BPFFilter::getQNameStats() while (res == 0) { if (bpf_lookup_elem(map.d_fd.getHandle(), &nextKey, &value) == 0) { nextKey.qname[sizeof(nextKey.qname) - 1 ] = '\0'; - result.push_back(std::make_tuple(DNSName(reinterpret_cast(nextKey.qname), sizeof(nextKey.qname), 0, false), key.qtype, value.counter)); + result.emplace_back(DNSName(reinterpret_cast(nextKey.qname), sizeof(nextKey.qname), 0, false), key.qtype, value.counter); } res = bpf_get_next_key(map.d_fd.getHandle(), &nextKey, &nextKey); diff --git a/pdns/channel.hh b/pdns/channel.hh index 2d848fc9eee3..d5a1ed6d7349 100644 --- a/pdns/channel.hh +++ b/pdns/channel.hh @@ -341,7 +341,7 @@ namespace channel setPipeBufferSize(receiver.getHandle(), pipeBufferSize); } - return std::pair(Sender(std::move(sender)), Receiver(std::move(receiver), throwOnEOF)); + return {Sender(std::move(sender)), Receiver(std::move(receiver), throwOnEOF)}; } } } diff --git a/pdns/dnsdist-dynbpf.cc b/pdns/dnsdist-dynbpf.cc index c19844de73de..9ede03fabf86 100644 --- a/pdns/dnsdist-dynbpf.cc +++ b/pdns/dnsdist-dynbpf.cc @@ -78,7 +78,7 @@ std::vector > DynBPFFilter:: for (const auto& stat : stats) { const container_t::iterator it = data->d_entries.find(stat.first); if (it != data->d_entries.end()) { - result.push_back(std::make_tuple(stat.first, stat.second, it->d_until)); + result.emplace_back(stat.first, stat.second, it->d_until); } } return result; diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index dcd7a5c3f5c4..34a6aaf51bb8 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -942,7 +942,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) LuaArray> ret; int count = 1; for (const auto& s : g_dstates.getCopy()) { - ret.push_back(make_pair(count++, s)); + ret.emplace_back(count++, s); } return ret; }); @@ -1683,7 +1683,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) const auto localPools = g_pools.getCopy(); for (const auto& entry : localPools) { const string& name = entry.first; - ret.push_back(make_pair(count++, name)); + ret.emplace_back(count++, name); } return ret; }); @@ -2380,7 +2380,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) LuaAssociativeTable customResponseHeaders; if (getOptionalValue(vars, "customResponseHeaders", customResponseHeaders) > 0) { for (auto const& headerMap : customResponseHeaders) { - std::pair headerResponse = std::make_pair(boost::to_lower_copy(headerMap.first), headerMap.second); + auto headerResponse = std::pair(boost::to_lower_copy(headerMap.first), headerMap.second); frontend->d_customResponseHeaders.insert(headerResponse); } } diff --git a/pdns/dnsdistdist/dnsdist-lbpolicies.cc b/pdns/dnsdistdist/dnsdist-lbpolicies.cc index 3aed13d54ab1..2a890f2e554a 100644 --- a/pdns/dnsdistdist/dnsdist-lbpolicies.cc +++ b/pdns/dnsdistdist/dnsdist-lbpolicies.cc @@ -41,7 +41,7 @@ template static std::shared_ptr getLeastOutstanding(c size_t usableServers = 0; for (const auto& d : servers) { if (d.second->isUp()) { - poss[usableServers] = std::make_pair(std::make_tuple(d.second->outstanding.load(), d.second->d_config.order, d.second->getRelevantLatencyUsec()), d.first); + poss[usableServers] = std::pair(std::tuple(d.second->outstanding.load(), d.second->d_config.order, d.second->getRelevantLatencyUsec()), d.first); usableServers++; } } @@ -101,7 +101,7 @@ template static std::shared_ptr getValRandom(const Se sum += d.second->d_config.d_weight; } - poss[usableServers] = std::make_pair(sum, d.first); + poss[usableServers] = std::pair(sum, d.first); usableServers++; } } diff --git a/pdns/gss_context.cc b/pdns/gss_context.cc index b76ca1a21845..4d5b7e7412af 100644 --- a/pdns/gss_context.cc +++ b/pdns/gss_context.cc @@ -25,7 +25,7 @@ #ifndef ENABLE_GSS_TSIG -std::tuple GssContext::getCounts() { return std::make_tuple(0, 0, 0); } +std::tuple GssContext::getCounts() { return std::tuple(0, 0, 0); } bool GssContext::supported() { return false; } GssContext::GssContext() : d_error(GSS_CONTEXT_UNSUPPORTED), d_type(GSS_CONTEXT_NONE) {} @@ -490,7 +490,7 @@ bool GssContext::getPeerPrincipal(std::string& name) std::tuple GssContext::getCounts() { - return std::make_tuple(s_gss_init_creds.lock()->size(), s_gss_accept_creds.lock()->size(), s_gss_sec_context.lock()->size()); + return {s_gss_init_creds.lock()->size(), s_gss_accept_creds.lock()->size(), s_gss_sec_context.lock()->size()}; } void GssContext::processError(const std::string& method, OM_uint32 maj, OM_uint32 min) diff --git a/pdns/libssl.cc b/pdns/libssl.cc index 84610832a8d2..7be834826195 100644 --- a/pdns/libssl.cc +++ b/pdns/libssl.cc @@ -1032,7 +1032,7 @@ std::pair, std::vectorregisterFunction("getRealRemote", [](DNSPacket &p) { return p.getRealRemote(); }); d_lw->registerFunction("getLocal", [](DNSPacket &p) { return p.getLocal(); }); d_lw->registerFunction("getRemotePort", [](DNSPacket &p) { return p.getInnerRemote().getPort(); }); - d_lw->registerFunction()>("getQuestion", [](DNSPacket &p) { return std::make_tuple(p.qdomain.toString(), static_cast(p.qtype.getCode())); }); + d_lw->registerFunction()>("getQuestion", [](DNSPacket &p) { return std::tuple(p.qdomain.toString(), static_cast(p.qtype.getCode())); }); d_lw->registerFunction("setA", [](DNSPacket &p, bool a) { return p.setA(a); }); d_lw->registerFunction("setID", [](DNSPacket &p, unsigned int id) { return p.setID(static_cast(id)); }); d_lw->registerFunction("setRA", [](DNSPacket &p, bool ra) { return p.setRA(ra); }); diff --git a/pdns/lua-record.cc b/pdns/lua-record.cc index af27031a032a..e3c7f52c0b2f 100644 --- a/pdns/lua-record.cc +++ b/pdns/lua-record.cc @@ -60,8 +60,8 @@ class IsUpOracle for(const auto& m : rhs.opts) rhsoopts[m.first]=m.second; - return std::make_tuple(rem, url, oopts) < - std::make_tuple(rhs.rem, rhs.url, rhsoopts); + return std::tuple(rem, url, oopts) < + std::tuple(rhs.rem, rhs.url, rhsoopts); } }; struct CheckState diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index bdf0d3347b97..078ebe5d1136 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -484,7 +484,7 @@ static int checkZone(DNSSECKeeper &dk, UeberBackend &B, const DNSName& zone, con } svcbAliases.insert(rr.qname); } - svcbTargets.emplace(std::make_tuple(rr.qname, svcbrc->getPriority(), svcbrc->getTarget(), svcbrc->autoHint(SvcParam::ipv4hint), svcbrc->autoHint(SvcParam::ipv6hint))); + svcbTargets.emplace(rr.qname, svcbrc->getPriority(), svcbrc->getTarget(), svcbrc->autoHint(SvcParam::ipv4hint), svcbrc->autoHint(SvcParam::ipv6hint)); svcbRecords.insert(rr.qname); break; case QType::HTTPS: @@ -495,7 +495,7 @@ static int checkZone(DNSSECKeeper &dk, UeberBackend &B, const DNSName& zone, con } httpsAliases.insert(rr.qname); } - httpsTargets.emplace(std::make_tuple(rr.qname, svcbrc->getPriority(), svcbrc->getTarget(), svcbrc->autoHint(SvcParam::ipv4hint), svcbrc->autoHint(SvcParam::ipv6hint))); + httpsTargets.emplace(rr.qname, svcbrc->getPriority(), svcbrc->getTarget(), svcbrc->autoHint(SvcParam::ipv4hint), svcbrc->autoHint(SvcParam::ipv6hint)); httpsRecords.insert(rr.qname); break; } diff --git a/pdns/recursordist/rec-lua-conf.cc b/pdns/recursordist/rec-lua-conf.cc index c53c95829a6a..ec169e454421 100644 --- a/pdns/recursordist/rec-lua-conf.cc +++ b/pdns/recursordist/rec-lua-conf.cc @@ -386,7 +386,7 @@ static void rpzPrimary(LuaConfigItems& lci, luaConfigDelayedThreads& delayedThre exit(1); // FIXME proper exit code? } - delayedThreads.rpzPrimaryThreads.push_back(std::make_tuple(primaries, defpol, defpolOverrideLocal, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes, localAddress, axfrTimeout, refresh, sr, dumpFile)); + delayedThreads.rpzPrimaryThreads.emplace_back(primaries, defpol, defpolOverrideLocal, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes, localAddress, axfrTimeout, refresh, sr, dumpFile); } // A wrapper class that loads the standard Lua defintions into the context, so that we can use things like pdns.A diff --git a/pdns/recursordist/rec-zonetocache.cc b/pdns/recursordist/rec-zonetocache.cc index 2f2cbfabec4e..408f486eacd3 100644 --- a/pdns/recursordist/rec-zonetocache.cc +++ b/pdns/recursordist/rec-zonetocache.cc @@ -289,7 +289,7 @@ vState ZoneData::dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const if (nsecs.records.size() > 0 && nsecs.signatures.size() > 0) { // Valdidate the NSEC nsecValidationStatus = validateWithKeySet(d_now, d_zone, nsecs.records, nsecs.signatures, validKeys, std::nullopt); - csp.emplace(std::make_pair(d_zone, QType::NSEC), nsecs); + csp.emplace(std::pair(d_zone, QType::NSEC), nsecs); } else if (nsec3s.records.size() > 0 && nsec3s.signatures.size() > 0) { // Validate NSEC3PARAMS @@ -304,7 +304,7 @@ vState ZoneData::dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const } // Valdidate the NSEC3 nsecValidationStatus = validateWithKeySet(d_now, zonemd.getNSEC3Label(), nsec3s.records, nsec3s.signatures, validKeys, std::nullopt); - csp.emplace(std::make_pair(zonemd.getNSEC3Label(), QType::NSEC3), nsec3s); + csp.emplace(std::pair(zonemd.getNSEC3Label(), QType::NSEC3), nsec3s); } else { d_log->info("No NSEC(3) records and/or RRSIGS found to deny ZONEMD"); @@ -438,7 +438,7 @@ void RecZoneToCache::maintainStates(const map& configs, mapemplace(std::make_pair(key, ProxyMappingCounts{entry.stats.netmaskMatches, entry.stats.suffixMatches})); + ret->emplace(key, ProxyMappingCounts{entry.stats.netmaskMatches, entry.stats.suffixMatches}); } } return ret; @@ -925,7 +925,7 @@ static RemoteLoggerStats_t* pleaseGetRemoteLoggerStats() if (t_protobufServers.servers) { for (const auto& server : *t_protobufServers.servers) { - ret->emplace(std::make_pair(server->address(), server->getStats())); + ret->emplace(server->address(), server->getStats()); } } return ret.release(); @@ -948,7 +948,7 @@ static RemoteLoggerStats_t* pleaseGetOutgoingRemoteLoggerStats() if (t_outgoingProtobufServers.servers) { for (const auto& server : *t_outgoingProtobufServers.servers) { - ret->emplace(std::make_pair(server->address(), server->getStats())); + ret->emplace(server->address(), server->getStats()); } } return ret.release(); @@ -961,7 +961,7 @@ static RemoteLoggerStats_t* pleaseGetFramestreamLoggerStats() if (t_frameStreamServersInfo.servers) { for (const auto& server : *t_frameStreamServersInfo.servers) { - ret->emplace(std::make_pair(server->address(), server->getStats())); + ret->emplace(server->address(), server->getStats()); } } return ret.release(); @@ -973,7 +973,7 @@ static RemoteLoggerStats_t* pleaseGetNODFramestreamLoggerStats() if (t_nodFrameStreamServersInfo.servers) { for (const auto& server : *t_nodFrameStreamServersInfo.servers) { - ret->emplace(std::make_pair(server->address(), server->getStats())); + ret->emplace(server->address(), server->getStats()); } } return ret.release(); diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index 0d237cd75089..60116e9ff141 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -240,7 +240,7 @@ MemRecursorCache::cache_t::const_iterator MemRecursorCache::getEntryUsingECSInde /* we have nothing more specific for you */ break; } - auto key = std::make_tuple(qname, qtype, boost::none, best); + auto key = std::tuple(qname, qtype, boost::none, best); auto entry = map.d_map.find(key); if (entry == map.d_map.end()) { /* ecsIndex is not up-to-date */ @@ -274,7 +274,7 @@ MemRecursorCache::cache_t::const_iterator MemRecursorCache::getEntryUsingECSInde } /* we have nothing specific, let's see if we have a generic one */ - auto key = std::make_tuple(qname, qtype, boost::none, Netmask()); + auto key = std::tuple(qname, qtype, boost::none, Netmask()); auto entry = map.d_map.find(key); if (entry != map.d_map.end()) { handleServeStaleBookkeeping(now, serveStale, entry); @@ -543,7 +543,7 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, // We only store with a tag if we have an ednsmask and the tag is available // We only store an ednsmask if we do not have a tag and we do have a mask. - auto key = std::make_tuple(qname, qt.getCode(), ednsmask ? routingTag : boost::none, (ednsmask && !routingTag) ? *ednsmask : Netmask()); + auto key = std::tuple(qname, qt.getCode(), ednsmask ? routingTag : boost::none, (ednsmask && !routingTag) ? *ednsmask : Netmask()); bool isNew = false; cache_t::iterator stored = lockedShard->d_map.find(key); if (stored == lockedShard->d_map.end()) { @@ -560,7 +560,7 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, if (isNew || stored->d_ttd <= now) { /* don't bother building an ecsIndex if we don't have any netmask-specific entries */ if (!routingTag && ednsmask && !ednsmask->empty()) { - auto ecsIndexKey = std::make_tuple(qname, qt.getCode()); + auto ecsIndexKey = std::tuple(qname, qt.getCode()); auto ecsIndex = lockedShard->d_ecsIndex.find(ecsIndexKey); if (ecsIndex == lockedShard->d_ecsIndex.end()) { ecsIndex = lockedShard->d_ecsIndex.insert(ECSIndexEntry(qname, qt.getCode())).first; diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index d6825567e775..2a5b46ae4eb3 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -878,7 +878,7 @@ bool SyncRes::doSpecialNamesResolve(const DNSName& qname, const QType qtype, con //! This is the 'out of band resolver', in other words, the authoritative server void SyncRes::AuthDomain::addSOA(std::vector& records) const { - SyncRes::AuthDomain::records_t::const_iterator ziter = d_records.find(std::make_tuple(getName(), QType::SOA)); + SyncRes::AuthDomain::records_t::const_iterator ziter = d_records.find(std::tuple(getName(), QType::SOA)); if (ziter != d_records.end()) { DNSRecord dr = *ziter; dr.d_place = DNSResourceRecord::AUTHORITY; @@ -958,7 +958,7 @@ int SyncRes::AuthDomain::getRecords(const DNSName& qname, const QType qtype, std DNSName wcarddomain(qname); while (wcarddomain != getName() && wcarddomain.chopOff()) { - range = d_records.equal_range(std::make_tuple(g_wildcarddnsname + wcarddomain)); + range = d_records.equal_range(std::tuple(g_wildcarddnsname + wcarddomain)); if (range.first == range.second) continue; @@ -982,7 +982,7 @@ int SyncRes::AuthDomain::getRecords(const DNSName& qname, const QType qtype, std /* Nothing for this name, no wildcard, let's see if there is some NS */ DNSName nsdomain(qname); while (nsdomain.chopOff() && nsdomain != getName()) { - range = d_records.equal_range(std::make_tuple(nsdomain, QType::NS)); + range = d_records.equal_range(std::tuple(nsdomain, QType::NS)); if (range.first == range.second) continue; @@ -1230,22 +1230,22 @@ void SyncRes::clearThrottle() bool SyncRes::isThrottled(time_t now, const ComboAddress& server, const DNSName& target, QType qtype) { - return s_throttle.lock()->shouldThrottle(now, std::make_tuple(server, target, qtype)); + return s_throttle.lock()->shouldThrottle(now, std::tuple(server, target, qtype)); } bool SyncRes::isThrottled(time_t now, const ComboAddress& server) { - return s_throttle.lock()->shouldThrottle(now, std::make_tuple(server, g_rootdnsname, 0)); + return s_throttle.lock()->shouldThrottle(now, std::tuple(server, g_rootdnsname, 0)); } void SyncRes::doThrottle(time_t now, const ComboAddress& server, time_t duration, unsigned int tries) { - s_throttle.lock()->throttle(now, std::make_tuple(server, g_rootdnsname, 0), duration, tries); + s_throttle.lock()->throttle(now, std::tuple(server, g_rootdnsname, 0), duration, tries); } void SyncRes::doThrottle(time_t now, const ComboAddress& server, const DNSName& name, QType qtype, time_t duration, unsigned int tries) { - s_throttle.lock()->throttle(now, std::make_tuple(server, name, qtype), duration, tries); + s_throttle.lock()->throttle(now, std::tuple(server, name, qtype), duration, tries); } uint64_t SyncRes::doDumpThrottleMap(int fd) diff --git a/pdns/shuffle.cc b/pdns/shuffle.cc index 0b890376550a..5f96fcd39bac 100644 --- a/pdns/shuffle.cc +++ b/pdns/shuffle.cc @@ -130,7 +130,7 @@ static uint16_t mapTypesToOrder(uint16_t type) void pdns::orderAndShuffle(vector& rrs, bool includingAdditionals) { std::stable_sort(rrs.begin(), rrs.end(), [](const DNSRecord& a, const DNSRecord& b) { - return std::make_tuple(a.d_place, mapTypesToOrder(a.d_type)) < std::make_tuple(b.d_place, mapTypesToOrder(b.d_type)); + return std::tuple(a.d_place, mapTypesToOrder(a.d_type)) < std::tuple(b.d_place, mapTypesToOrder(b.d_type)); }); shuffle(rrs, includingAdditionals); } diff --git a/pdns/signingpipe.cc b/pdns/signingpipe.cc index 2da3db7a24b6..0e0556056427 100644 --- a/pdns/signingpipe.cc +++ b/pdns/signingpipe.cc @@ -100,12 +100,12 @@ namespace { bool dedupLessThan(const DNSZoneRecord& a, const DNSZoneRecord &b) { - return std::make_tuple(a.dr.getContent()->getZoneRepresentation(), a.dr.d_ttl) < std::make_tuple(b.dr.getContent()->getZoneRepresentation(), b.dr.d_ttl); // XXX SLOW SLOW SLOW + return std::tuple(a.dr.getContent()->getZoneRepresentation(), a.dr.d_ttl) < std::tuple(b.dr.getContent()->getZoneRepresentation(), b.dr.d_ttl); // XXX SLOW SLOW SLOW } bool dedupEqual(const DNSZoneRecord& a, const DNSZoneRecord &b) { - return std::make_tuple(a.dr.getContent()->getZoneRepresentation(), a.dr.d_ttl) == std::make_tuple(b.dr.getContent()->getZoneRepresentation(), b.dr.d_ttl); // XXX SLOW SLOW SLOW + return std::tuple(a.dr.getContent()->getZoneRepresentation(), a.dr.d_ttl) == std::tuple(b.dr.getContent()->getZoneRepresentation(), b.dr.d_ttl); // XXX SLOW SLOW SLOW } } diff --git a/pdns/slavecommunicator.cc b/pdns/slavecommunicator.cc index e4a1ffc8d0cc..5029708ee67c 100644 --- a/pdns/slavecommunicator.cc +++ b/pdns/slavecommunicator.cc @@ -1052,7 +1052,7 @@ struct SlaveSenderReceiver { shuffle(dni.di.masters.begin(), dni.di.masters.end(), pdns::dns_random_engine()); try { - return std::make_tuple(dni.di.zone, + return {dni.di.zone, *dni.di.masters.begin(), d_resolver.sendResolve(*dni.di.masters.begin(), dni.localaddr, @@ -1060,7 +1060,7 @@ struct SlaveSenderReceiver QType::SOA, nullptr, dni.dnssecOk, dni.tsigkeyname, dni.tsigalgname, dni.tsigsecret) - ); + }; } catch(PDNSException& e) { throw runtime_error("While attempting to query freshness of '"+dni.di.zone.toLogString()+"': "+e.reason); diff --git a/pdns/statbag.hh b/pdns/statbag.hh index 7836e3c950ef..3e54e682d81b 100644 --- a/pdns/statbag.hh +++ b/pdns/statbag.hh @@ -121,7 +121,7 @@ public: if (it == d_dnsnameqtyperings.end()) { throw runtime_error("Attempting to account to nonexistent dnsname+qtype ring '"+std::string(name)+"'"); } - it->second.lock()->account(std::make_tuple(dnsname, qtype)); + it->second.lock()->account(std::tuple(dnsname, qtype)); } } diff --git a/pdns/test-ueberbackend_cc.cc b/pdns/test-ueberbackend_cc.cc index b11219a4a501..4a13aafad050 100644 --- a/pdns/test-ueberbackend_cc.cc +++ b/pdns/test-ueberbackend_cc.cc @@ -153,7 +153,7 @@ class SimpleBackend : public DNSBackend d_end = range.second; } else { - auto range = idx.equal_range(std::make_tuple(qdomain, qtype.getCode())); + auto range = idx.equal_range(std::tuple(qdomain, qtype.getCode())); d_iter = range.first; d_end = range.second; } @@ -200,7 +200,7 @@ class SimpleBackend : public DNSBackend bool getDomainMetadata(const DNSName& name, const std::string& kind, std::vector& meta) override { const auto& idx = boost::multi_index::get(s_metadata.at(d_backendId)); - auto it = idx.find(std::make_tuple(name, kind)); + auto it = idx.find(std::tuple(name, kind)); if (it == idx.end()) { /* funnily enough, we are expected to return true even though we might not know that zone */ return true; @@ -213,7 +213,7 @@ class SimpleBackend : public DNSBackend bool setDomainMetadata(const DNSName& name, const std::string& kind, const std::vector& meta) override { auto& idx = boost::multi_index::get(s_metadata.at(d_backendId)); - auto it = idx.find(std::make_tuple(name, kind)); + auto it = idx.find(std::tuple(name, kind)); if (it == idx.end()) { s_metadata.at(d_backendId).insert(SimpleMetaData(name, kind, meta)); return true; @@ -258,7 +258,7 @@ class SimpleBackendBestAuth : public SimpleBackend } auto& idx = records->get(); - auto range = idx.equal_range(std::make_tuple(best, QType::SOA)); + auto range = idx.equal_range(std::tuple(best, QType::SOA)); if (range.first == range.second) { return false; } @@ -1155,7 +1155,7 @@ BOOST_AUTO_TEST_CASE(test_multi_backends_metadata) { { // check that it has not been updated in the second backend - const auto& it = SimpleBackend::s_metadata[2].find(std::make_tuple(DNSName("powerdns.org."), "test-data-b")); + const auto& it = SimpleBackend::s_metadata[2].find(std::tuple(DNSName("powerdns.org."), "test-data-b")); BOOST_REQUIRE(it != SimpleBackend::s_metadata[2].end()); BOOST_REQUIRE_EQUAL(it->d_values.size(), 2U); BOOST_CHECK_EQUAL(it->d_values.at(0), "value1"); diff --git a/pdns/validate.cc b/pdns/validate.cc index eb96ca6bd426..decc2f3f64f8 100644 --- a/pdns/validate.cc +++ b/pdns/validate.cc @@ -118,7 +118,7 @@ static std::string getHashFromNSEC3(const DNSName& qname, const NSEC3RecordConte return result; } - auto key = std::make_tuple(qname, nsec3.d_salt, nsec3.d_iterations); + auto key = std::tuple(qname, nsec3.d_salt, nsec3.d_iterations); auto iter = cache.find(key); if (iter != cache.end()) { From f44081141772da42dd6830462ae357530d3a1fbf Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 1 Sep 2023 15:39:18 +0200 Subject: [PATCH 601/909] rec: implement a more fair way to prune the aggressive cache Fixes #13109 --- pdns/recursordist/aggressive_nsec.cc | 101 +++++++++---------- pdns/recursordist/test-aggressive_nsec_cc.cc | 61 +++++++++-- 2 files changed, 100 insertions(+), 62 deletions(-) diff --git a/pdns/recursordist/aggressive_nsec.cc b/pdns/recursordist/aggressive_nsec.cc index e17bf2dd3aad..22fe68aad8b3 100644 --- a/pdns/recursordist/aggressive_nsec.cc +++ b/pdns/recursordist/aggressive_nsec.cc @@ -126,76 +126,72 @@ void AggressiveNSECCache::prune(time_t now) { uint64_t maxNumberOfEntries = d_maxEntries; std::vector emptyEntries; - uint64_t erased = 0; - uint64_t lookedAt = 0; - uint64_t toLook = std::max(d_entriesCount / 5U, static_cast(1U)); - if (d_entriesCount > maxNumberOfEntries) { - uint64_t toErase = d_entriesCount - maxNumberOfEntries; - toLook = toErase * 5; - // we are full, scan at max 5 * toErase entries and stop once we have nuked enough + auto zones = d_zones.write_lock(); + // To start, just look through 10% of each zone and nuke everything that is expired + zones->visit([now, &erased, &emptyEntries](const SuffixMatchTree>>& node) { + if (!node.d_value) { + return; + } - auto zones = d_zones.write_lock(); - zones->visit([now, &erased, toErase, toLook, &lookedAt, &emptyEntries](const SuffixMatchTree>>& node) { - if (!node.d_value || erased > toErase || lookedAt > toLook) { - return; + auto zoneEntry = node.d_value->lock(); + auto& sidx = boost::multi_index::get(zoneEntry->d_entries); + const auto toLookAtForThisZone = (zoneEntry->d_entries.size() + 9) / 10; + uint64_t lookedAt = 0; + for (auto it = sidx.begin(); it != sidx.end() && lookedAt < toLookAtForThisZone; ++lookedAt) { + if (it->d_ttd < now) { + it = sidx.erase(it); + ++erased; + } + else { + ++it; } + } - auto zoneEntry = node.d_value->lock(); - auto& sidx = boost::multi_index::get(zoneEntry->d_entries); - for (auto it = sidx.begin(); it != sidx.end(); ++lookedAt) { - if (erased >= toErase || lookedAt >= toLook) { - break; - } + if (zoneEntry->d_entries.empty()) { + emptyEntries.push_back(zoneEntry->d_zone); + } + }); - if (it->d_ttd < now) { - it = sidx.erase(it); - ++erased; - } - else { - ++it; - } - } + d_entriesCount -= erased; - if (zoneEntry->d_entries.size() == 0) { - emptyEntries.push_back(zoneEntry->d_zone); - } - }); - } - else { - // we are not full, just look through 10% of the cache and nuke everything that is expired - auto zones = d_zones.write_lock(); - zones->visit([now, &erased, toLook, &lookedAt, &emptyEntries](const SuffixMatchTree>>& node) { - if (!node.d_value) { + // If we are still above try harder by nuking entries from each zone in LRU order + auto entriesCount = d_entriesCount.load(); + if (entriesCount > maxNumberOfEntries) { + erased = 0; + uint64_t toErase = entriesCount - maxNumberOfEntries; + zones->visit([&erased, &toErase, &entriesCount, &emptyEntries](const SuffixMatchTree>>& node) { + if (!node.d_value || entriesCount == 0) { return; } - auto zoneEntry = node.d_value->lock(); + const auto zoneSize = zoneEntry->d_entries.size(); auto& sidx = boost::multi_index::get(zoneEntry->d_entries); - for (auto it = sidx.begin(); it != sidx.end(); ++lookedAt) { - if (lookedAt >= toLook) { + const auto toTrimForThisZone = static_cast(std::round(static_cast(toErase) * static_cast(zoneSize) / static_cast(entriesCount))); + if (entriesCount < zoneSize) { + throw std::runtime_error("Inconsistent agggressive cache " + std::to_string(entriesCount) + " " + std::to_string(zoneSize)); + } + // This is comparable to what cachecleaner.hh::pruneMutexCollectionsVector() is doing, look there for an explanation + entriesCount -= zoneSize; + uint64_t trimmedFromThisZone = 0; + for (auto it = sidx.begin(); it != sidx.end() && trimmedFromThisZone < toTrimForThisZone; ) { + it = sidx.erase(it); + ++erased; + ++trimmedFromThisZone; + if (--toErase == 0) { break; } - if (it->d_ttd < now || lookedAt > toLook) { - it = sidx.erase(it); - ++erased; - } - else { - ++it; - } } - - if (zoneEntry->d_entries.size() == 0) { + if (zoneEntry->d_entries.empty()) { emptyEntries.push_back(zoneEntry->d_zone); } }); - } - d_entriesCount -= erased; + d_entriesCount -= erased; + } if (!emptyEntries.empty()) { - auto zones = d_zones.write_lock(); for (const auto& entry : emptyEntries) { zones->remove(entry); } @@ -399,13 +395,14 @@ bool AggressiveNSECCache::getNSECBefore(time_t now, std::shared_ptrd_entries.project(it); if (it->d_ttd <= now) { - moveCacheItemToFront(zoneEntry->d_entries, it); + moveCacheItemToFront(zoneEntry->d_entries, firstIndexIterator); return false; } entry = *it; - moveCacheItemToBack(zoneEntry->d_entries, it); + moveCacheItemToBack(zoneEntry->d_entries, firstIndexIterator); return true; } diff --git a/pdns/recursordist/test-aggressive_nsec_cc.cc b/pdns/recursordist/test-aggressive_nsec_cc.cc index 8222a812a211..879f81b9a341 100644 --- a/pdns/recursordist/test-aggressive_nsec_cc.cc +++ b/pdns/recursordist/test-aggressive_nsec_cc.cc @@ -1076,6 +1076,52 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec3_wildcard_synthesis) BOOST_CHECK_EQUAL(queriesCount, 5U); } +BOOST_AUTO_TEST_CASE(test_aggressive_nsec_replace) +{ + const size_t testSize = 10000; + auto cache = make_unique(testSize); + + struct timeval now{}; + Utility::gettimeofday(&now, nullptr); + + vector names; + names.reserve(testSize); + for (size_t i = 0; i < testSize; i++) { + names.emplace_back(std::to_string(i) + "powerdns.com"); + } + + DTime time; + time.set(); + + for (const auto& name : names) { + DNSRecord rec; + rec.d_name = name; + rec.d_type = QType::NSEC3; + rec.d_ttl = now.tv_sec + 10; + rec.setContent(getRecordContent(QType::NSEC3, "1 0 500 ab HASG==== A RRSIG NSEC3")); + auto rrsig = std::make_shared("NSEC3 5 3 10 20370101000000 20370101000000 24567 dummy. data"); + cache->insertNSEC(DNSName("powerdns.com"), rec.d_name, rec, {rrsig}, true); + } + auto diff1 = time.udiff(true); + + BOOST_CHECK_EQUAL(cache->getEntriesCount(), testSize); + for (const auto& name : names) { + DNSRecord rec; + rec.d_name = name; + rec.d_type = QType::NSEC3; + rec.d_ttl = now.tv_sec + 10; + rec.setContent(getRecordContent(QType::NSEC3, "1 0 500 ab HASG==== A RRSIG NSEC3")); + auto rrsig = std::make_shared("NSEC 5 3 10 20370101000000 20370101000000 24567 dummy. data"); + cache->insertNSEC(DNSName("powerdns.com"), rec.d_name, rec, {rrsig}, true); + } + + BOOST_CHECK_EQUAL(cache->getEntriesCount(), testSize); + + auto diff2 = time.udiff(true); + // Check that replace is about equally fast as insert + BOOST_ASSERT(diff1 < diff2 * 1.2 && diff2 < diff1 * 1.2); +} + BOOST_AUTO_TEST_CASE(test_aggressive_nsec_wiping) { auto cache = make_unique(10000); @@ -1152,7 +1198,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_pruning) rec.d_name = DNSName("www.powerdns.org"); rec.d_type = QType::NSEC3; - rec.d_ttl = now.tv_sec + 10; + rec.d_ttl = now.tv_sec + 20; rec.setContent(getRecordContent(QType::NSEC3, "1 0 500 ab HASG==== A RRSIG NSEC3")); rrsig = std::make_shared("NSEC3 5 3 10 20370101000000 20370101000000 24567 dummy. data"); cache->insertNSEC(DNSName("powerdns.org"), rec.d_name, rec, {rrsig}, true); @@ -1160,18 +1206,13 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_pruning) BOOST_CHECK_EQUAL(cache->getEntriesCount(), 3U); /* we have set a upper bound to 2 entries, so we are above, - and all entries are actually expired, so we will prune one entry + and one entry are actually expired, so we will prune one entry to get below the limit */ - cache->prune(now.tv_sec + 600); + cache->prune(now.tv_sec + 15); BOOST_CHECK_EQUAL(cache->getEntriesCount(), 2U); - /* now we are at the limit, so we will scan 1/5th of the entries, - and prune the expired ones, which mean we will also remove only one */ - cache->prune(now.tv_sec + 600); - BOOST_CHECK_EQUAL(cache->getEntriesCount(), 1U); - - /* now we are below the limit, so we will scan 1/5th of the entries again, - and prune the expired ones, which mean we will remove the last one */ + /* now we are at the limit, so we will scan 1/5th of all zones entries, rounded up, + and prune the expired ones, which mean we will also remoing twoe */ cache->prune(now.tv_sec + 600); BOOST_CHECK_EQUAL(cache->getEntriesCount(), 0U); } From 484edae63d47a28dc8691e2959a1f196f75c38b6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 5 Sep 2023 10:20:50 +0200 Subject: [PATCH 602/909] Implement a way to only dump specific cache(s), undocumented! --- pdns/recursordist/rec_channel_rec.cc | 45 ++++++++++++++++++++++++---- 1 file changed, 39 insertions(+), 6 deletions(-) diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index 34305559f546..9ff615ae4432 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -401,19 +401,52 @@ static RecursorControlChannel::Answer doDumpToFile(int s, uint64_t* (*function)( } // Does not follow the generic dump to file pattern, has a more complex lambda -static RecursorControlChannel::Answer doDumpCache(int socket) +template +static RecursorControlChannel::Answer doDumpCache(int socket, T begin, T end) { auto fdw = getfd(socket); if (fdw < 0) { return {1, "Error opening dump file for writing: " + stringerror() + "\n"}; } + bool dumpRecordCache = true; + bool dumpNegCache = true; + bool dumpPacketCache = true; + bool dumpAggrCache = true; + if (begin != end) { + dumpRecordCache = false; + dumpNegCache = false; + dumpPacketCache = false; + dumpAggrCache = false; + for (auto name = begin; name != end; ++name) { + if (*name == "r") { + dumpRecordCache = true; + } + else if (*name == "n") { + dumpNegCache = true; + } + else if (*name == "p") { + dumpPacketCache = true; + } + else if (*name == "a") { + dumpAggrCache = true; + } + } + } uint64_t total = 0; try { - total += g_recCache->doDump(fdw, g_maxCacheEntries.load()); - total += g_negCache->doDump(fdw, g_maxCacheEntries.load() / 8); - total += g_packetCache ? g_packetCache->doDump(fdw) : 0; - total += dumpAggressiveNSECCache(fdw); + if (dumpRecordCache) { + total += g_recCache->doDump(fdw, g_maxCacheEntries.load()); + } + if (dumpNegCache) { + total += g_negCache->doDump(fdw, g_maxCacheEntries.load() / 8); + } + if (dumpPacketCache) { + total += g_packetCache ? g_packetCache->doDump(fdw) : 0; + } + if (dumpAggrCache) { + total += dumpAggressiveNSECCache(fdw); + } } catch (...) { } @@ -2163,7 +2196,7 @@ RecursorControlChannel::Answer RecursorControlParser::getAnswer(int socket, cons return {0, "bye nicely\n"}; } if (cmd == "dump-cache") { - return doDumpCache(socket); + return doDumpCache(socket, begin, end); } if (cmd == "dump-dot-probe-map") { return doDumpToFile(socket, pleaseDumpDoTProbeMap, cmd, false); From 17806638ce9ae1643d881faa7328a85f98eeb265 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 5 Sep 2023 10:40:27 +0200 Subject: [PATCH 603/909] The proper "expired" test is ttd <= now --- pdns/recursordist/aggressive_nsec.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/aggressive_nsec.cc b/pdns/recursordist/aggressive_nsec.cc index 22fe68aad8b3..c22d81ea6119 100644 --- a/pdns/recursordist/aggressive_nsec.cc +++ b/pdns/recursordist/aggressive_nsec.cc @@ -140,7 +140,7 @@ void AggressiveNSECCache::prune(time_t now) const auto toLookAtForThisZone = (zoneEntry->d_entries.size() + 9) / 10; uint64_t lookedAt = 0; for (auto it = sidx.begin(); it != sidx.end() && lookedAt < toLookAtForThisZone; ++lookedAt) { - if (it->d_ttd < now) { + if (it->d_ttd <= now) { it = sidx.erase(it); ++erased; } From 75f569467599bc9c7ae3d85e9e657c15dc1a4e1a Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 5 Sep 2023 12:22:24 +0200 Subject: [PATCH 604/909] simplify text --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 4daf55b447a3..1ca0f96e904e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -10,7 +10,7 @@ assignees: '' - [ ] This is not a support question, I have read [about opensource](https://www.powerdns.com/opensource.html) and will send support questions to the mailinglist or ask them on IRC. -- [ ] I have read the ['out in the open' support policy](https://blog.powerdns.com/2016/01/18/open-source-support-out-in-the-open/) and am and will comply with it. +- [ ] I have read and understood the ['out in the open' support policy](https://blog.powerdns.com/2016/01/18/open-source-support-out-in-the-open/) - Program: Authoritative, Recursor, dnsdist From 7bf57c9ce7e387f37253f29756dc649d940711c0 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 5 Sep 2023 12:23:43 +0200 Subject: [PATCH 605/909] also link to Discussions --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 1ca0f96e904e..ea0fa2ba5fb6 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -9,7 +9,7 @@ assignees: '' -- [ ] This is not a support question, I have read [about opensource](https://www.powerdns.com/opensource.html) and will send support questions to the mailinglist or ask them on IRC. +- [ ] This is not a support question, I have read [about opensource](https://www.powerdns.com/opensource.html) and will send support questions to the IRC, [Github Discussions](https://github.com/PowerDNS/pdns/discussions/) or the mailing list. - [ ] I have read and understood the ['out in the open' support policy](https://blog.powerdns.com/2016/01/18/open-source-support-out-in-the-open/) From dab9636b332f680283636c66547489f9a2cdb250 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 5 Sep 2023 10:54:39 +0200 Subject: [PATCH 606/909] Formatting --- pdns/recursordist/aggressive_nsec.cc | 2 +- pdns/recursordist/test-aggressive_nsec_cc.cc | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/aggressive_nsec.cc b/pdns/recursordist/aggressive_nsec.cc index c22d81ea6119..b419f5ef2548 100644 --- a/pdns/recursordist/aggressive_nsec.cc +++ b/pdns/recursordist/aggressive_nsec.cc @@ -175,7 +175,7 @@ void AggressiveNSECCache::prune(time_t now) // This is comparable to what cachecleaner.hh::pruneMutexCollectionsVector() is doing, look there for an explanation entriesCount -= zoneSize; uint64_t trimmedFromThisZone = 0; - for (auto it = sidx.begin(); it != sidx.end() && trimmedFromThisZone < toTrimForThisZone; ) { + for (auto it = sidx.begin(); it != sidx.end() && trimmedFromThisZone < toTrimForThisZone;) { it = sidx.erase(it); ++erased; ++trimmedFromThisZone; diff --git a/pdns/recursordist/test-aggressive_nsec_cc.cc b/pdns/recursordist/test-aggressive_nsec_cc.cc index 879f81b9a341..54bd7c043b3b 100644 --- a/pdns/recursordist/test-aggressive_nsec_cc.cc +++ b/pdns/recursordist/test-aggressive_nsec_cc.cc @@ -1081,7 +1081,9 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_replace) const size_t testSize = 10000; auto cache = make_unique(testSize); - struct timeval now{}; + struct timeval now + { + }; Utility::gettimeofday(&now, nullptr); vector names; @@ -1119,7 +1121,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_replace) auto diff2 = time.udiff(true); // Check that replace is about equally fast as insert - BOOST_ASSERT(diff1 < diff2 * 1.2 && diff2 < diff1 * 1.2); + BOOST_CHECK(diff1 < diff2 * 1.2 && diff2 < diff1 * 1.2); } BOOST_AUTO_TEST_CASE(test_aggressive_nsec_wiping) From 90dad5ccf45971b739e7f88507829e308ec78923 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 5 Sep 2023 12:47:59 +0200 Subject: [PATCH 607/909] wording --- .github/ISSUE_TEMPLATE/bug_report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ea0fa2ba5fb6..f6c050358876 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -9,7 +9,7 @@ assignees: '' -- [ ] This is not a support question, I have read [about opensource](https://www.powerdns.com/opensource.html) and will send support questions to the IRC, [Github Discussions](https://github.com/PowerDNS/pdns/discussions/) or the mailing list. +- [ ] This is not a support question, I have read [about opensource](https://www.powerdns.com/opensource.html) and will send support questions to the IRC channel, [Github Discussions](https://github.com/PowerDNS/pdns/discussions/) or the mailing list. - [ ] I have read and understood the ['out in the open' support policy](https://blog.powerdns.com/2016/01/18/open-source-support-out-in-the-open/) From 5ee090c322039a47717115674fb7cdd409b6a1fa Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 5 Sep 2023 12:40:50 +0200 Subject: [PATCH 608/909] Use at(i) instead of [i] --- pdns/dnsdistdist/dnsdist-lbpolicies.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-lbpolicies.cc b/pdns/dnsdistdist/dnsdist-lbpolicies.cc index 2a890f2e554a..783b5ae21ae8 100644 --- a/pdns/dnsdistdist/dnsdist-lbpolicies.cc +++ b/pdns/dnsdistdist/dnsdist-lbpolicies.cc @@ -41,7 +41,7 @@ template static std::shared_ptr getLeastOutstanding(c size_t usableServers = 0; for (const auto& d : servers) { if (d.second->isUp()) { - poss[usableServers] = std::pair(std::tuple(d.second->outstanding.load(), d.second->d_config.order, d.second->getRelevantLatencyUsec()), d.first); + poss.at(usableServers) = std::pair(std::tuple(d.second->outstanding.load(), d.second->d_config.order, d.second->getRelevantLatencyUsec()), d.first); usableServers++; } } @@ -101,7 +101,7 @@ template static std::shared_ptr getValRandom(const Se sum += d.second->d_config.d_weight; } - poss[usableServers] = std::pair(sum, d.first); + poss.at(usableServers) = std::pair(sum, d.first); usableServers++; } } From a38ba9e0d5ad40f5aa4fc6203571c893efdf7401 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 5 Sep 2023 18:10:40 +0200 Subject: [PATCH 609/909] Better formatting of the fuzzing README --- fuzzing/README.md | 58 +++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/fuzzing/README.md b/fuzzing/README.md index f8ec89d19067..ca26a8b10033 100644 --- a/fuzzing/README.md +++ b/fuzzing/README.md @@ -4,39 +4,39 @@ Fuzzing the PowerDNS products This repository contains several fuzzing targets that can be used with generic fuzzing engines like AFL and libFuzzer. -These targets are built by passing the --enable-fuzz-targets option to the +These targets are built by passing the `--enable-fuzz-targets` option to the configure of the authoritative server and dnsdist, then building them as usual. You can also build only these targets manually by going into the pdns/ directory -and issuing a 'make fuzz_targets' command for the authoritative server, -or going into the pdns/dnsdistdist and issuing a 'make fuzz_targets' command for +and issuing a `make fuzz_targets` command for the authoritative server, +or going into the pdns/dnsdistdist and issuing a `make fuzz_targets` command for dnsdist. The current targets cover: -- the auth and rec packet cache (fuzz_target_packetcache) ; -- MOADNSParser (fuzz_target_moadnsparser) ; -- the Proxy Protocol parser (fuzz_target_proxyprotocol) ; -- the HTTP parser we use (YaHTTP, fuzz_target_yahttp) ; -- ZoneParserTNG (fuzz_target_zoneparsertng). -- Parts of the ragel-generated parser (parseRFC1035CharString in - fuzz_target_dnslabeltext) ; -- the dnsdist packet cache (fuzz_target_dnsdistcache). +- the auth and rec packet cache (`fuzz_target_packetcache`) ; +- MOADNSParser (`fuzz_target_moadnsparser`) ; +- the Proxy Protocol parser (`fuzz_target_proxyprotocol`) ; +- the HTTP parser we use (YaHTTP, `fuzz_target_yahttp`) ; +- ZoneParserTNG (`fuzz_target_zoneparsertng`). +- Parts of the ragel-generated parser (`parseRFC1035CharString` in + `fuzz_target_dnslabeltext`) ; +- the dnsdist packet cache (`fuzz_target_dnsdistcache`). By default the targets are linked against a standalone target, -standalone_fuzz_target_runner.cc, which does no fuzzing but makes it easy +`standalone_fuzz_target_runner.cc`, which does no fuzzing but makes it easy to check a given test file, or just that the fuzzing targets can be built properly. -This behaviour can be changed via the LIB_FUZZING_ENGINE variable, for example -by setting it to -lFuzzer, building with clang by setting CC=clang CXX=clang++ -before running the configure and adding '-fsanitize=fuzzer-no-link' to CFLAGS -and CXXFLAGS. Doing so instructs the compiler to instrument the code for -efficient fuzzing but not to link directly with -lFuzzer, which would make +This behaviour can be changed via the `LIB_FUZZING_ENGINE` variable, for example +by setting it to `-lFuzzer`, building with clang by setting `CC=clang CXX=clang++` +before running the `configure` and adding `-fsanitize=fuzzer-no-link` to `CFLAGS` +and `CXXFLAGS`. Doing so instructs the compiler to instrument the code for +efficient fuzzing but not to link directly with `-lFuzzer`, which would make the compilation tests done during the configure phase fail. Sanitizers ---------- In order to catch the maximum of issues during fuzzing, it makes sense to -enable the ASAN and UBSAN sanitizers via --enable-asan and --enable-ubsan +enable the `ASAN` and `UBSAN` sanitizers via `--enable-asan` and `--enable-ubsan` options to the configure, or to set the appropriate flags directly. Corpus @@ -45,20 +45,20 @@ Corpus This directory contains a few files used for continuous fuzzing of the PowerDNS products. -The 'corpus' directory contains three sub-directories: -- http-raw-payloads/ contains HTTP payloads of queries, used by - fuzz_target_yahttp ; -- proxy-protocol-raw-packets/ contains DNS queries prefixed with a Proxy - Protocol v2 header, used by fuzz_target_proxyprotocol ; -- raw-dns-packets/ contains DNS queries and responses as captured on - the wire. These are used by the fuzz_target_dnsdistcache, - fuzz_target_moadnsparser and fuzz_target_packetcache targets ; -- zones/ contains DNS zones, used by the fuzz_target_zoneparsertng +The `corpus` directory contains three sub-directories: +- `http-raw-payloads/` contains HTTP payloads of queries, used by + `fuzz_target_yahttp` ; +- `proxy-protocol-raw-packets/` contains DNS queries prefixed with a Proxy + Protocol v2 header, used by `fuzz_target_proxyprotocol` ; +- `raw-dns-packets/` contains DNS queries and responses as captured on + the wire. These are used by the `fuzz_target_dnsdistcache`, + `fuzz_target_moadnsparser` and `fuzz_target_packetcache` targets ; +- `zones/` contains DNS zones, used by the `fuzz_target_zoneparsertng` target. When run in the OSS-Fuzz environment, the zone files from the -regression-tests/zones/ directory are added to the ones present -in the fuzzing/corpus/zones/ directory. +`regression-tests/zones/` directory are added to the ones present +in the `fuzzing/corpus/zones/` directory. Quickly getting started (using clang 11) ---------------------------------------- From 1f736a6bc0e1311cf5f7f091c852a23035ea59d4 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 6 Sep 2023 10:24:13 +0200 Subject: [PATCH 610/909] rec: remove Before=nss-lookup.target line from unit file Fixes #13115 --- pdns/recursordist/pdns-recursor.service.in | 1 - 1 file changed, 1 deletion(-) diff --git a/pdns/recursordist/pdns-recursor.service.in b/pdns/recursordist/pdns-recursor.service.in index ddb923672017..6bad3edb0573 100644 --- a/pdns/recursordist/pdns-recursor.service.in +++ b/pdns/recursordist/pdns-recursor.service.in @@ -3,7 +3,6 @@ Description=PowerDNS Recursor Documentation=man:pdns_recursor(1) man:rec_control(1) Documentation=https://doc.powerdns.com Wants=network-online.target nss-lookup.target -Before=nss-lookup.target After=network-online.target time-sync.target [Service] From 845e1506d6ee99623e6bf7b608b626f8ea08a2ba Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 6 Sep 2023 11:49:23 +0200 Subject: [PATCH 611/909] Also remove Wants=nss-lookup.target --- pdns/recursordist/pdns-recursor.service.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/pdns-recursor.service.in b/pdns/recursordist/pdns-recursor.service.in index 6bad3edb0573..91d81fe1968d 100644 --- a/pdns/recursordist/pdns-recursor.service.in +++ b/pdns/recursordist/pdns-recursor.service.in @@ -2,7 +2,7 @@ Description=PowerDNS Recursor Documentation=man:pdns_recursor(1) man:rec_control(1) Documentation=https://doc.powerdns.com -Wants=network-online.target nss-lookup.target +Wants=network-online.target After=network-online.target time-sync.target [Service] From 1eeedb0c62a58033fdb6c5a7665cb66f8c7a3601 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 29 Aug 2023 15:07:19 +0200 Subject: [PATCH 612/909] switch from `docker-compose` to `sudo docker compose` and stop installing docker-compose because that uninstalls runc --- docs/changelog/4.8.rst | 2 +- regression-tests.auth-py/runtests | 4 ++-- tasks.py | 1 - 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/docs/changelog/4.8.rst b/docs/changelog/4.8.rst index f1039c37eb5d..b8374f947fc5 100644 --- a/docs/changelog/4.8.rst +++ b/docs/changelog/4.8.rst @@ -33,7 +33,7 @@ Changelogs for 4.8.x :tags: Bug Fixes :pullreq: 12992 - YaHTTP: Prevent integer overflow on very large chunks + YaHTTP: Prevent integer overflow on very 3large chunks .. change:: :tags: Improvements diff --git a/regression-tests.auth-py/runtests b/regression-tests.auth-py/runtests index 805f2af8771b..45c6d62f27ff 100755 --- a/regression-tests.auth-py/runtests +++ b/regression-tests.auth-py/runtests @@ -34,13 +34,13 @@ fi ignore="-I test_GSSTSIG.py" if [ "${WITHKERBEROS}" = "YES" ]; then ignore="" - (cd kerberos-server && docker-compose up --detach --build) + (cd kerberos-server && sudo docker compose up --detach --build) fi nosetests --with-xunit $ignore $@ ret=$? if [ "${WITHKERBEROS}" = "YES" ]; then - (cd kerberos-server && docker-compose stop || exit 0) + (cd kerberos-server && sudo docker compose stop || exit 0) fi exit $ret diff --git a/tasks.py b/tasks.py index 6115bd4ed5b7..ead7efb8941a 100644 --- a/tasks.py +++ b/tasks.py @@ -90,7 +90,6 @@ 'curl', 'default-jre-headless', 'dnsutils', - 'docker-compose', 'faketime', 'gawk', 'krb5-user', From 2ba25c1a966f2f751b446fc4e4c8ba219852ace2 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 31 Jul 2023 11:18:30 +0200 Subject: [PATCH 613/909] dnsdist: Prepare for a second incoming DoH provider h2o becomes optional, and is not enabled by default. --- pdns/dnsdist.cc | 18 +++++--- pdns/dnsdistdist/configure.ac | 10 ++++- pdns/dnsdistdist/doh.cc | 3 +- .../m4/pdns_check_libh2o_evloop.m4 | 43 +++++++++++++------ pdns/doh.hh | 2 + 5 files changed, 55 insertions(+), 21 deletions(-) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 4f27e84043b5..a673bd6f54e2 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -2576,16 +2576,20 @@ int main(int argc, char** argv) cout<<"gnutls"; #ifdef HAVE_LIBSSL cout<<" "; -#endif -#endif +#endif /* HAVE_LIBSSL */ +#endif /* HAVE_GNUTLS */ #ifdef HAVE_LIBSSL cout<<"openssl"; -#endif +#endif /* HAVE_LIBSSL */ cout<<") "; -#endif +#endif /* HAVE_DNS_OVER_TLS */ #ifdef HAVE_DNS_OVER_HTTPS - cout<<"dns-over-https(DOH) "; -#endif + cout<<"dns-over-https("; +#ifdef HAVE_LIBH2OEVLOOP + cout<<"h2o"; +#endif /* HAVE_LIBH2OEVLOOP */ + cout<<") "; +#endif /* HAVE_DNS_OVER_HTTPS */ #ifdef HAVE_DNSCRYPT cout<<"dnscrypt "; #endif @@ -2916,11 +2920,13 @@ int main(int argc, char** argv) for(auto& cs : g_frontends) { if (cs->dohFrontend != nullptr) { #ifdef HAVE_DNS_OVER_HTTPS +#ifdef HAVE_LIBH2OEVLOOP std::thread t1(dohThread, cs.get()); if (!cs->cpus.empty()) { mapThreadToCPUList(t1.native_handle(), cs->cpus); } t1.detach(); +#endif /* HAVE_LIBH2OEVLOOP */ #endif /* HAVE_DNS_OVER_HTTPS */ continue; } diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index aa7ffbf7a44e..5805bbdfe8f3 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -66,10 +66,11 @@ AS_IF([test "x$LUAPC" = "xluajit"], [ ]) PDNS_CHECK_LUA_HPP +AM_CONDITIONAL([HAVE_CDB], [false]) AM_CONDITIONAL([HAVE_GNUTLS], [false]) +AM_CONDITIONAL([HAVE_LIBH2OEVLOOP], [false]) AM_CONDITIONAL([HAVE_LIBSSL], [false]) AM_CONDITIONAL([HAVE_LMDB], [false]) -AM_CONDITIONAL([HAVE_CDB], [false]) PDNS_CHECK_LIBCRYPTO @@ -90,8 +91,9 @@ AS_IF([test "x$enable_dns_over_tls" != "xno"], [ ]) ]) -PDNS_CHECK_LIBH2OEVLOOP AS_IF([test "x$enable_dns_over_https" != "xno"], [ + PDNS_WITH_LIBH2OEVLOOP + AS_IF([test "x$HAVE_LIBH2OEVLOOP" != "x1"], [ AC_MSG_ERROR([DNS over HTTPS support requested but libh2o-evloop was not found]) ]) @@ -243,6 +245,10 @@ AS_IF([test "x$enable_dns_over_tls" != "xno" -o "x$enable_dns_over_https" != "xn [AC_MSG_NOTICE([OpenSSL: no])] )] ) +AS_IF([test "x$LIBH2OEVLOOP_LIBS" != "x"], + [AC_MSG_NOTICE([h2o-evloop: yes])], + [AC_MSG_NOTICE([h2o-evloop: no])] +) AS_IF([test "x$NGHTTP2_LIBS" != "x"], [AC_MSG_NOTICE([nghttp2: yes])], [AC_MSG_NOTICE([nghttp2: no])] diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index dac28e8ca921..3a05d1c2a744 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -2,6 +2,7 @@ #include "doh.hh" #ifdef HAVE_DNS_OVER_HTTPS +#ifdef HAVE_LIBH2OEVLOOP #define H2O_USE_EPOLL 1 #include @@ -1705,7 +1706,7 @@ void handleUDPResponseForDoH(DOHUnitUniquePtr&& du, PacketBuffer&& udpResponse, sendDoHUnitToTheMainThread(std::move(du), "DoH response"); } - +#endif /* HAVE_LIBH2OEVLOOP */ #else /* HAVE_DNS_OVER_HTTPS */ void handleDOHTimeout(DOHUnitUniquePtr&& oldDU) diff --git a/pdns/dnsdistdist/m4/pdns_check_libh2o_evloop.m4 b/pdns/dnsdistdist/m4/pdns_check_libh2o_evloop.m4 index 00781ce32b84..43c112249f38 100644 --- a/pdns/dnsdistdist/m4/pdns_check_libh2o_evloop.m4 +++ b/pdns/dnsdistdist/m4/pdns_check_libh2o_evloop.m4 @@ -1,21 +1,40 @@ -AC_DEFUN([PDNS_CHECK_LIBH2OEVLOOP], [ +AC_DEFUN([PDNS_WITH_LIBH2OEVLOOP], [ + AC_MSG_CHECKING([whether we will be linking in libh2o-evloop]) HAVE_LIBH2OEVLOOP=0 - PKG_CHECK_MODULES([LIBH2OEVLOOP], [libh2o-evloop], [ - [HAVE_LIBH2OEVLOOP=1] - AC_DEFINE([HAVE_LIBH2OEVLOOP], [1], [Define to 1 if you have libh2o-evloop]) - save_CFLAGS=$CFLAGS - save_LIBS=$LIBS - CFLAGS="$LIBH2OEVLOOP_CFLAGS $CFLAGS" - LIBS="$LIBH2OEVLOOP_LIBS $LIBS" - AC_CHECK_DECLS([h2o_socket_get_ssl_server_name], [ + AC_ARG_WITH([h2o], + AS_HELP_STRING([--with-h2o],[use libh2o-evloop @<:@default=no@:>@]), + [with_h2o=$withval], + [with_h2o=no], + ) + AC_MSG_RESULT([$with_h2o]) + + AS_IF([test "x$with_h2o" = "xyes" -o "x$with_h2o" = "xauto"], [ + PKG_CHECK_MODULES([LIBH2OEVLOOP], [libh2o-evloop], [ + [HAVE_LIBH2OEVLOOP=1] + AC_DEFINE([HAVE_LIBH2OEVLOOP], [1], [Define to 1 if you have libh2o-evloop]) + save_CFLAGS=$CFLAGS + save_LIBS=$LIBS + CFLAGS="$LIBH2OEVLOOP_CFLAGS $CFLAGS" + LIBS="$LIBH2OEVLOOP_LIBS $LIBS" + AC_CHECK_DECLS([h2o_socket_get_ssl_server_name], [ AC_DEFINE([HAVE_H2O_SOCKET_GET_SSL_SERVER_NAME], [1], [define to 1 if h2o_socket_get_ssl_server_name is available.]) ], [ : ], [AC_INCLUDES_DEFAULT #include ]) - CFLAGS=$save_CFLAGS - LIBS=$save_LIBS - ], [ : ]) + CFLAGS=$save_CFLAGS + LIBS=$save_LIBS + ], [ : ]) + ]) AM_CONDITIONAL([HAVE_LIBH2OEVLOOP], [test "x$LIBH2OEVLOOP_LIBS" != "x"]) + AM_COND_IF([HAVE_LIBH2OEVLOOP], [ + AC_DEFINE([HAVE_LIBH2OEVLOOP], [1], [Define to 1 if you enable h2o-evloop support]) + ]) + + AS_IF([test "x$with_h2o" = "xyes"], [ + AS_IF([test x"LIBH2OEVLOOP_LIBS" = "x"], [ + AC_MSG_ERROR([h2o-evloop requested but libraries were not found]) + ]) + ]) ]) diff --git a/pdns/doh.hh b/pdns/doh.hh index 2b8397d68805..b38c7bbf3020 100644 --- a/pdns/doh.hh +++ b/pdns/doh.hh @@ -197,6 +197,7 @@ struct DOHUnit }; #else /* HAVE_DNS_OVER_HTTPS */ +#ifdef HAVE_LIBH2OEVLOOP #include #include "dnsdist-idstate.hh" @@ -283,6 +284,7 @@ struct DNSQuestion; std::unique_ptr getDoHCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse); +#endif /* HAVE_LIBH2OEVLOOP */ #endif /* HAVE_DNS_OVER_HTTPS */ using DOHUnitUniquePtr = std::unique_ptr; From 9c784123eb64bdfbcc48d6c660480cb29179ce8c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 31 Jul 2023 11:46:16 +0200 Subject: [PATCH 614/909] dnsdist: Get rid of the reference counter for DOHUnit It is no longer needed since we now rely on moving the unique pointer around. --- pdns/dnsdist-idstate.hh | 9 ++------- pdns/dnsdistdist/doh.cc | 25 ++++++++++++------------ pdns/doh.hh | 42 +++-------------------------------------- 3 files changed, 17 insertions(+), 59 deletions(-) diff --git a/pdns/dnsdist-idstate.hh b/pdns/dnsdist-idstate.hh index b61984249e5a..cf5442fea0b2 100644 --- a/pdns/dnsdist-idstate.hh +++ b/pdns/dnsdist-idstate.hh @@ -99,12 +99,7 @@ struct InternalQueryState std::string d_requestorID; }; - static void DeleterPlaceHolder(DOHUnit*) - { - } - - InternalQueryState() : - du(std::unique_ptr(nullptr, DeleterPlaceHolder)) + InternalQueryState() { origDest.sin4.sin_family = 0; } @@ -130,7 +125,7 @@ struct InternalQueryState std::unique_ptr d_protoBufData{nullptr}; boost::optional tempFailureTTL{boost::none}; // 8 ClientState* cs{nullptr}; // 8 - std::unique_ptr du; // 8 + std::unique_ptr du{nullptr}; // 8 uint32_t cacheKey{0}; // 4 uint32_t cacheKeyNoECS{0}; // 4 // DoH-only */ diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 3a05d1c2a744..eeb0af480847 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -163,7 +163,6 @@ class DOHAcceptContext private: h2o_accept_ctx_t d_h2o_accept_ctx; - std::atomic d_refcnt{1}; time_t d_ticketsKeyNextRotation{0}; std::atomic_flag d_rotatingTicketsKey; }; @@ -176,14 +175,14 @@ struct DOHServerConfig { #ifndef USE_SINGLE_ACCEPTOR_THREAD { - auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverBlocking, internalPipeBufferSize); + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverBlocking, internalPipeBufferSize); d_querySender = std::move(sender); d_queryReceiver = std::move(receiver); } #endif /* USE_SINGLE_ACCEPTOR_THREAD */ { - auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, internalPipeBufferSize); + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, internalPipeBufferSize); d_responseSender = std::move(sender); d_responseReceiver = std::move(receiver); } @@ -209,11 +208,11 @@ struct DOHServerConfig ClientState* cs{nullptr}; std::shared_ptr df{nullptr}; #ifndef USE_SINGLE_ACCEPTOR_THREAD - pdns::channel::Sender d_querySender; - pdns::channel::Receiver d_queryReceiver; + pdns::channel::Sender d_querySender; + pdns::channel::Receiver d_queryReceiver; #endif /* USE_SINGLE_ACCEPTOR_THREAD */ - pdns::channel::Sender d_responseSender; - pdns::channel::Receiver d_responseReceiver; + pdns::channel::Sender d_responseSender; + pdns::channel::Receiver d_responseReceiver; }; /* This internal function sends back the object to the main thread to send a reply. @@ -839,7 +838,7 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re /* we are doing quite some copies here, sorry about that, but we can't keep accessing the req object once we are in a different thread because the request might get killed by h2o at pretty much any time */ - auto du = std::unique_ptr(new DOHUnit(std::move(query), std::move(path), std::string(req->authority.base, req->authority.len)), DOHUnit::release); + auto du = std::make_unique(std::move(query), std::move(path), std::string(req->authority.base, req->authority.len)); du->dsc = dsc; du->req = req; du->ids.origDest = local; @@ -870,7 +869,7 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re *(du->self) = du.get(); #ifdef USE_SINGLE_ACCEPTOR_THREAD - processDOHQuery(DOHUnitUniquePtr(du.release(), DOHUnit::release), true); + processDOHQuery(du, true); #else /* USE_SINGLE_ACCEPTOR_THREAD */ try { if (!dsc->d_querySender.send(std::move(du))) { @@ -1232,13 +1231,13 @@ void DOHUnit::setHTTPResponse(uint16_t statusCode, PacketBuffer&& body_, const s /* query has been parsed by h2o, which called doh_handler() in the main DoH thread. In order not to block for long, doh_handler() called doh_dispatch_query() which allocated a DOHUnit object and passed it to us */ -static void dnsdistclient(pdns::channel::Receiver&& receiver) +static void dnsdistclient(pdns::channel::Receiver&& receiver) { setThreadName("dnsdist/doh-cli"); for(;;) { try { - auto tmp = receiver.receive(DOHUnit::release); + auto tmp = receiver.receive(); if (!tmp) { continue; } @@ -1281,9 +1280,9 @@ static void on_dnsdist(h2o_socket_t *listener, const char *err) memory and likely coming up too late after the client has gone away */ auto* dsc = static_cast(listener->data); while (true) { - std::unique_ptr du{nullptr, DOHUnit::release}; + std::unique_ptr du{nullptr}; try { - auto tmp = dsc->d_responseReceiver.receive(DOHUnit::release); + auto tmp = dsc->d_responseReceiver.receive(); if (!tmp) { return; } diff --git a/pdns/doh.hh b/pdns/doh.hh index b38c7bbf3020..6f3816c300fa 100644 --- a/pdns/doh.hh +++ b/pdns/doh.hh @@ -180,18 +180,6 @@ struct DOHFrontend #ifndef HAVE_DNS_OVER_HTTPS struct DOHUnit { - static void release(DOHUnit*) - { - } - - void get() - { - } - - void release() - { - } - size_t proxyProtocolPayloadSize{0}; uint16_t status_code{200}; }; @@ -215,29 +203,6 @@ struct DOHUnit DOHUnit(const DOHUnit&) = delete; DOHUnit& operator=(const DOHUnit&) = delete; - void get() - { - ++d_refcnt; - } - - void release() - { - if (--d_refcnt == 0) { - if (self) { - *self = nullptr; - } - - delete this; - } - } - - static void release(DOHUnit* ptr) - { - if (ptr) { - ptr->release(); - } - } - InternalQueryState ids; std::string sni; std::string path; @@ -251,8 +216,7 @@ struct DOHUnit st_h2o_req_t* req{nullptr}; DOHUnit** self{nullptr}; DOHServerConfig* dsc{nullptr}; - pdns::channel::Sender* responseSender{nullptr}; - std::atomic d_refcnt{1}; + pdns::channel::Sender* responseSender{nullptr}; size_t query_at{0}; size_t proxyProtocolPayloadSize{0}; int rsock{-1}; @@ -277,7 +241,7 @@ struct DOHUnit void setHTTPResponse(uint16_t statusCode, PacketBuffer&& body, const std::string& contentType=""); }; -void handleUDPResponseForDoH(std::unique_ptr&&, PacketBuffer&& response, InternalQueryState&& state); +void handleUDPResponseForDoH(std::unique_ptr&&, PacketBuffer&& response, InternalQueryState&& state); struct CrossProtocolQuery; struct DNSQuestion; @@ -287,6 +251,6 @@ std::unique_ptr getDoHCrossProtocolQueryFromDQ(DNSQuestion& #endif /* HAVE_LIBH2OEVLOOP */ #endif /* HAVE_DNS_OVER_HTTPS */ -using DOHUnitUniquePtr = std::unique_ptr; +using DOHUnitUniquePtr = std::unique_ptr; void handleDOHTimeout(DOHUnitUniquePtr&& oldDU); From 5024b5e4340325a2fc057fecf21415f742d9f6c7 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 31 Jul 2023 11:56:30 +0200 Subject: [PATCH 615/909] dnsdist: Make TLSFrontend and TCPIOHandler suitable for DoH as well --- pdns/dnsdist-lua.cc | 2 +- pdns/tcpiohandler.cc | 57 ++++++++++++++++++++++++++------------------ pdns/tcpiohandler.hh | 7 ++++-- 3 files changed, 40 insertions(+), 26 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 34a6aaf51bb8..3224b8763fd5 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2579,7 +2579,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } setLuaSideEffect(); - shared_ptr frontend = std::make_shared(); + shared_ptr frontend = std::make_shared(TLSFrontend::ALPN::DoT); if (!loadTLSCertificateAndKeys("addTLSLocal", frontend->d_tlsConfig.d_certKeyPairs, certFiles, keyFiles)) { return; } diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index d085125553f9..1b7018c028ba 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -11,7 +11,7 @@ const bool TCPIOHandler::s_disableConnectForUnitTests = false; #include #endif /* HAVE_LIBSODIUM */ -#ifdef HAVE_DNS_OVER_TLS +#if defined(HAVE_DNS_OVER_TLS) || defined(HAVE_DNS_OVER_HTTPS) #ifdef HAVE_LIBSSL #include @@ -1811,7 +1811,7 @@ class GnuTLSIOCtx: public TLSCtx #endif /* HAVE_GNUTLS */ -#endif /* HAVE_DNS_OVER_TLS */ +#endif /* HAVE_DNS_OVER_TLS || HAVE_DNS_OVER_HTTPS */ bool setupDoTProtocolNegotiation(std::shared_ptr& ctx) { @@ -1824,46 +1824,57 @@ bool setupDoTProtocolNegotiation(std::shared_ptr& ctx) return true; } +bool setupDoHProtocolNegotiation(std::shared_ptr& ctx) +{ + if (ctx == nullptr) { + return false; + } + /* we want to set the ALPN to doh */ + const std::vector> dohAlpns = {{'h', '2'}}; + ctx->setALPNProtos(dohAlpns); + return true; +} + bool TLSFrontend::setupTLS() { -#ifdef HAVE_DNS_OVER_TLS +#if defined(HAVE_DNS_OVER_TLS) || defined(HAVE_DNS_OVER_HTTPS) std::shared_ptr newCtx{nullptr}; /* get the "best" available provider */ - if (!d_provider.empty()) { #ifdef HAVE_GNUTLS - if (d_provider == "gnutls") { - newCtx = std::make_shared(*this); - setupDoTProtocolNegotiation(newCtx); - std::atomic_store_explicit(&d_ctx, newCtx, std::memory_order_release); - return true; - } + if (d_provider == "gnutls") { + newCtx = std::make_shared(*this); + } #endif /* HAVE_GNUTLS */ #ifdef HAVE_LIBSSL - if (d_provider == "openssl") { - newCtx = std::make_shared(*this); - setupDoTProtocolNegotiation(newCtx); - std::atomic_store_explicit(&d_ctx, newCtx, std::memory_order_release); - return true; - } -#endif /* HAVE_LIBSSL */ + if (d_provider == "openssl") { + newCtx = std::make_shared(*this); } +#endif /* HAVE_LIBSSL */ + if (!newCtx) { #ifdef HAVE_LIBSSL - newCtx = std::make_shared(*this); + newCtx = std::make_shared(*this); #else /* HAVE_LIBSSL */ #ifdef HAVE_GNUTLS - newCtx = std::make_shared(*this); + newCtx = std::make_shared(*this); #endif /* HAVE_GNUTLS */ #endif /* HAVE_LIBSSL */ + } + + if (d_alpn == ALPN::DoT) { + setupDoTProtocolNegotiation(newCtx); + } + else if (d_alpn == ALPN::DoH) { + setupDoHProtocolNegotiation(newCtx); + } - setupDoTProtocolNegotiation(newCtx); std::atomic_store_explicit(&d_ctx, newCtx, std::memory_order_release); -#endif /* HAVE_DNS_OVER_TLS */ +#endif /* HAVE_DNS_OVER_TLS || HAVE_DNS_OVER_HTTPS */ return true; } std::shared_ptr getTLSContext([[maybe_unused]] const TLSContextParameters& params) { -#ifdef HAVE_DNS_OVER_TLS +#if defined(HAVE_DNS_OVER_TLS) || defined(HAVE_DNS_OVER_HTTPS) /* get the "best" available provider */ if (!params.d_provider.empty()) { #ifdef HAVE_GNUTLS @@ -1886,6 +1897,6 @@ std::shared_ptr getTLSContext([[maybe_unused]] const TLSContextParameter #endif /* HAVE_GNUTLS */ #endif /* HAVE_LIBSSL */ -#endif /* HAVE_DNS_OVER_TLS */ +#endif /* HAVE_DNS_OVER_TLS || HAVE_DNS_OVER_HTTPS */ return nullptr; } diff --git a/pdns/tcpiohandler.hh b/pdns/tcpiohandler.hh index 88f0dc724be7..29b59a01f9a4 100644 --- a/pdns/tcpiohandler.hh +++ b/pdns/tcpiohandler.hh @@ -136,7 +136,9 @@ protected: class TLSFrontend { public: - TLSFrontend() + enum class ALPN : uint8_t { Unset, DoT, DoH }; + + TLSFrontend(ALPN alpn) : d_alpn(alpn) { } @@ -223,7 +225,7 @@ public: TLSErrorCounters d_tlsCounters; ComboAddress d_addr; std::string d_provider; - + ALPN d_alpn{ALPN::Unset}; protected: std::shared_ptr d_ctx{nullptr}; }; @@ -582,3 +584,4 @@ struct TLSContextParameters std::shared_ptr getTLSContext(const TLSContextParameters& params); bool setupDoTProtocolNegotiation(std::shared_ptr& ctx); +bool setupDoHProtocolNegotiation(std::shared_ptr& ctx); From 9eb152c401dae2604773dd992837e96ddd041a1a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 31 Jul 2023 16:18:02 +0200 Subject: [PATCH 616/909] dnsdist: Refactor the DoH code to be able to have two libraries --- pdns/dnsdist-carbon.cc | 4 +- pdns/dnsdist-doh-common.hh | 240 ++++++++ pdns/dnsdist-idstate.hh | 10 +- pdns/dnsdist-lua-inspection.cc | 2 +- pdns/dnsdist-lua.cc | 43 +- pdns/dnsdist-web.cc | 8 +- pdns/dnsdist.cc | 23 +- pdns/dnsdist.hh | 8 +- pdns/dnsdistdist/Makefile.am | 2 + pdns/dnsdistdist/dnsdist-async.cc | 3 +- pdns/dnsdistdist/dnsdist-backend.cc | 12 +- pdns/dnsdistdist/dnsdist-doh-common.cc | 129 +++++ pdns/dnsdistdist/dnsdist-doh-common.hh | 1 + pdns/dnsdistdist/doh.cc | 517 +++++++++--------- pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc | 35 +- pdns/doh.hh | 239 +------- pdns/test-dnsdist_cc.cc | 4 +- 17 files changed, 708 insertions(+), 572 deletions(-) create mode 100644 pdns/dnsdist-doh-common.hh create mode 100644 pdns/dnsdistdist/dnsdist-doh-common.cc create mode 120000 pdns/dnsdistdist/dnsdist-doh-common.hh diff --git a/pdns/dnsdist-carbon.cc b/pdns/dnsdist-carbon.cc index 693f498c435f..d73d9ff8b7ef 100644 --- a/pdns/dnsdist-carbon.cc +++ b/pdns/dnsdist-carbon.cc @@ -147,7 +147,7 @@ static bool doOneCarbonExport(const Carbon::Endpoint& endpoint) errorCounters = &front->tlsFrontend->d_tlsCounters; } else if (front->dohFrontend != nullptr) { - errorCounters = &front->dohFrontend->d_tlsCounters; + errorCounters = &front->dohFrontend->d_tlsContext.d_tlsCounters; } if (errorCounters != nullptr) { str << base << "tlsdhkeytoosmall" << ' ' << errorCounters->d_dhKeyTooSmall << " " << now << "\r\n"; @@ -204,7 +204,7 @@ static bool doOneCarbonExport(const Carbon::Endpoint& endpoint) std::map dohFrontendDuplicates; const string base = "dnsdist." + hostname + ".main.doh."; for (const auto& doh : g_dohlocals) { - string name = doh->d_local.toStringWithPort(); + string name = doh->d_tlsContext.d_addr.toStringWithPort(); boost::replace_all(name, ".", "_"); boost::replace_all(name, ":", "_"); boost::replace_all(name, "[", "_"); diff --git a/pdns/dnsdist-doh-common.hh b/pdns/dnsdist-doh-common.hh new file mode 100644 index 000000000000..44ad826a88d8 --- /dev/null +++ b/pdns/dnsdist-doh-common.hh @@ -0,0 +1,240 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +#include +#include + +#include "config.h" +#include "iputils.hh" +#include "libssl.hh" +#include "noinitvector.hh" +#include "stat_t.hh" +#include "tcpiohandler.hh" + +struct DOHServerConfig; + +class DOHResponseMapEntry +{ +public: + DOHResponseMapEntry(const std::string& regex, uint16_t status, const PacketBuffer& content, const boost::optional>& headers) : + d_regex(regex), d_customHeaders(headers), d_content(content), d_status(status) + { + if (status >= 400 && !d_content.empty() && d_content.at(d_content.size() - 1) != 0) { + // we need to make sure it's null-terminated + d_content.push_back(0); + } + } + + bool matches(const std::string& path) const + { + return d_regex.match(path); + } + + uint16_t getStatusCode() const + { + return d_status; + } + + const PacketBuffer& getContent() const + { + return d_content; + } + + const boost::optional>& getHeaders() const + { + return d_customHeaders; + } + +private: + Regex d_regex; + boost::optional> d_customHeaders; + PacketBuffer d_content; + uint16_t d_status; +}; + +struct DOHFrontend +{ + DOHFrontend() + { + } + DOHFrontend(std::shared_ptr tlsCtx) : + d_tlsContext(std::move(tlsCtx)) + { + } + + virtual ~DOHFrontend() + { + } + + std::shared_ptr d_dsc{nullptr}; + std::shared_ptr>> d_responsesMap; + TLSFrontend d_tlsContext{TLSFrontend::ALPN::DoH}; + std::string d_serverTokens{"h2o/dnsdist"}; + std::unordered_map d_customResponseHeaders; + std::string d_library; + + uint32_t d_idleTimeout{30}; // HTTP idle timeout in seconds + std::set> d_urls; + + pdns::stat_t d_httpconnects{0}; // number of TCP/IP connections established + pdns::stat_t d_getqueries{0}; // valid DNS queries received via GET + pdns::stat_t d_postqueries{0}; // valid DNS queries received via POST + pdns::stat_t d_badrequests{0}; // request could not be converted to dns query + pdns::stat_t d_errorresponses{0}; // dnsdist set 'error' on response + pdns::stat_t d_redirectresponses{0}; // dnsdist set 'redirect' on response + pdns::stat_t d_validresponses{0}; // valid responses sent out + + struct HTTPVersionStats + { + pdns::stat_t d_nbQueries{0}; // valid DNS queries received + pdns::stat_t d_nb200Responses{0}; + pdns::stat_t d_nb400Responses{0}; + pdns::stat_t d_nb403Responses{0}; + pdns::stat_t d_nb500Responses{0}; + pdns::stat_t d_nb502Responses{0}; + pdns::stat_t d_nbOtherResponses{0}; + }; + + HTTPVersionStats d_http1Stats; + HTTPVersionStats d_http2Stats; +#ifdef __linux__ + // On Linux this gives us 128k pending queries (default is 8192 queries), + // which should be enough to deal with huge spikes + uint32_t d_internalPipeBufferSize{1024 * 1024}; +#else + uint32_t d_internalPipeBufferSize{0}; +#endif + bool d_sendCacheControlHeaders{true}; + bool d_trustForwardedForHeader{false}; + /* whether we require tue query path to exactly match one of configured ones, + or accept everything below these paths. */ + bool d_exactPathMatching{true}; + bool d_keepIncomingHeaders{false}; + + time_t getTicketsKeyRotationDelay() const + { + return d_tlsContext.d_tlsConfig.d_ticketsKeyRotationDelay; + } + + bool isHTTPS() const + { + return !d_tlsContext.d_tlsConfig.d_certKeyPairs.empty(); + } + +#ifndef HAVE_DNS_OVER_HTTPS + virtual void setup() + { + } + + virtual void reloadCertificates() + { + } + + virtual void rotateTicketsKey(time_t /* now */) + { + } + + virtual void loadTicketsKeys(const std::string& /* keyFile */) + { + } + + virtual void handleTicketsKeyRotation() + { + } + + virtual std::string getNextTicketsKeyRotation() + { + return std::string(); + } + + virtual size_t getTicketsKeysCount() const + { + size_t res = 0; + return res; + } + +#else + virtual void setup(); + virtual void reloadCertificates(); + + virtual void rotateTicketsKey(time_t now); + virtual void loadTicketsKeys(const std::string& keyFile); + virtual void handleTicketsKeyRotation(); + virtual std::string getNextTicketsKeyRotation() const; + virtual size_t getTicketsKeysCount(); +#endif /* HAVE_DNS_OVER_HTTPS */ +}; + +#include "dnsdist-idstate.hh" + +struct DownstreamState; + +#ifndef HAVE_DNS_OVER_HTTPS +struct DOHUnitInterface +{ + virtual ~DOHUnitInterface() + { + } + static void handleTimeout(std::unique_ptr) + { + } + + static void handleUDPResponse(std::unique_ptr, PacketBuffer&&, InternalQueryState&&, const std::shared_ptr&) + { + } +}; +#else /* HAVE_DNS_OVER_HTTPS */ +struct DOHUnitInterface +{ + virtual ~DOHUnitInterface() + { + } + + virtual std::string getHTTPPath() const = 0; + virtual std::string getHTTPQueryString() const = 0; + virtual const std::string& getHTTPHost() const = 0; + virtual const std::string& getHTTPScheme() const = 0; + virtual const std::unordered_map& getHTTPHeaders() const = 0; + virtual void setHTTPResponse(uint16_t statusCode, PacketBuffer&& body, const std::string& contentType = "") = 0; + virtual void handleTimeout() = 0; + virtual void handleUDPResponse(PacketBuffer&& response, InternalQueryState&& state, const std::shared_ptr&) = 0; + + static void handleTimeout(std::unique_ptr unit) + { + if (unit) { + unit->handleTimeout(); + unit.release(); + } + } + + static void handleUDPResponse(std::unique_ptr unit, PacketBuffer&& response, InternalQueryState&& state, const std::shared_ptr& ds) + { + if (unit) { + unit->handleUDPResponse(std::move(response), std::move(state), ds); + unit.release(); + } + } + + std::shared_ptr downstream{nullptr}; +}; +#endif /* HAVE_DNS_OVER_HTTPS */ diff --git a/pdns/dnsdist-idstate.hh b/pdns/dnsdist-idstate.hh index cf5442fea0b2..456e703fb3db 100644 --- a/pdns/dnsdist-idstate.hh +++ b/pdns/dnsdist-idstate.hh @@ -22,6 +22,7 @@ #pragma once #include "config.h" +#include "dnscrypt.hh" #include "dnsname.hh" #include "dnsdist-protocols.hh" #include "gettime.hh" @@ -29,11 +30,12 @@ #include "uuid-utils.hh" struct ClientState; -struct DOHUnit; +struct DOHUnitInterface; class DNSCryptQuery; class DNSDistPacketCache; using QTag = std::unordered_map; +using HeadersMap = std::unordered_map; struct StopWatch { @@ -89,6 +91,8 @@ private: bool d_needRealTime; }; +class CrossProtocolContext; + struct InternalQueryState { struct ProtoBufData @@ -125,7 +129,9 @@ struct InternalQueryState std::unique_ptr d_protoBufData{nullptr}; boost::optional tempFailureTTL{boost::none}; // 8 ClientState* cs{nullptr}; // 8 - std::unique_ptr du{nullptr}; // 8 + std::unique_ptr du; // 8 + size_t d_proxyProtocolPayloadSize{0}; // 8 + int32_t d_streamID{-1}; // 4 uint32_t cacheKey{0}; // 4 uint32_t cacheKeyNoECS{0}; // 4 // DoH-only */ diff --git a/pdns/dnsdist-lua-inspection.cc b/pdns/dnsdist-lua-inspection.cc index 66200df0eaa5..f778a492dded 100644 --- a/pdns/dnsdist-lua-inspection.cc +++ b/pdns/dnsdist-lua-inspection.cc @@ -706,7 +706,7 @@ void setupLuaInspection(LuaContext& luaCtx) errorCounters = &f->tlsFrontend->d_tlsCounters; } else if (f->dohFrontend != nullptr) { - errorCounters = &f->dohFrontend->d_tlsCounters; + errorCounters = &f->dohFrontend->d_tlsContext.d_tlsCounters; } if (errorCounters == nullptr) { continue; diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 3224b8763fd5..c829c2e1b5c1 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -57,6 +57,7 @@ #include "dnsdist-web.hh" #include "base64.hh" +#include "doh.hh" #include "dolog.hh" #include "sodcrypto.hh" #include "threadname.hh" @@ -2336,31 +2337,39 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) setLuaSideEffect(); auto frontend = std::make_shared(); +#ifdef HAVE_LIBH2OEVLOOP + frontend = std::make_shared(); + frontend->d_library = "h2o"; +#else /* HAVE_LIBH2OEVLOOP */ + errlog("DOH bind %s is configured to use libh2o but the library is not available", addr); + return; +#endif /* HAVE_LIBH2OEVLOOP */ + if (certFiles && !certFiles->empty()) { - if (!loadTLSCertificateAndKeys("addDOHLocal", frontend->d_tlsConfig.d_certKeyPairs, *certFiles, *keyFiles)) { + if (!loadTLSCertificateAndKeys("addDOHLocal", frontend->d_tlsContext.d_tlsConfig.d_certKeyPairs, *certFiles, *keyFiles)) { return; } - frontend->d_local = ComboAddress(addr, 443); + frontend->d_tlsContext.d_addr = ComboAddress(addr, 443); } else { - frontend->d_local = ComboAddress(addr, 80); - infolog("No certificate provided for DoH endpoint %s, running in DNS over HTTP mode instead of DNS over HTTPS", frontend->d_local.toStringWithPort()); + frontend->d_tlsContext.d_addr = ComboAddress(addr, 80); + infolog("No certificate provided for DoH endpoint %s, running in DNS over HTTP mode instead of DNS over HTTPS", frontend->d_tlsContext.d_addr.toStringWithPort()); } if (urls) { if (urls->type() == typeid(std::string)) { - frontend->d_urls.push_back(boost::get(*urls)); + frontend->d_urls.insert(boost::get(*urls)); } else if (urls->type() == typeid(LuaArray)) { auto urlsVect = boost::get>(*urls); for (const auto& p : urlsVect) { - frontend->d_urls.push_back(p.second); + frontend->d_urls.insert(p.second); } } } else { - frontend->d_urls = {"/dns-query"}; + frontend->d_urls.insert("/dns-query"); } bool reusePort = false; @@ -2405,7 +2414,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } } - parseTLSConfig(frontend->d_tlsConfig, "addDOHLocal", vars); + parseTLSConfig(frontend->d_tlsContext.d_tlsConfig, "addDOHLocal", vars); bool ignoreTLSConfigurationErrors = false; if (getOptionalValue(vars, "ignoreTLSConfigurationErrors", ignoreTLSConfigurationErrors) > 0 && ignoreTLSConfigurationErrors) { @@ -2413,7 +2422,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) // and properly ignore the frontend before actually launching it try { std::map ocspResponses = {}; - auto ctx = libssl_init_server_context(frontend->d_tlsConfig, ocspResponses); + auto ctx = libssl_init_server_context(frontend->d_tlsContext.d_tlsConfig, ocspResponses); } catch (const std::runtime_error& e) { errlog("Ignoring DoH frontend: '%s'", e.what()); @@ -2424,7 +2433,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) checkAllParametersConsumed("addDOHLocal", vars); } g_dohlocals.push_back(frontend); - auto cs = std::make_unique(frontend->d_local, true, reusePort, tcpFastOpenQueueSize, interface, cpus); + auto cs = std::make_unique(frontend->d_tlsContext.d_addr, true, reusePort, tcpFastOpenQueueSize, interface, cpus); cs->dohFrontend = frontend; cs->d_additionalAddresses = std::move(additionalAddresses); @@ -2435,9 +2444,9 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) cs->d_tcpConcurrentConnectionsLimit = tcpMaxConcurrentConnections; } g_frontends.push_back(std::move(cs)); -#else +#else /* HAVE_DNS_OVER_HTTPS */ throw std::runtime_error("addDOHLocal() called but DNS over HTTPS support is not present!"); -#endif +#endif /* HAVE_DNS_OVER_HTTPS */ }); luaCtx.writeFunction("showDOHFrontends", []() { @@ -2449,7 +2458,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) ret << (fmt % "#" % "Address" % "HTTP" % "HTTP/1" % "HTTP/2" % "GET" % "POST" % "Bad" % "Errors" % "Redirects" % "Valid" % "# ticket keys" % "Rotation delay" % "Next rotation") << endl; size_t counter = 0; for (const auto& ctx : g_dohlocals) { - ret << (fmt % counter % ctx->d_local.toStringWithPort() % ctx->d_httpconnects % ctx->d_http1Stats.d_nbQueries % ctx->d_http2Stats.d_nbQueries % ctx->d_getqueries % ctx->d_postqueries % ctx->d_badrequests % ctx->d_errorresponses % ctx->d_redirectresponses % ctx->d_validresponses % ctx->getTicketsKeysCount() % ctx->getTicketsKeyRotationDelay() % ctx->getNextTicketsKeyRotation()) << endl; + ret << (fmt % counter % ctx->d_tlsContext.d_addr.toStringWithPort() % ctx->d_httpconnects % ctx->d_http1Stats.d_nbQueries % ctx->d_http2Stats.d_nbQueries % ctx->d_getqueries % ctx->d_postqueries % ctx->d_badrequests % ctx->d_errorresponses % ctx->d_redirectresponses % ctx->d_validresponses % ctx->getTicketsKeysCount() % ctx->getTicketsKeyRotationDelay() % ctx->getNextTicketsKeyRotation()) << endl; counter++; } g_outputBuffer = ret.str(); @@ -2473,7 +2482,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) ret << (fmt % "#" % "Address" % "200" % "400" % "403" % "500" % "502" % "Others") << endl; size_t counter = 0; for (const auto& ctx : g_dohlocals) { - ret << (fmt % counter % ctx->d_local.toStringWithPort() % ctx->d_http1Stats.d_nb200Responses % ctx->d_http1Stats.d_nb400Responses % ctx->d_http1Stats.d_nb403Responses % ctx->d_http1Stats.d_nb500Responses % ctx->d_http1Stats.d_nb502Responses % ctx->d_http1Stats.d_nbOtherResponses) << endl; + ret << (fmt % counter % ctx->d_tlsContext.d_addr.toStringWithPort() % ctx->d_http1Stats.d_nb200Responses % ctx->d_http1Stats.d_nb400Responses % ctx->d_http1Stats.d_nb403Responses % ctx->d_http1Stats.d_nb500Responses % ctx->d_http1Stats.d_nb502Responses % ctx->d_http1Stats.d_nbOtherResponses) << endl; counter++; } g_outputBuffer += ret.str(); @@ -2483,7 +2492,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) ret << (fmt % "#" % "Address" % "200" % "400" % "403" % "500" % "502" % "Others") << endl; counter = 0; for (const auto& ctx : g_dohlocals) { - ret << (fmt % counter % ctx->d_local.toStringWithPort() % ctx->d_http2Stats.d_nb200Responses % ctx->d_http2Stats.d_nb400Responses % ctx->d_http2Stats.d_nb403Responses % ctx->d_http2Stats.d_nb500Responses % ctx->d_http2Stats.d_nb502Responses % ctx->d_http2Stats.d_nbOtherResponses) << endl; + ret << (fmt % counter % ctx->d_tlsContext.d_addr.toStringWithPort() % ctx->d_http2Stats.d_nb200Responses % ctx->d_http2Stats.d_nb400Responses % ctx->d_http2Stats.d_nb403Responses % ctx->d_http2Stats.d_nb500Responses % ctx->d_http2Stats.d_nb502Responses % ctx->d_http2Stats.d_nbOtherResponses) << endl; counter++; } g_outputBuffer += ret.str(); @@ -2537,7 +2546,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) luaCtx.registerFunction::*)(boost::variant, LuaArray, LuaArray>> certFiles, boost::variant> keyFiles)>("loadNewCertificatesAndKeys", [](std::shared_ptr frontend, boost::variant, LuaArray, LuaArray>> certFiles, boost::variant> keyFiles) { #ifdef HAVE_DNS_OVER_HTTPS if (frontend != nullptr) { - if (loadTLSCertificateAndKeys("DOHFrontend::loadNewCertificatesAndKeys", frontend->d_tlsConfig.d_certKeyPairs, certFiles, keyFiles)) { + if (loadTLSCertificateAndKeys("DOHFrontend::loadNewCertificatesAndKeys", frontend->d_tlsContext.d_tlsConfig.d_certKeyPairs, certFiles, keyFiles)) { frontend->reloadCertificates(); } } @@ -2579,7 +2588,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } setLuaSideEffect(); - shared_ptr frontend = std::make_shared(TLSFrontend::ALPN::DoT); + auto frontend = std::make_shared(TLSFrontend::ALPN::DoT); if (!loadTLSCertificateAndKeys("addTLSLocal", frontend->d_tlsConfig.d_certKeyPairs, certFiles, keyFiles)) { return; } diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index d1132d37839f..50379859725c 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -741,7 +741,7 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) errorCounters = &front->tlsFrontend->d_tlsCounters; } else if (front->dohFrontend != nullptr) { - errorCounters = &front->dohFrontend->d_tlsCounters; + errorCounters = &front->dohFrontend->d_tlsContext.d_tlsCounters; } if (errorCounters != nullptr) { @@ -779,7 +779,7 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) #ifdef HAVE_DNS_OVER_HTTPS std::map dohFrontendDuplicates; for(const auto& doh : g_dohlocals) { - const string frontName = doh->d_local.toStringWithPort(); + const string frontName = doh->d_tlsContext.d_addr.toStringWithPort(); uint64_t threadNumber = 0; auto dupPair = frontendDuplicates.emplace(frontName, 1); if (!dupPair.second) { @@ -1149,7 +1149,7 @@ static void handleStats(const YaHTTP::Request& req, YaHTTP::Response& resp) errorCounters = &front->tlsFrontend->d_tlsCounters; } else if (front->dohFrontend != nullptr) { - errorCounters = &front->dohFrontend->d_tlsCounters; + errorCounters = &front->dohFrontend->d_tlsContext.d_tlsCounters; } if (errorCounters != nullptr) { frontend["tlsHandshakeFailuresDHKeyTooSmall"] = (double)errorCounters->d_dhKeyTooSmall; @@ -1172,7 +1172,7 @@ static void handleStats(const YaHTTP::Request& req, YaHTTP::Response& resp) for (const auto& doh : g_dohlocals) { dohs.emplace_back(Json::object{ { "id", num++ }, - { "address", doh->d_local.toStringWithPort() }, + { "address", doh->d_tlsContext.d_addr.toStringWithPort() }, { "http-connects", (double) doh->d_httpconnects }, { "http1-queries", (double) doh->d_http1Stats.d_nbQueries }, { "http2-queries", (double) doh->d_http2Stats.d_nbQueries }, diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index a673bd6f54e2..fdf2797104c1 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -69,6 +69,7 @@ #include "base64.hh" #include "capabilities.hh" #include "delaypipe.hh" +#include "doh.hh" #include "dolog.hh" #include "dnsname.hh" #include "dnsparser.hh" @@ -784,7 +785,7 @@ void responderThread(std::shared_ptr dss) if (du) { #ifdef HAVE_DNS_OVER_HTTPS // DoH query, we cannot touch du after that - handleUDPResponseForDoH(std::move(du), std::move(response), std::move(*ids)); + DOHUnitInterface::handleUDPResponse(std::move(du), std::move(response), std::move(*ids), dss); #endif continue; } @@ -1539,19 +1540,14 @@ ProcessQueryResult processQuery(DNSQuestion& dq, LocalHolders& holders, std::sha return ProcessQueryResult::Drop; } -bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint16_t queryID, DNSQuestion& dq, PacketBuffer& query, ComboAddress& dest) +bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint16_t queryID, DNSQuestion& dq, PacketBuffer& query) { bool doh = dq.ids.du != nullptr; bool failed = false; - size_t proxyPayloadSize = 0; if (ds->d_config.useProxyProtocol) { try { - if (addProxyProtocol(dq, &proxyPayloadSize)) { - if (dq.ids.du) { - dq.ids.du->proxyProtocolPayloadSize = proxyPayloadSize; - } - } + addProxyProtocol(dq, &dq.ids.d_proxyProtocolPayloadSize); } catch (const std::exception& e) { vinfolog("Adding proxy protocol payload to %s query from %s failed: %s", (dq.ids.du ? "DoH" : ""), dq.ids.origDest.toStringWithPort(), e.what()); @@ -1559,6 +1555,10 @@ bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint1 } } + if (doh && !dq.ids.d_packet) { + dq.ids.d_packet = std::make_unique(query); + } + try { int fd = ds->pickSocketForSending(); dq.ids.backendFD = fd; @@ -1569,7 +1569,7 @@ bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint1 auto idOffset = ds->saveState(std::move(dq.ids)); /* set the correct ID */ - memcpy(query.data() + proxyPayloadSize, &idOffset, sizeof(idOffset)); + memcpy(query.data() + dq.ids.d_proxyProtocolPayloadSize, &idOffset, sizeof(idOffset)); /* you can't touch ids or du after this line, unless the call returned a non-negative value, because it might already have been freed */ @@ -1585,9 +1585,6 @@ bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint1 auto cleared = ds->getState(idOffset); if (cleared) { dq.ids.du = std::move(cleared->du); - if (dq.ids.du) { - dq.ids.du->status_code = 502; - } } ++dnsdist::metrics::g_stats.downstreamSendErrors; ++ds->sendErrors; @@ -1720,7 +1717,7 @@ static void processUDPQuery(ClientState& cs, LocalHolders& holders, const struct return; } - assignOutgoingUDPQueryToBackend(ss, dh->id, dq, query, dest); + assignOutgoingUDPQueryToBackend(ss, dh->id, dq, query); } catch(const std::exception& e){ vinfolog("Got an error in UDP question thread while parsing a query from %s, id %d: %s", ids.origRemote.toStringWithPort(), queryId, e.what()); diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 56b7421655d4..a9ecef017080 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -42,7 +42,7 @@ #include "dnsdist-lbpolicies.hh" #include "dnsdist-protocols.hh" #include "dnsname.hh" -#include "doh.hh" +#include "dnsdist-doh-common.hh" #include "ednsoptions.hh" #include "iputils.hh" #include "misc.hh" @@ -1088,10 +1088,6 @@ struct LocalHolders void tcpAcceptorThread(std::vector states); -#ifdef HAVE_DNS_OVER_HTTPS -void dohThread(ClientState* cs); -#endif /* HAVE_DNS_OVER_HTTPS */ - void setLuaNoSideEffect(); // if nothing has been declared, set that there are no side effects void setLuaSideEffect(); // set to report a side effect, cancelling all _no_ side effect calls bool getLuaNoSideEffect(); // set if there were only explicit declarations of _no_ side effect @@ -1123,7 +1119,7 @@ bool processResponse(PacketBuffer& response, const std::vector& cacheInsertedRespRuleActions, DNSResponse& dr, bool muted); -bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint16_t queryID, DNSQuestion& dq, PacketBuffer& query, ComboAddress& dest); +bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint16_t queryID, DNSQuestion& dq, PacketBuffer& query); ssize_t udpClientSendRequestToBackend(const std::shared_ptr& ss, const int sd, const PacketBuffer& request, bool healthCheck = false); bool sendUDPResponse(int origFD, const PacketBuffer& response, const int delayMsec, const ComboAddress& origDest, const ComboAddress& origRemote); diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 9b951a586694..99d7cdbe6475 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -147,6 +147,7 @@ dnsdist_SOURCES = \ dnsdist-discovery.cc dnsdist-discovery.hh \ dnsdist-dnscrypt.cc \ dnsdist-dnsparser.cc dnsdist-dnsparser.hh \ + dnsdist-doh-common.cc dnsdist-doh-common.hh \ dnsdist-downstream-connection.hh \ dnsdist-dynblocks.cc dnsdist-dynblocks.hh \ dnsdist-dynbpf.cc dnsdist-dynbpf.hh \ @@ -256,6 +257,7 @@ testrunner_SOURCES = \ dnsdist-cache.cc dnsdist-cache.hh \ dnsdist-concurrent-connections.hh \ dnsdist-dnsparser.cc dnsdist-dnsparser.hh \ + dnsdist-doh-common.cc dnsdist-doh-common.hh \ dnsdist-downstream-connection.hh \ dnsdist-dynblocks.cc dnsdist-dynblocks.hh \ dnsdist-dynbpf.cc dnsdist-dynbpf.hh \ diff --git a/pdns/dnsdistdist/dnsdist-async.cc b/pdns/dnsdistdist/dnsdist-async.cc index 19426468df74..f54b1c0b1446 100644 --- a/pdns/dnsdistdist/dnsdist-async.cc +++ b/pdns/dnsdistdist/dnsdist-async.cc @@ -282,7 +282,6 @@ bool resumeQuery(std::unique_ptr&& query) return resumeResponse(std::move(query)); } - auto& ids = query->query.d_idstate; DNSQuestion dnsQuestion = query->getDQ(); LocalHolders holders; @@ -311,7 +310,7 @@ bool resumeQuery(std::unique_ptr&& query) /* at this point 'du', if it is not nullptr, is owned by the DoHCrossProtocolQuery which will stop existing when we return, so we need to increment the reference count */ - return assignOutgoingUDPQueryToBackend(query->downstream, queryID, dnsQuestion, query->query.d_buffer, ids.origDest); + return assignOutgoingUDPQueryToBackend(query->downstream, queryID, dnsQuestion, query->query.d_buffer); } if (result == ProcessQueryResult::SendAnswer) { auto sender = query->getTCPQuerySender(); diff --git a/pdns/dnsdistdist/dnsdist-backend.cc b/pdns/dnsdistdist/dnsdist-backend.cc index 45a50446da71..44b3d9c39dc4 100644 --- a/pdns/dnsdistdist/dnsdist-backend.cc +++ b/pdns/dnsdistdist/dnsdist-backend.cc @@ -360,7 +360,7 @@ void DownstreamState::handleUDPTimeout(IDState& ids) { ids.age = 0; ids.inUse = false; - handleDOHTimeout(std::move(ids.internal.du)); + DOHUnitInterface::handleTimeout(std::move(ids.internal.du)); ++reuseds; --outstanding; ++dnsdist::metrics::g_stats.downstreamTimeouts; // this is an 'actively' discovered timeout @@ -463,7 +463,7 @@ uint16_t DownstreamState::saveState(InternalQueryState&& state) auto oldDU = std::move(it->second.internal.du); ++reuseds; ++dnsdist::metrics::g_stats.downstreamTimeouts; - handleDOHTimeout(std::move(oldDU)); + DOHUnitInterface::handleTimeout(std::move(oldDU)); } else { ++outstanding; @@ -490,7 +490,7 @@ uint16_t DownstreamState::saveState(InternalQueryState&& state) auto oldDU = std::move(ids.internal.du); ++reuseds; ++dnsdist::metrics::g_stats.downstreamTimeouts; - handleDOHTimeout(std::move(oldDU)); + DOHUnitInterface::handleTimeout(std::move(oldDU)); } else { ++outstanding; @@ -513,7 +513,7 @@ void DownstreamState::restoreState(uint16_t id, InternalQueryState&& state) /* already used */ ++reuseds; ++dnsdist::metrics::g_stats.downstreamTimeouts; - handleDOHTimeout(std::move(state.du)); + DOHUnitInterface::handleTimeout(std::move(state.du)); } else { it->second.internal = std::move(state); @@ -528,14 +528,14 @@ void DownstreamState::restoreState(uint16_t id, InternalQueryState&& state) /* already used */ ++reuseds; ++dnsdist::metrics::g_stats.downstreamTimeouts; - handleDOHTimeout(std::move(state.du)); + DOHUnitInterface::handleTimeout(std::move(state.du)); return; } if (ids.isInUse()) { /* already used */ ++reuseds; ++dnsdist::metrics::g_stats.downstreamTimeouts; - handleDOHTimeout(std::move(state.du)); + DOHUnitInterface::handleTimeout(std::move(state.du)); return; } ids.internal = std::move(state); diff --git a/pdns/dnsdistdist/dnsdist-doh-common.cc b/pdns/dnsdistdist/dnsdist-doh-common.cc new file mode 100644 index 000000000000..15fcb9672a9d --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-doh-common.cc @@ -0,0 +1,129 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "dnsdist-doh-common.hh" +#include "dnsdist-rules.hh" + +#ifdef HAVE_DNS_OVER_HTTPS + +HTTPHeaderRule::HTTPHeaderRule(const std::string& header, const std::string& regex) : + d_header(toLower(header)), d_regex(regex), d_visual("http[" + header + "] ~ " + regex) +{ +} + +bool HTTPHeaderRule::matches(const DNSQuestion* dq) const +{ + if (!dq->ids.du) { + return false; + } + + const auto& headers = dq->ids.du->getHTTPHeaders(); + for (const auto& header : headers) { + if (header.first == d_header) { + return d_regex.match(header.second); + } + } + return false; +} + +string HTTPHeaderRule::toString() const +{ + return d_visual; +} + +HTTPPathRule::HTTPPathRule(const std::string& path) : + d_path(path) +{ +} + +bool HTTPPathRule::matches(const DNSQuestion* dq) const +{ + if (!dq->ids.du) { + return false; + } + + const auto path = dq->ids.du->getHTTPPath(); + return d_path == path; +} + +string HTTPPathRule::toString() const +{ + return "url path == " + d_path; +} + +HTTPPathRegexRule::HTTPPathRegexRule(const std::string& regex) : + d_regex(regex), d_visual("http path ~ " + regex) +{ +} + +bool HTTPPathRegexRule::matches(const DNSQuestion* dq) const +{ + if (!dq->ids.du) { + return false; + } + + return d_regex.match(dq->ids.du->getHTTPPath()); +} + +string HTTPPathRegexRule::toString() const +{ + return d_visual; +} + +void DOHFrontend::rotateTicketsKey(time_t now) +{ + return d_tlsContext.rotateTicketsKey(now); +} + +void DOHFrontend::loadTicketsKeys(const std::string& keyFile) +{ + return d_tlsContext.loadTicketsKeys(keyFile); +} + +void DOHFrontend::handleTicketsKeyRotation() +{ +} + +std::string DOHFrontend::getNextTicketsKeyRotation() const +{ + return d_tlsContext.getNextTicketsKeyRotation(); +} + +size_t DOHFrontend::getTicketsKeysCount() +{ + return d_tlsContext.getTicketsKeysCount(); +} + +void DOHFrontend::reloadCertificates() +{ + d_tlsContext.setupTLS(); +} + +void DOHFrontend::setup() +{ + if (isHTTPS()) { + if (!d_tlsContext.setupTLS()) { + throw std::runtime_error("Error setting up TLS context for DoH listener on '" + d_tlsContext.d_addr.toStringWithPort()); + } + } +} + +#endif /* HAVE_DNS_OVER_HTTPS */ diff --git a/pdns/dnsdistdist/dnsdist-doh-common.hh b/pdns/dnsdistdist/dnsdist-doh-common.hh new file mode 120000 index 000000000000..56920844943f --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-doh-common.hh @@ -0,0 +1 @@ +../dnsdist-doh-common.hh \ No newline at end of file diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index eeb0af480847..91dcd9ad7674 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -167,6 +167,8 @@ class DOHAcceptContext std::atomic_flag d_rotatingTicketsKey; }; +struct DOHUnit; + // we create one of these per thread, and pass around a pointer to it // through the bowels of h2o struct DOHServerConfig @@ -215,6 +217,61 @@ struct DOHServerConfig pdns::channel::Receiver d_responseReceiver; }; +struct DOHUnit : public DOHUnitInterface +{ + DOHUnit(PacketBuffer&& q, std::string&& p, std::string&& h): path(std::move(p)), host(std::move(h)), query(std::move(q)) + { + ids.ednsAdded = false; + } + ~DOHUnit() + { + if (self) { + *self = nullptr; + } + } + + DOHUnit(const DOHUnit&) = delete; + DOHUnit& operator=(const DOHUnit&) = delete; + + InternalQueryState ids; + std::string sni; + std::string path; + std::string scheme; + std::string host; + std::string contentType; + PacketBuffer query; + PacketBuffer response; + std::unique_ptr> headers; + st_h2o_req_t* req{nullptr}; + DOHUnit** self{nullptr}; + DOHServerConfig* dsc{nullptr}; + pdns::channel::Sender* responseSender{nullptr}; + size_t query_at{0}; + int rsock{-1}; + /* the status_code is set from + processDOHQuery() (which is executed in + the DOH client thread) so that the correct + response can be sent in on_dnsdist(), + after the DOHUnit has been passed back to + the main DoH thread. + */ + uint16_t status_code{200}; + /* whether the query was re-sent to the backend over + TCP after receiving a truncated answer over UDP */ + bool tcp{false}; + bool truncated{false}; + + std::string getHTTPPath() const override; + std::string getHTTPQueryString() const override; + const std::string& getHTTPHost() const override; + const std::string& getHTTPScheme() const override; + const std::unordered_map& getHTTPHeaders() const override; + void setHTTPResponse(uint16_t statusCode, PacketBuffer&& body, const std::string& contentType="") override; + virtual void handleTimeout() override; + virtual void handleUDPResponse(PacketBuffer&& response, InternalQueryState&& state, const std::shared_ptr&) override; +}; +using DOHUnitUniquePtr = std::unique_ptr; + /* This internal function sends back the object to the main thread to send a reply. The caller should NOT release or touch the unit after calling this function */ static void sendDoHUnitToTheMainThread(DOHUnitUniquePtr&& du, const char* description) @@ -233,18 +290,11 @@ static void sendDoHUnitToTheMainThread(DOHUnitUniquePtr&& du, const char* descri } /* This function is called from other threads than the main DoH one, - instructing it to send a 502 error to the client. - It takes ownership of the unit. */ -void handleDOHTimeout(DOHUnitUniquePtr&& oldDU) + instructing it to send a 502 error to the client. */ +void DOHUnit::handleTimeout() { - if (oldDU == nullptr) { - return; - } - - /* we are about to erase an existing DU */ - oldDU->status_code = 502; - - sendDoHUnitToTheMainThread(std::move(oldDU), "DoH timeout"); + status_code = 502; + sendDoHUnitToTheMainThread(std::unique_ptr(this), "DoH timeout"); } struct DOHConnection @@ -385,7 +435,7 @@ static void handleResponse(DOHFrontend& df, st_h2o_req_t* req, uint16_t statusCo h2o_send_error_400(req, getReasonFromStatusCode(statusCode).c_str(), "invalid DNS query" , 0); break; case 403: - h2o_send_error_403(req, getReasonFromStatusCode(statusCode).c_str(), "dns query not allowed", 0); + h2o_send_error_403(req, getReasonFromStatusCode(statusCode).c_str(), "DoH query not allowed", 0); break; case 502: h2o_send_error_502(req, getReasonFromStatusCode(statusCode).c_str(), "no downstream server available", 0); @@ -402,6 +452,12 @@ static void handleResponse(DOHFrontend& df, st_h2o_req_t* req, uint16_t statusCo } } +static std::unique_ptr getDUFromIDS(InternalQueryState& ids) +{ + auto du = std::unique_ptr(dynamic_cast(ids.du.release())); + return du; +} + class DoHTCPCrossQuerySender : public TCPQuerySender { public: @@ -420,7 +476,7 @@ class DoHTCPCrossQuerySender : public TCPQuerySender return; } - auto du = std::move(response.d_idstate.du); + auto du = getDUFromIDS(response.d_idstate); if (du->responseSender == nullptr) { return; } @@ -438,10 +494,11 @@ class DoHTCPCrossQuerySender : public TCPQuerySender dr.ids.du = std::move(du); - if (!processResponse(dr.ids.du->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) { + if (!processResponse(dynamic_cast(dr.ids.du.get())->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) { if (dr.ids.du) { - dr.ids.du->status_code = 503; - sendDoHUnitToTheMainThread(std::move(dr.ids.du), "Response dropped by rules"); + du = getDUFromIDS(dr.ids); + du->status_code = 503; + sendDoHUnitToTheMainThread(std::move(du), "Response dropped by rules"); } return; } @@ -450,7 +507,7 @@ class DoHTCPCrossQuerySender : public TCPQuerySender return; } - du = std::move(dr.ids.du); + du = getDUFromIDS(dr.ids); } if (!du->ids.selfGenerated) { @@ -483,11 +540,11 @@ class DoHTCPCrossQuerySender : public TCPQuerySender return; } - if (query.du->responseSender == nullptr) { + auto du = getDUFromIDS(query); + if (du->responseSender == nullptr) { return; } - auto du = std::move(query.du); du->ids = std::move(query); du->status_code = 502; sendDoHUnitToTheMainThread(std::move(du), "cross-protocol error response"); @@ -519,20 +576,23 @@ class DoHCrossProtocolQuery : public CrossProtocolQuery Leave it for now because we know that the onky case where the payload has been added is when we tried over UDP, got a TC=1 answer and retried over TCP/DoT, and we know the TCP/DoT code can handle it. */ - query.d_proxyProtocolPayloadAdded = query.d_idstate.du->proxyProtocolPayloadSize > 0; + query.d_proxyProtocolPayloadAdded = query.d_idstate.d_proxyProtocolPayloadSize > 0; downstream = query.d_idstate.du->downstream; - proxyProtocolPayloadSize = query.d_idstate.du->proxyProtocolPayloadSize; } void handleInternalError() { - query.d_idstate.du->status_code = 502; - sendDoHUnitToTheMainThread(std::move(query.d_idstate.du), "DoH internal error"); + auto du = getDUFromIDS(query.d_idstate); + if (!du) { + return; + } + du->status_code = 502; + sendDoHUnitToTheMainThread(std::move(du), "DoH internal error"); } std::shared_ptr getTCPQuerySender() override { - query.d_idstate.du->downstream = downstream; + dynamic_cast(query.d_idstate.du.get())->downstream = downstream; return s_sender; } @@ -550,9 +610,9 @@ class DoHCrossProtocolQuery : public CrossProtocolQuery return dr; } - DOHUnitUniquePtr&& releaseDU() + DOHUnitUniquePtr releaseDU() { - return std::move(query.d_idstate.du); + return getDUFromIDS(query.d_idstate); } private: @@ -567,7 +627,7 @@ std::unique_ptr getDoHCrossProtocolQueryFromDQ(DNSQuestion& throw std::runtime_error("Trying to create a DoH cross protocol query without a valid DoH unit"); } - auto du = std::move(dq.ids.du); + auto du = getDUFromIDS(dq.ids); if (&dq.ids != &du->ids) { du->ids = std::move(dq.ids); } @@ -606,121 +666,116 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) }; auto& ids = unit->ids; - ids.du = std::move(unit); - auto& du = ids.du; uint16_t queryId = 0; ComboAddress remote; try { - if (!du->req) { + if (!unit->req) { // we got closed meanwhile. XXX small race condition here // but we should be fine as long as we don't touch du->req // outside of the main DoH thread - du->status_code = 500; - handleImmediateResponse(std::move(du), "DoH killed in flight"); + unit->status_code = 500; + handleImmediateResponse(std::move(unit), "DoH killed in flight"); return; } - { - // if there was no EDNS, we add it with a large buffer size - // so we can use UDP to talk to the backend. - auto dh = const_cast(reinterpret_cast(du->query.data())); - - if (!dh->arcount) { - if (generateOptRR(std::string(), du->query, 4096, 4096, 0, false)) { - dh = const_cast(reinterpret_cast(du->query.data())); // may have reallocated - dh->arcount = htons(1); - du->ids.ednsAdded = true; - } - } - else { - // we leave existing EDNS in place - } - } - - remote = du->ids.origRemote; - DOHServerConfig* dsc = du->dsc; + remote = ids.origRemote; + DOHServerConfig* dsc = unit->dsc; auto& holders = dsc->holders; ClientState& cs = *dsc->cs; - if (du->query.size() < sizeof(dnsheader)) { + if (unit->query.size() < sizeof(dnsheader)) { ++dnsdist::metrics::g_stats.nonCompliantQueries; ++cs.nonCompliantQueries; - du->status_code = 400; - handleImmediateResponse(std::move(du), "DoH non-compliant query"); + unit->status_code = 400; + handleImmediateResponse(std::move(unit), "DoH non-compliant query"); return; } ++cs.queries; ++dnsdist::metrics::g_stats.queries; - du->ids.queryRealTime.start(); + ids.queryRealTime.start(); { /* don't keep that pointer around, it will be invalidated if the buffer is ever resized */ - struct dnsheader* dh = reinterpret_cast(du->query.data()); + struct dnsheader* dh = reinterpret_cast(unit->query.data()); if (!checkQueryHeaders(dh, cs)) { - du->status_code = 400; - handleImmediateResponse(std::move(du), "DoH invalid headers"); + unit->status_code = 400; + handleImmediateResponse(std::move(unit), "DoH invalid headers"); return; } if (dh->qdcount == 0) { dh->rcode = RCode::NotImp; dh->qr = true; - du->response = std::move(du->query); + unit->response = std::move(unit->query); - handleImmediateResponse(std::move(du), "DoH empty query"); + handleImmediateResponse(std::move(unit), "DoH empty query"); return; } queryId = ntohs(dh->id); } - auto downstream = du->downstream; - du->ids.qname = DNSName(reinterpret_cast(du->query.data()), du->query.size(), sizeof(dnsheader), false, &du->ids.qtype, &du->ids.qclass); - DNSQuestion dq(du->ids, du->query); + { + // if there was no EDNS, we add it with a large buffer size + // so we can use UDP to talk to the backend. + auto dh = const_cast(reinterpret_cast(unit->query.data())); + if (!dh->arcount) { + if (addEDNS(unit->query, 4096, false, 4096, 0)) { + ids.ednsAdded = true; + } + } + } + + auto downstream = unit->downstream; + ids.qname = DNSName(reinterpret_cast(unit->query.data()), unit->query.size(), sizeof(dnsheader), false, &ids.qtype, &ids.qclass); + DNSQuestion dq(ids, unit->query); const uint16_t* flags = getFlagsFromDNSHeader(dq.getHeader()); ids.origFlags = *flags; - du->ids.cs = &cs; - dq.sni = std::move(du->sni); - + ids.cs = &cs; + dq.sni = std::move(unit->sni); + ids.du = std::move(unit); auto result = processQuery(dq, holders, downstream); if (result == ProcessQueryResult::Drop) { - du->status_code = 403; - handleImmediateResponse(std::move(du), "DoH dropped query"); + unit = getDUFromIDS(ids); + unit->status_code = 403; + handleImmediateResponse(std::move(unit), "DoH dropped query"); return; } else if (result == ProcessQueryResult::Asynchronous) { return; } else if (result == ProcessQueryResult::SendAnswer) { - if (du->response.empty()) { - du->response = std::move(du->query); + unit = getDUFromIDS(ids); + if (unit->response.empty()) { + unit->response = std::move(unit->query); } - if (du->response.size() >= sizeof(dnsheader) && du->contentType.empty()) { - auto dh = reinterpret_cast(du->response.data()); + if (unit->response.size() >= sizeof(dnsheader) && unit->contentType.empty()) { + auto dh = reinterpret_cast(unit->response.data()); - handleResponseSent(du->ids.qname, QType(du->ids.qtype), 0., du->ids.origDest, ComboAddress(), du->response.size(), *dh, dnsdist::Protocol::DoH, dnsdist::Protocol::DoH, false); + handleResponseSent(unit->ids.qname, QType(unit->ids.qtype), 0., unit->ids.origDest, ComboAddress(), unit->response.size(), *dh, dnsdist::Protocol::DoH, dnsdist::Protocol::DoH, false); } - handleImmediateResponse(std::move(du), "DoH self-answered response"); + handleImmediateResponse(std::move(unit), "DoH self-answered response"); return; } + unit = getDUFromIDS(ids); if (result != ProcessQueryResult::PassToBackend) { - du->status_code = 500; - handleImmediateResponse(std::move(du), "DoH no backend available"); + unit->status_code = 500; + handleImmediateResponse(std::move(unit), "DoH no backend available"); return; } if (downstream == nullptr) { - du->status_code = 502; - handleImmediateResponse(std::move(du), "DoH no backend available"); + unit->status_code = 502; + handleImmediateResponse(std::move(unit), "DoH no backend available"); return; } - du->downstream = downstream; + unit->downstream = downstream; if (downstream->isTCPOnly()) { std::string proxyProtocolPayload; @@ -730,11 +785,11 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) proxyProtocolPayload = getProxyProtocolPayload(dq); } - du->ids.origID = htons(queryId); - du->tcp = true; + unit->ids.origID = htons(queryId); + unit->tcp = true; /* this moves du->ids, careful! */ - auto cpq = std::make_unique(std::move(du), false); + auto cpq = std::make_unique(std::move(unit), false); cpq->query.d_proxyProtocolPayload = std::move(proxyProtocolPayload); if (downstream->passCrossProtocolQuery(std::move(cpq))) { @@ -742,9 +797,9 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) } else { if (inMainThread) { - du = cpq->releaseDU(); - du->status_code = 502; - handleImmediateResponse(std::move(du), "DoH internal error"); + unit = cpq->releaseDU(); + unit->status_code = 502; + handleImmediateResponse(std::move(unit), "DoH internal error"); } else { cpq->handleInternalError(); @@ -753,17 +808,19 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) } } - ComboAddress dest = dq.ids.origDest; - if (!assignOutgoingUDPQueryToBackend(downstream, htons(queryId), dq, du->query, dest)) { - du->status_code = 502; - handleImmediateResponse(std::move(du), "DoH internal error"); + auto& query = unit->query; + ids.du = std::move(unit); + if (!assignOutgoingUDPQueryToBackend(downstream, htons(queryId), dq, query)) { + unit = getDUFromIDS(ids); + unit->status_code = 502; + handleImmediateResponse(std::move(unit), "DoH internal error"); return; } } catch (const std::exception& e) { vinfolog("Got an error in DOH question thread while parsing a query from %s, id %d: %s", remote.toStringWithPort(), queryId, e.what()); - du->status_code = 500; - handleImmediateResponse(std::move(du), "DoH internal error"); + unit->status_code = 500; + handleImmediateResponse(std::move(unit), "DoH internal error"); return; } @@ -838,7 +895,7 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re /* we are doing quite some copies here, sorry about that, but we can't keep accessing the req object once we are in a different thread because the request might get killed by h2o at pretty much any time */ - auto du = std::make_unique(std::move(query), std::move(path), std::string(req->authority.base, req->authority.len)); + auto du = DOHUnitUniquePtr(new DOHUnit(std::move(query), std::move(path), std::string(req->authority.base, req->authority.len))); du->dsc = dsc; du->req = req; du->ids.origDest = local; @@ -869,7 +926,7 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re *(du->self) = du.get(); #ifdef USE_SINGLE_ACCEPTOR_THREAD - processDOHQuery(du, true); + processDOHQuery(std::move(du), true); #else /* USE_SINGLE_ACCEPTOR_THREAD */ try { if (!dsc->d_querySender.send(std::move(du))) { @@ -1102,85 +1159,13 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) } } -HTTPHeaderRule::HTTPHeaderRule(const std::string& header, const std::string& regex) - : d_header(toLower(header)), d_regex(regex), d_visual("http[" + header+ "] ~ " + regex) -{ -} - -bool HTTPHeaderRule::matches(const DNSQuestion* dq) const -{ - if (!dq->ids.du || !dq->ids.du->headers) { - return false; - } - - for (const auto& header : *dq->ids.du->headers) { - if (header.first == d_header) { - return d_regex.match(header.second); - } - } - return false; -} - -string HTTPHeaderRule::toString() const -{ - return d_visual; -} - -HTTPPathRule::HTTPPathRule(const std::string& path) - : d_path(path) -{ - -} - -bool HTTPPathRule::matches(const DNSQuestion* dq) const -{ - if (!dq->ids.du) { - return false; - } - - if (dq->ids.du->query_at == SIZE_MAX) { - return dq->ids.du->path == d_path; - } - else { - return d_path.compare(0, d_path.size(), dq->ids.du->path, 0, dq->ids.du->query_at) == 0; - } -} - -string HTTPPathRule::toString() const -{ - return "url path == " + d_path; -} - -HTTPPathRegexRule::HTTPPathRegexRule(const std::string& regex): d_regex(regex), d_visual("http path ~ " + regex) -{ -} - -bool HTTPPathRegexRule::matches(const DNSQuestion* dq) const -{ - if (!dq->ids.du) { - return false; - } - - return d_regex.match(dq->ids.du->getHTTPPath()); -} - -string HTTPPathRegexRule::toString() const -{ - return d_visual; -} - -std::unordered_map DOHUnit::getHTTPHeaders() const +const std::unordered_map& DOHUnit::getHTTPHeaders() const { - std::unordered_map results; - if (headers) { - results.reserve(headers->size()); - - for (const auto& header : *headers) { - results.insert(header); - } + if (!headers) { + static const HeadersMap empty{}; + return empty; } - - return results; + return *headers; } std::string DOHUnit::getHTTPPath() const @@ -1193,12 +1178,12 @@ std::string DOHUnit::getHTTPPath() const } } -std::string DOHUnit::getHTTPHost() const +const std::string& DOHUnit::getHTTPHost() const { return host; } -std::string DOHUnit::getHTTPScheme() const +const std::string& DOHUnit::getHTTPScheme() const { return scheme; } @@ -1280,7 +1265,7 @@ static void on_dnsdist(h2o_socket_t *listener, const char *err) memory and likely coming up too late after the client has gone away */ auto* dsc = static_cast(listener->data); while (true) { - std::unique_ptr du{nullptr}; + DOHUnitUniquePtr du{nullptr}; try { auto tmp = dsc->d_responseReceiver.receive(); if (!tmp) { @@ -1300,10 +1285,10 @@ static void on_dnsdist(h2o_socket_t *listener, const char *err) if (!du->tcp && du->truncated && - du->query.size() > du->proxyProtocolPayloadSize && - (du->query.size() - du->proxyProtocolPayloadSize) > sizeof(dnsheader)) { + du->query.size() > du->ids.d_proxyProtocolPayloadSize && + (du->query.size() - du->ids.d_proxyProtocolPayloadSize) > sizeof(dnsheader)) { /* restoring the original ID */ - dnsheader* queryDH = reinterpret_cast(du->query.data() + du->proxyProtocolPayloadSize); + dnsheader* queryDH = reinterpret_cast(du->query.data() + du->ids.d_proxyProtocolPayloadSize); queryDH->id = du->ids.origID; du->ids.forwardedOverUDP = false; du->tcp = true; @@ -1494,84 +1479,22 @@ static void setupAcceptContext(DOHAcceptContext& ctx, DOHServerConfig& dsc, bool auto nativeCtx = ctx.get(); nativeCtx->ctx = &dsc.h2o_ctx; nativeCtx->hosts = dsc.h2o_config.hosts; - ctx.d_ticketsKeyRotationDelay = dsc.df->d_tlsConfig.d_ticketsKeyRotationDelay; + auto df = std::atomic_load_explicit(&dsc.df, std::memory_order_acquire); + ctx.d_ticketsKeyRotationDelay = df->d_tlsContext.d_tlsConfig.d_ticketsKeyRotationDelay; - if (setupTLS && dsc.df->isHTTPS()) { + if (setupTLS && df->isHTTPS()) { try { setupTLSContext(ctx, - dsc.df->d_tlsConfig, - dsc.df->d_tlsCounters); + df->d_tlsContext.d_tlsConfig, + df->d_tlsContext.d_tlsCounters); } catch (const std::runtime_error& e) { - throw std::runtime_error("Error setting up TLS context for DoH listener on '" + dsc.df->d_local.toStringWithPort() + "': " + e.what()); + throw std::runtime_error("Error setting up TLS context for DoH listener on '" + df->d_tlsContext.d_addr.toStringWithPort() + "': " + e.what()); } } ctx.d_cs = dsc.cs; } -void DOHFrontend::rotateTicketsKey(time_t now) -{ - if (d_dsc && d_dsc->accept_ctx) { - d_dsc->accept_ctx->rotateTicketsKey(now); - } -} - -void DOHFrontend::loadTicketsKeys(const std::string& keyFile) -{ - if (d_dsc && d_dsc->accept_ctx) { - d_dsc->accept_ctx->loadTicketsKeys(keyFile); - } -} - -void DOHFrontend::handleTicketsKeyRotation() -{ - if (d_dsc && d_dsc->accept_ctx) { - d_dsc->accept_ctx->handleTicketsKeyRotation(); - } -} - -time_t DOHFrontend::getNextTicketsKeyRotation() const -{ - if (d_dsc && d_dsc->accept_ctx) { - return d_dsc->accept_ctx->getNextTicketsKeyRotation(); - } - return 0; -} - -size_t DOHFrontend::getTicketsKeysCount() const -{ - size_t res = 0; - if (d_dsc && d_dsc->accept_ctx) { - res = d_dsc->accept_ctx->getTicketsKeysCount(); - } - return res; -} - -void DOHFrontend::reloadCertificates() -{ - auto newAcceptContext = std::make_shared(); - setupAcceptContext(*newAcceptContext, *d_dsc, true); - std::atomic_store_explicit(&d_dsc->accept_ctx, newAcceptContext, std::memory_order_release); -} - -void DOHFrontend::setup() -{ - registerOpenSSLUser(); - - d_dsc = std::make_shared(d_idleTimeout, d_internalPipeBufferSize); - - if (isHTTPS()) { - try { - setupTLSContext(*d_dsc->accept_ctx, - d_tlsConfig, - d_tlsCounters); - } - catch (const std::runtime_error& e) { - throw std::runtime_error("Error setting up TLS context for DoH listener on '" + d_local.toStringWithPort() + "': " + e.what()); - } - } -} - static h2o_pathconf_t *register_handler(h2o_hostconf_t *hostconf, const char *path, int (*on_req)(h2o_handler_t *, h2o_req_t *)) { h2o_pathconf_t *pathconf = h2o_config_register_path(hostconf, path, 0); @@ -1598,7 +1521,7 @@ void dohThread(ClientState* cs) std::shared_ptr& df = cs->dohFrontend; auto& dsc = df->d_dsc; dsc->cs = cs; - dsc->df = cs->dohFrontend; + std::atomic_store_explicit(&dsc->df, cs->dohFrontend, std::memory_order_release); dsc->h2o_config.server_name = h2o_iovec_init(df->d_serverTokens.c_str(), df->d_serverTokens.size()); #ifndef USE_SINGLE_ACCEPTOR_THREAD @@ -1609,11 +1532,11 @@ void dohThread(ClientState* cs) setThreadName("dnsdist/doh"); // I wonder if this registers an IP address.. I think it does // this may mean we need to actually register a site "name" here and not the IP address - h2o_hostconf_t *hostconf = h2o_config_register_host(&dsc->h2o_config, h2o_iovec_init(df->d_local.toString().c_str(), df->d_local.toString().size()), 65535); + h2o_hostconf_t *hostconf = h2o_config_register_host(&dsc->h2o_config, h2o_iovec_init(df->d_tlsContext.d_addr.toString().c_str(), df->d_tlsContext.d_addr.toString().size()), 65535); - for(const auto& url : df->d_urls) { + dsc->paths = df->d_urls; + for (const auto& url : dsc->paths) { register_handler(hostconf, url.c_str(), doh_handler); - dsc->paths.insert(url); } h2o_context_init(&dsc->h2o_ctx, h2o_evloop_create(), &dsc->h2o_config); @@ -1632,11 +1555,11 @@ void dohThread(ClientState* cs) setupAcceptContext(*dsc->accept_ctx, *dsc, false); if (create_listener(dsc, cs->tcpFD) != 0) { - throw std::runtime_error("DOH server failed to listen on " + df->d_local.toStringWithPort() + ": " + strerror(errno)); + throw std::runtime_error("DOH server failed to listen on " + df->d_tlsContext.d_addr.toStringWithPort() + ": " + strerror(errno)); } for (const auto& [addr, fd] : cs->d_additionalAddresses) { if (create_listener(dsc, fd) != 0) { - throw std::runtime_error("DOH server failed to listen on additional address " + addr.toStringWithPort() + " for DOH local" + df->d_local.toStringWithPort() + ": " + strerror(errno)); + throw std::runtime_error("DOH server failed to listen on additional address " + addr.toStringWithPort() + " for DOH local" + df->d_tlsContext.d_addr.toStringWithPort() + ": " + strerror(errno)); } } @@ -1661,25 +1584,31 @@ void dohThread(ClientState* cs) } } -void handleUDPResponseForDoH(DOHUnitUniquePtr&& du, PacketBuffer&& udpResponse, InternalQueryState&& state) +void DOHUnit::handleUDPResponse(PacketBuffer&& udpResponse, InternalQueryState&& state, const std::shared_ptr&) { - du->response = std::move(udpResponse); + auto du = std::unique_ptr(this); du->ids = std::move(state); - const dnsheader* dh = reinterpret_cast(du->response.data()); - if (!dh->tc) { + { + const dnsheader* dh = reinterpret_cast(udpResponse.data()); + if (dh->tc) { + du->truncated = true; + } + } + if (!du->truncated) { static thread_local LocalStateHolder> localRespRuleActions = g_respruleactions.getLocal(); static thread_local LocalStateHolder> localCacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal(); - DNSResponse dr(du->ids, du->response, du->downstream); + DNSResponse dr(du->ids, udpResponse, du->downstream); dnsheader cleartextDH; memcpy(&cleartextDH, dr.getHeader(), sizeof(cleartextDH)); dr.ids.du = std::move(du); - if (!processResponse(dr.ids.du->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) { + if (!processResponse(udpResponse, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) { if (dr.ids.du) { - dr.ids.du->status_code = 503; - sendDoHUnitToTheMainThread(std::move(dr.ids.du), "Response dropped by rules"); + du = getDUFromIDS(dr.ids); + du->status_code = 503; + sendDoHUnitToTheMainThread(std::move(du), "Response dropped by rules"); } return; } @@ -1688,7 +1617,8 @@ void handleUDPResponseForDoH(DOHUnitUniquePtr&& du, PacketBuffer&& udpResponse, return; } - du = std::move(dr.ids.du); + du = getDUFromIDS(dr.ids); + du->response = std::move(udpResponse); double udiff = du->ids.queryRealTime.udiff(); vinfolog("Got answer from %s, relayed to %s (https), took %f us", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); @@ -1699,17 +1629,72 @@ void handleUDPResponseForDoH(DOHUnitUniquePtr&& du, PacketBuffer&& udpResponse, ++du->ids.cs->responses; } } - else { - du->truncated = true; - } sendDoHUnitToTheMainThread(std::move(du), "DoH response"); } -#endif /* HAVE_LIBH2OEVLOOP */ -#else /* HAVE_DNS_OVER_HTTPS */ -void handleDOHTimeout(DOHUnitUniquePtr&& oldDU) +void H2ODOHFrontend::rotateTicketsKey(time_t now) +{ + if (d_dsc && d_dsc->accept_ctx) { + d_dsc->accept_ctx->rotateTicketsKey(now); + } +} + +void H2ODOHFrontend::loadTicketsKeys(const std::string& keyFile) +{ + if (d_dsc && d_dsc->accept_ctx) { + d_dsc->accept_ctx->loadTicketsKeys(keyFile); + } +} + +void H2ODOHFrontend::handleTicketsKeyRotation() +{ + if (d_dsc && d_dsc->accept_ctx) { + d_dsc->accept_ctx->handleTicketsKeyRotation(); + } +} + +std::string H2ODOHFrontend::getNextTicketsKeyRotation() const +{ + if (d_dsc && d_dsc->accept_ctx) { + return std::to_string(d_dsc->accept_ctx->getNextTicketsKeyRotation()); + } + return 0; +} + +size_t H2ODOHFrontend::getTicketsKeysCount() +{ + size_t res = 0; + if (d_dsc && d_dsc->accept_ctx) { + res = d_dsc->accept_ctx->getTicketsKeysCount(); + } + return res; +} + +void H2ODOHFrontend::reloadCertificates() +{ + auto newAcceptContext = std::make_shared(); + setupAcceptContext(*newAcceptContext, *d_dsc, true); + std::atomic_store_explicit(&d_dsc->accept_ctx, newAcceptContext, std::memory_order_release); +} + +void H2ODOHFrontend::setup() { + registerOpenSSLUser(); + + d_dsc = std::make_shared(d_idleTimeout, d_internalPipeBufferSize); + + if (isHTTPS()) { + try { + setupTLSContext(*d_dsc->accept_ctx, + d_tlsContext.d_tlsConfig, + d_tlsContext.d_tlsCounters); + } + catch (const std::runtime_error& e) { + throw std::runtime_error("Error setting up TLS context for DoH listener on '" + d_tlsContext.d_addr.toStringWithPort() + "': " + e.what()); + } + } } -#endif /* HAVE_DNS_OVER_HTTPS */ +#endif /* HAVE_LIBH2OEVLOOP */ +#endif /* HAVE_LIBH2OEVLOOP */ diff --git a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc index c7e638b21967..9d437578f77f 100644 --- a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc @@ -34,39 +34,10 @@ std::vector> g_frontends; /* add stub implementations, we don't want to include the corresponding object files and their dependencies */ -#ifdef HAVE_DNS_OVER_HTTPS -std::unordered_map DOHUnit::getHTTPHeaders() const -{ - return {}; -} - -std::string DOHUnit::getHTTPPath() const -{ - return ""; -} - -std::string DOHUnit::getHTTPHost() const -{ - return ""; -} - -std::string DOHUnit::getHTTPScheme() const -{ - return ""; -} - -std::string DOHUnit::getHTTPQueryString() const -{ - return ""; -} - -void DOHUnit::setHTTPResponse(uint16_t statusCode, PacketBuffer&& body_, const std::string& contentType_) -{ -} -#endif /* HAVE_DNS_OVER_HTTPS */ - -void handleDOHTimeout(DOHUnitUniquePtr&& oldDU) +// NOLINTNEXTLINE(readability-convert-member-functions-to-static): this is a stub, the real one is not that simple.. +bool TLSFrontend::setupTLS() { + return true; } std::string DNSQuestion::getTrailingData() const diff --git a/pdns/doh.hh b/pdns/doh.hh index 6f3816c300fa..58a26f16918f 100644 --- a/pdns/doh.hh +++ b/pdns/doh.hh @@ -21,236 +21,37 @@ */ #pragma once -#pragma once - -#include - -#include "channel.hh" -#include "iputils.hh" -#include "libssl.hh" -#include "noinitvector.hh" -#include "stat_t.hh" - -struct DOHServerConfig; - -class DOHResponseMapEntry -{ -public: - DOHResponseMapEntry(const std::string& regex, uint16_t status, const PacketBuffer& content, const boost::optional>& headers): d_regex(regex), d_customHeaders(headers), d_content(content), d_status(status) - { - if (status >= 400 && !d_content.empty() && d_content.at(d_content.size() -1) != 0) { - // we need to make sure it's null-terminated - d_content.push_back(0); - } - } - - bool matches(const std::string& path) const - { - return d_regex.match(path); - } - - uint16_t getStatusCode() const - { - return d_status; - } - - const PacketBuffer& getContent() const - { - return d_content; - } - - const boost::optional>& getHeaders() const - { - return d_customHeaders; - } - -private: - Regex d_regex; - boost::optional> d_customHeaders; - PacketBuffer d_content; - uint16_t d_status; -}; - -struct DOHFrontend -{ - DOHFrontend() - { - } - - std::shared_ptr d_dsc{nullptr}; - std::shared_ptr>> d_responsesMap; - TLSConfig d_tlsConfig; - TLSErrorCounters d_tlsCounters; - std::string d_serverTokens{"h2o/dnsdist"}; - std::unordered_map d_customResponseHeaders; - ComboAddress d_local; - - uint32_t d_idleTimeout{30}; // HTTP idle timeout in seconds - std::vector d_urls; - - pdns::stat_t d_httpconnects{0}; // number of TCP/IP connections established - pdns::stat_t d_getqueries{0}; // valid DNS queries received via GET - pdns::stat_t d_postqueries{0}; // valid DNS queries received via POST - pdns::stat_t d_badrequests{0}; // request could not be converted to dns query - pdns::stat_t d_errorresponses{0}; // dnsdist set 'error' on response - pdns::stat_t d_redirectresponses{0}; // dnsdist set 'redirect' on response - pdns::stat_t d_validresponses{0}; // valid responses sent out - - struct HTTPVersionStats - { - pdns::stat_t d_nbQueries{0}; // valid DNS queries received - pdns::stat_t d_nb200Responses{0}; - pdns::stat_t d_nb400Responses{0}; - pdns::stat_t d_nb403Responses{0}; - pdns::stat_t d_nb500Responses{0}; - pdns::stat_t d_nb502Responses{0}; - pdns::stat_t d_nbOtherResponses{0}; - }; - - HTTPVersionStats d_http1Stats; - HTTPVersionStats d_http2Stats; -#ifdef __linux__ - // On Linux this gives us 128k pending queries (default is 8192 queries), - // which should be enough to deal with huge spikes - uint32_t d_internalPipeBufferSize{1024*1024}; -#else - uint32_t d_internalPipeBufferSize{0}; -#endif - bool d_sendCacheControlHeaders{true}; - bool d_trustForwardedForHeader{false}; - /* whether we require tue query path to exactly match one of configured ones, - or accept everything below these paths. */ - bool d_exactPathMatching{true}; - bool d_keepIncomingHeaders{false}; - - time_t getTicketsKeyRotationDelay() const - { - return d_tlsConfig.d_ticketsKeyRotationDelay; - } - - bool isHTTPS() const - { - return !d_tlsConfig.d_certKeyPairs.empty(); - } - -#ifndef HAVE_DNS_OVER_HTTPS - void setup() - { - } - - void reloadCertificates() - { - } +#include "config.h" - void rotateTicketsKey(time_t /* now */) - { - } - - void loadTicketsKeys(const std::string& /* keyFile */) - { - } - - void handleTicketsKeyRotation() - { - } - - time_t getNextTicketsKeyRotation() const - { - return 0; - } - - size_t getTicketsKeysCount() const - { - size_t res = 0; - return res; - } - -#else - void setup(); - void reloadCertificates(); - - void rotateTicketsKey(time_t now); - void loadTicketsKeys(const std::string& keyFile); - void handleTicketsKeyRotation(); - time_t getNextTicketsKeyRotation() const; - size_t getTicketsKeysCount() const; -#endif /* HAVE_DNS_OVER_HTTPS */ -}; +#ifdef HAVE_DNS_OVER_HTTPS +#ifdef HAVE_LIBH2OEVLOOP -#ifndef HAVE_DNS_OVER_HTTPS -struct DOHUnit -{ - size_t proxyProtocolPayloadSize{0}; - uint16_t status_code{200}; -}; +#include +#include +#include -#else /* HAVE_DNS_OVER_HTTPS */ -#ifdef HAVE_LIBH2OEVLOOP -#include +struct CrossProtocolQuery; +struct DNSQuestion; -#include "dnsdist-idstate.hh" +std::unique_ptr getDoHCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse); -struct st_h2o_req_t; -struct DownstreamState; +#include "dnsdist-doh-common.hh" -struct DOHUnit +struct H2ODOHFrontend : public DOHFrontend { - DOHUnit(PacketBuffer&& q, std::string&& p, std::string&& h): path(std::move(p)), host(std::move(h)), query(std::move(q)) - { - ids.ednsAdded = false; - } - - DOHUnit(const DOHUnit&) = delete; - DOHUnit& operator=(const DOHUnit&) = delete; +public: - InternalQueryState ids; - std::string sni; - std::string path; - std::string scheme; - std::string host; - std::string contentType; - PacketBuffer query; - PacketBuffer response; - std::shared_ptr downstream{nullptr}; - std::unique_ptr> headers; - st_h2o_req_t* req{nullptr}; - DOHUnit** self{nullptr}; - DOHServerConfig* dsc{nullptr}; - pdns::channel::Sender* responseSender{nullptr}; - size_t query_at{0}; - size_t proxyProtocolPayloadSize{0}; - int rsock{-1}; - /* the status_code is set from - processDOHQuery() (which is executed in - the DOH client thread) so that the correct - response can be sent in on_dnsdist(), - after the DOHUnit has been passed back to - the main DoH thread. - */ - uint16_t status_code{200}; - /* whether the query was re-sent to the backend over - TCP after receiving a truncated answer over UDP */ - bool tcp{false}; - bool truncated{false}; + void setup() override; + void reloadCertificates() override; - std::string getHTTPPath() const; - std::string getHTTPHost() const; - std::string getHTTPScheme() const; - std::string getHTTPQueryString() const; - std::unordered_map getHTTPHeaders() const; - void setHTTPResponse(uint16_t statusCode, PacketBuffer&& body, const std::string& contentType=""); + void rotateTicketsKey(time_t now) override; + void loadTicketsKeys(const std::string& keyFile) override; + void handleTicketsKeyRotation() override; + std::string getNextTicketsKeyRotation() const override; + size_t getTicketsKeysCount() override; }; -void handleUDPResponseForDoH(std::unique_ptr&&, PacketBuffer&& response, InternalQueryState&& state); - -struct CrossProtocolQuery; -struct DNSQuestion; - -std::unique_ptr getDoHCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse); +void dohThread(ClientState* clientState); #endif /* HAVE_LIBH2OEVLOOP */ #endif /* HAVE_DNS_OVER_HTTPS */ - -using DOHUnitUniquePtr = std::unique_ptr; - -void handleDOHTimeout(DOHUnitUniquePtr&& oldDU); diff --git a/pdns/test-dnsdist_cc.cc b/pdns/test-dnsdist_cc.cc index c4fe42b8aafe..c51a930c04f8 100644 --- a/pdns/test-dnsdist_cc.cc +++ b/pdns/test-dnsdist_cc.cc @@ -54,9 +54,9 @@ bool sendUDPResponse(int origFD, const PacketBuffer& response, const int delayMs return false; } -bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint16_t queryID, DNSQuestion& dq, PacketBuffer& query, ComboAddress& dest) +bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint16_t queryID, DNSQuestion& dq, PacketBuffer& query) { - return false; + return true; } namespace dnsdist { From 7e8a05fa482317dc40e17be9e9dafa29992363fd Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 31 Jul 2023 17:07:05 +0200 Subject: [PATCH 617/909] dnsdist: Implement incoming DoH support via nghttp2 --- pdns/dnsdist-doh-common.hh | 5 +- pdns/dnsdist-lua-bindings-dnsquestion.cc | 2 +- pdns/dnsdist-lua.cc | 52 +- pdns/dnsdist-tcp.cc | 600 ++++---- pdns/dnsdist.cc | 19 +- pdns/dnsdistdist/Makefile.am | 10 + pdns/dnsdistdist/configure.ac | 15 +- pdns/dnsdistdist/dnsdist-async.cc | 3 +- pdns/dnsdistdist/dnsdist-healthchecks.cc | 2 +- pdns/dnsdistdist/dnsdist-internal-queries.cc | 8 +- pdns/dnsdistdist/dnsdist-lua-ffi.cc | 3 +- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 1214 +++++++++++++++++ pdns/dnsdistdist/dnsdist-nghttp2-in.hh | 114 ++ pdns/dnsdistdist/dnsdist-nghttp2.cc | 82 +- pdns/dnsdistdist/dnsdist-tcp-downstream.cc | 27 +- pdns/dnsdistdist/dnsdist-tcp-upstream.hh | 41 +- pdns/dnsdistdist/dnsdist-tcp.hh | 16 +- pdns/dnsdistdist/doh.cc | 12 +- pdns/dnsdistdist/m4/dnsdist_enable_doh.m4 | 2 +- pdns/dnsdistdist/m4/pdns_with_nghttp2.m4 | 7 + pdns/dnsdistdist/test-dnsdistasync.cc | 2 +- pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc | 1 - pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc | 4 +- pdns/dnsdistdist/test-dnsdisttcp_cc.cc | 92 +- pdns/doh.hh | 2 +- pdns/tcpiohandler.cc | 5 +- pdns/tcpiohandler.hh | 3 +- pdns/test-dnsdist_cc.cc | 2 +- regression-tests.dnsdist/dnsdisttests.py | 8 +- regression-tests.dnsdist/test_DOH.py | 19 +- regression-tests.dnsdist/test_Protobuf.py | 1 - 31 files changed, 1948 insertions(+), 425 deletions(-) create mode 100644 pdns/dnsdistdist/dnsdist-nghttp2-in.cc create mode 100644 pdns/dnsdistdist/dnsdist-nghttp2-in.hh diff --git a/pdns/dnsdist-doh-common.hh b/pdns/dnsdist-doh-common.hh index 44ad826a88d8..41166de9f302 100644 --- a/pdns/dnsdist-doh-common.hh +++ b/pdns/dnsdist-doh-common.hh @@ -77,10 +77,6 @@ struct DOHFrontend DOHFrontend() { } - DOHFrontend(std::shared_ptr tlsCtx) : - d_tlsContext(std::move(tlsCtx)) - { - } virtual ~DOHFrontend() { @@ -126,6 +122,7 @@ struct DOHFrontend #endif bool d_sendCacheControlHeaders{true}; bool d_trustForwardedForHeader{false}; + bool d_earlyACLDrop{true}; /* whether we require tue query path to exactly match one of configured ones, or accept everything below these paths. */ bool d_exactPathMatching{true}; diff --git a/pdns/dnsdist-lua-bindings-dnsquestion.cc b/pdns/dnsdist-lua-bindings-dnsquestion.cc index a29c17c3ade0..f71a9bbf4d97 100644 --- a/pdns/dnsdist-lua-bindings-dnsquestion.cc +++ b/pdns/dnsdist-lua-bindings-dnsquestion.cc @@ -284,7 +284,7 @@ class AsynchronousObject struct timeval now; gettimeofday(&now, nullptr); - sender->notifyIOError(std::move(object->query.d_idstate), now); + sender->notifyIOError(now, TCPResponse(std::move(object->query))); return true; } diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index c829c2e1b5c1..fedd9c5d868a 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2337,14 +2337,34 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) setLuaSideEffect(); auto frontend = std::make_shared(); + if (getOptionalValue(vars, "library", frontend->d_library) == 0) { +#ifdef HAVE_NGHTTP2 + frontend->d_library = "nghttp2"; +#else /* HAVE_NGHTTP2 */ + frontend->d_library = "h2o"; +#endif /* HAVE_NGHTTP2 */ + } + if (frontend->d_library == "h2o") { #ifdef HAVE_LIBH2OEVLOOP - frontend = std::make_shared(); - frontend->d_library = "h2o"; + frontend = std::make_shared(); + frontend->d_library = "h2o"; #else /* HAVE_LIBH2OEVLOOP */ - errlog("DOH bind %s is configured to use libh2o but the library is not available", addr); - return; + errlog("DOH bind %s is configured to use libh2o but the library is not available", addr); + return; #endif /* HAVE_LIBH2OEVLOOP */ + } + else if (frontend->d_library == "nghttp2") { +#ifndef HAVE_NGHTTP2 + errlog("DOH bind %s is configured to use nghttp2 but the library is not available", addr); + return; +#endif /* HAVE_NGHTTP2 */ + } + else { + errlog("DOH bind %s is configured to use an unknown library ('%s')", addr, frontend->d_library); + return; + } + bool useTLS = true; if (certFiles && !certFiles->empty()) { if (!loadTLSCertificateAndKeys("addDOHLocal", frontend->d_tlsContext.d_tlsConfig.d_certKeyPairs, *certFiles, *keyFiles)) { return; @@ -2355,6 +2375,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) else { frontend->d_tlsContext.d_addr = ComboAddress(addr, 80); infolog("No certificate provided for DoH endpoint %s, running in DNS over HTTP mode instead of DNS over HTTPS", frontend->d_tlsContext.d_addr.toStringWithPort()); + useTLS = false; } if (urls) { @@ -2385,6 +2406,8 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) parseLocalBindVars(vars, reusePort, tcpFastOpenQueueSize, interface, cpus, tcpListenQueueSize, maxInFlightQueriesPerConn, tcpMaxConcurrentConnections); getOptionalValue(vars, "idleTimeout", frontend->d_idleTimeout); getOptionalValue(vars, "serverTokens", frontend->d_serverTokens); + getOptionalValue(vars, "provider", frontend->d_tlsContext.d_provider); + boost::algorithm::to_lower(frontend->d_tlsContext.d_provider); LuaAssociativeTable customResponseHeaders; if (getOptionalValue(vars, "customResponseHeaders", customResponseHeaders) > 0) { @@ -2397,6 +2420,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) getOptionalValue(vars, "sendCacheControlHeaders", frontend->d_sendCacheControlHeaders); getOptionalValue(vars, "keepIncomingHeaders", frontend->d_keepIncomingHeaders); getOptionalValue(vars, "trustForwardedForHeader", frontend->d_trustForwardedForHeader); + getOptionalValue(vars, "earlyACLDrop", frontend->d_earlyACLDrop); getOptionalValue(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize); getOptionalValue(vars, "exactPathMatching", frontend->d_exactPathMatching); @@ -2432,6 +2456,21 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) checkAllParametersConsumed("addDOHLocal", vars); } + + if (useTLS && frontend->d_library == "nghttp2") { + if (!frontend->d_tlsContext.d_provider.empty()) { + vinfolog("Loading TLS provider '%s'", frontend->d_tlsContext.d_provider); + } + else { +#ifdef HAVE_LIBSSL + const std::string provider("openssl"); +#else + const std::string provider("gnutls"); +#endif + vinfolog("Loading default TLS provider '%s'", provider); + } + } + g_dohlocals.push_back(frontend); auto cs = std::make_unique(frontend->d_tlsContext.d_addr, true, reusePort, tcpFastOpenQueueSize, interface, cpus); cs->dohFrontend = frontend; @@ -2648,10 +2687,11 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } else { #ifdef HAVE_LIBSSL - vinfolog("Loading default TLS provider 'openssl'"); + const std::string provider("openssl"); #else - vinfolog("Loading default TLS provider 'gnutls'"); + const std::string provider("gnutls"); #endif + vinfolog("Loading default TLS provider '%s'", provider); } // only works pre-startup, so no sync necessary auto cs = std::make_unique(frontend->d_addr, true, reusePort, tcpFastOpenQueueSize, interface, cpus); diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 14af2564e32c..751ba986722a 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -27,6 +27,7 @@ #include "dnsdist.hh" #include "dnsdist-concurrent-connections.hh" #include "dnsdist-ecs.hh" +#include "dnsdist-nghttp2-in.hh" #include "dnsdist-proxy-protocol.hh" #include "dnsdist-rings.hh" #include "dnsdist-tcp.hh" @@ -96,6 +97,17 @@ IncomingTCPConnectionState::~IncomingTCPConnectionState() d_handler.close(); } +dnsdist::Protocol IncomingTCPConnectionState::getProtocol() const +{ + if (d_ci.cs->dohFrontend) { + return dnsdist::Protocol::DoH; + } + if (d_handler.isTLS()) { + return dnsdist::Protocol::DoT; + } + return dnsdist::Protocol::DoTCP; +} + size_t IncomingTCPConnectionState::clearAllDownstreamConnections() { return t_downstreamTCPConnectionsManager.clear(); @@ -173,7 +185,7 @@ static IOState sendQueuedResponses(std::shared_ptr& TCPResponse resp = std::move(state->d_queuedResponses.front()); state->d_queuedResponses.pop_front(); state->d_state = IncomingTCPConnectionState::State::idle; - result = state->sendResponse(state, now, std::move(resp)); + result = state->sendResponse(now, std::move(resp)); if (result != IOState::Done) { return result; } @@ -183,28 +195,28 @@ static IOState sendQueuedResponses(std::shared_ptr& return IOState::Done; } -static void handleResponseSent(std::shared_ptr& state, TCPResponse& currentResponse) +void IncomingTCPConnectionState::handleResponseSent(TCPResponse& currentResponse) { if (currentResponse.d_idstate.qtype == QType::AXFR || currentResponse.d_idstate.qtype == QType::IXFR) { return; } - --state->d_currentQueriesCount; + --d_currentQueriesCount; const auto& ds = currentResponse.d_connection ? currentResponse.d_connection->getDS() : currentResponse.d_ds; if (currentResponse.d_idstate.selfGenerated == false && ds) { const auto& ids = currentResponse.d_idstate; double udiff = ids.queryRealTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (%s, %d bytes), took %f us", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), currentResponse.d_buffer.size(), udiff); + vinfolog("Got answer from %s, relayed to %s (%s, %d bytes), took %f us", ds->d_config.remote.toStringWithPort(), ids.origRemote.toStringWithPort(), getProtocol().toString(), currentResponse.d_buffer.size(), udiff); auto backendProtocol = ds->getProtocol(); - if (backendProtocol == dnsdist::Protocol::DoUDP) { + if (backendProtocol == dnsdist::Protocol::DoUDP && !currentResponse.d_idstate.forwardedOverUDP) { backendProtocol = dnsdist::Protocol::DoTCP; } - ::handleResponseSent(ids, udiff, state->d_ci.remote, ds->d_config.remote, static_cast(currentResponse.d_buffer.size()), currentResponse.d_cleartextDH, backendProtocol, true); + ::handleResponseSent(ids, udiff, d_ci.remote, ds->d_config.remote, static_cast(currentResponse.d_buffer.size()), currentResponse.d_cleartextDH, backendProtocol, true); } else { const auto& ids = currentResponse.d_idstate; - ::handleResponseSent(ids, 0., state->d_ci.remote, ComboAddress(), static_cast(currentResponse.d_buffer.size()), currentResponse.d_cleartextDH, ids.protocol, false); + ::handleResponseSent(ids, 0., d_ci.remote, ComboAddress(), static_cast(currentResponse.d_buffer.size()), currentResponse.d_cleartextDH, ids.protocol, false); } currentResponse.d_buffer.clear(); @@ -232,7 +244,8 @@ bool IncomingTCPConnectionState::canAcceptNewQueries(const struct timeval& now) return false; } - if (d_currentQueriesCount >= d_ci.cs->d_maxInFlightQueriesPerConn) { + // for DoH, this is already handled by the underlying library + if (!d_ci.cs->dohFrontend && d_currentQueriesCount >= d_ci.cs->d_maxInFlightQueriesPerConn) { DEBUGLOG("not accepting new queries because we already have "<d_maxInFlightQueriesPerConn); return false; } @@ -284,9 +297,9 @@ void IncomingTCPConnectionState::registerOwnedDownstreamConnection(std::shared_p } /* called when the buffer has been set and the rules have been processed, and only from handleIO (sometimes indirectly via handleQuery) */ -IOState IncomingTCPConnectionState::sendResponse(std::shared_ptr& state, const struct timeval& now, TCPResponse&& response) +IOState IncomingTCPConnectionState::sendResponse(const struct timeval& now, TCPResponse&& response) { - state->d_state = IncomingTCPConnectionState::State::sendingResponse; + d_state = IncomingTCPConnectionState::State::sendingResponse; uint16_t responseSize = static_cast(response.d_buffer.size()); const uint8_t sizeBytes[] = { static_cast(responseSize / 256), static_cast(responseSize % 256) }; @@ -294,27 +307,27 @@ IOState IncomingTCPConnectionState::sendResponse(std::shared_ptrd_currentPos = 0; - state->d_currentResponse = std::move(response); + d_currentPos = 0; + d_currentResponse = std::move(response); try { - auto iostate = state->d_handler.tryWrite(state->d_currentResponse.d_buffer, state->d_currentPos, state->d_currentResponse.d_buffer.size()); + auto iostate = d_handler.tryWrite(d_currentResponse.d_buffer, d_currentPos, d_currentResponse.d_buffer.size()); if (iostate == IOState::Done) { DEBUGLOG("response sent from "<<__PRETTY_FUNCTION__); - handleResponseSent(state, state->d_currentResponse); + handleResponseSent(d_currentResponse); return iostate; } else { - state->d_lastIOBlocked = true; + d_lastIOBlocked = true; DEBUGLOG("partial write"); return iostate; } } catch (const std::exception& e) { - vinfolog("Closing TCP client connection with %s: %s", state->d_ci.remote.toStringWithPort(), e.what()); + vinfolog("Closing TCP client connection with %s: %s", d_ci.remote.toStringWithPort(), e.what()); DEBUGLOG("Closing TCP client connection: "<d_ci.cs->tcpDiedSendingResponse; + ++d_ci.cs->tcpDiedSendingResponse; - state->terminateClientConnection(); + terminateClientConnection(); return IOState::Done; } @@ -408,9 +421,7 @@ void IncomingTCPConnectionState::handleAsyncReady(int fd, FDMultiplexer::funcpar if (state->active()) { /* and now we restart our own I/O state machine */ - struct timeval now; - gettimeofday(&now, nullptr); - handleIO(state, now); + state->handleIO(); } else { /* we were only waiting for the engine to come back, @@ -476,16 +487,17 @@ void IncomingTCPConnectionState::handleResponse(const struct timeval& now, TCPRe try { auto& ids = response.d_idstate; unsigned int qnameWireLength; - if (!response.d_connection || !responseContentMatches(response.d_buffer, ids.qname, ids.qtype, ids.qclass, response.d_connection->getDS(), qnameWireLength)) { + std::shared_ptr ds = response.d_ds ? response.d_ds : (response.d_connection ? response.d_connection->getDS() : nullptr); + if (!ds || !responseContentMatches(response.d_buffer, ids.qname, ids.qtype, ids.qclass, ds, qnameWireLength)) { state->terminateClientConnection(); return; } - if (response.d_connection->getDS()) { - ++response.d_connection->getDS()->responses; + if (ds) { + ++ds->responses; } - DNSResponse dr(ids, response.d_buffer, response.d_connection->getDS()); + DNSResponse dr(ids, response.d_buffer, ds); dr.d_incomingTCPState = state; memcpy(&response.d_cleartextDH, dr.getHeader(), sizeof(response.d_cleartextDH)); @@ -529,7 +541,6 @@ class TCPCrossProtocolQuery : public CrossProtocolQuery public: TCPCrossProtocolQuery(PacketBuffer&& buffer, InternalQueryState&& ids, std::shared_ptr ds, std::shared_ptr sender): CrossProtocolQuery(InternalQuery(std::move(buffer), std::move(ids)), ds), d_sender(std::move(sender)) { - proxyProtocolPayloadSize = 0; } ~TCPCrossProtocolQuery() @@ -561,6 +572,11 @@ class TCPCrossProtocolQuery : public CrossProtocolQuery std::shared_ptr d_sender; }; +std::unique_ptr IncomingTCPConnectionState::getCrossProtocolQuery(PacketBuffer&& query, InternalQueryState&& state, const std::shared_ptr& ds) +{ + return std::make_unique(std::move(query), std::move(state), ds, shared_from_this()); +} + std::unique_ptr getTCPCrossProtocolQueryFromDQ(DNSQuestion& dq) { auto state = dq.getIncomingTCPState(); @@ -587,60 +603,63 @@ void IncomingTCPConnectionState::handleCrossProtocolResponse(const struct timeva } } -static void handleQuery(std::shared_ptr& state, const struct timeval& now) +IncomingTCPConnectionState::QueryProcessingResult IncomingTCPConnectionState::handleQuery(PacketBuffer&& queryIn, const struct timeval& now, std::optional streamID) { - if (state->d_querySize < sizeof(dnsheader)) { + auto query = std::move(queryIn); + if (query.size() < sizeof(dnsheader)) { ++dnsdist::metrics::g_stats.nonCompliantQueries; - ++state->d_ci.cs->nonCompliantQueries; - state->terminateClientConnection(); - return; + ++d_ci.cs->nonCompliantQueries; + return QueryProcessingResult::TooSmall; } - ++state->d_queriesCount; - ++state->d_ci.cs->queries; + ++d_queriesCount; + ++d_ci.cs->queries; ++dnsdist::metrics::g_stats.queries; - if (state->d_handler.isTLS()) { - auto tlsVersion = state->d_handler.getTLSVersion(); + if (d_handler.isTLS()) { + auto tlsVersion = d_handler.getTLSVersion(); switch (tlsVersion) { case LibsslTLSVersion::TLS10: - ++state->d_ci.cs->tls10queries; + ++d_ci.cs->tls10queries; break; case LibsslTLSVersion::TLS11: - ++state->d_ci.cs->tls11queries; + ++d_ci.cs->tls11queries; break; case LibsslTLSVersion::TLS12: - ++state->d_ci.cs->tls12queries; + ++d_ci.cs->tls12queries; break; case LibsslTLSVersion::TLS13: - ++state->d_ci.cs->tls13queries; + ++d_ci.cs->tls13queries; break; default: - ++state->d_ci.cs->tlsUnknownqueries; + ++d_ci.cs->tlsUnknownqueries; } } + auto state = shared_from_this(); InternalQueryState ids; - ids.origDest = state->d_proxiedDestination; - ids.origRemote = state->d_proxiedRemote; - ids.cs = state->d_ci.cs; + ids.origDest = d_proxiedDestination; + ids.origRemote = d_proxiedRemote; + ids.cs = d_ci.cs; ids.queryRealTime.start(); + if (streamID) { + ids.d_streamID = *streamID; + } - auto dnsCryptResponse = checkDNSCryptQuery(*state->d_ci.cs, state->d_buffer, ids.dnsCryptQuery, ids.queryRealTime.d_start.tv_sec, true); + auto dnsCryptResponse = checkDNSCryptQuery(*d_ci.cs, query, ids.dnsCryptQuery, ids.queryRealTime.d_start.tv_sec, true); if (dnsCryptResponse) { TCPResponse response; - state->d_state = IncomingTCPConnectionState::State::idle; - ++state->d_currentQueriesCount; - state->queueResponse(state, now, std::move(response)); - return; + d_state = IncomingTCPConnectionState::State::idle; + ++d_currentQueriesCount; + queueResponse(state, now, std::move(response)); + return QueryProcessingResult::SelfAnswered; } { /* this pointer will be invalidated the second the buffer is resized, don't hold onto it! */ - auto* dh = reinterpret_cast(state->d_buffer.data()); - if (!checkQueryHeaders(dh, *state->d_ci.cs)) { - state->terminateClientConnection(); - return; + auto* dh = reinterpret_cast(query.data()); + if (!checkQueryHeaders(dh, *d_ci.cs)) { + return QueryProcessingResult::InvalidHeaders; } if (dh->qdcount == 0) { @@ -648,81 +667,105 @@ static void handleQuery(std::shared_ptr& state, cons dh->rcode = RCode::NotImp; dh->qr = true; response.d_idstate.selfGenerated = true; - response.d_buffer = std::move(state->d_buffer); - state->d_state = IncomingTCPConnectionState::State::idle; - ++state->d_currentQueriesCount; - state->queueResponse(state, now, std::move(response)); - return; + response.d_buffer = std::move(query); + d_state = IncomingTCPConnectionState::State::idle; + ++d_currentQueriesCount; + queueResponse(state, now, std::move(response)); + return QueryProcessingResult::Empty; } } - ids.qname = DNSName(reinterpret_cast(state->d_buffer.data()), state->d_buffer.size(), sizeof(dnsheader), false, &ids.qtype, &ids.qclass); - ids.protocol = dnsdist::Protocol::DoTCP; + ids.qname = DNSName(reinterpret_cast(query.data()), query.size(), sizeof(dnsheader), false, &ids.qtype, &ids.qclass); + ids.protocol = getProtocol(); if (ids.dnsCryptQuery) { ids.protocol = dnsdist::Protocol::DNSCryptTCP; } - else if (state->d_handler.isTLS()) { - ids.protocol = dnsdist::Protocol::DoT; - } - DNSQuestion dq(ids, state->d_buffer); + DNSQuestion dq(ids, query); const uint16_t* flags = getFlagsFromDNSHeader(dq.getHeader()); ids.origFlags = *flags; dq.d_incomingTCPState = state; - dq.sni = state->d_handler.getServerNameIndication(); + dq.sni = d_handler.getServerNameIndication(); - if (state->d_proxyProtocolValues) { + if (d_proxyProtocolValues) { /* we need to copy them, because the next queries received on that connection will need to get the _unaltered_ values */ - dq.proxyProtocolValues = make_unique>(*state->d_proxyProtocolValues); + dq.proxyProtocolValues = make_unique>(*d_proxyProtocolValues); } if (dq.ids.qtype == QType::AXFR || dq.ids.qtype == QType::IXFR) { dq.ids.skipCache = true; } - std::shared_ptr ds; - auto result = processQuery(dq, state->d_threadData.holders, ds); + if (forwardViaUDPFirst()) { + // if there was no EDNS, we add it with a large buffer size + // so we can use UDP to talk to the backend. + auto dh = const_cast(reinterpret_cast(query.data())); + if (!dh->arcount) { + if (addEDNS(query, 4096, false, 4096, 0)) { + dq.ids.ednsAdded = true; + } + } + } - if (result == ProcessQueryResult::Drop) { - state->terminateClientConnection(); - return; + if (streamID) { + auto unit = getDOHUnit(*streamID); + dq.ids.du = std::move(unit); } - else if (result == ProcessQueryResult::Asynchronous) { + + std::shared_ptr ds; + auto result = processQuery(dq, d_threadData.holders, ds); + + if (result == ProcessQueryResult::Asynchronous) { /* we are done for now */ - ++state->d_currentQueriesCount; - return; + ++d_currentQueriesCount; + return QueryProcessingResult::Asynchronous; + } + + if (streamID) { + restoreDOHUnit(std::move(dq.ids.du)); + } + + if (result == ProcessQueryResult::Drop) { + return QueryProcessingResult::Dropped; } // the buffer might have been invalidated by now - const dnsheader* dh = dq.getHeader(); + uint16_t queryID; + { + const dnsheader* dh = dq.getHeader(); + queryID = dh->id; + } + if (result == ProcessQueryResult::SendAnswer) { TCPResponse response; - memcpy(&response.d_cleartextDH, dh, sizeof(response.d_cleartextDH)); + { + const dnsheader* dh = dq.getHeader(); + memcpy(&response.d_cleartextDH, dh, sizeof(response.d_cleartextDH)); + } response.d_idstate = std::move(ids); - response.d_idstate.origID = dh->id; + response.d_idstate.origID = queryID; response.d_idstate.selfGenerated = true; - response.d_idstate.cs = state->d_ci.cs; - response.d_buffer = std::move(state->d_buffer); + response.d_idstate.cs = d_ci.cs; + response.d_buffer = std::move(query); - state->d_state = IncomingTCPConnectionState::State::idle; - ++state->d_currentQueriesCount; - state->queueResponse(state, now, std::move(response)); - return; + d_state = IncomingTCPConnectionState::State::idle; + ++d_currentQueriesCount; + queueResponse(state, now, std::move(response)); + return QueryProcessingResult::SelfAnswered; } if (result != ProcessQueryResult::PassToBackend || ds == nullptr) { - state->terminateClientConnection(); - return; + return QueryProcessingResult::NoBackend; } - dq.ids.origID = dh->id; + dq.ids.origID = queryID; - ++state->d_currentQueriesCount; + ++d_currentQueriesCount; std::string proxyProtocolPayload; if (ds->isDoH()) { - vinfolog("Got query for %s|%s from %s (%s, %d bytes), relayed to %s", ids.qname.toLogString(), QType(ids.qtype).toString(), state->d_proxiedRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), state->d_buffer.size(), ds->getNameWithAddr()); + vinfolog("Got query for %s|%s from %s (%s, %d bytes), relayed to %s", ids.qname.toLogString(), QType(ids.qtype).toString(), d_proxiedRemote.toStringWithPort(), getProtocol().toString(), query.size(), ds->getNameWithAddr()); /* we need to do this _before_ creating the cross protocol query because after that the buffer will have been moved */ @@ -730,21 +773,30 @@ static void handleQuery(std::shared_ptr& state, cons proxyProtocolPayload = getProxyProtocolPayload(dq); } - auto cpq = std::make_unique(std::move(state->d_buffer), std::move(ids), ds, state); + auto cpq = std::make_unique(std::move(query), std::move(ids), ds, state); cpq->query.d_proxyProtocolPayload = std::move(proxyProtocolPayload); ds->passCrossProtocolQuery(std::move(cpq)); - return; + return QueryProcessingResult::Forwarded; + } + else if (!ds->isTCPOnly() && forwardViaUDPFirst()) { + auto unit = getDOHUnit(*streamID); + dq.ids.du = std::move(unit); + if (assignOutgoingUDPQueryToBackend(ds, queryID, dq, query)) { + return QueryProcessingResult::Forwarded; + } + restoreDOHUnit(std::move(dq.ids.du)); + // fallback to the normal flow } - prependSizeToTCPQuery(state->d_buffer, 0); + prependSizeToTCPQuery(query, 0); - auto downstreamConnection = state->getDownstreamConnection(ds, dq.proxyProtocolValues, now); + auto downstreamConnection = getDownstreamConnection(ds, dq.proxyProtocolValues, now); if (ds->d_config.useProxyProtocol) { /* if we ever sent a TLV over a connection, we can never go back */ - if (!state->d_proxyProtocolPayloadHasTLV) { - state->d_proxyProtocolPayloadHasTLV = dq.proxyProtocolValues && !dq.proxyProtocolValues->empty(); + if (!d_proxyProtocolPayloadHasTLV) { + d_proxyProtocolPayloadHasTLV = dq.proxyProtocolValues && !dq.proxyProtocolValues->empty(); } proxyProtocolPayload = getProxyProtocolPayload(dq); @@ -754,12 +806,13 @@ static void handleQuery(std::shared_ptr& state, cons downstreamConnection->setProxyProtocolValuesSent(std::move(dq.proxyProtocolValues)); } - TCPQuery query(std::move(state->d_buffer), std::move(ids)); - query.d_proxyProtocolPayload = std::move(proxyProtocolPayload); + TCPQuery tcpquery(std::move(query), std::move(ids)); + tcpquery.d_proxyProtocolPayload = std::move(proxyProtocolPayload); - vinfolog("Got query for %s|%s from %s (%s, %d bytes), relayed to %s", query.d_idstate.qname.toLogString(), QType(query.d_idstate.qtype).toString(), state->d_proxiedRemote.toStringWithPort(), (state->d_handler.isTLS() ? "DoT" : "TCP"), query.d_buffer.size(), ds->getNameWithAddr()); + vinfolog("Got query for %s|%s from %s (%s, %d bytes), relayed to %s", tcpquery.d_idstate.qname.toLogString(), QType(tcpquery.d_idstate.qtype).toString(), d_proxiedRemote.toStringWithPort(), getProtocol().toString(), tcpquery.d_buffer.size(), ds->getNameWithAddr()); std::shared_ptr incoming = state; - downstreamConnection->queueQuery(incoming, std::move(query)); + downstreamConnection->queueQuery(incoming, std::move(tcpquery)); + return QueryProcessingResult::Forwarded; } void IncomingTCPConnectionState::handleIOCallback(int fd, FDMultiplexer::funcparam_t& param) @@ -769,159 +822,194 @@ void IncomingTCPConnectionState::handleIOCallback(int fd, FDMultiplexer::funcpar throw std::runtime_error("Unexpected socket descriptor " + std::to_string(fd) + " received in " + std::string(__PRETTY_FUNCTION__) + ", expected " + std::to_string(conn->d_handler.getDescriptor())); } - struct timeval now; - gettimeofday(&now, nullptr); - handleIO(conn, now); + conn->handleIO(); } -void IncomingTCPConnectionState::handleIO(std::shared_ptr& state, const struct timeval& now) +void IncomingTCPConnectionState::handleHandshakeDone(const struct timeval& now) +{ + if (d_handler.isTLS()) { + if (!d_handler.hasTLSSessionBeenResumed()) { + ++d_ci.cs->tlsNewSessions; + } + else { + ++d_ci.cs->tlsResumptions; + } + if (d_handler.getResumedFromInactiveTicketKey()) { + ++d_ci.cs->tlsInactiveTicketKey; + } + if (d_handler.getUnknownTicketKey()) { + ++d_ci.cs->tlsUnknownTicketKey; + } + } + + d_handshakeDoneTime = now; +} + +IncomingTCPConnectionState::ProxyProtocolResult IncomingTCPConnectionState::handleProxyProtocolPayload() +{ + do { + DEBUGLOG("reading proxy protocol header"); + auto iostate = d_handler.tryRead(d_buffer, d_currentPos, d_proxyProtocolNeed); + if (iostate == IOState::Done) { + d_buffer.resize(d_currentPos); + ssize_t remaining = isProxyHeaderComplete(d_buffer); + if (remaining == 0) { + vinfolog("Unable to consume proxy protocol header in packet from TCP client %s", d_ci.remote.toStringWithPort()); + ++dnsdist::metrics::g_stats.proxyProtocolInvalid; + return ProxyProtocolResult::Error; + } + else if (remaining < 0) { + d_proxyProtocolNeed += -remaining; + d_buffer.resize(d_currentPos + d_proxyProtocolNeed); + /* we need to keep reading, since we might have buffered data */ + } + else { + /* proxy header received */ + std::vector proxyProtocolValues; + if (!handleProxyProtocol(d_ci.remote, true, *d_threadData.holders.acl, d_buffer, d_proxiedRemote, d_proxiedDestination, proxyProtocolValues)) { + vinfolog("Error handling the Proxy Protocol received from TCP client %s", d_ci.remote.toStringWithPort()); + return ProxyProtocolResult::Error; + } + + if (!proxyProtocolValues.empty()) { + d_proxyProtocolValues = make_unique>(std::move(proxyProtocolValues)); + } + + return ProxyProtocolResult::Done; + } + } + else { + d_lastIOBlocked = true; + } + } + while (active() && !d_lastIOBlocked); + + return ProxyProtocolResult::Reading; +} + +void IncomingTCPConnectionState::handleIO() { // why do we loop? Because the TLS layer does buffering, and thus can have data ready to read // even though the underlying socket is not ready, so we need to actually ask for the data first IOState iostate = IOState::Done; + struct timeval now; + gettimeofday(&now, nullptr); + do { iostate = IOState::Done; - IOStateGuard ioGuard(state->d_ioState); + IOStateGuard ioGuard(d_ioState); - if (state->maxConnectionDurationReached(g_maxTCPConnectionDuration, now)) { - vinfolog("Terminating TCP connection from %s because it reached the maximum TCP connection duration", state->d_ci.remote.toStringWithPort()); + if (maxConnectionDurationReached(g_maxTCPConnectionDuration, now)) { + vinfolog("Terminating TCP connection from %s because it reached the maximum TCP connection duration", d_ci.remote.toStringWithPort()); // will be handled by the ioGuard //handleNewIOState(state, IOState::Done, fd, handleIOCallback); return; } - state->d_lastIOBlocked = false; + d_lastIOBlocked = false; try { - if (state->d_state == IncomingTCPConnectionState::State::doingHandshake) { + if (d_state == IncomingTCPConnectionState::State::doingHandshake) { DEBUGLOG("doing handshake"); - iostate = state->d_handler.tryHandshake(); + iostate = d_handler.tryHandshake(); if (iostate == IOState::Done) { DEBUGLOG("handshake done"); - if (state->d_handler.isTLS()) { - if (!state->d_handler.hasTLSSessionBeenResumed()) { - ++state->d_ci.cs->tlsNewSessions; - } - else { - ++state->d_ci.cs->tlsResumptions; - } - if (state->d_handler.getResumedFromInactiveTicketKey()) { - ++state->d_ci.cs->tlsInactiveTicketKey; - } - if (state->d_handler.getUnknownTicketKey()) { - ++state->d_ci.cs->tlsUnknownTicketKey; - } - } + handleHandshakeDone(now); - state->d_handshakeDoneTime = now; - if (expectProxyProtocolFrom(state->d_ci.remote)) { - state->d_state = IncomingTCPConnectionState::State::readingProxyProtocolHeader; - state->d_buffer.resize(s_proxyProtocolMinimumHeaderSize); - state->d_proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; + if (expectProxyProtocolFrom(d_ci.remote)) { + d_state = IncomingTCPConnectionState::State::readingProxyProtocolHeader; + d_buffer.resize(s_proxyProtocolMinimumHeaderSize); + d_proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; } else { - state->d_state = IncomingTCPConnectionState::State::readingQuerySize; + d_state = IncomingTCPConnectionState::State::readingQuerySize; } } else { - state->d_lastIOBlocked = true; + d_lastIOBlocked = true; } } - if (!state->d_lastIOBlocked && state->d_state == IncomingTCPConnectionState::State::readingProxyProtocolHeader) { - do { - DEBUGLOG("reading proxy protocol header"); - iostate = state->d_handler.tryRead(state->d_buffer, state->d_currentPos, state->d_proxyProtocolNeed); - if (iostate == IOState::Done) { - state->d_buffer.resize(state->d_currentPos); - ssize_t remaining = isProxyHeaderComplete(state->d_buffer); - if (remaining == 0) { - vinfolog("Unable to consume proxy protocol header in packet from TCP client %s", state->d_ci.remote.toStringWithPort()); - ++dnsdist::metrics::g_stats.proxyProtocolInvalid; - break; - } - else if (remaining < 0) { - state->d_proxyProtocolNeed += -remaining; - state->d_buffer.resize(state->d_currentPos + state->d_proxyProtocolNeed); - /* we need to keep reading, since we might have buffered data */ - iostate = IOState::NeedRead; - } - else { - /* proxy header received */ - std::vector proxyProtocolValues; - if (!handleProxyProtocol(state->d_ci.remote, true, *state->d_threadData.holders.acl, state->d_buffer, state->d_proxiedRemote, state->d_proxiedDestination, proxyProtocolValues)) { - vinfolog("Error handling the Proxy Protocol received from TCP client %s", state->d_ci.remote.toStringWithPort()); - break; - } - - if (!proxyProtocolValues.empty()) { - state->d_proxyProtocolValues = make_unique>(std::move(proxyProtocolValues)); - } - - state->d_state = IncomingTCPConnectionState::State::readingQuerySize; - state->d_buffer.resize(sizeof(uint16_t)); - state->d_currentPos = 0; - state->d_proxyProtocolNeed = 0; - break; - } - } - else { - state->d_lastIOBlocked = true; - } + if (!d_lastIOBlocked && d_state == IncomingTCPConnectionState::State::readingProxyProtocolHeader) { + auto status = handleProxyProtocolPayload(); + if (status == ProxyProtocolResult::Done) { + d_state = IncomingTCPConnectionState::State::readingQuerySize; + d_buffer.resize(sizeof(uint16_t)); + d_currentPos = 0; + d_proxyProtocolNeed = 0; + } + else if (status == ProxyProtocolResult::Error) { + iostate = IOState::Done; + } + else { + iostate = IOState::NeedRead; } - while (state->active() && !state->d_lastIOBlocked); } - if (!state->d_lastIOBlocked && (state->d_state == IncomingTCPConnectionState::State::waitingForQuery || - state->d_state == IncomingTCPConnectionState::State::readingQuerySize)) { + if (!d_lastIOBlocked && (d_state == IncomingTCPConnectionState::State::waitingForQuery || + d_state == IncomingTCPConnectionState::State::readingQuerySize)) { DEBUGLOG("reading query size"); - state->d_buffer.resize(sizeof(uint16_t)); - iostate = state->d_handler.tryRead(state->d_buffer, state->d_currentPos, sizeof(uint16_t)); - if (state->d_currentPos > 0) { + d_buffer.resize(sizeof(uint16_t)); + iostate = d_handler.tryRead(d_buffer, d_currentPos, sizeof(uint16_t)); + if (d_currentPos > 0) { /* if we got at least one byte, we can't go around sending responses */ - state->d_state = IncomingTCPConnectionState::State::readingQuerySize; + d_state = IncomingTCPConnectionState::State::readingQuerySize; } if (iostate == IOState::Done) { DEBUGLOG("query size received"); - state->d_state = IncomingTCPConnectionState::State::readingQuery; - state->d_querySizeReadTime = now; - if (state->d_queriesCount == 0) { - state->d_firstQuerySizeReadTime = now; + d_state = IncomingTCPConnectionState::State::readingQuery; + d_querySizeReadTime = now; + if (d_queriesCount == 0) { + d_firstQuerySizeReadTime = now; } - state->d_querySize = state->d_buffer.at(0) * 256 + state->d_buffer.at(1); - if (state->d_querySize < sizeof(dnsheader)) { + d_querySize = d_buffer.at(0) * 256 + d_buffer.at(1); + if (d_querySize < sizeof(dnsheader)) { /* go away */ - state->terminateClientConnection(); + terminateClientConnection(); return; } /* allocate a bit more memory to be able to spoof the content, get an answer from the cache or to add ECS without allocating a new buffer */ - state->d_buffer.resize(std::max(state->d_querySize + static_cast(512), s_maxPacketCacheEntrySize)); - state->d_currentPos = 0; + d_buffer.resize(std::max(d_querySize + static_cast(512), s_maxPacketCacheEntrySize)); + d_currentPos = 0; } else { - state->d_lastIOBlocked = true; + d_lastIOBlocked = true; } } - if (!state->d_lastIOBlocked && state->d_state == IncomingTCPConnectionState::State::readingQuery) { + if (!d_lastIOBlocked && d_state == IncomingTCPConnectionState::State::readingQuery) { DEBUGLOG("reading query"); - iostate = state->d_handler.tryRead(state->d_buffer, state->d_currentPos, state->d_querySize); + iostate = d_handler.tryRead(d_buffer, d_currentPos, d_querySize); if (iostate == IOState::Done) { DEBUGLOG("query received"); - state->d_buffer.resize(state->d_querySize); + d_buffer.resize(d_querySize); + + d_state = IncomingTCPConnectionState::State::idle; + auto processingResult = handleQuery(std::move(d_buffer), now, std::nullopt); + switch (processingResult) { + case QueryProcessingResult::TooSmall: + /* fall-through */ + case QueryProcessingResult::InvalidHeaders: + /* fall-through */ + case QueryProcessingResult::Dropped: + /* fall-through */ + case QueryProcessingResult::NoBackend: + terminateClientConnection(); + break; + default: + break; + } - state->d_state = IncomingTCPConnectionState::State::idle; - handleQuery(state, now); /* the state might have been updated in the meantime, we don't want to override it in that case */ - if (state->active() && state->d_state != IncomingTCPConnectionState::State::idle) { - if (state->d_ioState->isWaitingForRead()) { + if (active() && d_state != IncomingTCPConnectionState::State::idle) { + if (d_ioState->isWaitingForRead()) { iostate = IOState::NeedRead; } - else if (state->d_ioState->isWaitingForWrite()) { + else if (d_ioState->isWaitingForWrite()) { iostate = IOState::NeedWrite; } else { @@ -930,55 +1018,56 @@ void IncomingTCPConnectionState::handleIO(std::shared_ptrd_lastIOBlocked = true; + d_lastIOBlocked = true; } } - if (!state->d_lastIOBlocked && state->d_state == IncomingTCPConnectionState::State::sendingResponse) { + if (!d_lastIOBlocked && d_state == IncomingTCPConnectionState::State::sendingResponse) { DEBUGLOG("sending response"); - iostate = state->d_handler.tryWrite(state->d_currentResponse.d_buffer, state->d_currentPos, state->d_currentResponse.d_buffer.size()); + iostate = d_handler.tryWrite(d_currentResponse.d_buffer, d_currentPos, d_currentResponse.d_buffer.size()); if (iostate == IOState::Done) { DEBUGLOG("response sent from "<<__PRETTY_FUNCTION__); - handleResponseSent(state, state->d_currentResponse); - state->d_state = IncomingTCPConnectionState::State::idle; + handleResponseSent(d_currentResponse); + d_state = IncomingTCPConnectionState::State::idle; } else { - state->d_lastIOBlocked = true; + d_lastIOBlocked = true; } } - if (state->active() && - !state->d_lastIOBlocked && + if (active() && + !d_lastIOBlocked && iostate == IOState::Done && - (state->d_state == IncomingTCPConnectionState::State::idle || - state->d_state == IncomingTCPConnectionState::State::waitingForQuery)) + (d_state == IncomingTCPConnectionState::State::idle || + d_state == IncomingTCPConnectionState::State::waitingForQuery)) { // try sending queued responses DEBUGLOG("send responses, if any"); + auto state = shared_from_this(); iostate = sendQueuedResponses(state, now); - if (!state->d_lastIOBlocked && state->active() && iostate == IOState::Done) { + if (!d_lastIOBlocked && active() && iostate == IOState::Done) { // if the query has been passed to a backend, or dropped, and the responses have been sent, // we can start reading again - if (state->canAcceptNewQueries(now)) { - state->resetForNewQuery(); + if (canAcceptNewQueries(now)) { + resetForNewQuery(); iostate = IOState::NeedRead; } else { - state->d_state = IncomingTCPConnectionState::State::idle; + d_state = IncomingTCPConnectionState::State::idle; iostate = IOState::Done; } } } - if (state->d_state != IncomingTCPConnectionState::State::idle && - state->d_state != IncomingTCPConnectionState::State::doingHandshake && - state->d_state != IncomingTCPConnectionState::State::readingProxyProtocolHeader && - state->d_state != IncomingTCPConnectionState::State::waitingForQuery && - state->d_state != IncomingTCPConnectionState::State::readingQuerySize && - state->d_state != IncomingTCPConnectionState::State::readingQuery && - state->d_state != IncomingTCPConnectionState::State::sendingResponse) { - vinfolog("Unexpected state %d in handleIOCallback", static_cast(state->d_state)); + if (d_state != IncomingTCPConnectionState::State::idle && + d_state != IncomingTCPConnectionState::State::doingHandshake && + d_state != IncomingTCPConnectionState::State::readingProxyProtocolHeader && + d_state != IncomingTCPConnectionState::State::waitingForQuery && + d_state != IncomingTCPConnectionState::State::readingQuerySize && + d_state != IncomingTCPConnectionState::State::readingQuery && + d_state != IncomingTCPConnectionState::State::sendingResponse) { + vinfolog("Unexpected state %d in handleIOCallback", static_cast(d_state)); } } catch (const std::exception& e) { @@ -986,55 +1075,56 @@ void IncomingTCPConnectionState::handleIO(std::shared_ptrd_state == IncomingTCPConnectionState::State::idle || - state->d_state == IncomingTCPConnectionState::State::waitingForQuery) { + if (d_state == IncomingTCPConnectionState::State::idle || + d_state == IncomingTCPConnectionState::State::waitingForQuery) { /* no need to increase any counters in that case, the client is simply done with us */ } - else if (state->d_state == IncomingTCPConnectionState::State::doingHandshake || - state->d_state != IncomingTCPConnectionState::State::readingProxyProtocolHeader || - state->d_state == IncomingTCPConnectionState::State::waitingForQuery || - state->d_state == IncomingTCPConnectionState::State::readingQuerySize || - state->d_state == IncomingTCPConnectionState::State::readingQuery) { - ++state->d_ci.cs->tcpDiedReadingQuery; + else if (d_state == IncomingTCPConnectionState::State::doingHandshake || + d_state != IncomingTCPConnectionState::State::readingProxyProtocolHeader || + d_state == IncomingTCPConnectionState::State::waitingForQuery || + d_state == IncomingTCPConnectionState::State::readingQuerySize || + d_state == IncomingTCPConnectionState::State::readingQuery) { + ++d_ci.cs->tcpDiedReadingQuery; } - else if (state->d_state == IncomingTCPConnectionState::State::sendingResponse) { + else if (d_state == IncomingTCPConnectionState::State::sendingResponse) { /* unlikely to happen here, the exception should be handled in sendResponse() */ - ++state->d_ci.cs->tcpDiedSendingResponse; + ++d_ci.cs->tcpDiedSendingResponse; } - if (state->d_ioState->isWaitingForWrite() || state->d_queriesCount == 0) { + if (d_ioState->isWaitingForWrite() || d_queriesCount == 0) { DEBUGLOG("Got an exception while handling TCP query: "<d_ioState->isWaitingForRead() ? "reading" : "writing"), state->d_ci.remote.toStringWithPort(), e.what()); + vinfolog("Got an exception while handling (%s) TCP query from %s: %s", (d_ioState->isWaitingForRead() ? "reading" : "writing"), d_ci.remote.toStringWithPort(), e.what()); } else { - vinfolog("Closing TCP client connection with %s: %s", state->d_ci.remote.toStringWithPort(), e.what()); + vinfolog("Closing TCP client connection with %s: %s", d_ci.remote.toStringWithPort(), e.what()); DEBUGLOG("Closing TCP client connection: "<terminateClientConnection(); + terminateClientConnection(); } - if (!state->active()) { + if (!active()) { DEBUGLOG("state is no longer active"); return; } + auto state = shared_from_this(); if (iostate == IOState::Done) { - state->d_ioState->update(iostate, handleIOCallback, state); + d_ioState->update(iostate, handleIOCallback, state); } else { updateIO(state, iostate, now); } ioGuard.release(); } - while ((iostate == IOState::NeedRead || iostate == IOState::NeedWrite) && !state->d_lastIOBlocked); + while ((iostate == IOState::NeedRead || iostate == IOState::NeedWrite) && !d_lastIOBlocked); } -void IncomingTCPConnectionState::notifyIOError(InternalQueryState&& query, const struct timeval& now) +void IncomingTCPConnectionState::notifyIOError(const struct timeval& now, TCPResponse&& response) { if (std::this_thread::get_id() != d_creatorThreadID) { /* empty buffer will signal an IO error */ - TCPResponse response(PacketBuffer(), std::move(query), nullptr, nullptr); + response.d_buffer.clear(); handleCrossProtocolResponse(now, std::move(response)); return; } @@ -1115,8 +1205,17 @@ static void handleIncomingTCPQuery(int pipefd, FDMultiplexer::funcparam_t& param struct timeval now; gettimeofday(&now, nullptr); - auto state = std::make_shared(std::move(*citmp), *threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + + if (citmp->cs->dohFrontend) { +#ifdef HAVE_NGHTTP2 + auto state = std::make_shared(std::move(*citmp), *threadData, now); + state->handleIO(); +#endif /* HAVE_NGHTTP2 */ + } + else { + auto state = std::make_shared(std::move(*citmp), *threadData, now); + state->handleIO(); + } } static void handleCrossProtocolQuery(int pipefd, FDMultiplexer::funcparam_t& param) @@ -1141,20 +1240,18 @@ static void handleCrossProtocolQuery(int pipefd, FDMultiplexer::funcparam_t& par std::shared_ptr tqs = cpq->getTCPQuerySender(); auto query = std::move(cpq->query); auto downstreamServer = std::move(cpq->downstream); - auto proxyProtocolPayloadSize = cpq->proxyProtocolPayloadSize; try { auto downstream = t_downstreamTCPConnectionsManager.getConnectionToDownstream(threadData->mplexer, downstreamServer, now, std::string()); - prependSizeToTCPQuery(query.d_buffer, proxyProtocolPayloadSize); - query.d_proxyProtocolPayloadAddedSize = proxyProtocolPayloadSize; + prependSizeToTCPQuery(query.d_buffer, query.d_idstate.d_proxyProtocolPayloadSize); vinfolog("Got query for %s|%s from %s (%s, %d bytes), relayed to %s", query.d_idstate.qname.toLogString(), QType(query.d_idstate.qtype).toString(), query.d_idstate.origRemote.toStringWithPort(), query.d_idstate.protocol.toString(), query.d_buffer.size(), downstreamServer->getNameWithAddr()); downstream->queueQuery(tqs, std::move(query)); } catch (...) { - tqs->notifyIOError(std::move(query.d_idstate), now); + tqs->notifyIOError(now, std::move(query)); } } @@ -1178,7 +1275,7 @@ static void handleCrossProtocolResponse(int pipefd, FDMultiplexer::funcparam_t& try { if (response.d_response.d_buffer.empty()) { - response.d_state->notifyIOError(std::move(response.d_response.d_idstate), response.d_now); + response.d_state->notifyIOError(response.d_now, std::move(response.d_response)); } else if (response.d_response.d_idstate.qtype == QType::AXFR || response.d_response.d_idstate.qtype == QType::IXFR) { response.d_state->handleXFRResponse(response.d_now, std::move(response.d_response)); @@ -1337,7 +1434,8 @@ static void acceptNewConnection(const TCPAcceptorParam& param, TCPClientThreadDa { auto& cs = param.cs; auto& acl = param.acl; - int socket = param.socket; + const bool checkACL = !cs.dohFrontend || (!cs.dohFrontend->d_trustForwardedForHeader && cs.dohFrontend->d_earlyACLDrop); + const int socket = param.socket; bool tcpClientCountIncremented = false; ComboAddress remote; remote.sin4.sin_family = param.local.sin4.sin_family; @@ -1358,7 +1456,7 @@ static void acceptNewConnection(const TCPAcceptorParam& param, TCPClientThreadDa throw std::runtime_error((boost::format("accepting new connection on socket: %s") % stringerror()).str()); } - if (!acl->match(remote)) { + if (checkACL && !acl->match(remote)) { ++dnsdist::metrics::g_stats.aclDrops; vinfolog("Dropped TCP connection from %s because of ACL", remote.toStringWithPort()); return; @@ -1395,6 +1493,7 @@ static void acceptNewConnection(const TCPAcceptorParam& param, TCPClientThreadDa vinfolog("Got TCP connection from %s", remote.toStringWithPort()); ci.remote = remote; + if (threadData == nullptr) { if (!g_tcpclientthreads->passConnectionToThread(std::make_unique(std::move(ci)))) { if (tcpClientCountIncremented) { @@ -1405,8 +1504,17 @@ static void acceptNewConnection(const TCPAcceptorParam& param, TCPClientThreadDa else { struct timeval now; gettimeofday(&now, nullptr); - auto state = std::make_shared(std::move(ci), *threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + + if (ci.cs->dohFrontend) { +#ifdef HAVE_NGHTTP2 + auto state = std::make_shared(std::move(ci), *threadData, now); + state->handleIO(); +#endif /* HAVE_NGHTTP2 */ + } + else { + auto state = std::make_shared(std::move(ci), *threadData, now); + state->handleIO(); + } } } catch (const std::exception& e) { diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index fdf2797104c1..19e477ce798f 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -1469,7 +1469,7 @@ class UDPTCPCrossQuerySender : public TCPQuerySender return handleResponse(now, std::move(response)); } - void notifyIOError(InternalQueryState&& query, const struct timeval& now) override + void notifyIOError(const struct timeval&, TCPResponse&&) override { // nothing to do } @@ -2573,18 +2573,24 @@ int main(int argc, char** argv) cout<<"gnutls"; #ifdef HAVE_LIBSSL cout<<" "; -#endif /* HAVE_LIBSSL */ +#endif #endif /* HAVE_GNUTLS */ #ifdef HAVE_LIBSSL cout<<"openssl"; -#endif /* HAVE_LIBSSL */ +#endif cout<<") "; #endif /* HAVE_DNS_OVER_TLS */ #ifdef HAVE_DNS_OVER_HTTPS cout<<"dns-over-https("; #ifdef HAVE_LIBH2OEVLOOP cout<<"h2o"; +#ifdef HAVE_NGHTTP2 + cout<<" "; +#endif #endif /* HAVE_LIBH2OEVLOOP */ +#ifdef HAVE_NGHTTP2 + cout<<"nghttp2"; +#endif cout<<") "; #endif /* HAVE_DNS_OVER_HTTPS */ #ifdef HAVE_DNSCRYPT @@ -2608,9 +2614,6 @@ int main(int argc, char** argv) #ifdef HAVE_LMDB cout<<"lmdb "; #endif -#ifdef HAVE_NGHTTP2 - cout<<"outgoing-dns-over-https(nghttp2) "; -#endif #ifndef DISABLE_PROTOBUF cout<<"protobuf "; #endif @@ -2914,8 +2917,8 @@ int main(int argc, char** argv) std::vector tcpStates; std::vector udpStates; - for(auto& cs : g_frontends) { - if (cs->dohFrontend != nullptr) { + for (auto& cs : g_frontends) { + if (cs->dohFrontend != nullptr && cs->dohFrontend->d_library == "h2o") { #ifdef HAVE_DNS_OVER_HTTPS #ifdef HAVE_LIBH2OEVLOOP std::thread t1(dohThread, cs.get()); diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 99d7cdbe6475..e4f30eaa83ab 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -80,6 +80,10 @@ if HAVE_LIBSSL AM_CPPFLAGS += $(LIBSSL_CFLAGS) endif +if HAVE_GNUTLS +AM_CPPFLAGS += $(GNUTLS_CFLAGS) +endif + if HAVE_LIBH2OEVLOOP AM_CPPFLAGS += $(LIBH2OEVLOOP_CFLAGS) endif @@ -178,6 +182,7 @@ dnsdist_SOURCES = \ dnsdist-lua.cc dnsdist-lua.hh \ dnsdist-mac-address.cc dnsdist-mac-address.hh \ dnsdist-metrics.cc dnsdist-metrics.hh \ + dnsdist-nghttp2-in.cc dnsdist-nghttp2-in.hh \ dnsdist-nghttp2.cc dnsdist-nghttp2.hh \ dnsdist-prometheus.hh \ dnsdist-protobuf.cc dnsdist-protobuf.hh \ @@ -274,6 +279,7 @@ testrunner_SOURCES = \ dnsdist-lua-vars.cc \ dnsdist-mac-address.cc dnsdist-mac-address.hh \ dnsdist-metrics.cc dnsdist-metrics.hh \ + dnsdist-nghttp2-in.cc dnsdist-nghttp2-in.hh \ dnsdist-nghttp2.cc dnsdist-nghttp2.hh \ dnsdist-protocols.cc dnsdist-protocols.hh \ dnsdist-proxy-protocol.cc dnsdist-proxy-protocol.hh \ @@ -411,6 +417,10 @@ endif if HAVE_DNS_OVER_HTTPS +if HAVE_GNUTLS +dnsdist_LDADD += -lgnutls +endif + if HAVE_LIBH2OEVLOOP dnsdist_LDADD += $(LIBH2OEVLOOP_LIBS) endif diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index 5805bbdfe8f3..af9f8c422a15 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -71,6 +71,7 @@ AM_CONDITIONAL([HAVE_GNUTLS], [false]) AM_CONDITIONAL([HAVE_LIBH2OEVLOOP], [false]) AM_CONDITIONAL([HAVE_LIBSSL], [false]) AM_CONDITIONAL([HAVE_LMDB], [false]) +AM_CONDITIONAL([HAVE_NGHTTP2], [false]) PDNS_CHECK_LIBCRYPTO @@ -81,30 +82,28 @@ DNSDIST_ENABLE_DNS_OVER_HTTPS AS_IF([test "x$enable_dns_over_tls" != "xno" -o "x$enable_dns_over_https" != "xno"], [ PDNS_WITH_LIBSSL + PDNS_WITH_GNUTLS ]) AS_IF([test "x$enable_dns_over_tls" != "xno"], [ - PDNS_WITH_GNUTLS - AS_IF([test "x$HAVE_GNUTLS" != "x1" -a "x$HAVE_LIBSSL" != "x1"], [ AC_MSG_ERROR([DNS over TLS support requested but neither GnuTLS nor OpenSSL are available]) ]) ]) AS_IF([test "x$enable_dns_over_https" != "xno"], [ + PDNS_WITH_NGHTTP2 PDNS_WITH_LIBH2OEVLOOP - AS_IF([test "x$HAVE_LIBH2OEVLOOP" != "x1"], [ - AC_MSG_ERROR([DNS over HTTPS support requested but libh2o-evloop was not found]) + AS_IF([test "x$HAVE_LIBH2OEVLOOP" != "x1" -a "x$HAVE_NGHTTP2" != "x1" ], [ + AC_MSG_ERROR([DNS over HTTPS support requested but neither libh2o-evloop nor nghttp2 was not found]) ]) - AS_IF([test "x$HAVE_LIBSSL" != "x1"], [ - AC_MSG_ERROR([DNS over HTTPS support requested but OpenSSL was not found]) + AS_IF([test "x$HAVE_GNUTLS" != "x1" -a "x$HAVE_LIBSSL" != "x1"], [ + AC_MSG_ERROR([DNS over HTTPS support requested but neither GnuTLS nor OpenSSL are available]) ]) ]) -PDNS_WITH_NGHTTP2 - DNSDIST_WITH_CDB PDNS_CHECK_LMDB PDNS_ENABLE_IPCIPHER diff --git a/pdns/dnsdistdist/dnsdist-async.cc b/pdns/dnsdistdist/dnsdist-async.cc index f54b1c0b1446..9cb96d83a226 100644 --- a/pdns/dnsdistdist/dnsdist-async.cc +++ b/pdns/dnsdistdist/dnsdist-async.cc @@ -137,7 +137,8 @@ void AsynchronousHolder::mainThread(std::shared_ptr data) vinfolog("Asynchronous query %d has expired at %d.%d, notifying the sender", queryID, now.tv_sec, now.tv_usec); auto sender = query->getTCPQuerySender(); if (sender) { - sender->notifyIOError(std::move(query->query.d_idstate), now); + TCPResponse tresponse(std::move(query->query)); + sender->notifyIOError(now, std::move(tresponse)); } } else { diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index 66f421479e71..67b65796d429 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -168,7 +168,7 @@ class HealthCheckQuerySender : public TCPQuerySender throw std::runtime_error("Unexpected XFR reponse to a health check query"); } - void notifyIOError(InternalQueryState&& query, const struct timeval& now) override + void notifyIOError(const struct timeval& now, TCPResponse&&) override { ++d_data->d_ds->d_healthCheckMetrics.d_networkErrors; d_data->d_ds->submitHealthCheckResult(d_data->d_initial, false); diff --git a/pdns/dnsdistdist/dnsdist-internal-queries.cc b/pdns/dnsdistdist/dnsdist-internal-queries.cc index 49f95e42b4b4..ea4c54139709 100644 --- a/pdns/dnsdistdist/dnsdist-internal-queries.cc +++ b/pdns/dnsdistdist/dnsdist-internal-queries.cc @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "dnsdist-internal-queries.hh" +#include "dnsdist-nghttp2-in.hh" #include "dnsdist-tcp.hh" #include "doh.hh" @@ -35,7 +36,12 @@ std::unique_ptr getInternalQueryFromDQ(DNSQuestion& dq, bool } #ifdef HAVE_DNS_OVER_HTTPS else if (protocol == dnsdist::Protocol::DoH) { - return getDoHCrossProtocolQueryFromDQ(dq, isResponse); +#ifdef HAVE_LIBH2OEVLOOP + if (dq.ids.cs->dohFrontend->d_library == "h2o") { + return getDoHCrossProtocolQueryFromDQ(dq, isResponse); + } +#endif /* HAVE_LIBH2OEVLOOP */ + return getTCPCrossProtocolQueryFromDQ(dq); } #endif else { diff --git a/pdns/dnsdistdist/dnsdist-lua-ffi.cc b/pdns/dnsdistdist/dnsdist-lua-ffi.cc index 20c866931a84..48ce507da8e7 100644 --- a/pdns/dnsdistdist/dnsdist-lua-ffi.cc +++ b/pdns/dnsdistdist/dnsdist-lua-ffi.cc @@ -929,7 +929,8 @@ bool dnsdist_ffi_drop_from_async(uint16_t asyncID, uint16_t queryID) struct timeval now; gettimeofday(&now, nullptr); - sender->notifyIOError(std::move(query->query.d_idstate), now); + TCPResponse tresponse(std::move(query->query)); + sender->notifyIOError(now, std::move(tresponse)); return true; } diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc new file mode 100644 index 000000000000..aefa50d777a5 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -0,0 +1,1214 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "base64.hh" +#include "dnsdist-nghttp2-in.hh" +#include "dnsdist-proxy-protocol.hh" +#include "dnsparser.hh" + +#ifdef HAVE_NGHTTP2 + +#if 0 +class IncomingDoHCrossProtocolContext : public CrossProtocolContext +{ +public: + IncomingDoHCrossProtocolContext(IncomingHTTP2Connection::PendingQuery&& query, std::shared_ptr connection, IncomingHTTP2Connection::StreamID streamID): CrossProtocolContext(std::move(query.d_buffer)), d_connection(connection), d_query(std::move(query)) + { + } + + std::optional getHTTPPath() const override + { + return d_query.d_path; + } + + std::optional getHTTPScheme() const override + { + return d_query.d_scheme; + } + + std::optional getHTTPHost() const override + { + return d_query.d_host; + } + + std::optional getHTTPQueryString() const override + { + return d_query.d_queryString; + } + + std::optional getHTTPHeaders() const override + { + if (!d_query.d_headers) { + return std::nullopt; + } + return *d_query.d_headers; + } + + void handleResponse(PacketBuffer&& response, InternalQueryState&& state) override + { + auto conn = d_connection.lock(); + if (!conn) { + /* the connection has been closed in the meantime */ + return; + } + } + + void handleTimeout() override + { + auto conn = d_connection.lock(); + if (!conn) { + /* the connection has been closed in the meantime */ + return; + } + } + + ~IncomingDoHCrossProtocolContext() override + { + } + +private: + std::weak_ptr d_connection; + IncomingHTTP2Connection::PendingQuery d_query; + IncomingHTTP2Connection::StreamID d_streamID{-1}; +}; +#endif + +class IncomingDoHCrossProtocolContext : public DOHUnitInterface +{ +public: + IncomingDoHCrossProtocolContext(IncomingHTTP2Connection::PendingQuery&& query, std::shared_ptr connection, IncomingHTTP2Connection::StreamID streamID) : + d_connection(connection), d_query(std::move(query)), d_streamID(streamID) + { + } + + std::string getHTTPPath() const override + { + return d_query.d_path; + } + + const std::string& getHTTPScheme() const override + { + return d_query.d_scheme; + } + + const std::string& getHTTPHost() const override + { + return d_query.d_host; + } + + std::string getHTTPQueryString() const override + { + return d_query.d_queryString; + } + + const HeadersMap& getHTTPHeaders() const override + { + if (!d_query.d_headers) { + static const HeadersMap empty{}; + return empty; + } + return *d_query.d_headers; + } + + void setHTTPResponse(uint16_t statusCode, PacketBuffer&& body, const std::string& contentType = "") override + { + d_query.d_statusCode = statusCode; + d_query.d_response = std::move(body); + d_query.d_contentTypeOut = contentType; + } + + void handleUDPResponse(PacketBuffer&& response, InternalQueryState&& state, const std::shared_ptr& ds) override + { + std::unique_ptr unit(this); + auto conn = d_connection.lock(); + if (!conn) { + /* the connection has been closed in the meantime */ + return; + } + + state.du = std::move(unit); + TCPResponse resp(std::move(response), std::move(state), nullptr, nullptr); + resp.d_ds = ds; + struct timeval now; + gettimeofday(&now, nullptr); + conn->handleResponse(now, std::move(resp)); + } + + void handleTimeout() override + { + std::unique_ptr unit(this); + auto conn = d_connection.lock(); + if (!conn) { + /* the connection has been closed in the meantime */ + return; + } + struct timeval now; + gettimeofday(&now, nullptr); + TCPResponse resp; + resp.d_idstate.d_streamID = d_streamID; + conn->notifyIOError(now, std::move(resp)); + } + + ~IncomingDoHCrossProtocolContext() override + { + } + + std::weak_ptr d_connection; + IncomingHTTP2Connection::PendingQuery d_query; + IncomingHTTP2Connection::StreamID d_streamID{-1}; +}; + +void IncomingHTTP2Connection::handleResponse(const struct timeval& now, TCPResponse&& response) +{ + if (std::this_thread::get_id() != d_creatorThreadID) { + handleCrossProtocolResponse(now, std::move(response)); + return; + } + + auto& state = response.d_idstate; + if (state.forwardedOverUDP) { + dnsheader* responseDH = reinterpret_cast(response.d_buffer.data()); + + if (responseDH->tc && state.d_packet && state.d_packet->size() > state.d_proxyProtocolPayloadSize && state.d_packet->size() - state.d_proxyProtocolPayloadSize > sizeof(dnsheader)) { + auto& query = *state.d_packet; + dnsheader* queryDH = reinterpret_cast(query.data() + state.d_proxyProtocolPayloadSize); + /* restoring the original ID */ + queryDH->id = state.origID; + + state.forwardedOverUDP = false; + auto cpq = getCrossProtocolQuery(std::move(query), std::move(state), response.d_ds); + cpq->query.d_proxyProtocolPayloadAdded = state.d_proxyProtocolPayloadSize > 0; + if (g_tcpclientthreads && g_tcpclientthreads->passCrossProtocolQueryToThread(std::move(cpq))) { + return; + } + else { + vinfolog("Unable to pass DoH query to a TCP worker thread after getting a TC response over UDP"); + notifyIOError(now, std::move(response)); + return; + } + } + } + + IncomingTCPConnectionState::handleResponse(now, std::move(response)); +} + +std::unique_ptr IncomingHTTP2Connection::getDOHUnit(uint32_t streamID) +{ + auto query = std::move(d_currentStreams.at(streamID)); + return std::make_unique(std::move(query), std::dynamic_pointer_cast(shared_from_this()), streamID); +} + +void IncomingHTTP2Connection::restoreDOHUnit(std::unique_ptr&& unit) +{ + auto context = std::unique_ptr(dynamic_cast(unit.release())); + d_currentStreams.at(context->d_streamID) = std::move(context->d_query); +} + +void IncomingHTTP2Connection::restoreContext(uint32_t streamID, IncomingHTTP2Connection::PendingQuery&& context) +{ + d_currentStreams.at(streamID) = std::move(context); +} + +IncomingHTTP2Connection::IncomingHTTP2Connection(ConnectionInfo&& ci, TCPClientThreadData& threadData, const struct timeval& now) : + IncomingTCPConnectionState(std::move(ci), threadData, now) +{ + nghttp2_session_callbacks* cbs = nullptr; + if (nghttp2_session_callbacks_new(&cbs) != 0) { + throw std::runtime_error("Unable to create a callback object for a new incoming HTTP/2 session"); + } + std::unique_ptr callbacks(cbs, nghttp2_session_callbacks_del); + cbs = nullptr; + + nghttp2_session_callbacks_set_send_callback(callbacks.get(), send_callback); + nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks.get(), on_frame_recv_callback); + nghttp2_session_callbacks_set_on_stream_close_callback(callbacks.get(), on_stream_close_callback); + nghttp2_session_callbacks_set_on_begin_headers_callback(callbacks.get(), on_begin_headers_callback); + nghttp2_session_callbacks_set_on_header_callback(callbacks.get(), on_header_callback); + nghttp2_session_callbacks_set_on_data_chunk_recv_callback(callbacks.get(), on_data_chunk_recv_callback); + nghttp2_session_callbacks_set_error_callback2(callbacks.get(), on_error_callback); + + nghttp2_session* sess = nullptr; + if (nghttp2_session_server_new(&sess, callbacks.get(), this) != 0) { + throw std::runtime_error("Coult not allocate a new incoming HTTP/2 session"); + } + + d_session = std::unique_ptr(sess, nghttp2_session_del); + sess = nullptr; +} + +bool IncomingHTTP2Connection::checkALPN() +{ + constexpr std::array h2{'h', '2'}; + auto protocols = d_handler.getNextProtocol(); + if (protocols.size() == h2.size() && memcmp(protocols.data(), h2.data(), h2.size()) == 0) { + return true; + } + vinfolog("DoH connection from %s expected ALPN value 'h2', got '%s'", d_ci.remote.toStringWithPort(), std::string(protocols.begin(), protocols.end())); + return false; +} + +void IncomingHTTP2Connection::handleConnectionReady() +{ + constexpr std::array iv{{{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100U}}}; + auto ret = nghttp2_submit_settings(d_session.get(), NGHTTP2_FLAG_NONE, iv.data(), iv.size()); + if (ret != 0) { + throw std::runtime_error("Fatal error: " + std::string(nghttp2_strerror(ret))); + } + ret = nghttp2_session_send(d_session.get()); + if (ret != 0) { + throw std::runtime_error("Fatal error: " + std::string(nghttp2_strerror(ret))); + } +} + +void IncomingHTTP2Connection::handleIO() +{ + IOState iostate = IOState::Done; + struct timeval now; + gettimeofday(&now, nullptr); + + try { + if (maxConnectionDurationReached(g_maxTCPConnectionDuration, now)) { + vinfolog("Terminating DoH connection from %s because it reached the maximum TCP connection duration", d_ci.remote.toStringWithPort()); + stopIO(); + d_connectionDied = true; + return; + } + + if (d_state == State::doingHandshake) { + iostate = d_handler.tryHandshake(); + if (iostate == IOState::Done) { + handleHandshakeDone(now); + if (d_handler.isTLS()) { + if (!checkALPN()) { + d_connectionDied = true; + stopIO(); + return; + } + } + + if (expectProxyProtocolFrom(d_ci.remote)) { + d_state = IncomingTCPConnectionState::State::readingProxyProtocolHeader; + d_buffer.resize(s_proxyProtocolMinimumHeaderSize); + d_proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; + } + else { + d_state = State::waitingForQuery; + handleConnectionReady(); + } + } + } + + if (d_state == IncomingTCPConnectionState::State::readingProxyProtocolHeader) { + auto status = handleProxyProtocolPayload(); + if (status == ProxyProtocolResult::Done) { + d_currentPos = 0; + d_proxyProtocolNeed = 0; + d_buffer.clear(); + d_state = State::waitingForQuery; + handleConnectionReady(); + } + else if (status == ProxyProtocolResult::Error) { + d_connectionDied = true; + stopIO(); + return; + } + } + + if (d_state == State::waitingForQuery) { + readHTTPData(); + } + + if (!d_connectionDied) { + auto shared = std::dynamic_pointer_cast(shared_from_this()); + if (nghttp2_session_want_read(d_session.get())) { + d_ioState->add(IOState::NeedRead, &handleReadableIOCallback, shared, boost::none); + } + if (nghttp2_session_want_write(d_session.get())) { + d_ioState->add(IOState::NeedWrite, &handleWritableIOCallback, shared, boost::none); + } + } + } + catch (const std::exception& e) { + vinfolog("Exception when processing IO for incoming DoH connection from %s: %s", d_ci.remote.toStringWithPort(), e.what()); + d_connectionDied = true; + stopIO(); + } +} + +ssize_t IncomingHTTP2Connection::send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data) +{ + IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + bool bufferWasEmpty = conn->d_out.empty(); + conn->d_out.insert(conn->d_out.end(), data, data + length); + + if (bufferWasEmpty) { + try { + auto state = conn->d_handler.tryWrite(conn->d_out, conn->d_outPos, conn->d_out.size()); + if (state == IOState::Done) { + conn->d_out.clear(); + conn->d_outPos = 0; + if (!conn->isIdle()) { + conn->updateIO(IOState::NeedRead, handleReadableIOCallback); + } + else { + conn->watchForRemoteHostClosingConnection(); + } + } + else { + conn->updateIO(state, handleWritableIOCallback); + } + } + catch (const std::exception& e) { + vinfolog("Exception while trying to write (send) to incoming HTTP connection: %s", e.what()); + conn->handleIOError(); + } + } + + return length; +} + +static const std::unordered_map s_constants{ + {"200-value", "200"}, + {"method-name", ":method"}, + {"method-value", "POST"}, + {"scheme-name", ":scheme"}, + {"scheme-value", "https"}, + {"authority-name", ":authority"}, + {"x-forwarded-for-name", "x-forwarded-for"}, + {"path-name", ":path"}, + {"content-length-name", "content-length"}, + {"status-name", ":status"}, + {"location-name", "location"}, + {"accept-name", "accept"}, + {"accept-value", "application/dns-message"}, + {"cache-control-name", "cache-control"}, + {"content-type-name", "content-type"}, + {"content-type-value", "application/dns-message"}, + {"user-agent-name", "user-agent"}, + {"user-agent-value", "nghttp2-" NGHTTP2_VERSION "/dnsdist"}, + {"x-forwarded-port-name", "x-forwarded-port"}, + {"x-forwarded-proto-name", "x-forwarded-proto"}, + {"x-forwarded-proto-value-dns-over-udp", "dns-over-udp"}, + {"x-forwarded-proto-value-dns-over-tcp", "dns-over-tcp"}, + {"x-forwarded-proto-value-dns-over-tls", "dns-over-tls"}, + {"x-forwarded-proto-value-dns-over-http", "dns-over-http"}, + {"x-forwarded-proto-value-dns-over-https", "dns-over-https"}, +}; + +static const std::string s_authorityHeaderName(":authority"); +static const std::string s_pathHeaderName(":path"); +static const std::string s_methodHeaderName(":method"); +static const std::string s_schemeHeaderName(":scheme"); +static const std::string s_xForwardedForHeaderName("x-forwarded-for"); + +void NGHTTP2Headers::addStaticHeader(std::vector& headers, const std::string& nameKey, const std::string& valueKey) +{ + const auto& name = s_constants.at(nameKey); + const auto& value = s_constants.at(valueKey); + + headers.push_back({const_cast(reinterpret_cast(name.c_str())), const_cast(reinterpret_cast(value.c_str())), name.size(), value.size(), NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE}); +} + +void NGHTTP2Headers::addCustomDynamicHeader(std::vector& headers, const std::string& name, const std::string_view& value) +{ + headers.push_back({const_cast(reinterpret_cast(name.data())), const_cast(reinterpret_cast(value.data())), name.size(), value.size(), NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE}); +} + +void NGHTTP2Headers::addDynamicHeader(std::vector& headers, const std::string& nameKey, const std::string_view& value) +{ + const auto& name = s_constants.at(nameKey); + NGHTTP2Headers::addCustomDynamicHeader(headers, name, value); +} + +IOState IncomingHTTP2Connection::sendResponse(const struct timeval& now, TCPResponse&& response) +{ + assert(response.d_idstate.d_streamID != -1); + auto& context = d_currentStreams.at(response.d_idstate.d_streamID); + + uint32_t statusCode = 200U; + std::string contentType; + bool sendContentType = true; + auto& responseBuffer = context.d_buffer; + if (context.d_statusCode != 0) { + responseBuffer = std::move(context.d_response); + statusCode = context.d_statusCode; + contentType = std::move(context.d_contentTypeOut); + } + else { + responseBuffer = std::move(response.d_buffer); + } + + sendResponse(response.d_idstate.d_streamID, statusCode, d_ci.cs->dohFrontend->d_customResponseHeaders, contentType, sendContentType); + handleResponseSent(response); + + return IOState::Done; +} + +void IncomingHTTP2Connection::notifyIOError(const struct timeval& now, TCPResponse&& response) +{ + if (std::this_thread::get_id() != d_creatorThreadID) { + /* empty buffer will signal an IO error */ + response.d_buffer.clear(); + handleCrossProtocolResponse(now, std::move(response)); + return; + } + + assert(response.d_idstate.d_streamID != -1); + d_currentStreams.at(response.d_idstate.d_streamID).d_buffer = std::move(response.d_buffer); + sendResponse(response.d_idstate.d_streamID, 502, d_ci.cs->dohFrontend->d_customResponseHeaders); +} + +bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID streamID, uint16_t responseCode, const HeadersMap& customResponseHeaders, const std::string& contentType, bool addContentType) +{ + /* if data_prd is not NULL, it provides data which will be sent in subsequent DATA frames. In this case, a method that allows request message bodies (https://tools.ietf.org/html/rfc7231#section-4) must be specified with :method key (e.g. POST). This function does not take ownership of the data_prd. The function copies the members of the data_prd. If data_prd is NULL, HEADERS have END_STREAM set. + */ + nghttp2_data_provider data_provider; + + data_provider.source.ptr = this; + data_provider.read_callback = [](nghttp2_session*, IncomingHTTP2Connection::StreamID stream_id, uint8_t* buf, size_t length, uint32_t* data_flags, nghttp2_data_source* source, void* cb_data) -> ssize_t { + auto connection = reinterpret_cast(cb_data); + auto& obj = connection->d_currentStreams.at(stream_id); + size_t toCopy = 0; + if (obj.d_queryPos < obj.d_buffer.size()) { + size_t remaining = obj.d_buffer.size() - obj.d_queryPos; + toCopy = length > remaining ? remaining : length; + memcpy(buf, &obj.d_buffer.at(obj.d_queryPos), toCopy); + obj.d_queryPos += toCopy; + } + + if (obj.d_queryPos >= obj.d_buffer.size()) { + *data_flags |= NGHTTP2_DATA_FLAG_EOF; + } + return toCopy; + }; + + const auto& df = d_ci.cs->dohFrontend; + auto& responseBody = d_currentStreams.at(streamID).d_buffer; + + std::vector headers; + std::string responseCodeStr; + std::string cacheControlValue; + std::string location; + /* remember that dynamic header values should be kept alive + until we have called nghttp2_submit_response(), at least */ + + if (responseCode == 200) { + NGHTTP2Headers::addStaticHeader(headers, "status-name", "200-value"); + ++df->d_validresponses; + ++df->d_http2Stats.d_nb200Responses; + + if (addContentType) { + if (contentType.empty()) { + NGHTTP2Headers::addStaticHeader(headers, "content-type-name", "content-type-value"); + } + else { + NGHTTP2Headers::addDynamicHeader(headers, "content-type-name", contentType); + } + } + + if (df->d_sendCacheControlHeaders && responseBody.size() > sizeof(dnsheader)) { + uint32_t minTTL = getDNSPacketMinTTL(reinterpret_cast(responseBody.data()), responseBody.size()); + if (minTTL != std::numeric_limits::max()) { + cacheControlValue = "max-age=" + std::to_string(minTTL); + NGHTTP2Headers::addDynamicHeader(headers, "cache-control-name", cacheControlValue); + } + } + } + else { + responseCodeStr = std::to_string(responseCode); + NGHTTP2Headers::addDynamicHeader(headers, "status-name", responseCodeStr); + + if (responseCode >= 300 && responseCode < 400) { + location = std::string(reinterpret_cast(responseBody.data()), responseBody.size()); + NGHTTP2Headers::addDynamicHeader(headers, "content-type-name", "text/html; charset=utf-8"); + NGHTTP2Headers::addDynamicHeader(headers, "location-name", location); + static const std::string s_redirectStart{"Moved

      The document has moved here"}; + responseBody.reserve(s_redirectStart.size() + responseBody.size() + s_redirectEnd.size()); + responseBody.insert(responseBody.begin(), s_redirectStart.begin(), s_redirectStart.end()); + responseBody.insert(responseBody.end(), s_redirectEnd.begin(), s_redirectEnd.end()); + ++df->d_redirectresponses; + } + else { + ++df->d_errorresponses; + switch (responseCode) { + case 400: + ++df->d_http2Stats.d_nb400Responses; + break; + case 403: + ++df->d_http2Stats.d_nb403Responses; + break; + case 500: + ++df->d_http2Stats.d_nb500Responses; + break; + case 502: + ++df->d_http2Stats.d_nb502Responses; + break; + default: + ++df->d_http2Stats.d_nbOtherResponses; + break; + } + + if (!responseBody.empty()) { + NGHTTP2Headers::addDynamicHeader(headers, "content-type-name", "text/plain; charset=utf-8"); + } + else { + static const std::string invalid{"invalid DNS query"}; + static const std::string notAllowed{"dns query not allowed"}; + static const std::string noDownstream{"no downstream server available"}; + static const std::string internalServerError{"Internal Server Error"}; + + switch (responseCode) { + case 400: + responseBody.insert(responseBody.begin(), invalid.begin(), invalid.end()); + break; + case 403: + responseBody.insert(responseBody.begin(), notAllowed.begin(), notAllowed.end()); + break; + case 502: + responseBody.insert(responseBody.begin(), noDownstream.begin(), noDownstream.end()); + break; + case 500: + /* fall-through */ + default: + responseBody.insert(responseBody.begin(), internalServerError.begin(), internalServerError.end()); + break; + } + } + } + } + + const std::string contentLength = std::to_string(responseBody.size()); + NGHTTP2Headers::addDynamicHeader(headers, "content-length-name", contentLength); + + for (const auto& [key, value] : customResponseHeaders) { + NGHTTP2Headers::addCustomDynamicHeader(headers, key, value); + } + + auto ret = nghttp2_submit_response(d_session.get(), streamID, headers.data(), headers.size(), &data_provider); + if (ret != 0) { + d_currentStreams.erase(streamID); + vinfolog("Error submitting HTTP response for stream %d: %s", streamID, nghttp2_strerror(ret)); + return false; + } + + ret = nghttp2_session_send(d_session.get()); + if (ret != 0) { + d_currentStreams.erase(streamID); + vinfolog("Error flushing HTTP response for stream %d: %s", streamID, nghttp2_strerror(ret)); + return false; + } + + return true; +} + +static void processForwardedForHeader(const std::unique_ptr& headers, ComboAddress& remote) +{ + if (!headers) { + return; + } + + auto it = headers->find(s_xForwardedForHeaderName); + if (it == headers->end()) { + return; + } + + std::string_view value = it->second; + try { + auto pos = value.rfind(','); + if (pos != std::string_view::npos) { + ++pos; + for (; pos < value.size() && value[pos] == ' '; ++pos) { + } + + if (pos < value.size()) { + value = value.substr(pos); + } + } + auto newRemote = ComboAddress(std::string(value)); + remote = newRemote; + } + catch (const std::exception& e) { + vinfolog("Invalid X-Forwarded-For header ('%s') received from %s : %s", std::string(value), remote.toStringWithPort(), e.what()); + } + catch (const PDNSException& e) { + vinfolog("Invalid X-Forwarded-For header ('%s') received from %s : %s", std::string(value), remote.toStringWithPort(), e.reason); + } +} + +static std::optional getPayloadFromPath(const std::string_view& path) +{ + std::optional result{std::nullopt}; + + if (path.size() <= 5) { + return result; + } + + auto pos = path.find("?dns="); + if (pos == string::npos) { + pos = path.find("&dns="); + } + + if (pos == string::npos) { + return result; + } + + // need to base64url decode this + string sdns(path.substr(pos + 5)); + boost::replace_all(sdns, "-", "+"); + boost::replace_all(sdns, "_", "/"); + + // re-add padding that may have been missing + switch (sdns.size() % 4) { + case 2: + sdns.append(2, '='); + break; + case 3: + sdns.append(1, '='); + break; + } + + PacketBuffer decoded; + /* rough estimate so we hopefully don't need a new allocation later */ + /* We reserve at few additional bytes to be able to add EDNS later */ + const size_t estimate = ((sdns.size() * 3) / 4); + decoded.reserve(estimate); + if (B64Decode(sdns, decoded) < 0) { + return result; + } + + result = std::move(decoded); + return result; +} + +void IncomingHTTP2Connection::handleIncomingQuery(IncomingHTTP2Connection::PendingQuery&& query, IncomingHTTP2Connection::StreamID streamID) +{ + const auto handleImmediateResponse = [this, &query, streamID](uint16_t code, const std::string& reason, PacketBuffer&& response = PacketBuffer()) { + if (response.empty()) { + query.d_buffer.clear(); + query.d_buffer.insert(query.d_buffer.begin(), reason.begin(), reason.end()); + } + else { + query.d_buffer = std::move(response); + } + vinfolog("Sending an immediate %d response to incoming DoH query: %s", code, reason); + sendResponse(streamID, code, d_ci.cs->dohFrontend->d_customResponseHeaders); + }; + + ++d_ci.cs->dohFrontend->d_http2Stats.d_nbQueries; + + if (d_ci.cs->dohFrontend->d_trustForwardedForHeader) { + processForwardedForHeader(query.d_headers, d_proxiedRemote); + + /* second ACL lookup based on the updated address */ + auto& holders = d_threadData.holders; + if (!holders.acl->match(d_proxiedRemote)) { + ++dnsdist::metrics::g_stats.aclDrops; + vinfolog("Query from %s (%s) (DoH) dropped because of ACL", d_ci.remote.toStringWithPort(), d_proxiedRemote.toStringWithPort()); + handleImmediateResponse(403, "DoH query not allowed because of ACL"); + return; + } + + if (!d_ci.cs->dohFrontend->d_keepIncomingHeaders) { + query.d_headers.reset(); + } + } + + if (d_ci.cs->dohFrontend->d_exactPathMatching) { + if (d_ci.cs->dohFrontend->d_urls.count(query.d_path) == 0) { + handleImmediateResponse(404, "there is no endpoint configured for this path"); + return; + } + } + else { + bool found = false; + for (const auto& path : d_ci.cs->dohFrontend->d_urls) { + if (boost::starts_with(query.d_path, path)) { + found = true; + break; + } + } + if (!found) { + handleImmediateResponse(404, "there is no endpoint configured for this path"); + return; + } + } + + /* the responses map can be updated at runtime, so we need to take a copy of + the shared pointer, increasing the reference counter */ + auto responsesMap = d_ci.cs->dohFrontend->d_responsesMap; + if (responsesMap) { + for (const auto& entry : *responsesMap) { + if (entry->matches(query.d_path)) { + const auto& customHeaders = entry->getHeaders(); + query.d_buffer = entry->getContent(); + if (entry->getStatusCode() >= 400 && query.d_buffer.size() >= 1) { + // legacy trailing 0 from the h2o era + query.d_buffer.pop_back(); + } + + sendResponse(streamID, entry->getStatusCode(), customHeaders ? *customHeaders : d_ci.cs->dohFrontend->d_customResponseHeaders, std::string(), false); + return; + } + } + } + + if (query.d_buffer.empty() && query.d_method == PendingQuery::Method::Get && !query.d_queryString.empty()) { + auto payload = getPayloadFromPath(query.d_queryString); + if (payload) { + query.d_buffer = std::move(*payload); + } + else { + ++d_ci.cs->dohFrontend->d_badrequests; + handleImmediateResponse(400, "DoH unable to decode BASE64-URL"); + return; + } + } + + if (query.d_method == PendingQuery::Method::Get) { + ++d_ci.cs->dohFrontend->d_getqueries; + } + else if (query.d_method == PendingQuery::Method::Post) { + ++d_ci.cs->dohFrontend->d_postqueries; + } + + try { + struct timeval now; + gettimeofday(&now, nullptr); + auto processingResult = handleQuery(std::move(query.d_buffer), now, streamID); + + switch (processingResult) { + case QueryProcessingResult::TooSmall: + handleImmediateResponse(400, "DoH non-compliant query"); + break; + case QueryProcessingResult::InvalidHeaders: + handleImmediateResponse(400, "DoH invalid headers"); + break; + case QueryProcessingResult::Empty: + handleImmediateResponse(200, "DoH empty query", std::move(query.d_buffer)); + break; + case QueryProcessingResult::Dropped: + handleImmediateResponse(403, "DoH dropped query"); + break; + case QueryProcessingResult::NoBackend: + handleImmediateResponse(502, "DoH no backend available"); + return; + case QueryProcessingResult::Forwarded: + case QueryProcessingResult::Asynchronous: + case QueryProcessingResult::SelfAnswered: + break; + } + } + catch (const std::exception& e) { + vinfolog("Exception while processing DoH query: %s", e.what()); + handleImmediateResponse(400, "DoH non-compliant query"); + return; + } +} + +int IncomingHTTP2Connection::on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data) +{ + IncomingHTTP2Connection* conn = reinterpret_cast(user_data); +#if 0 + switch (frame->hd.type) { + case NGHTTP2_HEADERS: + cerr<<"got headers"<headers.cat == NGHTTP2_HCAT_RESPONSE) { + cerr<<"All headers received"<headers.cat == NGHTTP2_HCAT_REQUEST) { + cerr<<"All headers received - query"<settings.niv<settings.niv; idx++) { + cerr<<"- "<settings.iv[idx].settings_id<<" "<settings.iv[idx].value<hd.type == NGHTTP2_GOAWAY) { + conn->stopIO(); + if (conn->isIdle()) { + if (nghttp2_session_want_write(conn->d_session.get())) { + conn->d_ioState->add(IOState::NeedWrite, &handleWritableIOCallback, conn, boost::none); + } + } + } + + /* is this the last frame for this stream? */ + else if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { + auto streamID = frame->hd.stream_id; + auto stream = conn->d_currentStreams.find(streamID); + if (stream != conn->d_currentStreams.end()) { + conn->handleIncomingQuery(std::move(stream->second), streamID); + + if (conn->isIdle()) { + conn->watchForRemoteHostClosingConnection(); + } + } + else { + vinfolog("Stream %d NOT FOUND", streamID); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + } + + return 0; +} + +int IncomingHTTP2Connection::on_stream_close_callback(nghttp2_session* session, IncomingHTTP2Connection::StreamID stream_id, uint32_t error_code, void* user_data) +{ + IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + + if (error_code == 0) { + return 0; + } + + auto stream = conn->d_currentStreams.find(stream_id); + if (stream == conn->d_currentStreams.end()) { + /* we don't care, then */ + return 0; + } + + struct timeval now; + gettimeofday(&now, nullptr); + auto request = std::move(stream->second); + conn->d_currentStreams.erase(stream->first); + + if (conn->isIdle()) { + conn->watchForRemoteHostClosingConnection(); + } + + return 0; +} + +int IncomingHTTP2Connection::on_begin_headers_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data) +{ + if (frame->hd.type != NGHTTP2_HEADERS || frame->headers.cat != NGHTTP2_HCAT_REQUEST) { + return 0; + } + + IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + auto insertPair = conn->d_currentStreams.insert({frame->hd.stream_id, PendingQuery()}); + if (!insertPair.second) { + /* there is a stream ID collision, something is very wrong! */ + vinfolog("Stream ID collision (%d) on connection from %d", frame->hd.stream_id, conn->d_ci.remote.toStringWithPort()); + conn->d_connectionDied = true; + nghttp2_session_terminate_session(conn->d_session.get(), NGHTTP2_NO_ERROR); + auto ret = nghttp2_session_send(conn->d_session.get()); + if (ret != 0) { + vinfolog("Error flushing HTTP response for stream %d from %s: %s", frame->hd.stream_id, conn->d_ci.remote.toStringWithPort(), nghttp2_strerror(ret)); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + + return 0; + } + + return 0; +} + +static std::string::size_type getLengthOfPathWithoutParameters(const std::string_view& path) +{ + auto pos = path.find("?"); + if (pos == string::npos) { + return path.size(); + } + + return pos; +} + +int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const nghttp2_frame* frame, const uint8_t* name, size_t nameLen, const uint8_t* value, size_t valuelen, uint8_t flags, void* user_data) +{ + IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + + if (frame->hd.type == NGHTTP2_HEADERS && frame->headers.cat == NGHTTP2_HCAT_REQUEST) { + if (nghttp2_check_header_name(name, nameLen) == 0) { + vinfolog("Invalid header name"); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + +#if HAVE_NGHTTP2_CHECK_HEADER_VALUE_RFC9113 + if (nghttp2_check_header_value_rfc9113(value, valuelen) == 0) { + vinfolog("Invalid header value"); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } +#endif /* HAVE_NGHTTP2_CHECK_HEADER_VALUE_RFC9113 */ + + auto headerMatches = [name, nameLen](const std::string& expected) -> bool { + return nameLen == expected.size() && memcmp(name, expected.data(), expected.size()) == 0; + }; + + auto stream = conn->d_currentStreams.find(frame->hd.stream_id); + if (stream == conn->d_currentStreams.end()) { + vinfolog("Unable to match the stream ID %d to a known one!", frame->hd.stream_id); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + auto& query = stream->second; + auto valueView = std::string_view(reinterpret_cast(value), valuelen); + if (headerMatches(s_pathHeaderName)) { +#if HAVE_NGHTTP2_CHECK_PATH + if (nghttp2_check_path(value, valuelen) == 0) { + vinfolog("Invalid path value"); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } +#endif /* HAVE_NGHTTP2_CHECK_PATH */ + + auto pathLen = getLengthOfPathWithoutParameters(valueView); + query.d_path = valueView.substr(0, pathLen); + if (pathLen < valueView.size()) { + query.d_queryString = valueView.substr(pathLen); + } + } + else if (headerMatches(s_authorityHeaderName)) { + query.d_host = valueView; + } + else if (headerMatches(s_schemeHeaderName)) { + query.d_scheme = valueView; + } + else if (headerMatches(s_methodHeaderName)) { +#if HAVE_NGHTTP2_CHECK_METHOD + if (nghttp2_check_method(value, valuelen) == 0) { + vinfolog("Invalid method value"); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } +#endif /* HAVE_NGHTTP2_CHECK_METHOD */ + + if (valueView == "GET") { + query.d_method = PendingQuery::Method::Get; + } + else if (valueView == "POST") { + query.d_method = PendingQuery::Method::Post; + } + else { + vinfolog("Unsupported method value"); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + } + + if (conn->d_ci.cs->dohFrontend->d_keepIncomingHeaders || (conn->d_ci.cs->dohFrontend->d_trustForwardedForHeader && headerMatches(s_xForwardedForHeaderName))) { + if (!query.d_headers) { + query.d_headers = std::make_unique(); + } + query.d_headers->insert({std::string(reinterpret_cast(name), nameLen), std::string(valueView)}); + } + } + return 0; +} + +int IncomingHTTP2Connection::on_data_chunk_recv_callback(nghttp2_session* session, uint8_t flags, IncomingHTTP2Connection::StreamID stream_id, const uint8_t* data, size_t len, void* user_data) +{ + IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + auto stream = conn->d_currentStreams.find(stream_id); + if (stream == conn->d_currentStreams.end()) { + vinfolog("Unable to match the stream ID %d to a known one!", stream_id); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + if (len > std::numeric_limits::max() || (std::numeric_limits::max() - stream->second.d_buffer.size()) < len) { + vinfolog("Data frame of size %d is too large for a DNS query (we already have %d)", len, stream->second.d_buffer.size()); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + + stream->second.d_buffer.insert(stream->second.d_buffer.end(), data, data + len); + + return 0; +} + +int IncomingHTTP2Connection::on_error_callback(nghttp2_session* session, int lib_error_code, const char* msg, size_t len, void* user_data) +{ + IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + + vinfolog("Error in HTTP/2 connection from %d: %s", conn->d_ci.remote.toStringWithPort(), std::string(msg, len)); + conn->d_connectionDied = true; + nghttp2_session_terminate_session(conn->d_session.get(), NGHTTP2_NO_ERROR); + auto ret = nghttp2_session_send(conn->d_session.get()); + if (ret != 0) { + vinfolog("Error flushing HTTP response on connection from %s: %s", conn->d_ci.remote.toStringWithPort(), nghttp2_strerror(ret)); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + + return 0; +} + +void IncomingHTTP2Connection::readHTTPData() +{ + IOStateGuard ioGuard(d_ioState); + do { + size_t got = 0; + d_in.resize(d_in.size() + 512); + try { + IOState newState = d_handler.tryRead(d_in, got, d_in.size(), true); + d_in.resize(got); + + if (got > 0) { + /* we got something */ + auto readlen = nghttp2_session_mem_recv(d_session.get(), d_in.data(), d_in.size()); + /* as long as we don't require a pause by returning nghttp2_error.NGHTTP2_ERR_PAUSE from a CB, + all data should be consumed before returning */ + if (readlen < 0 || static_cast(readlen) < d_in.size()) { + throw std::runtime_error("Fatal error while passing received data to nghttp2: " + std::string(nghttp2_strerror((int)readlen))); + } + + nghttp2_session_send(d_session.get()); + } + + if (newState == IOState::Done) { + if (isIdle()) { + watchForRemoteHostClosingConnection(); + ioGuard.release(); + break; + } + } + else { + if (newState == IOState::NeedWrite) { + updateIO(IOState::NeedWrite, handleReadableIOCallback); + } + ioGuard.release(); + break; + } + } + catch (const std::exception& e) { + vinfolog("Exception while trying to read from HTTP backend connection: %s", e.what()); + handleIOError(); + break; + } + } while (getConcurrentStreamsCount() > 0); +} + +void IncomingHTTP2Connection::handleReadableIOCallback(int fd, FDMultiplexer::funcparam_t& param) +{ + auto conn = boost::any_cast>(param); + conn->handleIO(); +} + +void IncomingHTTP2Connection::handleWritableIOCallback(int fd, FDMultiplexer::funcparam_t& param) +{ + auto conn = boost::any_cast>(param); + IOStateGuard ioGuard(conn->d_ioState); + + try { + IOState newState = conn->d_handler.tryWrite(conn->d_out, conn->d_outPos, conn->d_out.size()); + if (newState == IOState::NeedRead) { + conn->updateIO(IOState::NeedRead, handleWritableIOCallback); + } + else if (newState == IOState::Done) { + conn->d_out.clear(); + conn->d_outPos = 0; + if (!conn->isIdle()) { + conn->updateIO(IOState::NeedRead, handleReadableIOCallback); + } + else { + conn->watchForRemoteHostClosingConnection(); + } + } + ioGuard.release(); + } + catch (const std::exception& e) { + vinfolog("Exception while trying to write (ready) to HTTP backend connection: %s", e.what()); + conn->handleIOError(); + } +} + +bool IncomingHTTP2Connection::isIdle() const +{ + return getConcurrentStreamsCount() == 0; +} + +void IncomingHTTP2Connection::stopIO() +{ + d_ioState->reset(); +} + +uint32_t IncomingHTTP2Connection::getConcurrentStreamsCount() const +{ + return d_currentStreams.size(); +} + +boost::optional IncomingHTTP2Connection::getIdleClientReadTTD(struct timeval now) const +{ + auto idleTimeout = d_ci.cs->dohFrontend->d_idleTimeout; + if (g_maxTCPConnectionDuration == 0 && idleTimeout == 0) { + return boost::none; + } + + if (g_maxTCPConnectionDuration > 0) { + auto elapsed = now.tv_sec - d_connectionStartTime.tv_sec; + if (elapsed < 0 || (static_cast(elapsed) >= g_maxTCPConnectionDuration)) { + return now; + } + auto remaining = g_maxTCPConnectionDuration - elapsed; + if (idleTimeout == 0 || remaining <= static_cast(idleTimeout)) { + now.tv_sec += remaining; + return now; + } + } + + now.tv_sec += idleTimeout; + return now; +} + +void IncomingHTTP2Connection::updateIO(IOState newState, FDMultiplexer::callbackfunc_t callback) +{ + boost::optional ttd{boost::none}; + + auto shared = std::dynamic_pointer_cast(shared_from_this()); + if (shared) { + struct timeval now; + gettimeofday(&now, nullptr); + + if (newState == IOState::NeedRead) { + if (isIdle()) { + ttd = getIdleClientReadTTD(now); + } + else { + ttd = getClientReadTTD(now); + } + d_ioState->update(newState, callback, shared, ttd); + } + else if (newState == IOState::NeedWrite) { + ttd = getClientWriteTTD(now); + d_ioState->update(newState, callback, shared, ttd); + } + } +} + +void IncomingHTTP2Connection::watchForRemoteHostClosingConnection() +{ + updateIO(IOState::NeedRead, handleReadableIOCallback); +} + +void IncomingHTTP2Connection::handleIOError() +{ + d_connectionDied = true; + nghttp2_session_terminate_session(d_session.get(), NGHTTP2_PROTOCOL_ERROR); + d_currentStreams.clear(); + stopIO(); +} +#endif /* HAVE_NGHTTP2 */ diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh new file mode 100644 index 000000000000..3ee1c96d10a6 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -0,0 +1,114 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +#include "config.h" +#ifdef HAVE_NGHTTP2 +#include + +#include "dnsdist-tcp-upstream.hh" + +class IncomingHTTP2Connection : public IncomingTCPConnectionState +{ +public: + using StreamID = int32_t; + + class PendingQuery + { + public: + enum class Method : uint8_t + { + Unknown, + Get, + Post + }; + + PacketBuffer d_buffer; + PacketBuffer d_response; + std::string d_path; + std::string d_scheme; + std::string d_host; + std::string d_queryString; + std::string d_sni; + std::string d_contentTypeOut; + std::unique_ptr d_headers; + size_t d_queryPos{0}; + uint32_t d_statusCode{0}; + Method d_method{Method::Unknown}; + }; + + IncomingHTTP2Connection(ConnectionInfo&& ci, TCPClientThreadData& threadData, const struct timeval& now); + ~IncomingHTTP2Connection() = default; + void handleIO() override; + void handleResponse(const struct timeval& now, TCPResponse&& response) override; + void notifyIOError(const struct timeval& now, TCPResponse&& response) override; + void restoreContext(uint32_t streamID, PendingQuery&& context); + +private: + static ssize_t send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data); + static int on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data); + static int on_data_chunk_recv_callback(nghttp2_session* session, uint8_t flags, StreamID stream_id, const uint8_t* data, size_t len, void* user_data); + static int on_stream_close_callback(nghttp2_session* session, StreamID stream_id, uint32_t error_code, void* user_data); + static int on_header_callback(nghttp2_session* session, const nghttp2_frame* frame, const uint8_t* name, size_t namelen, const uint8_t* value, size_t valuelen, uint8_t flags, void* user_data); + static int on_begin_headers_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data); + static int on_error_callback(nghttp2_session* session, int lib_error_code, const char* msg, size_t len, void* user_data); + static void handleReadableIOCallback(int fd, FDMultiplexer::funcparam_t& param); + static void handleWritableIOCallback(int fd, FDMultiplexer::funcparam_t& param); + + IOState sendResponse(const struct timeval& now, TCPResponse&& response) override; + bool forwardViaUDPFirst() const override + { + return true; + } + void restoreDOHUnit(std::unique_ptr&&) override; + std::unique_ptr getDOHUnit(uint32_t streamID) override; + + void stopIO(); + bool isIdle() const; + uint32_t getConcurrentStreamsCount() const; + void updateIO(IOState newState, FDMultiplexer::callbackfunc_t callback); + void watchForRemoteHostClosingConnection(); + void handleIOError(); + bool sendResponse(StreamID streamID, uint16_t responseCode, const HeadersMap& customResponseHeaders, const std::string& contentType = "", bool addContentType = true); + void handleIncomingQuery(PendingQuery&& query, StreamID streamID); + bool checkALPN(); + void readHTTPData(); + void handleConnectionReady(); + boost::optional getIdleClientReadTTD(struct timeval now) const; + + std::unique_ptr d_session{nullptr, nghttp2_session_del}; + std::unordered_map d_currentStreams; + PacketBuffer d_out; + PacketBuffer d_in; + size_t d_outPos{0}; + bool d_connectionDied{false}; +}; + +class NGHTTP2Headers +{ +public: + static void addStaticHeader(std::vector& headers, const std::string& nameKey, const std::string& valueKey); + static void addDynamicHeader(std::vector& headers, const std::string& nameKey, const std::string_view& value); + static void addCustomDynamicHeader(std::vector& headers, const std::string& name, const std::string_view& value); +}; + +#endif /* HAVE_NGHTTP2 */ diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 39e60009e05d..692b73275771 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -27,6 +27,7 @@ #endif /* HAVE_NGHTTP2 */ #include "dnsdist-nghttp2.hh" +#include "dnsdist-nghttp2-in.hh" #include "dnsdist-tcp.hh" #include "dnsdist-tcp-downstream.hh" #include "dnsdist-downstream-connection.hh" @@ -153,7 +154,11 @@ void DoHConnectionToBackend::handleResponse(PendingRequest&& request) } } - request.d_sender->handleResponse(now, TCPResponse(std::move(request.d_buffer), std::move(request.d_query.d_idstate), shared_from_this(), d_ds)); + TCPResponse response(std::move(request.d_query)); + response.d_buffer = std::move(request.d_buffer); + response.d_connection = shared_from_this(); + response.d_ds = d_ds; + request.d_sender->handleResponse(now, std::move(response)); } catch (const std::exception& e) { vinfolog("Got exception while handling response for cross-protocol DoH: %s", e.what()); @@ -167,7 +172,8 @@ void DoHConnectionToBackend::handleResponseError(PendingRequest&& request, const d_ds->reportTimeoutOrError(); } - request.d_sender->notifyIOError(std::move(request.d_query.d_idstate), now); + TCPResponse response(PacketBuffer(), std::move(request.d_query.d_idstate), nullptr, nullptr); + request.d_sender->notifyIOError(now, std::move(response)); } catch (const std::exception& e) { vinfolog("Got exception while handling response for cross-protocol DoH: %s", e.what()); @@ -230,45 +236,6 @@ bool DoHConnectionToBackend::isIdle() const return getConcurrentStreamsCount() == 0; } -const std::unordered_map DoHConnectionToBackend::s_constants = { - {"method-name", ":method"}, - {"method-value", "POST"}, - {"scheme-name", ":scheme"}, - {"scheme-value", "https"}, - {"accept-name", "accept"}, - {"accept-value", "application/dns-message"}, - {"content-type-name", "content-type"}, - {"content-type-value", "application/dns-message"}, - {"user-agent-name", "user-agent"}, - {"user-agent-value", "nghttp2-" NGHTTP2_VERSION "/dnsdist"}, - {"authority-name", ":authority"}, - {"path-name", ":path"}, - {"content-length-name", "content-length"}, - {"x-forwarded-for-name", "x-forwarded-for"}, - {"x-forwarded-port-name", "x-forwarded-port"}, - {"x-forwarded-proto-name", "x-forwarded-proto"}, - {"x-forwarded-proto-value-dns-over-udp", "dns-over-udp"}, - {"x-forwarded-proto-value-dns-over-tcp", "dns-over-tcp"}, - {"x-forwarded-proto-value-dns-over-tls", "dns-over-tls"}, - {"x-forwarded-proto-value-dns-over-http", "dns-over-http"}, - {"x-forwarded-proto-value-dns-over-https", "dns-over-https"}, -}; - -void DoHConnectionToBackend::addStaticHeader(std::vector& headers, const std::string& nameKey, const std::string& valueKey) -{ - const auto& name = s_constants.at(nameKey); - const auto& value = s_constants.at(valueKey); - - headers.push_back({const_cast(reinterpret_cast(name.c_str())), const_cast(reinterpret_cast(value.c_str())), name.size(), value.size(), NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE}); -} - -void DoHConnectionToBackend::addDynamicHeader(std::vector& headers, const std::string& nameKey, const std::string& value) -{ - const auto& name = s_constants.at(nameKey); - - headers.push_back({const_cast(reinterpret_cast(name.c_str())), const_cast(reinterpret_cast(value.c_str())), name.size(), value.size(), NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE}); -} - void DoHConnectionToBackend::queueQuery(std::shared_ptr& sender, TCPQuery&& query) { auto payloadSize = std::to_string(query.d_buffer.size()); @@ -284,37 +251,37 @@ void DoHConnectionToBackend::queueQuery(std::shared_ptr& sender, headers.reserve(8 + (addXForwarded ? 3 : 0)); /* Pseudo-headers need to come first (rfc7540 8.1.2.1) */ - addStaticHeader(headers, "method-name", "method-value"); - addStaticHeader(headers, "scheme-name", "scheme-value"); - addDynamicHeader(headers, "authority-name", d_ds->d_config.d_tlsSubjectName); - addDynamicHeader(headers, "path-name", d_ds->d_config.d_dohPath); - addStaticHeader(headers, "accept-name", "accept-value"); - addStaticHeader(headers, "content-type-name", "content-type-value"); - addStaticHeader(headers, "user-agent-name", "user-agent-value"); - addDynamicHeader(headers, "content-length-name", payloadSize); + NGHTTP2Headers::addStaticHeader(headers, "method-name", "method-value"); + NGHTTP2Headers::addStaticHeader(headers, "scheme-name", "scheme-value"); + NGHTTP2Headers::addDynamicHeader(headers, "authority-name", d_ds->d_config.d_tlsSubjectName); + NGHTTP2Headers::addDynamicHeader(headers, "path-name", d_ds->d_config.d_dohPath); + NGHTTP2Headers::addStaticHeader(headers, "accept-name", "accept-value"); + NGHTTP2Headers::addStaticHeader(headers, "content-type-name", "content-type-value"); + NGHTTP2Headers::addStaticHeader(headers, "user-agent-name", "user-agent-value"); + NGHTTP2Headers::addDynamicHeader(headers, "content-length-name", payloadSize); /* no need to add these headers for health-check queries */ if (addXForwarded && query.d_idstate.origRemote.getPort() != 0) { remote = query.d_idstate.origRemote.toString(); remotePort = std::to_string(query.d_idstate.origRemote.getPort()); - addDynamicHeader(headers, "x-forwarded-for-name", remote); - addDynamicHeader(headers, "x-forwarded-port-name", remotePort); + NGHTTP2Headers::addDynamicHeader(headers, "x-forwarded-for-name", remote); + NGHTTP2Headers::addDynamicHeader(headers, "x-forwarded-port-name", remotePort); if (query.d_idstate.cs != nullptr) { if (query.d_idstate.cs->isUDP()) { - addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-udp"); + NGHTTP2Headers::addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-udp"); } else if (query.d_idstate.cs->isDoH()) { if (query.d_idstate.cs->hasTLS()) { - addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-https"); + NGHTTP2Headers::addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-https"); } else { - addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-http"); + NGHTTP2Headers::addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-http"); } } else if (query.d_idstate.cs->hasTLS()) { - addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-tls"); + NGHTTP2Headers::addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-tls"); } else { - addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-tcp"); + NGHTTP2Headers::addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-tcp"); } } } @@ -920,7 +887,8 @@ static void handleCrossProtocolQuery(int pipefd, FDMultiplexer::funcparam_t& par downstream->queueQuery(tqs, std::move(query)); } catch (...) { - tqs->notifyIOError(std::move(query.d_idstate), now); + TCPResponse response(std::move(query)); + tqs->notifyIOError(now, std::move(response)); } } diff --git a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc index 6c6fcf222902..43de71fc58f7 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc +++ b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc @@ -173,7 +173,7 @@ static uint32_t getSerialFromRawSOAContent(const std::vector& raw) static bool getSerialFromIXFRQuery(TCPQuery& query) { try { - size_t proxyPayloadSize = query.d_proxyProtocolPayloadAdded ? query.d_proxyProtocolPayloadAddedSize : 0; + size_t proxyPayloadSize = query.d_proxyProtocolPayloadAdded ? query.d_idstate.d_proxyProtocolPayloadSize : 0; if (query.d_buffer.size() <= (proxyPayloadSize + sizeof(uint16_t))) { return false; } @@ -232,24 +232,24 @@ static void prepareQueryForSending(TCPQuery& query, uint16_t id, QueryState quer if (query.d_proxyProtocolPayload.size() > 0 && !query.d_proxyProtocolPayloadAdded) { query.d_buffer.insert(query.d_buffer.begin(), query.d_proxyProtocolPayload.begin(), query.d_proxyProtocolPayload.end()); query.d_proxyProtocolPayloadAdded = true; - query.d_proxyProtocolPayloadAddedSize = query.d_proxyProtocolPayload.size(); + query.d_idstate.d_proxyProtocolPayloadSize = query.d_proxyProtocolPayload.size(); } } else if (connectionState == ConnectionState::proxySent) { if (query.d_proxyProtocolPayloadAdded) { - if (query.d_buffer.size() < query.d_proxyProtocolPayloadAddedSize) { + if (query.d_buffer.size() < query.d_idstate.d_proxyProtocolPayloadSize) { throw std::runtime_error("Trying to remove a proxy protocol payload of size " + std::to_string(query.d_proxyProtocolPayload.size()) + " from a buffer of size " + std::to_string(query.d_buffer.size())); } - query.d_buffer.erase(query.d_buffer.begin(), query.d_buffer.begin() + query.d_proxyProtocolPayloadAddedSize); + query.d_buffer.erase(query.d_buffer.begin(), query.d_buffer.begin() + query.d_idstate.d_proxyProtocolPayloadSize); query.d_proxyProtocolPayloadAdded = false; - query.d_proxyProtocolPayloadAddedSize = 0; + query.d_idstate.d_proxyProtocolPayloadSize = 0; } } if (query.d_idstate.qclass == QClass::IN && query.d_idstate.qtype == QType::IXFR) { getSerialFromIXFRQuery(query); } - editPayloadID(query.d_buffer, id, query.d_proxyProtocolPayloadAdded ? query.d_proxyProtocolPayloadAddedSize : 0, true); + editPayloadID(query.d_buffer, id, query.d_proxyProtocolPayloadAdded ? query.d_idstate.d_proxyProtocolPayloadSize : 0, true); } IOState TCPConnectionToBackend::queueNextQuery(std::shared_ptr& conn) @@ -433,7 +433,8 @@ void TCPConnectionToBackend::handleIO(std::shared_ptr& c /* this one can't be restarted, sorry */ DEBUGLOG("A XFR for which a response has already been sent cannot be restarted"); try { - pending.second.d_sender->notifyIOError(std::move(pending.second.d_query.d_idstate), now); + TCPResponse response(std::move(pending.second.d_query)); + pending.second.d_sender->notifyIOError(now, std::move(response)); } catch (const std::exception& e) { vinfolog("Got an exception while notifying: %s", e.what()); @@ -608,7 +609,8 @@ void TCPConnectionToBackend::notifyAllQueriesFailed(const struct timeval& now, F increaseCounters(d_currentQuery.d_query.d_idstate.cs); auto sender = d_currentQuery.d_sender; if (sender->active()) { - sender->notifyIOError(std::move(d_currentQuery.d_query.d_idstate), now); + TCPResponse response(std::move(d_currentQuery.d_query)); + sender->notifyIOError(now, std::move(response)); } } @@ -616,7 +618,8 @@ void TCPConnectionToBackend::notifyAllQueriesFailed(const struct timeval& now, F increaseCounters(query.d_query.d_idstate.cs); auto sender = query.d_sender; if (sender->active()) { - sender->notifyIOError(std::move(query.d_query.d_idstate), now); + TCPResponse response(std::move(query.d_query)); + sender->notifyIOError(now, std::move(response)); } } @@ -624,7 +627,8 @@ void TCPConnectionToBackend::notifyAllQueriesFailed(const struct timeval& now, F increaseCounters(response.second.d_query.d_idstate.cs); auto sender = response.second.d_sender; if (sender->active()) { - sender->notifyIOError(std::move(response.second.d_query.d_idstate), now); + TCPResponse tresp(std::move(response.second.d_query)); + sender->notifyIOError(now, std::move(tresp)); } } } @@ -726,7 +730,8 @@ IOState TCPConnectionToBackend::handleResponse(std::shared_ptractive()) { DEBUGLOG("passing response to client connection for "<handleResponse(now, TCPResponse(std::move(d_responseBuffer), std::move(ids), conn, conn->d_ds)); + TCPResponse response(std::move(d_responseBuffer), std::move(ids), conn, conn->d_ds); + sender->handleResponse(now, std::move(response)); } if (!d_pendingQueries.empty()) { diff --git a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh index b668c2f9eb7c..4318892659f6 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh +++ b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh @@ -2,6 +2,7 @@ #include "dolog.hh" #include "dnsdist-tcp.hh" +#include "dnsdist-tcp-downstream.hh" struct TCPCrossProtocolResponse; @@ -26,7 +27,10 @@ public: class IncomingTCPConnectionState : public TCPQuerySender, public std::enable_shared_from_this { public: - IncomingTCPConnectionState(ConnectionInfo&& ci, TCPClientThreadData& threadData, const struct timeval& now): d_buffer(s_maxPacketCacheEntrySize), d_ci(std::move(ci)), d_handler(d_ci.fd, timeval{g_tcpRecvTimeout,0}, d_ci.cs->tlsFrontend ? d_ci.cs->tlsFrontend->getContext() : nullptr, now.tv_sec), d_connectionStartTime(now), d_ioState(make_unique(*threadData.mplexer, d_ci.fd)), d_threadData(threadData), d_creatorThreadID(std::this_thread::get_id()) + enum class QueryProcessingResult : uint8_t { Forwarded, TooSmall, InvalidHeaders, Empty, Dropped, SelfAnswered, NoBackend, Asynchronous }; + enum class ProxyProtocolResult : uint8_t { Reading, Done, Error }; + + IncomingTCPConnectionState(ConnectionInfo&& ci, TCPClientThreadData& threadData, const struct timeval& now): d_buffer(s_maxPacketCacheEntrySize), d_ci(std::move(ci)), d_handler(d_ci.fd, timeval{g_tcpRecvTimeout,0}, d_ci.cs->tlsFrontend ? d_ci.cs->tlsFrontend->getContext() : (d_ci.cs->dohFrontend ? d_ci.cs->dohFrontend->d_tlsContext.getContext() : nullptr), now.tv_sec), d_connectionStartTime(now), d_ioState(make_unique(*threadData.mplexer, d_ci.fd)), d_threadData(threadData), d_creatorThreadID(std::this_thread::get_id()) { d_origDest.reset(); d_origDest.sin4.sin_family = d_ci.remote.sin4.sin_family; @@ -46,7 +50,7 @@ public: IncomingTCPConnectionState(const IncomingTCPConnectionState& rhs) = delete; IncomingTCPConnectionState& operator=(const IncomingTCPConnectionState& rhs) = delete; - ~IncomingTCPConnectionState(); + virtual ~IncomingTCPConnectionState(); void resetForNewQuery(); @@ -118,24 +122,27 @@ public: static size_t clearAllDownstreamConnections(); - static void handleIO(std::shared_ptr& conn, const struct timeval& now); static void handleIOCallback(int fd, FDMultiplexer::funcparam_t& param); static void handleAsyncReady(int fd, FDMultiplexer::funcparam_t& param); static void updateIO(std::shared_ptr& state, IOState newState, const struct timeval& now); - static IOState sendResponse(std::shared_ptr& state, const struct timeval& now, TCPResponse&& response); static void queueResponse(std::shared_ptr& state, const struct timeval& now, TCPResponse&& response); -static void handleTimeout(std::shared_ptr& state, bool write); + static void handleTimeout(std::shared_ptr& state, bool write); + + virtual void handleIO(); - /* we take a copy of a shared pointer, not a reference, because the initial shared pointer might be released during the handling of the response */ - void handleResponse(const struct timeval& now, TCPResponse&& response) override; + QueryProcessingResult handleQuery(PacketBuffer&& query, const struct timeval& now, std::optional streamID); + virtual void handleResponse(const struct timeval& now, TCPResponse&& response) override; + virtual void notifyIOError(const struct timeval& now, TCPResponse&& response) override; void handleXFRResponse(const struct timeval& now, TCPResponse&& response) override; - void notifyIOError(InternalQueryState&& query, const struct timeval& now) override; + virtual IOState sendResponse(const struct timeval& now, TCPResponse&& response); + void handleResponseSent(TCPResponse& currentResponse); + void handleHandshakeDone(const struct timeval& now); + ProxyProtocolResult handleProxyProtocolPayload(); void handleCrossProtocolResponse(const struct timeval& now, TCPResponse&& response); void terminateClientConnection(); - void queueQuery(TCPQuery&& query); bool canAcceptNewQueries(const struct timeval& now); @@ -143,6 +150,20 @@ static void handleTimeout(std::shared_ptr& state, bo { return d_ioState != nullptr; } + virtual bool forwardViaUDPFirst() const + { + return false; + } + virtual std::unique_ptr getDOHUnit(uint32_t streamID) + { + throw std::runtime_error("Getting a DOHUnit state from a generic TCP/DoT connection is not supported"); + } + virtual void restoreDOHUnit(std::unique_ptr&&) + { + throw std::runtime_error("Restoring a DOHUnit state to a generic TCP/DoT connection is not supported"); + } + + std::unique_ptr getCrossProtocolQuery(PacketBuffer&& query, InternalQueryState&& state, const std::shared_ptr& ds); std::string toString() const { @@ -151,6 +172,8 @@ static void handleTimeout(std::shared_ptr& state, bo return o.str(); } + dnsdist::Protocol getProtocol() const; + enum class State : uint8_t { doingHandshake, readingProxyProtocolHeader, waitingForQuery, readingQuerySize, readingQuery, sendingResponse, idle /* in case of XFR, we stop processing queries */ }; TCPResponse d_currentResponse; diff --git a/pdns/dnsdistdist/dnsdist-tcp.hh b/pdns/dnsdistdist/dnsdist-tcp.hh index d5f2edb0d1e8..aef6cf6ec38a 100644 --- a/pdns/dnsdistdist/dnsdist-tcp.hh +++ b/pdns/dnsdistdist/dnsdist-tcp.hh @@ -21,6 +21,7 @@ */ #pragma once +#include #include #include "channel.hh" #include "iputils.hh" @@ -100,7 +101,6 @@ public: InternalQueryState d_idstate; std::string d_proxyProtocolPayload; PacketBuffer d_buffer; - uint32_t d_proxyProtocolPayloadAddedSize{0}; uint32_t d_ixfrQuerySerial{0}; uint32_t d_xfrMasterSerial{0}; uint32_t d_xfrSerialCount{0}; @@ -133,6 +133,17 @@ struct TCPResponse : public TCPQuery } } + TCPResponse(TCPQuery&& query) : + TCPQuery(std::move(query)) + { + if (d_buffer.size() >= sizeof(dnsheader)) { + memcpy(&d_cleartextDH, reinterpret_cast(d_buffer.data()), sizeof(d_cleartextDH)); + } + else { + memset(&d_cleartextDH, 0, sizeof(d_cleartextDH)); + } + } + bool isAsync() const { return d_async; @@ -154,7 +165,7 @@ public: virtual bool active() const = 0; virtual void handleResponse(const struct timeval& now, TCPResponse&& response) = 0; virtual void handleXFRResponse(const struct timeval& now, TCPResponse&& response) = 0; - virtual void notifyIOError(InternalQueryState&& query, const struct timeval& now) = 0; + virtual void notifyIOError(const struct timeval& now, TCPResponse&& response) = 0; /* whether the connection should be automatically released to the pool after handleResponse() has been called */ @@ -199,7 +210,6 @@ struct CrossProtocolQuery InternalQuery query; std::shared_ptr downstream{nullptr}; - size_t proxyProtocolPayloadSize{0}; bool d_isResponse{false}; }; diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 91dcd9ad7674..a2747400f47b 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -534,8 +534,9 @@ class DoHTCPCrossQuerySender : public TCPQuerySender return handleResponse(now, std::move(response)); } - void notifyIOError(InternalQueryState&& query, const struct timeval& now) override + void notifyIOError(const struct timeval& now, TCPResponse&& response) override { + auto& query = response.d_idstate; if (!query.du) { return; } @@ -1041,7 +1042,7 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) if (!holders.acl->match(remote)) { ++dnsdist::metrics::g_stats.aclDrops; vinfolog("Query from %s (DoH) dropped because of ACL", remote.toStringWithPort()); - h2o_send_error_403(req, "Forbidden", "dns query not allowed because of ACL", 0); + h2o_send_error_403(req, "Forbidden", "DoH query not allowed because of ACL", 0); return 0; } @@ -1344,6 +1345,13 @@ static void on_accept(h2o_socket_t *listener, const char *err) return; } + if (dsc->df->d_earlyACLDrop && !dsc->df->d_trustForwardedForHeader && !dsc->holders.acl->match(remote)) { + ++dnsdist::metrics::g_stats.aclDrops; + vinfolog("Dropping DoH connection from %s because of ACL", remote.toStringWithPort()); + h2o_socket_close(sock); + return; + } + if (!dnsdist::IncomingConcurrentTCPConnectionsManager::accountNewTCPConnection(remote)) { vinfolog("Dropping DoH connection from %s because we have too many from this client already", remote.toStringWithPort()); h2o_socket_close(sock); diff --git a/pdns/dnsdistdist/m4/dnsdist_enable_doh.m4 b/pdns/dnsdistdist/m4/dnsdist_enable_doh.m4 index 876a21890f2b..baf9118e6729 100644 --- a/pdns/dnsdistdist/m4/dnsdist_enable_doh.m4 +++ b/pdns/dnsdistdist/m4/dnsdist_enable_doh.m4 @@ -1,7 +1,7 @@ AC_DEFUN([DNSDIST_ENABLE_DNS_OVER_HTTPS], [ AC_MSG_CHECKING([whether to enable incoming DNS over HTTPS (DoH) support]) AC_ARG_ENABLE([dns-over-https], - AS_HELP_STRING([--enable-dns-over-https], [enable incoming DNS over HTTPS (DoH) support (requires libh2o) @<:@default=no@:>@]), + AS_HELP_STRING([--enable-dns-over-https], [enable incoming DNS over HTTPS (DoH) support (requires libh2o or nghttp2) @<:@default=no@:>@]), [enable_dns_over_https=$enableval], [enable_dns_over_https=no] ) diff --git a/pdns/dnsdistdist/m4/pdns_with_nghttp2.m4 b/pdns/dnsdistdist/m4/pdns_with_nghttp2.m4 index 8305b2b90673..273385cf242d 100644 --- a/pdns/dnsdistdist/m4/pdns_with_nghttp2.m4 +++ b/pdns/dnsdistdist/m4/pdns_with_nghttp2.m4 @@ -13,6 +13,13 @@ AC_DEFUN([PDNS_WITH_NGHTTP2], [ PKG_CHECK_MODULES([NGHTTP2], [libnghttp2], [ [HAVE_NGHTTP2=1] AC_DEFINE([HAVE_NGHTTP2], [1], [Define to 1 if you have nghttp2]) + save_CFLAGS=$CFLAGS + save_LIBS=$LIBS + CFLAGS="$NGHTTP2_CFLAGS $CFLAGS" + LIBS="$NGHTTP2_LIBS $LIBS" + AC_CHECK_FUNCS([nghttp2_check_header_value_rfc9113 nghttp2_check_method nghttp2_check_path]) + CFLAGS=$save_CFLAGS + LIBS=$save_LIBS ], [ : ]) ]) ]) diff --git a/pdns/dnsdistdist/test-dnsdistasync.cc b/pdns/dnsdistdist/test-dnsdistasync.cc index b1fbebca053b..65a9c4a53fba 100644 --- a/pdns/dnsdistdist/test-dnsdistasync.cc +++ b/pdns/dnsdistdist/test-dnsdistasync.cc @@ -44,7 +44,7 @@ class DummyQuerySender : public TCPQuerySender { } - void notifyIOError(InternalQueryState&&, const struct timeval&) override + void notifyIOError(const struct timeval&, TCPResponse&&) override { errorRaised = true; } diff --git a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc index 9d437578f77f..19cafc004ce2 100644 --- a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc @@ -34,7 +34,6 @@ std::vector> g_frontends; /* add stub implementations, we don't want to include the corresponding object files and their dependencies */ -// NOLINTNEXTLINE(readability-convert-member-functions-to-static): this is a stub, the real one is not that simple.. bool TLSFrontend::setupTLS() { return true; diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc index 41d9992cda3b..c43297b53e5f 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc @@ -626,11 +626,11 @@ class MockupQuerySender : public TCPQuerySender d_valid = true; } - void handleXFRResponse(const struct timeval& now, TCPResponse&& response) override + void handleXFRResponse(const struct timeval&, TCPResponse&&) override { } - void notifyIOError(InternalQueryState&& query, const struct timeval& now) override + void notifyIOError(const struct timeval&, TCPResponse&&) override { d_error = true; } diff --git a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc index 2aa5adbe2063..22e137c24b3b 100644 --- a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc +++ b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc @@ -500,7 +500,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_SelfAnswered) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); } @@ -523,7 +523,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_SelfAnswered) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size()); BOOST_CHECK(s_writeBuffer == query); } @@ -558,7 +558,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_SelfAnswered) dynamic_cast(threadData.mplexer.get())->setReady(-1); auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { threadData.mplexer->run(&now); } @@ -582,7 +582,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_SelfAnswered) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); } @@ -610,7 +610,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_SelfAnswered) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size() * count); #endif } @@ -636,7 +636,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_SelfAnswered) dynamic_cast(threadData.mplexer.get())->setNotReady(-1); auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(threadData.mplexer->run(&now), 0); struct timeval later = now; later.tv_sec += g_tcpRecvTimeout + 1; @@ -672,7 +672,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_SelfAnswered) dynamic_cast(threadData.mplexer.get())->setNotReady(-1); auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(threadData.mplexer->run(&now), 0); struct timeval later = now; later.tv_sec += g_tcpRecvTimeout + 1; @@ -705,7 +705,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_SelfAnswered) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); } } @@ -766,7 +766,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionWithProxyProtocol_SelfAnswered) dynamic_cast(threadData.mplexer.get())->setNotReady(-1); auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(threadData.mplexer->run(&now), 0); BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size() * 2U); } @@ -793,7 +793,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionWithProxyProtocol_SelfAnswered) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); } @@ -823,7 +823,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionWithProxyProtocol_SelfAnswered) dynamic_cast(threadData.mplexer.get())->setNotReady(-1); auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(threadData.mplexer->run(&now), 0); struct timeval later = now; later.tv_sec += g_tcpRecvTimeout + 1; @@ -903,7 +903,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size()); BOOST_CHECK(s_writeBuffer == query); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); @@ -943,7 +943,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); BOOST_CHECK(s_backendWriteBuffer == query); @@ -982,7 +982,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); BOOST_CHECK(s_backendWriteBuffer == query); @@ -1025,7 +1025,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); BOOST_CHECK(s_backendWriteBuffer == query); @@ -1052,7 +1052,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), 0U); BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); @@ -1090,7 +1090,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); @@ -1160,7 +1160,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) /* set the incoming descriptor as ready! */ dynamic_cast(threadData.mplexer.get())->setReady(-1); auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { threadData.mplexer->run(&now); } @@ -1221,7 +1221,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), 0U); BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); @@ -1257,7 +1257,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); struct timeval later = now; later.tv_sec += backend->d_config.tcpSendTimeout + 1; auto expiredWriteConns = threadData.mplexer->getTimeouts(later, true); @@ -1303,7 +1303,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); struct timeval later = now; later.tv_sec += backend->d_config.tcpRecvTimeout + 1; auto expiredConns = threadData.mplexer->getTimeouts(later, false); @@ -1360,7 +1360,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), 0U); BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); @@ -1416,7 +1416,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size()); BOOST_CHECK(s_writeBuffer == query); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); @@ -1475,7 +1475,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), 0U); BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); @@ -1527,7 +1527,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size() * backend->d_config.d_retries); BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); @@ -1587,7 +1587,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size()); BOOST_CHECK(s_writeBuffer == query); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size() * backend->d_config.d_retries); @@ -1628,7 +1628,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), 0U); BOOST_CHECK_EQUAL(s_backendWriteBuffer.size(), query.size()); BOOST_CHECK(s_backendWriteBuffer == query); @@ -1690,7 +1690,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(s_writeBuffer.size(), query.size() * count); BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); @@ -1732,7 +1732,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); BOOST_CHECK_EQUAL(backend->outstanding.load(), 0U); /* we need to clear them now, otherwise we end up with dangling pointers to the steps via the TLS context, etc */ @@ -1916,7 +1916,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { threadData.mplexer->run(&now); } @@ -2048,7 +2048,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); @@ -2228,7 +2228,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); @@ -2304,7 +2304,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); } @@ -2387,7 +2387,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while ((threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); } @@ -2504,7 +2504,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); } @@ -2656,7 +2656,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { threadData.mplexer->run(&now); } @@ -2863,7 +2863,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); } @@ -3037,7 +3037,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); } @@ -3301,7 +3301,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); } @@ -3427,7 +3427,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { threadData.mplexer->run(&now); } @@ -3512,7 +3512,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { threadData.mplexer->run(&now); } @@ -3577,7 +3577,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); } @@ -3768,7 +3768,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { threadData.mplexer->run(&now); } @@ -3853,7 +3853,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); } @@ -4085,7 +4085,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendNotOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { threadData.mplexer->run(&now); } @@ -4137,7 +4137,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendNotOOOR) }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); - IncomingTCPConnectionState::handleIO(state, now); + state->handleIO(); while (!timeout && (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0)) { threadData.mplexer->run(&now); } diff --git a/pdns/doh.hh b/pdns/doh.hh index 58a26f16918f..c482b7a0fa2a 100644 --- a/pdns/doh.hh +++ b/pdns/doh.hh @@ -51,7 +51,7 @@ public: size_t getTicketsKeysCount() override; }; -void dohThread(ClientState* clientState); +void dohThread(ClientState* cs); #endif /* HAVE_LIBH2OEVLOOP */ #endif /* HAVE_DNS_OVER_HTTPS */ diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index 1b7018c028ba..78f23f9df414 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -1850,6 +1850,7 @@ bool TLSFrontend::setupTLS() newCtx = std::make_shared(*this); } #endif /* HAVE_LIBSSL */ + if (!newCtx) { #ifdef HAVE_LIBSSL newCtx = std::make_shared(*this); @@ -1874,7 +1875,7 @@ bool TLSFrontend::setupTLS() std::shared_ptr getTLSContext([[maybe_unused]] const TLSContextParameters& params) { -#if defined(HAVE_DNS_OVER_TLS) || defined(HAVE_DNS_OVER_HTTPS) +#ifdef HAVE_DNS_OVER_TLS /* get the "best" available provider */ if (!params.d_provider.empty()) { #ifdef HAVE_GNUTLS @@ -1897,6 +1898,6 @@ std::shared_ptr getTLSContext([[maybe_unused]] const TLSContextParameter #endif /* HAVE_GNUTLS */ #endif /* HAVE_LIBSSL */ -#endif /* HAVE_DNS_OVER_TLS || HAVE_DNS_OVER_HTTPS */ +#endif /* HAVE_DNS_OVER_TLS */ return nullptr; } diff --git a/pdns/tcpiohandler.hh b/pdns/tcpiohandler.hh index 29b59a01f9a4..5e1d23e737c6 100644 --- a/pdns/tcpiohandler.hh +++ b/pdns/tcpiohandler.hh @@ -138,7 +138,7 @@ class TLSFrontend public: enum class ALPN : uint8_t { Unset, DoT, DoH }; - TLSFrontend(ALPN alpn) : d_alpn(alpn) + TLSFrontend(ALPN alpn): d_alpn(alpn) { } @@ -233,7 +233,6 @@ protected: class TCPIOHandler { public: - enum class Type : uint8_t { Client, Server }; TCPIOHandler(const std::string& host, bool hostIsAddr, int socket, const struct timeval& timeout, std::shared_ptr ctx): d_socket(socket) { diff --git a/pdns/test-dnsdist_cc.cc b/pdns/test-dnsdist_cc.cc index c51a930c04f8..850273eb8a67 100644 --- a/pdns/test-dnsdist_cc.cc +++ b/pdns/test-dnsdist_cc.cc @@ -56,7 +56,7 @@ bool sendUDPResponse(int origFD, const PacketBuffer& response, const int delayMs bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint16_t queryID, DNSQuestion& dq, PacketBuffer& query) { - return true; + return false; } namespace dnsdist { diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 156ba192198f..6bc56cdb7a71 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -624,7 +624,7 @@ def openTCPConnection(cls, timeout=None, port=None): return sock @classmethod - def openTLSConnection(cls, port, serverName, caCert=None, timeout=None): + def openTLSConnection(cls, port, serverName, caCert=None, timeout=None, alpn=[]): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) if timeout: @@ -633,6 +633,8 @@ def openTLSConnection(cls, port, serverName, caCert=None, timeout=None): # 2.7.9+ if hasattr(ssl, 'create_default_context'): sslctx = ssl.create_default_context(cafile=caCert) + if len(alpn)> 0 and hasattr(sslctx, 'set_alpn_protocols'): + sslctx.set_alpn_protocols(alpn) sslsock = sslctx.wrap_socket(sock, server_hostname=serverName) else: sslsock = ssl.wrap_socket(sock, ca_certs=caCert, cert_reqs=ssl.CERT_REQUIRED) @@ -992,6 +994,8 @@ def sendDOHQuery(cls, port, servername, baseurl, query, response=None, timeout=2 #conn.setopt(pycurl.VERBOSE, True) conn.setopt(pycurl.URL, url) conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (servername, port)]) + # this means "really do HTTP/2, not HTTP/1 with Upgrade headers" + conn.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) if useHTTPS: conn.setopt(pycurl.SSL_VERIFYPEER, 1) conn.setopt(pycurl.SSL_VERIFYHOST, 2) @@ -1036,6 +1040,8 @@ def sendDOHPostQuery(cls, port, servername, baseurl, query, response=None, timeo #conn.setopt(pycurl.VERBOSE, True) conn.setopt(pycurl.URL, url) conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (servername, port)]) + # this means "really do HTTP/2, not HTTP/1 with Upgrade headers" + conn.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) if useHTTPS: conn.setopt(pycurl.SSL_VERIFYPEER, 1) conn.setopt(pycurl.SSL_VERIFYHOST, 2) diff --git a/regression-tests.dnsdist/test_DOH.py b/regression-tests.dnsdist/test_DOH.py index 5999021f5dd8..d4d6606faf01 100644 --- a/regression-tests.dnsdist/test_DOH.py +++ b/regression-tests.dnsdist/test_DOH.py @@ -573,7 +573,7 @@ def testSubPath(self): # this path is not in the URLs map and should lead to a 404 (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL + "NotPowerDNS", query, caFile=self._caCert, useQueue=False, rawResponse=True) self.assertTrue(receivedResponse) - self.assertEqual(receivedResponse, b'not found') + self.assertIn(receivedResponse, [b'there is no endpoint configured for this path', b'not found']) self.assertEqual(self._rcode, 404) # this path is below one in the URLs map and exactPathMatching is false, so we should be good @@ -1116,7 +1116,7 @@ def testDOHDeniedForwarded(self): (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert, useQueue=False, rawResponse=True, customHeaders=['x-forwarded-for: 127.0.0.1:42, 127.0.0.1']) self.assertEqual(self._rcode, 403) - self.assertEqual(receivedResponse, b'dns query not allowed because of ACL') + self.assertEqual(receivedResponse, b'DoH query not allowed because of ACL') class TestDOHForwardedForNoTrusted(DNSDistDOHTest): @@ -1130,7 +1130,7 @@ class TestDOHForwardedForNoTrusted(DNSDistDOHTest): newServer{address="127.0.0.1:%s"} setACL('192.0.2.1/32') - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }) + addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {earlyACLDrop=true}) """ _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey'] @@ -1151,10 +1151,15 @@ def testDOHForwardedUntrusted(self): '127.0.0.1') response.answer.append(rrset) - (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert, useQueue=False, rawResponse=True, customHeaders=['x-forwarded-for: 192.0.2.1:4200']) + dropped = False + try: + (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert, useQueue=False, rawResponse=True, customHeaders=['x-forwarded-for: 192.0.2.1:4200']) + self.assertEqual(self._rcode, 403) + self.assertEqual(receivedResponse, b'DoH query not allowed because of ACL') + except pycurl.error as e: + dropped = True - self.assertEqual(self._rcode, 403) - self.assertEqual(receivedResponse, b'dns query not allowed because of ACL') + self.assertTrue(dropped) class TestDOHFrontendLimits(DNSDistDOHTest): @@ -1190,7 +1195,7 @@ def testTCPConnsPerDOHFrontend(self): for idx in range(self._maxTCPConnsPerDOHFrontend + 1): try: - conns.append(self.openTLSConnection(self._dohServerPort, self._serverName, self._caCert)) + conns.append(self.openTLSConnection(self._dohServerPort, self._serverName, self._caCert, alpn=['h2'])) except: conns.append(None) diff --git a/regression-tests.dnsdist/test_Protobuf.py b/regression-tests.dnsdist/test_Protobuf.py index e4f0b0232c17..092cdef74534 100644 --- a/regression-tests.dnsdist/test_Protobuf.py +++ b/regression-tests.dnsdist/test_Protobuf.py @@ -546,7 +546,6 @@ def testProtobufMetaDoH(self): elif method == "sendDOHQueryWrapper": pbMessageType = dnsmessage_pb2.PBDNSMessage.DOH - print(method) self.checkProtobufQuery(msg, pbMessageType, query, dns.rdataclass.IN, dns.rdatatype.A, name) self.assertEqual(len(msg.meta), 5) tags = {} From e8330238fdaf135664dfd610970427f1662967f8 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 27 Mar 2023 13:41:36 +0200 Subject: [PATCH 618/909] dnsdist: Log when a TC=1 response is received for a DoH query --- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index aefa50d777a5..8e225ee2ca00 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -189,6 +189,7 @@ void IncomingHTTP2Connection::handleResponse(const struct timeval& now, TCPRespo dnsheader* responseDH = reinterpret_cast(response.d_buffer.data()); if (responseDH->tc && state.d_packet && state.d_packet->size() > state.d_proxyProtocolPayloadSize && state.d_packet->size() - state.d_proxyProtocolPayloadSize > sizeof(dnsheader)) { + vinfolog("Response received from backend %s via UDP, for query %d received from %s via DoH, is truncated, retrying over TCP", response.d_ds->getNameWithAddr(), state.d_streamID, state.origRemote.toStringWithPort()); auto& query = *state.d_packet; dnsheader* queryDH = reinterpret_cast(query.data() + state.d_proxyProtocolPayloadSize); /* restoring the original ID */ From 83abf7f6b68dfb8473c83054d3a670becef321a6 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 5 May 2023 17:10:14 +0200 Subject: [PATCH 619/909] dnsdist: Small optimization for nghttp2 headers --- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 84 +++++++++++++------------- pdns/dnsdistdist/dnsdist-nghttp2-in.hh | 33 +++++++++- pdns/dnsdistdist/dnsdist-nghttp2.cc | 33 +++++----- 3 files changed, 89 insertions(+), 61 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 8e225ee2ca00..578cdc6d731d 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -387,32 +387,32 @@ ssize_t IncomingHTTP2Connection::send_callback(nghttp2_session* session, const u return length; } -static const std::unordered_map s_constants{ - {"200-value", "200"}, - {"method-name", ":method"}, - {"method-value", "POST"}, - {"scheme-name", ":scheme"}, - {"scheme-value", "https"}, - {"authority-name", ":authority"}, - {"x-forwarded-for-name", "x-forwarded-for"}, - {"path-name", ":path"}, - {"content-length-name", "content-length"}, - {"status-name", ":status"}, - {"location-name", "location"}, - {"accept-name", "accept"}, - {"accept-value", "application/dns-message"}, - {"cache-control-name", "cache-control"}, - {"content-type-name", "content-type"}, - {"content-type-value", "application/dns-message"}, - {"user-agent-name", "user-agent"}, - {"user-agent-value", "nghttp2-" NGHTTP2_VERSION "/dnsdist"}, - {"x-forwarded-port-name", "x-forwarded-port"}, - {"x-forwarded-proto-name", "x-forwarded-proto"}, - {"x-forwarded-proto-value-dns-over-udp", "dns-over-udp"}, - {"x-forwarded-proto-value-dns-over-tcp", "dns-over-tcp"}, - {"x-forwarded-proto-value-dns-over-tls", "dns-over-tls"}, - {"x-forwarded-proto-value-dns-over-http", "dns-over-http"}, - {"x-forwarded-proto-value-dns-over-https", "dns-over-https"}, +static const std::array(NGHTTP2Headers::HeaderConstantIndexes::COUNT)> s_headerConstants{ + "200", + ":method", + "POST", + ":scheme", + "https", + ":authority", + "x-forwarded-for", + ":path", + "content-length", + ":status", + "location", + "accept", + "application/dns-message", + "cache-control", + "content-type", + "application/dns-message", + "user-agent", + "nghttp2-" NGHTTP2_VERSION "/dnsdist", + "x-forwarded-port", + "x-forwarded-proto", + "dns-over-udp", + "dns-over-tcp", + "dns-over-tls", + "dns-over-http", + "dns-over-https" }; static const std::string s_authorityHeaderName(":authority"); @@ -421,10 +421,10 @@ static const std::string s_methodHeaderName(":method"); static const std::string s_schemeHeaderName(":scheme"); static const std::string s_xForwardedForHeaderName("x-forwarded-for"); -void NGHTTP2Headers::addStaticHeader(std::vector& headers, const std::string& nameKey, const std::string& valueKey) +void NGHTTP2Headers::addStaticHeader(std::vector& headers, NGHTTP2Headers::HeaderConstantIndexes nameKey, NGHTTP2Headers::HeaderConstantIndexes valueKey) { - const auto& name = s_constants.at(nameKey); - const auto& value = s_constants.at(valueKey); + const auto& name = s_headerConstants.at(static_cast(nameKey)); + const auto& value = s_headerConstants.at(static_cast(valueKey)); headers.push_back({const_cast(reinterpret_cast(name.c_str())), const_cast(reinterpret_cast(value.c_str())), name.size(), value.size(), NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE}); } @@ -434,9 +434,9 @@ void NGHTTP2Headers::addCustomDynamicHeader(std::vector& headers, co headers.push_back({const_cast(reinterpret_cast(name.data())), const_cast(reinterpret_cast(value.data())), name.size(), value.size(), NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE}); } -void NGHTTP2Headers::addDynamicHeader(std::vector& headers, const std::string& nameKey, const std::string_view& value) +void NGHTTP2Headers::addDynamicHeader(std::vector& headers, NGHTTP2Headers::HeaderConstantIndexes nameKey, const std::string_view& value) { - const auto& name = s_constants.at(nameKey); + const auto& name = s_headerConstants.at(static_cast(nameKey)); NGHTTP2Headers::addCustomDynamicHeader(headers, name, value); } @@ -511,18 +511,20 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str std::string location; /* remember that dynamic header values should be kept alive until we have called nghttp2_submit_response(), at least */ + /* status, content-type, cache-control, content-length */ + headers.reserve(4); if (responseCode == 200) { - NGHTTP2Headers::addStaticHeader(headers, "status-name", "200-value"); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::STATUS_NAME, NGHTTP2Headers::HeaderConstantIndexes::OK_200_VALUE); ++df->d_validresponses; ++df->d_http2Stats.d_nb200Responses; if (addContentType) { if (contentType.empty()) { - NGHTTP2Headers::addStaticHeader(headers, "content-type-name", "content-type-value"); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_TYPE_NAME, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_TYPE_VALUE); } else { - NGHTTP2Headers::addDynamicHeader(headers, "content-type-name", contentType); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_TYPE_NAME, contentType); } } @@ -530,18 +532,18 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str uint32_t minTTL = getDNSPacketMinTTL(reinterpret_cast(responseBody.data()), responseBody.size()); if (minTTL != std::numeric_limits::max()) { cacheControlValue = "max-age=" + std::to_string(minTTL); - NGHTTP2Headers::addDynamicHeader(headers, "cache-control-name", cacheControlValue); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CACHE_CONTROL_NAME, cacheControlValue); } } } else { responseCodeStr = std::to_string(responseCode); - NGHTTP2Headers::addDynamicHeader(headers, "status-name", responseCodeStr); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::STATUS_NAME, responseCodeStr); if (responseCode >= 300 && responseCode < 400) { location = std::string(reinterpret_cast(responseBody.data()), responseBody.size()); - NGHTTP2Headers::addDynamicHeader(headers, "content-type-name", "text/html; charset=utf-8"); - NGHTTP2Headers::addDynamicHeader(headers, "location-name", location); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_TYPE_NAME, "text/html; charset=utf-8"); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::LOCATION_NAME, location); static const std::string s_redirectStart{"Moved

      The document has moved here"}; responseBody.reserve(s_redirectStart.size() + responseBody.size() + s_redirectEnd.size()); @@ -570,7 +572,7 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str } if (!responseBody.empty()) { - NGHTTP2Headers::addDynamicHeader(headers, "content-type-name", "text/plain; charset=utf-8"); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_TYPE_NAME, "text/plain; charset=utf-8"); } else { static const std::string invalid{"invalid DNS query"}; @@ -599,7 +601,7 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str } const std::string contentLength = std::to_string(responseBody.size()); - NGHTTP2Headers::addDynamicHeader(headers, "content-length-name", contentLength); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_LENGTH_NAME, contentLength); for (const auto& [key, value] : customResponseHeaders) { NGHTTP2Headers::addCustomDynamicHeader(headers, key, value); @@ -918,7 +920,7 @@ int IncomingHTTP2Connection::on_begin_headers_callback(nghttp2_session* session, } IncomingHTTP2Connection* conn = reinterpret_cast(user_data); - auto insertPair = conn->d_currentStreams.insert({frame->hd.stream_id, PendingQuery()}); + auto insertPair = conn->d_currentStreams.emplace(frame->hd.stream_id, PendingQuery()); if (!insertPair.second) { /* there is a stream ID collision, something is very wrong! */ vinfolog("Stream ID collision (%d) on connection from %d", frame->hd.stream_id, conn->d_ci.remote.toStringWithPort()); diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh index 3ee1c96d10a6..a8e68777c1ef 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -106,8 +106,37 @@ private: class NGHTTP2Headers { public: - static void addStaticHeader(std::vector& headers, const std::string& nameKey, const std::string& valueKey); - static void addDynamicHeader(std::vector& headers, const std::string& nameKey, const std::string_view& value); + enum class HeaderConstantIndexes { + OK_200_VALUE = 0, + METHOD_NAME, + METHOD_VALUE, + SCHEME_NAME, + SCHEME_VALUE, + AUTHORITY_NAME, + X_FORWARDED_FOR_NAME, + PATH_NAME, + CONTENT_LENGTH_NAME, + STATUS_NAME, + LOCATION_NAME, + ACCEPT_NAME, + ACCEPT_VALUE, + CACHE_CONTROL_NAME, + CONTENT_TYPE_NAME, + CONTENT_TYPE_VALUE, + USER_AGENT_NAME, + USER_AGENT_VALUE, + X_FORWARDED_PORT_NAME, + X_FORWARDED_PROTO_NAME, + X_FORWARDED_PROTO_VALUE_DNS_OVER_UDP, + X_FORWARDED_PROTO_VALUE_DNS_OVER_TCP, + X_FORWARDED_PROTO_VALUE_DNS_OVER_TLS, + X_FORWARDED_PROTO_VALUE_DNS_OVER_HTTP, + X_FORWARDED_PROTO_VALUE_DNS_OVER_HTTPS, + COUNT + }; + + static void addStaticHeader(std::vector& headers, HeaderConstantIndexes nameKey, HeaderConstantIndexes valueKey); + static void addDynamicHeader(std::vector& headers, HeaderConstantIndexes nameKey, const std::string_view& value); static void addCustomDynamicHeader(std::vector& headers, const std::string& name, const std::string_view& value); }; diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 692b73275771..03fa0bfca5a6 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -84,9 +84,6 @@ class DoHConnectionToBackend : public ConnectionToBackend static void handleReadableIOCallback(int fd, FDMultiplexer::funcparam_t& param); static void handleWritableIOCallback(int fd, FDMultiplexer::funcparam_t& param); - static void addStaticHeader(std::vector& headers, const std::string& nameKey, const std::string& valueKey); - static void addDynamicHeader(std::vector& headers, const std::string& nameKey, const std::string& value); - class PendingRequest { public: @@ -251,37 +248,37 @@ void DoHConnectionToBackend::queueQuery(std::shared_ptr& sender, headers.reserve(8 + (addXForwarded ? 3 : 0)); /* Pseudo-headers need to come first (rfc7540 8.1.2.1) */ - NGHTTP2Headers::addStaticHeader(headers, "method-name", "method-value"); - NGHTTP2Headers::addStaticHeader(headers, "scheme-name", "scheme-value"); - NGHTTP2Headers::addDynamicHeader(headers, "authority-name", d_ds->d_config.d_tlsSubjectName); - NGHTTP2Headers::addDynamicHeader(headers, "path-name", d_ds->d_config.d_dohPath); - NGHTTP2Headers::addStaticHeader(headers, "accept-name", "accept-value"); - NGHTTP2Headers::addStaticHeader(headers, "content-type-name", "content-type-value"); - NGHTTP2Headers::addStaticHeader(headers, "user-agent-name", "user-agent-value"); - NGHTTP2Headers::addDynamicHeader(headers, "content-length-name", payloadSize); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::METHOD_NAME, NGHTTP2Headers::HeaderConstantIndexes::METHOD_VALUE); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::SCHEME_NAME, NGHTTP2Headers::HeaderConstantIndexes::SCHEME_VALUE); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::AUTHORITY_NAME, d_ds->d_config.d_tlsSubjectName); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::PATH_NAME, d_ds->d_config.d_dohPath); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::ACCEPT_NAME, NGHTTP2Headers::HeaderConstantIndexes::ACCEPT_VALUE); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_TYPE_NAME, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_TYPE_VALUE); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::USER_AGENT_NAME, NGHTTP2Headers::HeaderConstantIndexes::USER_AGENT_VALUE); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_LENGTH_NAME, payloadSize); /* no need to add these headers for health-check queries */ if (addXForwarded && query.d_idstate.origRemote.getPort() != 0) { remote = query.d_idstate.origRemote.toString(); remotePort = std::to_string(query.d_idstate.origRemote.getPort()); - NGHTTP2Headers::addDynamicHeader(headers, "x-forwarded-for-name", remote); - NGHTTP2Headers::addDynamicHeader(headers, "x-forwarded-port-name", remotePort); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_FOR_NAME, remote); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PORT_NAME, remotePort); if (query.d_idstate.cs != nullptr) { if (query.d_idstate.cs->isUDP()) { - NGHTTP2Headers::addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-udp"); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PROTO_NAME, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PROTO_VALUE_DNS_OVER_UDP); } else if (query.d_idstate.cs->isDoH()) { if (query.d_idstate.cs->hasTLS()) { - NGHTTP2Headers::addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-https"); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PROTO_NAME, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PROTO_VALUE_DNS_OVER_HTTPS); } else { - NGHTTP2Headers::addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-http"); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PROTO_NAME, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PROTO_VALUE_DNS_OVER_HTTP); } } else if (query.d_idstate.cs->hasTLS()) { - NGHTTP2Headers::addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-tls"); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PROTO_NAME, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PROTO_VALUE_DNS_OVER_TLS); } else { - NGHTTP2Headers::addStaticHeader(headers, "x-forwarded-proto-name", "x-forwarded-proto-value-dns-over-tcp"); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PROTO_NAME, NGHTTP2Headers::HeaderConstantIndexes::X_FORWARDED_PROTO_VALUE_DNS_OVER_TCP); } } } From aecb2f4503753be6c151ada93ba40b57d6632392 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 11 May 2023 17:49:39 +0200 Subject: [PATCH 620/909] dnsdist: Small optimizations for incoming DoH --- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 49 +++++++++++++++++--------- pdns/dnsdistdist/dnsdist-nghttp2-in.hh | 2 +- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 578cdc6d731d..95b5705fd142 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -96,7 +96,7 @@ class IncomingDoHCrossProtocolContext : public DOHUnitInterface { public: IncomingDoHCrossProtocolContext(IncomingHTTP2Connection::PendingQuery&& query, std::shared_ptr connection, IncomingHTTP2Connection::StreamID streamID) : - d_connection(connection), d_query(std::move(query)), d_streamID(streamID) + d_connection(std::move(connection)), d_query(std::move(query)), d_streamID(streamID) { } @@ -458,7 +458,7 @@ IOState IncomingHTTP2Connection::sendResponse(const struct timeval& now, TCPResp responseBuffer = std::move(response.d_buffer); } - sendResponse(response.d_idstate.d_streamID, statusCode, d_ci.cs->dohFrontend->d_customResponseHeaders, contentType, sendContentType); + sendResponse(response.d_idstate.d_streamID, context, statusCode, d_ci.cs->dohFrontend->d_customResponseHeaders, contentType, sendContentType); handleResponseSent(response); return IOState::Done; @@ -474,11 +474,12 @@ void IncomingHTTP2Connection::notifyIOError(const struct timeval& now, TCPRespon } assert(response.d_idstate.d_streamID != -1); - d_currentStreams.at(response.d_idstate.d_streamID).d_buffer = std::move(response.d_buffer); - sendResponse(response.d_idstate.d_streamID, 502, d_ci.cs->dohFrontend->d_customResponseHeaders); + auto& context = d_currentStreams.at(response.d_idstate.d_streamID); + context.d_buffer = std::move(response.d_buffer); + sendResponse(response.d_idstate.d_streamID, context, 502, d_ci.cs->dohFrontend->d_customResponseHeaders); } -bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID streamID, uint16_t responseCode, const HeadersMap& customResponseHeaders, const std::string& contentType, bool addContentType) +bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID streamID, IncomingHTTP2Connection::PendingQuery& context, uint16_t responseCode, const HeadersMap& customResponseHeaders, const std::string& contentType, bool addContentType) { /* if data_prd is not NULL, it provides data which will be sent in subsequent DATA frames. In this case, a method that allows request message bodies (https://tools.ietf.org/html/rfc7231#section-4) must be specified with :method key (e.g. POST). This function does not take ownership of the data_prd. The function copies the members of the data_prd. If data_prd is NULL, HEADERS have END_STREAM set. */ @@ -498,12 +499,13 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str if (obj.d_queryPos >= obj.d_buffer.size()) { *data_flags |= NGHTTP2_DATA_FLAG_EOF; + obj.d_buffer.clear(); } return toCopy; }; const auto& df = d_ci.cs->dohFrontend; - auto& responseBody = d_currentStreams.at(streamID).d_buffer; + auto& responseBody = context.d_buffer; std::vector headers; std::string responseCodeStr; @@ -676,19 +678,34 @@ static std::optional getPayloadFromPath(const std::string_view& pa } // need to base64url decode this - string sdns(path.substr(pos + 5)); - boost::replace_all(sdns, "-", "+"); - boost::replace_all(sdns, "_", "/"); - - // re-add padding that may have been missing - switch (sdns.size() % 4) { + string sdns; + const size_t payloadSize = path.size() - pos - 5; + size_t neededPadding = 0; + switch (payloadSize % 4) { case 2: - sdns.append(2, '='); + neededPadding = 2; break; case 3: - sdns.append(1, '='); + neededPadding = 1; break; } + sdns.reserve(payloadSize + neededPadding); + sdns = path.substr(pos + 5); + for (auto &entry : sdns) { + switch (entry) { + case '-': + entry = '+'; + break; + case '_': + entry = '/'; + break; + } + } + + if (neededPadding) { + // re-add padding that may have been missing + sdns.append(neededPadding, '='); + } PacketBuffer decoded; /* rough estimate so we hopefully don't need a new allocation later */ @@ -714,7 +731,7 @@ void IncomingHTTP2Connection::handleIncomingQuery(IncomingHTTP2Connection::Pendi query.d_buffer = std::move(response); } vinfolog("Sending an immediate %d response to incoming DoH query: %s", code, reason); - sendResponse(streamID, code, d_ci.cs->dohFrontend->d_customResponseHeaders); + sendResponse(streamID, query, code, d_ci.cs->dohFrontend->d_customResponseHeaders); }; ++d_ci.cs->dohFrontend->d_http2Stats.d_nbQueries; @@ -769,7 +786,7 @@ void IncomingHTTP2Connection::handleIncomingQuery(IncomingHTTP2Connection::Pendi query.d_buffer.pop_back(); } - sendResponse(streamID, entry->getStatusCode(), customHeaders ? *customHeaders : d_ci.cs->dohFrontend->d_customResponseHeaders, std::string(), false); + sendResponse(streamID, query, entry->getStatusCode(), customHeaders ? *customHeaders : d_ci.cs->dohFrontend->d_customResponseHeaders, std::string(), false); return; } } diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh index a8e68777c1ef..1fa2b83a2ee5 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -88,7 +88,7 @@ private: void updateIO(IOState newState, FDMultiplexer::callbackfunc_t callback); void watchForRemoteHostClosingConnection(); void handleIOError(); - bool sendResponse(StreamID streamID, uint16_t responseCode, const HeadersMap& customResponseHeaders, const std::string& contentType = "", bool addContentType = true); + bool sendResponse(StreamID streamID, PendingQuery& context, uint16_t responseCode, const HeadersMap& customResponseHeaders, const std::string& contentType = "", bool addContentType = true); void handleIncomingQuery(PendingQuery&& query, StreamID streamID); bool checkALPN(); void readHTTPData(); From ac25db031dd51ea37791560f782e45a5313cc0db Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 6 Sep 2023 15:49:26 +0200 Subject: [PATCH 621/909] auth-4.8.2: secpoll&docs --- docs/changelog/4.8.rst | 40 ++++++++++++++++++++++++++++++++++++++++ docs/secpoll.zone | 3 ++- 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/docs/changelog/4.8.rst b/docs/changelog/4.8.rst index b8374f947fc5..37f772e6bd64 100644 --- a/docs/changelog/4.8.rst +++ b/docs/changelog/4.8.rst @@ -1,6 +1,46 @@ Changelogs for 4.8.x ==================== +.. changelog:: + :version: 4.8.2 + :released: 7th of September 2023 + + This is release 4.8.2 of the Authoritative Server. + + Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x. + + This release contains a small collection of fixes: + + .. change:: + :tags: Bug Fixes + :pullreq: 13186 + + (I)XFR: handle partial read of len prefix + + .. change:: + :tags: Bug Fixes + :pullreq: 13187 + + fix code producing json + + .. change:: + :tags: Bug Fixes + :pullreq: 13188 + + calidns: fix setting an ECS source of 0 + + .. change:: + :tags: Bug Fixes + :pullreq: 13189 + + Fix incorrect optsize + + .. change:: + :tags: Bug Fixes + :pullreq: 13099 + + lmdb: when broadcasting indexes, -do- rewrite them even if they are unchanged + .. changelog:: :version: 4.8.1 :released: 7th of July 2023 diff --git a/docs/secpoll.zone b/docs/secpoll.zone index a0cecc6af8eb..1a6a35ba13a3 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023082501 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023090701 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -122,6 +122,7 @@ auth-4.8.0-alpha1.security-status 60 IN TXT "2 Unsupported auth-4.8.0-beta1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" auth-4.8.0.security-status 60 IN TXT "1 OK" auth-4.8.1.security-status 60 IN TXT "1 OK" +auth-4.8.2.security-status 60 IN TXT "1 OK" ; Auth Debian auth-3.4.1-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2015-02/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-03/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-04/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-05/" From d2c3ef4bc03fb07c459f3aa858dc1f602e960a38 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 24 Mar 2023 18:08:14 +0100 Subject: [PATCH 622/909] dnsdist: Check both h2o and nghttp2 in the DoH regression tests --- regression-tests.dnsdist/test_DOH.py | 196 +++++++++++++++++++-------- 1 file changed, 141 insertions(+), 55 deletions(-) diff --git a/regression-tests.dnsdist/test_DOH.py b/regression-tests.dnsdist/test_DOH.py index d4d6606faf01..ae6aac46a44f 100644 --- a/regression-tests.dnsdist/test_DOH.py +++ b/regression-tests.dnsdist/test_DOH.py @@ -12,8 +12,7 @@ import pycurl from io import BytesIO -class TestDOH(DNSDistDOHTest): - +class DOHTests(object): _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' @@ -23,11 +22,7 @@ class TestDOH(DNSDistDOHTest): _customResponseHeader2 = 'user-agent: derp' _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ - newServer{address="127.0.0.1:%s"} - - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/", "/coffee", "/PowerDNS", "/PowerDNS2", "/PowerDNS-999" }, {customResponseHeaders={["access-control-allow-origin"]="*",["user-agent"]="derp",["UPPERCASE"]="VaLuE"}, keepIncomingHeaders=true}) - dohFE = getDOHFrontend(0) - dohFE:setResponsesMap({newDOHResponseMapEntry('^/coffee$', 418, 'C0FFEE', {['FoO']='bar'})}) + newServer{address="127.0.0.1:%d"} addAction("drop.doh.tests.powerdns.com.", DropAction()) addAction("refused.doh.tests.powerdns.com.", RCodeAction(DNSRCode.REFUSED)) @@ -56,8 +51,13 @@ class TestDOH(DNSDistDOHTest): return DNSAction.None end addAction("http-lua.doh.tests.powerdns.com.", LuaAction(dohHandler)) + + addDOHLocal("127.0.0.1:%d", "%s", "%s", { "/", "/coffee", "/PowerDNS", "/PowerDNS2", "/PowerDNS-999" }, {customResponseHeaders={["access-control-allow-origin"]="*",["user-agent"]="derp",["UPPERCASE"]="VaLuE"}, keepIncomingHeaders=true, library='%s'}) + dohFE = getDOHFrontend(0) + dohFE:setResponsesMap({newDOHResponseMapEntry('^/coffee$', 418, 'C0FFEE', {['FoO']='bar'})}) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_serverName', '_dohServerPort'] + _config_params = ['_testServerPort', '_serverName', '_dohServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary'] + _verboseMode = True def testDOHSimple(self): """ @@ -522,8 +522,13 @@ def testHTTPEarlyResponse(self): self.assertIn('foo: bar', headers) self.assertNotIn(self._customResponseHeader2, headers) -class TestDOHSubPaths(DNSDistDOHTest): +class TestDoHNGHTTP2(DOHTests, DNSDistDOHTest): + _dohLibrary = 'nghttp2' +class TestDoHH2O(DOHTests, DNSDistDOHTest): + _dohLibrary = 'h2o' + +class DOHSubPathsTests(object): _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' @@ -535,9 +540,9 @@ class TestDOHSubPaths(DNSDistDOHTest): addAction(AllRule(), SpoofAction("3.4.5.6")) - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/PowerDNS" }, {exactPathMatching=false}) + addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/PowerDNS" }, {exactPathMatching=false, library='%s'}) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary'] def testSubPath(self): """ @@ -580,7 +585,13 @@ def testSubPath(self): (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL + 'PowerDNS/something', caFile=self._caCert, query=query, response=None, useQueue=False) self.assertEqual(receivedResponse, expectedResponse) -class TestDOHAddingECS(DNSDistDOHTest): +class TestDoHSubPathsNGHTTP2(DOHSubPathsTests, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + +class TestDoHSubPathsH2O(DOHSubPathsTests, DNSDistDOHTest): + _dohLibrary = 'h2o' + +class DOHAddingECSTests(object): _serverKey = 'server.key' _serverCert = 'server.chain' @@ -590,10 +601,10 @@ class TestDOHAddingECS(DNSDistDOHTest): _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s", useClientSubnet=true} - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }) + addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {library='%s'}) setECSOverride(true) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary'] def testDOHSimple(self): """ @@ -675,19 +686,21 @@ def testDOHExistingECS(self): self.checkQueryEDNSWithECS(expectedQuery, receivedQuery) self.checkResponseEDNSWithECS(response, receivedResponse) -class TestDOHOverHTTP(DNSDistDOHTest): +class TestDoHAddingECSNGHTTP2(DOHAddingECSTests, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + +class TestDoHAddingECSH2O(DOHAddingECSTests, DNSDistDOHTest): + _dohLibrary = 'h2o' +class DOHOverHTTP(object): _dohServerPort = pickAvailablePort() _serverName = 'tls.tests.dnsdist.org' _dohBaseURL = ("http://%s:%d/dns-query" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s"} - addDOHLocal("127.0.0.1:%s") + addDOHLocal("127.0.0.1:%s", nil, nil, '/dns-query', {library='%s'}) """ - _config_params = ['_testServerPort', '_dohServerPort'] - _checkConfigExpectedOutput = b"""No certificate provided for DoH endpoint 127.0.0.1:%d, running in DNS over HTTP mode instead of DNS over HTTPS -Configuration 'configs/dnsdist_TestDOHOverHTTP.conf' OK! -""" % (_dohServerPort) + _config_params = ['_testServerPort', '_dohServerPort', '_dohLibrary'] def testDOHSimple(self): """ @@ -740,7 +753,19 @@ def testDOHSimplePOST(self): self.assertEqual(response, receivedResponse) self.checkResponseNoEDNS(response, receivedResponse) -class TestDOHWithCache(DNSDistDOHTest): +class TestDOHOverHTTPNGHTTP2(DOHOverHTTP, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + _checkConfigExpectedOutput = b"""No certificate provided for DoH endpoint 127.0.0.1:%d, running in DNS over HTTP mode instead of DNS over HTTPS +Configuration 'configs/dnsdist_TestDOHOverHTTPNGHTTP2.conf' OK! +""" % (DOHOverHTTP._dohServerPort) + +class TestDOHOverHTTPH2O(DOHOverHTTP, DNSDistDOHTest): + _dohLibrary = 'h2o' + _checkConfigExpectedOutput = b"""No certificate provided for DoH endpoint 127.0.0.1:%d, running in DNS over HTTP mode instead of DNS over HTTPS +Configuration 'configs/dnsdist_TestDOHOverHTTPH2O.conf' OK! +""" % (DOHOverHTTP._dohServerPort) + +class DOHWithCache(object): _serverKey = 'server.key' _serverCert = 'server.chain' @@ -751,12 +776,12 @@ class TestDOHWithCache(DNSDistDOHTest): _config_template = """ newServer{address="127.0.0.1:%s"} - addDOHLocal("127.0.0.1:%s", "%s", "%s") + addDOHLocal("127.0.0.1:%s", "%s", "%s", '/dns-query', {library='%s'}) pc = newPacketCache(100, {maxTTL=86400, minTTL=1}) getPool(""):setCache(pc) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary'] def testDOHCacheLargeAnswer(self): """ @@ -949,7 +974,14 @@ def testResponsesReceivedOverUDP(self): (_, receivedResponse) = self.sendUDPQuery(expectedQuery, response=None, useQueue=False) self.assertEqual(response, receivedResponse) -class TestDOHWithoutCacheControl(DNSDistDOHTest): +class TestDOHWithCacheNGHTTP2(DOHWithCache, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + _verboseMode = True + +class TestDOHWithCacheH2O(DOHWithCache, DNSDistDOHTest): + _dohLibrary = 'h2o' + +class DOHWithoutCacheControl(object): _serverKey = 'server.key' _serverCert = 'server.chain' @@ -960,9 +992,9 @@ class TestDOHWithoutCacheControl(DNSDistDOHTest): _config_template = """ newServer{address="127.0.0.1:%s"} - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {sendCacheControlHeaders=false}) + addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {sendCacheControlHeaders=false, library='%s'}) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary'] def testDOHSimple(self): """ @@ -990,8 +1022,13 @@ def testDOHSimple(self): self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) self.assertEqual(response, receivedResponse) -class TestDOHFFI(DNSDistDOHTest): +class TestDOHWithoutCacheControlNGHTTP2(DOHWithoutCacheControl, DNSDistDOHTest): + _dohLibrary = 'nghttp2' +class TestDOHWithoutCacheControlH2O(DOHWithoutCacheControl, DNSDistDOHTest): + _dohLibrary = 'h2o' + +class DOHFFI(object): _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' @@ -1003,7 +1040,7 @@ class TestDOHFFI(DNSDistDOHTest): _config_template = """ newServer{address="127.0.0.1:%s"} - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {customResponseHeaders={["access-control-allow-origin"]="*",["user-agent"]="derp",["UPPERCASE"]="VaLuE"}, keepIncomingHeaders=true}) + addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {customResponseHeaders={["access-control-allow-origin"]="*",["user-agent"]="derp",["UPPERCASE"]="VaLuE"}, keepIncomingHeaders=true, library='%s'}) local ffi = require("ffi") @@ -1036,7 +1073,7 @@ class TestDOHFFI(DNSDistDOHTest): end addAction("http-lua-ffi.doh.tests.powerdns.com.", LuaFFIAction(dohHandler)) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_serverName', '_dohServerPort'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary', '_serverName', '_dohServerPort'] def testHTTPLuaFFIResponse(self): """ @@ -1052,8 +1089,13 @@ def testHTTPLuaFFIResponse(self): self.assertEqual(self._rcode, 200) self.assertTrue('content-type: text/plain' in self._response_headers.decode()) -class TestDOHForwardedFor(DNSDistDOHTest): +class TestDOHFFINGHTTP2(DOHFFI, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + +class TestDOHFFIH2O(DOHFFI, DNSDistDOHTest): + _dohLibrary = 'h2o' +class DOHForwardedFor(object): _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' @@ -1064,12 +1106,12 @@ class TestDOHForwardedFor(DNSDistDOHTest): newServer{address="127.0.0.1:%s"} setACL('192.0.2.1/32') - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {trustForwardedForHeader=true}) + addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {trustForwardedForHeader=true, library='%s'}) -- Set a maximum number of TCP connections per client, to exercise -- that code along with X-Forwarded-For support setMaxTCPConnectionsPerClient(2) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary'] def testDOHAllowedForwarded(self): """ @@ -1118,7 +1160,13 @@ def testDOHDeniedForwarded(self): self.assertEqual(self._rcode, 403) self.assertEqual(receivedResponse, b'DoH query not allowed because of ACL') -class TestDOHForwardedForNoTrusted(DNSDistDOHTest): +class TestDOHForwardedForNGHTTP2(DOHForwardedFor, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + +class TestDOHForwardedForH2O(DOHForwardedFor, DNSDistDOHTest): + _dohLibrary = 'h2o' + +class DOHForwardedForNoTrusted(object): _serverKey = 'server.key' _serverCert = 'server.chain' @@ -1130,9 +1178,9 @@ class TestDOHForwardedForNoTrusted(DNSDistDOHTest): newServer{address="127.0.0.1:%s"} setACL('192.0.2.1/32') - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {earlyACLDrop=true}) + addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {earlyACLDrop=true, library='%s'}) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary'] def testDOHForwardedUntrusted(self): """ @@ -1161,7 +1209,13 @@ def testDOHForwardedUntrusted(self): self.assertTrue(dropped) -class TestDOHFrontendLimits(DNSDistDOHTest): +class TestDOHForwardedForNoTrustedNGHTTP2(DOHForwardedForNoTrusted, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + +class TestDOHForwardedForNoTrustedH2O(DOHForwardedForNoTrusted, DNSDistDOHTest): + _dohLibrary = 'h2o' + +class DOHFrontendLimits(object): # this test suite uses a different responder port # because it uses a different health check configuration @@ -1174,14 +1228,13 @@ class TestDOHFrontendLimits(DNSDistDOHTest): _caCert = 'ca.pem' _dohServerPort = pickAvailablePort() _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) - _skipListeningOnCL = True _maxTCPConnsPerDOHFrontend = 5 _config_template = """ newServer{address="127.0.0.1:%s"} - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, { maxConcurrentTCPConnections=%d }) + addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, { maxConcurrentTCPConnections=%d, library='%s' }) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_maxTCPConnsPerDOHFrontend'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_maxTCPConnsPerDOHFrontend', '_dohLibrary'] _alternateListeningAddr = '127.0.0.1' _alternateListeningPort = _dohServerPort @@ -1195,7 +1248,10 @@ def testTCPConnsPerDOHFrontend(self): for idx in range(self._maxTCPConnsPerDOHFrontend + 1): try: - conns.append(self.openTLSConnection(self._dohServerPort, self._serverName, self._caCert, alpn=['h2'])) + alpn = [] + if self._dohLibrary != 'h2o': + alpn.append('h2') + conns.append(self.openTLSConnection(self._dohServerPort, self._serverName, self._caCert, alpn=alpn)) except: conns.append(None) @@ -1228,7 +1284,13 @@ def testTCPConnsPerDOHFrontend(self): self.assertEqual(count, self._maxTCPConnsPerDOHFrontend) self.assertEqual(failed, 1) -class TestProtocols(DNSDistDOHTest): +class TestDOHFrontendLimitsNGHTTP2(DOHFrontendLimits, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + +class TestDOHFrontendLimitsH2O(DOHFrontendLimits, DNSDistDOHTest): + _dohLibrary = 'h2o' + +class Protocols(object): _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' @@ -1247,9 +1309,9 @@ class TestProtocols(DNSDistDOHTest): addAction("protocols.doh.tests.powerdns.com.", LuaAction(checkDOH)) newServer{address="127.0.0.1:%s"} - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }) + addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {library='%s'}) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary'] def testProtocolDOH(self): """ @@ -1269,7 +1331,13 @@ def testProtocolDOH(self): self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) self.assertEqual(response, receivedResponse) -class TestDOHWithPKCS12Cert(DNSDistDOHTest): +class TestProtocolsNGHTTP2(Protocols, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + +class TestProtocolsH2O(Protocols, DNSDistDOHTest): + _dohLibrary = 'h2o' + +class DOHWithPKCS12Cert(object): _serverCert = 'server.p12' _pkcs12Password = 'passw0rd' _serverName = 'tls.tests.dnsdist.org' @@ -1279,11 +1347,11 @@ class TestDOHWithPKCS12Cert(DNSDistDOHTest): _config_template = """ newServer{address="127.0.0.1:%s"} cert=newTLSCertificate("%s", {password="%s"}) - addDOHLocal("127.0.0.1:%s", cert, "", { "/" }) + addDOHLocal("127.0.0.1:%s", cert, "", { "/" }, {library='%s'}) """ - _config_params = ['_testServerPort', '_serverCert', '_pkcs12Password', '_dohServerPort'] + _config_params = ['_testServerPort', '_serverCert', '_pkcs12Password', '_dohServerPort', '_dohLibrary'] - def testProtocolDOH(self): + def testPKCS12DOH(self): """ DoH: Test Simple DOH Query with a password protected PKCS12 file configured """ @@ -1306,7 +1374,13 @@ def testProtocolDOH(self): receivedQuery.id = expectedQuery.id self.assertEqual(expectedQuery, receivedQuery) -class TestDOHForwardedToTCPOnly(DNSDistDOHTest): +class TestDOHWithPKCS12CertNGHTTP2(DOHWithPKCS12Cert, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + +class TestDOHWithPKCS12CertH2O(DOHWithPKCS12Cert, DNSDistDOHTest): + _dohLibrary = 'h2o' + +class DOHForwardedToTCPOnly(object): _serverKey = 'server.key' _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' @@ -1315,9 +1389,9 @@ class TestDOHForwardedToTCPOnly(DNSDistDOHTest): _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) _config_template = """ newServer{address="127.0.0.1:%s", tcpOnly=true} - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }) + addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, {library='%s'}) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary'] def testDOHTCPOnly(self): """ @@ -1341,7 +1415,13 @@ def testDOHTCPOnly(self): self.assertEqual(receivedQuery, query) self.assertEqual(receivedResponse, response) -class TestDOHLimits(DNSDistDOHTest): +class TestDOHForwardedToTCPOnlyNGHTTP2(DOHForwardedToTCPOnly, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + +class TestDOHForwardedToTCPOnlyH2O(DOHForwardedToTCPOnly, DNSDistDOHTest): + _dohLibrary = 'h2o' + +class DOHLimits(object): _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' _dohServerPort = pickAvailablePort() @@ -1350,11 +1430,11 @@ class TestDOHLimits(DNSDistDOHTest): _serverCert = 'server.chain' _maxTCPConnsPerClient = 3 _config_template = """ - newServer{address="127.0.0.1:%s"} - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }) - setMaxTCPConnectionsPerClient(%s) + newServer{address="127.0.0.1:%d"} + addDOHLocal("127.0.0.1:%d", "%s", "%s", { "/" }, {library='%s'}) + setMaxTCPConnectionsPerClient(%d) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_maxTCPConnsPerClient'] + _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_dohLibrary', '_maxTCPConnsPerClient'] def testConnsPerClient(self): """ @@ -1394,3 +1474,9 @@ def testConnsPerClient(self): self.assertEqual(count, self._maxTCPConnsPerClient) self.assertEqual(failed, 1) + +class TestDOHLimitsNGHTTP2(DOHLimits, DNSDistDOHTest): + _dohLibrary = 'nghttp2' + +class TestDOHLimitsH2O(DOHLimits, DNSDistDOHTest): + _dohLibrary = 'h2o' From f31d8bad67d63d259fdc2756d2202daf3eb957e9 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 24 Mar 2023 18:12:26 +0100 Subject: [PATCH 623/909] dnsdist: Enable h2o in our workflows since it is now optional --- .github/workflows/codeql-analysis.yml | 2 +- tasks.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 874ec85e773a..7cb260b4291d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -120,7 +120,7 @@ jobs: run: | cd pdns/dnsdistdist autoreconf -vfi - ./configure --enable-unit-tests --enable-dnstap --enable-dnscrypt --enable-dns-over-tls --enable-dns-over-https LIBS=-lwslay CFLAGS='-O0' CXXFLAGS='-O0' + ./configure --enable-unit-tests --enable-dnstap --enable-dnscrypt --enable-dns-over-tls --enable-dns-over-https --with-h2o LIBS=-lwslay CFLAGS='-O0' CXXFLAGS='-O0' make -j8 -C ext/arc4random make -j8 -C ext/ipcrypt make -j8 -C ext/yahttp diff --git a/tasks.py b/tasks.py index ead7efb8941a..211bb424ccf1 100644 --- a/tasks.py +++ b/tasks.py @@ -458,6 +458,7 @@ def ci_dnsdist_configure(c, features): --enable-systemd \ --prefix=/opt/dnsdist \ --with-gnutls \ + --with-h2o \ --with-libsodium \ --with-lua=luajit \ --with-libcap \ @@ -472,6 +473,7 @@ def ci_dnsdist_configure(c, features): --without-cdb \ --without-ebpf \ --without-gnutls \ + --without-h2o \ --without-libedit \ --without-libsodium \ --without-lmdb \ From 1cc232f973648d911f8f3265b95889904be47d69 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 27 Mar 2023 13:42:08 +0200 Subject: [PATCH 624/909] dnsdist: Test both incoming DoH implementations in Async tests --- regression-tests.dnsdist/test_Async.py | 249 +++++++++---------------- 1 file changed, 83 insertions(+), 166 deletions(-) diff --git a/regression-tests.dnsdist/test_Async.py b/regression-tests.dnsdist/test_Async.py index 8be405df6dde..057bee47e9a7 100644 --- a/regression-tests.dnsdist/test_Async.py +++ b/regression-tests.dnsdist/test_Async.py @@ -86,6 +86,22 @@ def AsyncResponder(listenPath, responsePath): asyncResponder.start() class AsyncTests(object): + _serverKey = 'server.key' + _serverCert = 'server.chain' + _serverName = 'tls.tests.dnsdist.org' + _caCert = 'ca.pem' + _tlsServerPort = pickAvailablePort() + _dohWithNGHTTP2ServerPort = pickAvailablePort() + _dohWithH2OServerPort = pickAvailablePort() + _dohWithNGHTTP2BaseURL = ("https://%s:%d/" % (_serverName, _dohWithNGHTTP2ServerPort)) + _dohWithH2OBaseURL = ("https://%s:%d/" % (_serverName, _dohWithH2OServerPort)) + + def sendDOHWithNGHTTP2QueryWrapper(self, query, response, useQueue=True): + return self.sendDOHQuery(self._dohWithNGHTTP2ServerPort, self._serverName, self._dohWithNGHTTP2BaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) + + def sendDOHWithH2OQueryWrapper(self, query, response, useQueue=True): + return self.sendDOHQuery(self._dohWithH2OServerPort, self._serverName, self._dohWithH2OBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) + def testPass(self): """ Async: Accept @@ -101,23 +117,13 @@ def testPass(self): '192.0.2.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - def testPassCached(self): """ Async: Accept (cached) @@ -133,29 +139,21 @@ def testPassCached(self): '192.0.2.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery"): - # first time to fill the cache + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) - (receivedQuery, receivedResponse) = sender(query, response) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) + if method != 'sendDOTQueryWrapper' and method != 'sendDOHWithH2OQueryWrapper': + # first time to fill the cache + # disabled for DoT since it was already filled via TCP + (receivedQuery, receivedResponse) = sender(query, response) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + # second time from the cache sender = getattr(self, method) (_, receivedResponse) = sender(query, response=None, useQueue=False) self.assertEqual(response, receivedResponse) - (_, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=None, useQueue=False, caFile=self._caCert) - self.assertEqual(response, receivedResponse) - - (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=None, useQueue=False, caFile=self._caCert) - self.assertEqual(response, receivedResponse) - def testTimeoutThenAccept(self): """ Async: Timeout then accept @@ -171,23 +169,13 @@ def testTimeoutThenAccept(self): '192.0.2.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - def testAcceptThenTimeout(self): """ Async: Accept then timeout @@ -203,23 +191,13 @@ def testAcceptThenTimeout(self): '192.0.2.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - - (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(response, receivedResponse) - def testAcceptThenRefuse(self): """ Async: Accept then refuse @@ -239,23 +217,13 @@ def testAcceptThenRefuse(self): expectedResponse.flags |= dns.flags.RA expectedResponse.set_rcode(dns.rcode.REFUSED) - for method in ("sendUDPQuery", "sendTCPQuery"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) self.assertEqual(expectedResponse, receivedResponse) - (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(expectedResponse, receivedResponse) - - (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(expectedResponse, receivedResponse) - def testAcceptThenCustom(self): """ Async: Accept then custom @@ -278,23 +246,13 @@ def testAcceptThenCustom(self): expectedResponse.flags |= dns.flags.RA expectedResponse.set_rcode(dns.rcode.FORMERR) - for method in ("sendUDPQuery", "sendTCPQuery"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) self.assertEqual(expectedResponse, receivedResponse) - (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(expectedResponse, receivedResponse) - - (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(expectedResponse, receivedResponse) - def testAcceptThenDrop(self): """ Async: Accept then drop @@ -310,23 +268,13 @@ def testAcceptThenDrop(self): '192.0.2.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) self.assertEqual(receivedResponse, None) - (receivedQuery, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, None) - - (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert) - receivedQuery.id = query.id - self.assertEqual(query, receivedQuery) - self.assertEqual(receivedResponse, None) - def testRefused(self): """ Async: Refused @@ -338,18 +286,12 @@ def testRefused(self): expectedResponse.flags |= dns.flags.RA expectedResponse.set_rcode(dns.rcode.REFUSED) - for method in ("sendUDPQuery", "sendTCPQuery"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) (_, receivedResponse) = sender(query, response=None, useQueue=False) self.assertTrue(receivedResponse) self.assertEqual(expectedResponse, receivedResponse) - (_, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) - self.assertEqual(expectedResponse, receivedResponse) - - (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=None, caFile=self._caCert, useQueue=False) - self.assertEqual(expectedResponse, receivedResponse) - def testDrop(self): """ Async: Drop @@ -357,17 +299,11 @@ def testDrop(self): name = 'drop.async.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') - for method in ("sendUDPQuery", "sendTCPQuery"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) (_, receivedResponse) = sender(query, response=None, useQueue=False) self.assertEqual(receivedResponse, None) - (_, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) - self.assertEqual(receivedResponse, None) - - (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=None, caFile=self._caCert, useQueue=False) - self.assertEqual(receivedResponse, None) - def testCustom(self): """ Async: Custom answer @@ -379,77 +315,66 @@ def testCustom(self): expectedResponse.flags |= dns.flags.RA expectedResponse.set_rcode(dns.rcode.FORMERR) - for method in ("sendUDPQuery", "sendTCPQuery"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) (_, receivedResponse) = sender(query, response=None, useQueue=False) self.assertTrue(receivedResponse) self.assertEqual(expectedResponse, receivedResponse) - (_, receivedResponse) = self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) - self.assertEqual(expectedResponse, receivedResponse) - - (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=None, caFile=self._caCert, useQueue=False) - self.assertEqual(expectedResponse, receivedResponse) - def testTruncation(self): """ Async: DoH query, timeout then truncated answer over UDP, then valid over TCP and accept """ # the query is first forwarded over UDP, leading to a TC=1 answer from the # backend, then over TCP - name = 'timeout-then-accept.tc.async.tests.powerdns.com.' - query = dns.message.make_query(name, 'A', 'IN') - query.id = 42 - expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096) - expectedQuery.id = 42 - response = dns.message.make_response(query) - rrset = dns.rrset.from_text(name, - 3600, - dns.rdataclass.IN, - dns.rdatatype.A, - '127.0.0.1') - response.answer.append(rrset) - # first response is a TC=1 - tcResponse = dns.message.make_response(query) - tcResponse.flags |= dns.flags.TC - self._toResponderQueue.put(tcResponse, True, 2.0) - - (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, caFile=self._caCert, response=response) - # first query, received by the responder over UDP - self.assertTrue(receivedQuery) - receivedQuery.id = expectedQuery.id - self.assertEqual(expectedQuery, receivedQuery) - self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) - - # check the response - self.assertTrue(receivedResponse) - self.assertEqual(response, receivedResponse) - - # check the second query, received by the responder over TCP - receivedQuery = self._fromResponderQueue.get(True, 2.0) - self.assertTrue(receivedQuery) - receivedQuery.id = expectedQuery.id - self.assertEqual(expectedQuery, receivedQuery) - self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) + for method in ("sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + sender = getattr(self, method) + name = 'timeout-then-accept.' + method + '.tc.async.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + query.id = 42 + expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096) + expectedQuery.id = 42 + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 3600, + dns.rdataclass.IN, + dns.rdatatype.A, + '127.0.0.1') + response.answer.append(rrset) + + # first response is a TC=1 + tcResponse = dns.message.make_response(query) + tcResponse.flags |= dns.flags.TC + self._toResponderQueue.put(tcResponse, True, 2.0) -@unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled') -class TestAsyncFFI(DNSDistTest, AsyncTests): + # first query, received by the responder over UDP + (receivedQuery, receivedResponse) = sender(query, response=response) + self.assertTrue(receivedQuery) + receivedQuery.id = expectedQuery.id + self.assertEqual(expectedQuery, receivedQuery) + self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) - _serverKey = 'server.key' - _serverCert = 'server.chain' - _serverName = 'tls.tests.dnsdist.org' - _caCert = 'ca.pem' - _tlsServerPort = pickAvailablePort() - _dohServerPort = pickAvailablePort() - _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) + # check the response + self.assertTrue(receivedResponse) + self.assertEqual(response, receivedResponse) + # check the second query, received by the responder over TCP + receivedQuery = self._fromResponderQueue.get(True, 2.0) + self.assertTrue(receivedQuery) + receivedQuery.id = expectedQuery.id + self.assertEqual(expectedQuery, receivedQuery) + self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) + +@unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled') +class TestAsyncFFI(DNSDistTest, AsyncTests): _config_template = """ - newServer{address="127.0.0.1:%s", pool={'', 'cache'}} - newServer{address="127.0.0.1:%s", pool="tcp-only", tcpOnly=true } + newServer{address="127.0.0.1:%d", pool={'', 'cache'}} + newServer{address="127.0.0.1:%d", pool="tcp-only", tcpOnly=true } - addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="openssl" }) - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/"}) + addTLSLocal("127.0.0.1:%d", "%s", "%s", { provider="openssl" }) + addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="h2o"}) + addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="nghttp2"}) local ffi = require("ffi") local C = ffi.C @@ -540,26 +465,18 @@ class TestAsyncFFI(DNSDistTest, AsyncTests): """ _asyncResponderSocketPath = asyncResponderSocketPath _dnsdistSocketPath = dnsdistSocketPath - _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath'] + _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath'] _verboseMode = True @unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled') class TestAsyncLua(DNSDistTest, AsyncTests): - - _serverKey = 'server.key' - _serverCert = 'server.chain' - _serverName = 'tls.tests.dnsdist.org' - _caCert = 'ca.pem' - _tlsServerPort = pickAvailablePort() - _dohServerPort = pickAvailablePort() - _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) - _config_template = """ - newServer{address="127.0.0.1:%s", pool={'', 'cache'}} - newServer{address="127.0.0.1:%s", pool="tcp-only", tcpOnly=true } + newServer{address="127.0.0.1:%d", pool={'', 'cache'}} + newServer{address="127.0.0.1:%d", pool="tcp-only", tcpOnly=true } - addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="openssl" }) - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/"}) + addTLSLocal("127.0.0.1:%d", "%s", "%s", { provider="openssl" }) + addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="h2o"}) + addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="nghttp2"}) local filteringTagName = 'filtering' local filteringTagValue = 'pass' @@ -648,5 +565,5 @@ class TestAsyncLua(DNSDistTest, AsyncTests): """ _asyncResponderSocketPath = asyncResponderSocketPath _dnsdistSocketPath = dnsdistSocketPath - _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath'] + _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath'] _verboseMode = True From 8015d52507fc6c9ca358058c137ca7b297b5d094 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 27 Mar 2023 13:54:28 +0200 Subject: [PATCH 625/909] dnsdist: Test both incoming DoH implementations in OCSP tests --- regression-tests.dnsdist/test_OCSP.py | 51 +++++++++++++++------------ 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/regression-tests.dnsdist/test_OCSP.py b/regression-tests.dnsdist/test_OCSP.py index 953415082441..de520dcdaf50 100644 --- a/regression-tests.dnsdist/test_OCSP.py +++ b/regression-tests.dnsdist/test_OCSP.py @@ -46,17 +46,19 @@ class TestOCSPStaplingDOH(DNSDistOCSPStaplingTest): _ocspFile = 'server.ocsp' _caCert = 'ca.pem' _caKey = 'ca.key' - _dohServerPort = pickAvailablePort() + _dohWithNGHTTP2ServerPort = pickAvailablePort() + _dohWithH2OServerPort = pickAvailablePort() _config_template = """ - newServer{address="127.0.0.1:%s"} + newServer{address="127.0.0.1:%d"} setKey("%s") - controlSocket("127.0.0.1:%s") + controlSocket("127.0.0.1:%d") -- generate an OCSP response file for our certificate, valid one day generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0) - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, { ocspResponses={"%s"}}) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { "/" }, { ocspResponses={"%s"}, library='nghttp2'}) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { "/" }, { ocspResponses={"%s"}, library='h2o'}) """ - _config_params = ['_testServerPort', '_consoleKeyB64', '_consolePort', '_serverCert', '_caCert', '_caKey', '_ocspFile', '_dohServerPort', '_serverCert', '_serverKey', '_ocspFile'] + _config_params = ['_testServerPort', '_consoleKeyB64', '_consolePort', '_serverCert', '_caCert', '_caKey', '_ocspFile', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_ocspFile', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_ocspFile'] @classmethod def setUpClass(cls): @@ -75,21 +77,22 @@ def testOCSPStapling(self): """ OCSP Stapling: DOH """ - output = self.checkOCSPStaplingStatus('127.0.0.1', self._dohServerPort, self._serverName, self._caCert) - self.assertIn('OCSP Response Status: successful (0x0)', output) + for port in [self._dohWithNGHTTP2ServerPort, self._dohWithH2OServerPort]: + output = self.checkOCSPStaplingStatus('127.0.0.1', port, self._serverName, self._caCert) + self.assertIn('OCSP Response Status: successful (0x0)', output) - serialNumber = self.getOCSPSerial(output) - self.assertTrue(serialNumber) + serialNumber = self.getOCSPSerial(output) + self.assertTrue(serialNumber) - self.generateNewCertificateAndKey() - self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile)) - self.sendConsoleCommand("reloadAllCertificates()") + self.generateNewCertificateAndKey() + self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile)) + self.sendConsoleCommand("reloadAllCertificates()") - output = self.checkOCSPStaplingStatus('127.0.0.1', self._dohServerPort, self._serverName, self._caCert) - self.assertIn('OCSP Response Status: successful (0x0)', output) - serialNumber2 = self.getOCSPSerial(output) - self.assertTrue(serialNumber2) - self.assertNotEqual(serialNumber, serialNumber2) + output = self.checkOCSPStaplingStatus('127.0.0.1', port, self._serverName, self._caCert) + self.assertIn('OCSP Response Status: successful (0x0)', output) + serialNumber2 = self.getOCSPSerial(output) + self.assertTrue(serialNumber2) + self.assertNotEqual(serialNumber, serialNumber2) class TestBrokenOCSPStaplingDoH(DNSDistOCSPStaplingTest): @@ -101,22 +104,26 @@ class TestBrokenOCSPStaplingDoH(DNSDistOCSPStaplingTest): _caCert = 'ca.pem' # invalid OCSP file! _ocspFile = '/dev/null' - _tlsServerPort = pickAvailablePort() + _dohWithNGHTTP2ServerPort = pickAvailablePort() + _dohWithH2OServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%s"} setKey("%s") controlSocket("127.0.0.1:%s") - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, { ocspResponses={"%s"}}) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { "/" }, { ocspResponses={"%s"}, library='nghttp2'}) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { "/" }, { ocspResponses={"%s"}, library='h2o'}) + """ - _config_params = ['_testServerPort', '_consoleKeyB64', '_consolePort', '_tlsServerPort', '_serverCert', '_serverKey', '_ocspFile'] + _config_params = ['_testServerPort', '_consoleKeyB64', '_consolePort', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_ocspFile', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_ocspFile'] def testBrokenOCSPStapling(self): """ OCSP Stapling: Broken (DoH) """ - output = self.checkOCSPStaplingStatus('127.0.0.1', self._tlsServerPort, self._serverName, self._caCert) - self.assertNotIn('OCSP Response Status: successful (0x0)', output) + for port in [self._dohWithNGHTTP2ServerPort, self._dohWithH2OServerPort]: + output = self.checkOCSPStaplingStatus('127.0.0.1', port, self._serverName, self._caCert) + self.assertNotIn('OCSP Response Status: successful (0x0)', output) class TestOCSPStaplingTLSGnuTLS(DNSDistOCSPStaplingTest): From b030f5bb217c2f247169508035a1e49a0b41d05a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 27 Mar 2023 13:54:49 +0200 Subject: [PATCH 626/909] dnsdist: Test both incoming DoH implementations in Protobuf tests --- regression-tests.dnsdist/test_Protobuf.py | 35 ++++++++++++++++------- 1 file changed, 25 insertions(+), 10 deletions(-) diff --git a/regression-tests.dnsdist/test_Protobuf.py b/regression-tests.dnsdist/test_Protobuf.py index 092cdef74534..8a5aac6b2e38 100644 --- a/regression-tests.dnsdist/test_Protobuf.py +++ b/regression-tests.dnsdist/test_Protobuf.py @@ -492,20 +492,29 @@ class TestProtobufMetaDOH(DNSDistProtobufTest): _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' _tlsServerPort = pickAvailablePort() - _dohServerPort = pickAvailablePort() - _dohBaseURL = ("https://%s:%d/dns-query" % (_serverName, _dohServerPort)) - _config_params = ['_testServerPort', '_protobufServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohServerPort', '_serverCert', '_serverKey'] + _dohWithNGHTTP2ServerPort = pickAvailablePort() + _dohWithNGHTTP2BaseURL = ("https://%s:%d/dns-query" % (_serverName, _dohWithNGHTTP2ServerPort)) + _dohWithH2OServerPort = pickAvailablePort() + _dohWithH2OBaseURL = ("https://%s:%d/dns-query" % (_serverName, _dohWithH2OServerPort)) _config_template = """ newServer{address="127.0.0.1:%d"} rl = newRemoteLogger('127.0.0.1:%d') addTLSLocal("127.0.0.1:%s", "%s", "%s", { provider="openssl" }) - addDOHLocal("127.0.0.1:%s", "%s", "%s", { '/dns-query' }, { keepIncomingHeaders=true }) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { '/dns-query' }, { keepIncomingHeaders=true, library='nghttp2' }) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { '/dns-query' }, { keepIncomingHeaders=true, library='h2o' }) local mytags = {path='doh-path', host='doh-host', ['query-string']='doh-query-string', scheme='doh-scheme', agent='doh-header:user-agent'} addAction(AllRule(), RemoteLogAction(rl, nil, {serverID='dnsdist-server-1'}, mytags)) addResponseAction(AllRule(), RemoteLogResponseAction(rl, nil, false, {serverID='dnsdist-server-1'}, mytags)) """ + _config_params = ['_testServerPort', '_protobufServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey'] + + def sendDOHWithNGHTTP2QueryWrapper(self, query, response, useQueue=True): + return self.sendDOHQuery(self._dohWithNGHTTP2ServerPort, self._serverName, self._dohWithNGHTTP2BaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) + + def sendDOHWithH2OQueryWrapper(self, query, response, useQueue=True): + return self.sendDOHQuery(self._dohWithH2OServerPort, self._serverName, self._dohWithH2OBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) def testProtobufMetaDoH(self): """ @@ -521,7 +530,7 @@ def testProtobufMetaDoH(self): '127.0.0.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) @@ -543,7 +552,7 @@ def testProtobufMetaDoH(self): pbMessageType = dnsmessage_pb2.PBDNSMessage.TCP elif method == "sendDOTQueryWrapper": pbMessageType = dnsmessage_pb2.PBDNSMessage.DOT - elif method == "sendDOHQueryWrapper": + elif method == "sendDOHWithNGHTTP2QueryWrapper" or method == "sendDOHWithH2OQueryWrapper": pbMessageType = dnsmessage_pb2.PBDNSMessage.DOH self.checkProtobufQuery(msg, pbMessageType, query, dns.rdataclass.IN, dns.rdatatype.A, name) @@ -554,10 +563,13 @@ def testProtobufMetaDoH(self): tags[entry.key] = entry.value.stringVal[0] self.assertIn('agent', tags) - if method == "sendDOHQueryWrapper": + if method == "sendDOHWithNGHTTP2QueryWrapper" or method == "sendDOHWithH2OQueryWrapper": self.assertIn('PycURL', tags['agent']) self.assertIn('host', tags) - self.assertEqual(tags['host'], self._serverName + ':' + str(self._dohServerPort)) + if method == "sendDOHWithNGHTTP2QueryWrapper": + self.assertEqual(tags['host'], self._serverName + ':' + str(self._dohWithNGHTTP2ServerPort)) + elif method == "sendDOHWithH2OQueryWrapper": + self.assertEqual(tags['host'], self._serverName + ':' + str(self._dohWithH2OServerPort)) self.assertIn('path', tags) self.assertEqual(tags['path'], '/dns-query') self.assertIn('query-string', tags) @@ -575,10 +587,13 @@ def testProtobufMetaDoH(self): tags[entry.key] = entry.value.stringVal[0] self.assertIn('agent', tags) - if method == "sendDOHQueryWrapper": + if method == "sendDOHWithNGHTTP2QueryWrapper" or method == "sendDOHWithH2OQueryWrapper": self.assertIn('PycURL', tags['agent']) self.assertIn('host', tags) - self.assertEqual(tags['host'], self._serverName + ':' + str(self._dohServerPort)) + if method == "sendDOHWithNGHTTP2QueryWrapper": + self.assertEqual(tags['host'], self._serverName + ':' + str(self._dohWithNGHTTP2ServerPort)) + elif method == "sendDOHWithH2OQueryWrapper": + self.assertEqual(tags['host'], self._serverName + ':' + str(self._dohWithH2OServerPort)) self.assertIn('path', tags) self.assertEqual(tags['path'], '/dns-query') self.assertIn('query-string', tags) From 2f4ac048d066519a14834321026ba58fbb673ef2 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 27 Mar 2023 14:30:57 +0200 Subject: [PATCH 627/909] dnsdist: Test both incoming DoH implementations in ProxyProtocol tests --- regression-tests.dnsdist/dnsdisttests.py | 6 + regression-tests.dnsdist/test_Async.py | 6 - regression-tests.dnsdist/test_Protobuf.py | 6 - .../test_ProxyProtocol.py | 116 +++++++++--------- 4 files changed, 67 insertions(+), 67 deletions(-) diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 6bc56cdb7a71..1e7968aa3d2d 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -1079,5 +1079,11 @@ def sendDOHPostQuery(cls, port, servername, baseurl, query, response=None, timeo def sendDOHQueryWrapper(self, query, response, useQueue=True): return self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) + def sendDOHWithNGHTTP2QueryWrapper(self, query, response, useQueue=True): + return self.sendDOHQuery(self._dohWithNGHTTP2ServerPort, self._serverName, self._dohWithNGHTTP2BaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) + + def sendDOHWithH2OQueryWrapper(self, query, response, useQueue=True): + return self.sendDOHQuery(self._dohWithH2OServerPort, self._serverName, self._dohWithH2OBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) + def sendDOTQueryWrapper(self, query, response, useQueue=True): return self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response, self._caCert, useQueue=useQueue) diff --git a/regression-tests.dnsdist/test_Async.py b/regression-tests.dnsdist/test_Async.py index 057bee47e9a7..8856df30f59a 100644 --- a/regression-tests.dnsdist/test_Async.py +++ b/regression-tests.dnsdist/test_Async.py @@ -96,12 +96,6 @@ class AsyncTests(object): _dohWithNGHTTP2BaseURL = ("https://%s:%d/" % (_serverName, _dohWithNGHTTP2ServerPort)) _dohWithH2OBaseURL = ("https://%s:%d/" % (_serverName, _dohWithH2OServerPort)) - def sendDOHWithNGHTTP2QueryWrapper(self, query, response, useQueue=True): - return self.sendDOHQuery(self._dohWithNGHTTP2ServerPort, self._serverName, self._dohWithNGHTTP2BaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) - - def sendDOHWithH2OQueryWrapper(self, query, response, useQueue=True): - return self.sendDOHQuery(self._dohWithH2OServerPort, self._serverName, self._dohWithH2OBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) - def testPass(self): """ Async: Accept diff --git a/regression-tests.dnsdist/test_Protobuf.py b/regression-tests.dnsdist/test_Protobuf.py index 8a5aac6b2e38..99a97183de7a 100644 --- a/regression-tests.dnsdist/test_Protobuf.py +++ b/regression-tests.dnsdist/test_Protobuf.py @@ -510,12 +510,6 @@ class TestProtobufMetaDOH(DNSDistProtobufTest): """ _config_params = ['_testServerPort', '_protobufServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey'] - def sendDOHWithNGHTTP2QueryWrapper(self, query, response, useQueue=True): - return self.sendDOHQuery(self._dohWithNGHTTP2ServerPort, self._serverName, self._dohWithNGHTTP2BaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) - - def sendDOHWithH2OQueryWrapper(self, query, response, useQueue=True): - return self.sendDOHQuery(self._dohWithH2OServerPort, self._serverName, self._dohWithH2OBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) - def testProtobufMetaDoH(self): """ Protobuf: Meta values - DoH diff --git a/regression-tests.dnsdist/test_ProxyProtocol.py b/regression-tests.dnsdist/test_ProxyProtocol.py index 1d7aa5c5c900..2ff4a2d74100 100644 --- a/regression-tests.dnsdist/test_ProxyProtocol.py +++ b/regression-tests.dnsdist/test_ProxyProtocol.py @@ -729,23 +729,27 @@ class TestDOHWithOutgoingProxyProtocol(DNSDistDOHTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = pickAvailablePort() - _dohBaseURL = ("https://%s:%d/dns-query" % (_serverName, _dohServerPort)) + _dohWithNGHTTP2ServerPort = pickAvailablePort() + _dohWithNGHTTP2BaseURL = ("https://%s:%d/dns-query" % (_serverName, _dohWithNGHTTP2ServerPort)) + _dohWithH2OServerPort = pickAvailablePort() + _dohWithH2OBaseURL = ("https://%s:%d/dns-query" % (_serverName, _dohWithH2OServerPort)) _proxyResponderPort = proxyResponderPort _config_template = """ newServer{address="127.0.0.1:%s", useProxyProtocol=true} - addDOHLocal("127.0.0.1:%s", "%s", "%s", { '/dns-query' }, { trustForwardedForHeader=true }) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { '/dns-query' }, { trustForwardedForHeader=true, library='nghttp2' }) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { '/dns-query' }, { trustForwardedForHeader=true, library='h2o' }) setACL( { "::1/128", "127.0.0.0/8" } ) """ - _config_params = ['_proxyResponderPort', '_dohServerPort', '_serverCert', '_serverKey'] + _config_params = ['_proxyResponderPort', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey'] + _verboseMode = True def testTruncation(self): """ - DOH: Truncation over UDP (with cache) + DOH: Truncation over UDP """ # the query is first forwarded over UDP, leading to a TC=1 answer from the # backend, then over TCP - name = 'truncated-udp.doh-with-cache.tests.powerdns.com.' + name = 'truncated-udp.doh.proxy-protocol.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') query.id = 42 expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096) @@ -758,39 +762,40 @@ def testTruncation(self): '127.0.0.1') response.answer.append(rrset) - # first response is a TC=1 - tcResponse = dns.message.make_response(query) - tcResponse.flags |= dns.flags.TC - toProxyQueue.put(tcResponse, True, 2.0) + for (port,url) in [(self._dohWithNGHTTP2ServerPort, self._dohWithNGHTTP2BaseURL), (self._dohWithH2OServerPort, self._dohWithH2OBaseURL)]: + # first response is a TC=1 + tcResponse = dns.message.make_response(query) + tcResponse.flags |= dns.flags.TC + toProxyQueue.put(tcResponse, True, 2.0) - ((receivedProxyPayload, receivedDNSData), receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, caFile=self._caCert, response=response, fromQueue=fromProxyQueue, toQueue=toProxyQueue) - # first query, received by the responder over UDP - self.assertTrue(receivedProxyPayload) - self.assertTrue(receivedDNSData) - receivedQuery = dns.message.from_wire(receivedDNSData) - self.assertTrue(receivedQuery) - receivedQuery.id = expectedQuery.id - self.assertEqual(expectedQuery, receivedQuery) - self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) - self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.1', '127.0.0.1', True, destinationPort=self._dohServerPort) + ((receivedProxyPayload, receivedDNSData), receivedResponse) = self.sendDOHQuery(port, self._serverName, url, query, caFile=self._caCert, response=response, fromQueue=fromProxyQueue, toQueue=toProxyQueue) + # first query, received by the responder over UDP + self.assertTrue(receivedProxyPayload) + self.assertTrue(receivedDNSData) + receivedQuery = dns.message.from_wire(receivedDNSData) + self.assertTrue(receivedQuery) + receivedQuery.id = expectedQuery.id + self.assertEqual(expectedQuery, receivedQuery) + self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) + self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.1', '127.0.0.1', True, destinationPort=port) - # check the response - self.assertTrue(receivedResponse) - self.assertEqual(response, receivedResponse) + # check the response + self.assertTrue(receivedResponse) + self.assertEqual(response, receivedResponse) - # check the second query, received by the responder over TCP - (receivedProxyPayload, receivedDNSData) = fromProxyQueue.get(True, 2.0) - self.assertTrue(receivedDNSData) - receivedQuery = dns.message.from_wire(receivedDNSData) - self.assertTrue(receivedQuery) - receivedQuery.id = expectedQuery.id - self.assertEqual(expectedQuery, receivedQuery) - self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) - self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.1', '127.0.0.1', True, destinationPort=self._dohServerPort) + # check the second query, received by the responder over TCP + (receivedProxyPayload, receivedDNSData) = fromProxyQueue.get(True, 2.0) + self.assertTrue(receivedDNSData) + receivedQuery = dns.message.from_wire(receivedDNSData) + self.assertTrue(receivedQuery) + receivedQuery.id = expectedQuery.id + self.assertEqual(expectedQuery, receivedQuery) + self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) + self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.1', '127.0.0.1', True, destinationPort=port) - # make sure we consumed everything - self.assertTrue(toProxyQueue.empty()) - self.assertTrue(fromProxyQueue.empty()) + # make sure we consumed everything + self.assertTrue(toProxyQueue.empty()) + self.assertTrue(fromProxyQueue.empty()) def testAddressFamilyMismatch(self): """ @@ -809,25 +814,26 @@ def testAddressFamilyMismatch(self): '127.0.0.1') response.answer.append(rrset) - # the query should be dropped - (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, caFile=self._caCert, customHeaders=['x-forwarded-for: [::1]:8080'], useQueue=False) - self.assertFalse(receivedQuery) - self.assertFalse(receivedResponse) + for (port,url) in [(self._dohWithNGHTTP2ServerPort, self._dohWithNGHTTP2BaseURL), (self._dohWithH2OServerPort, self._dohWithH2OBaseURL)]: + # the query should be dropped + (receivedQuery, receivedResponse) = self.sendDOHQuery(port, self._serverName, url, query, caFile=self._caCert, customHeaders=['x-forwarded-for: [::1]:8080'], useQueue=False) + self.assertFalse(receivedQuery) + self.assertFalse(receivedResponse) - # make sure the timeout is detected, if any - time.sleep(4) + # make sure the timeout is detected, if any + time.sleep(4) - # this one should not - ((receivedProxyPayload, receivedDNSData), receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, caFile=self._caCert, customHeaders=['x-forwarded-for: 127.0.0.42:8080'], response=response, fromQueue=fromProxyQueue, toQueue=toProxyQueue) - self.assertTrue(receivedProxyPayload) - self.assertTrue(receivedDNSData) - receivedQuery = dns.message.from_wire(receivedDNSData) - self.assertTrue(receivedQuery) - receivedQuery.id = expectedQuery.id - self.assertEqual(expectedQuery, receivedQuery) - self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) - self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.42', '127.0.0.1', True, destinationPort=self._dohServerPort) - # check the response - self.assertTrue(receivedResponse) - receivedResponse.id = response.id - self.assertEqual(response, receivedResponse) + # this one should not + ((receivedProxyPayload, receivedDNSData), receivedResponse) = self.sendDOHQuery(port, self._serverName, url, query, caFile=self._caCert, customHeaders=['x-forwarded-for: 127.0.0.42:8080'], response=response, fromQueue=fromProxyQueue, toQueue=toProxyQueue) + self.assertTrue(receivedProxyPayload) + self.assertTrue(receivedDNSData) + receivedQuery = dns.message.from_wire(receivedDNSData) + self.assertTrue(receivedQuery) + receivedQuery.id = expectedQuery.id + self.assertEqual(expectedQuery, receivedQuery) + self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) + self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.42', '127.0.0.1', True, destinationPort=port) + # check the response + self.assertTrue(receivedResponse) + receivedResponse.id = response.id + self.assertEqual(response, receivedResponse) From 188dbe7176cbb364b45eec5e622263989ebd79fd Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 27 Mar 2023 14:48:19 +0200 Subject: [PATCH 628/909] dnsdist: Test both incoming DoH implementations for TLS resumption --- .../test_TLSSessionResumption.py | 166 +++++++++--------- 1 file changed, 86 insertions(+), 80 deletions(-) diff --git a/regression-tests.dnsdist/test_TLSSessionResumption.py b/regression-tests.dnsdist/test_TLSSessionResumption.py index 0cacf448cf05..97eb826c3be7 100644 --- a/regression-tests.dnsdist/test_TLSSessionResumption.py +++ b/regression-tests.dnsdist/test_TLSSessionResumption.py @@ -65,21 +65,24 @@ class TestNoTLSSessionResumptionDOH(DNSDistTLSSessionResumptionTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = pickAvailablePort() + _dohWithNGHTTP2ServerPort = pickAvailablePort() + _dohWithH2OServerPort = pickAvailablePort() _numberOfKeys = 0 _config_template = """ newServer{address="127.0.0.1:%s"} - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, { numberOfTicketsKeys=%d, numberOfStoredSessions=0, sessionTickets=false }) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { "/" }, { numberOfTicketsKeys=%d, numberOfStoredSessions=0, sessionTickets=false, library='nghttp2' }) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { "/" }, { numberOfTicketsKeys=%d, numberOfStoredSessions=0, sessionTickets=false, library='h2o' }) """ - _config_params = ['_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_numberOfKeys'] + _config_params = ['_testServerPort', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_numberOfKeys', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_numberOfKeys'] def testNoSessionResumption(self): """ Session Resumption: DoH (disabled) """ - self.assertFalse(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/no-session.out.doh', None, allowNoTicket=True)) - self.assertFalse(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/no-session.out.doh', '/tmp/no-session.out.doh', allowNoTicket=True)) + for port in [self._dohWithNGHTTP2ServerPort, self._dohWithH2OServerPort]: + self.assertFalse(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/no-session.out.doh', None, allowNoTicket=True)) + self.assertFalse(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/no-session.out.doh', '/tmp/no-session.out.doh', allowNoTicket=True)) @unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled') class TestTLSSessionResumptionDOH(DNSDistTLSSessionResumptionTest): @@ -88,93 +91,96 @@ class TestTLSSessionResumptionDOH(DNSDistTLSSessionResumptionTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = pickAvailablePort() + _dohWithNGHTTP2ServerPort = pickAvailablePort() + _dohWithH2OServerPort = pickAvailablePort() _numberOfKeys = 5 _config_template = """ setKey("%s") controlSocket("127.0.0.1:%s") newServer{address="127.0.0.1:%s"} - addDOHLocal("127.0.0.1:%s", "%s", "%s", { "/" }, { numberOfTicketsKeys=%d }) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { "/" }, { numberOfTicketsKeys=%d, library='nghttp2' }) + addDOHLocal("127.0.0.1:%d", "%s", "%s", { "/" }, { numberOfTicketsKeys=%d, library='h2o' }) """ - _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_dohServerPort', '_serverCert', '_serverKey', '_numberOfKeys'] + _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_numberOfKeys', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_numberOfKeys'] def testSessionResumption(self): """ Session Resumption: DoH """ - self.assertFalse(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', None)) - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh', allowNoTicket=True)) - - # rotate the TLS session ticket keys several times, but keep the previously active one around so we can resume - for _ in range(self._numberOfKeys - 1): - self.sendConsoleCommand("getDOHFrontend(0):rotateTicketsKey()") - - # the session should be resumed and a new ticket, encrypted with the newly active key, should be stored - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh')) - - # rotate the TLS session ticket keys several times, but keep the previously active one around so we can resume - for _ in range(self._numberOfKeys - 1): - self.sendConsoleCommand("getDOHFrontend(0):rotateTicketsKey()") - - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh')) - - # rotate the TLS session ticket keys several times, not keeping any key around this time! - for _ in range(self._numberOfKeys): - self.sendConsoleCommand("getDOHFrontend(0):rotateTicketsKey()") - - # we should not be able to resume - self.assertFalse(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh')) - - # generate a file containing _numberOfKeys ticket keys - self.generateTicketKeysFile(self._numberOfKeys, '/tmp/ticketKeys.1') - self.generateTicketKeysFile(self._numberOfKeys - 1, '/tmp/ticketKeys.2') - # load all ticket keys from the file - self.sendConsoleCommand("getDOHFrontend(0):loadTicketsKeys('/tmp/ticketKeys.1')") - - # create a new session, resume it - self.assertFalse(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', None)) - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh', allowNoTicket=True)) - - # reload the same keys - self.sendConsoleCommand("getDOHFrontend(0):loadTicketsKeys('/tmp/ticketKeys.1')") - - # should still be able to resume - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh', allowNoTicket=True)) - - # rotate the TLS session ticket keys several times, but keep the previously active one around so we can resume - for _ in range(self._numberOfKeys - 1): - self.sendConsoleCommand("getDOHFrontend(0):rotateTicketsKey()") - # should still be able to resume - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh')) - - # reload the same keys - self.sendConsoleCommand("getDOHFrontend(0):loadTicketsKeys('/tmp/ticketKeys.1')") - # since the last key was only present in memory, we should not be able to resume - self.assertFalse(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh')) - - # but now we can - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh', allowNoTicket=True)) - - # generate a file with only _numberOfKeys - 1 keys, so the last active one should still be around after loading that one - self.generateTicketKeysFile(self._numberOfKeys - 1, '/tmp/ticketKeys.2') - self.sendConsoleCommand("getDOHFrontend(0):loadTicketsKeys('/tmp/ticketKeys.2')") - # we should be able to resume, and the ticket should be re-encrypted with the new key (NOTE THAT we store into a new file!!) - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh.2', '/tmp/session.doh')) - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh.2', '/tmp/session.doh.2', allowNoTicket=True)) - - # rotate all keys, we should not be able to resume - for _ in range(self._numberOfKeys): - self.sendConsoleCommand("getDOHFrontend(0):rotateTicketsKey()") - self.assertFalse(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh.3', '/tmp/session.doh.2')) - - # reload from file 1, the old session should resume - self.sendConsoleCommand("getDOHFrontend(0):loadTicketsKeys('/tmp/ticketKeys.1')") - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh', allowNoTicket=True)) - - # reload from file 2, the latest session should resume - self.sendConsoleCommand("getDOHFrontend(0):loadTicketsKeys('/tmp/ticketKeys.2')") - self.assertTrue(self.checkSessionResumed('127.0.0.1', self._dohServerPort, self._serverName, self._caCert, '/tmp/session.doh.2', '/tmp/session.doh.2', allowNoTicket=True)) + for (port, bindIdx) in [(self._dohWithNGHTTP2ServerPort, 0), (self._dohWithH2OServerPort, 1)]: + self.assertFalse(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', None)) + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh', allowNoTicket=True)) + + # rotate the TLS session ticket keys several times, but keep the previously active one around so we can resume + for _ in range(self._numberOfKeys - 1): + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):rotateTicketsKey()") + + # the session should be resumed and a new ticket, encrypted with the newly active key, should be stored + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh')) + + # rotate the TLS session ticket keys several times, but keep the previously active one around so we can resume + for _ in range(self._numberOfKeys - 1): + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):rotateTicketsKey()") + + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh')) + + # rotate the TLS session ticket keys several times, not keeping any key around this time! + for _ in range(self._numberOfKeys): + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):rotateTicketsKey()") + + # we should not be able to resume + self.assertFalse(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh')) + + # generate a file containing _numberOfKeys ticket keys + self.generateTicketKeysFile(self._numberOfKeys, '/tmp/ticketKeys.1') + self.generateTicketKeysFile(self._numberOfKeys - 1, '/tmp/ticketKeys.2') + # load all ticket keys from the file + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):loadTicketsKeys('/tmp/ticketKeys.1')") + + # create a new session, resume it + self.assertFalse(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', None)) + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh', allowNoTicket=True)) + + # reload the same keys + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):loadTicketsKeys('/tmp/ticketKeys.1')") + + # should still be able to resume + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh', allowNoTicket=True)) + + # rotate the TLS session ticket keys several times, but keep the previously active one around so we can resume + for _ in range(self._numberOfKeys - 1): + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):rotateTicketsKey()") + # should still be able to resume + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh')) + + # reload the same keys + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):loadTicketsKeys('/tmp/ticketKeys.1')") + # since the last key was only present in memory, we should not be able to resume + self.assertFalse(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh')) + + # but now we can + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh', allowNoTicket=True)) + + # generate a file with only _numberOfKeys - 1 keys, so the last active one should still be around after loading that one + self.generateTicketKeysFile(self._numberOfKeys - 1, '/tmp/ticketKeys.2') + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):loadTicketsKeys('/tmp/ticketKeys.2')") + # we should be able to resume, and the ticket should be re-encrypted with the new key (NOTE THAT we store into a new file!!) + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh.2', '/tmp/session.doh')) + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh.2', '/tmp/session.doh.2', allowNoTicket=True)) + + # rotate all keys, we should not be able to resume + for _ in range(self._numberOfKeys): + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):rotateTicketsKey()") + self.assertFalse(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh.3', '/tmp/session.doh.2')) + + # reload from file 1, the old session should resume + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):loadTicketsKeys('/tmp/ticketKeys.1')") + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh', '/tmp/session.doh', allowNoTicket=True)) + + # reload from file 2, the latest session should resume + self.sendConsoleCommand(f"getDOHFrontend({bindIdx}):loadTicketsKeys('/tmp/ticketKeys.2')") + self.assertTrue(self.checkSessionResumed('127.0.0.1', port, self._serverName, self._caCert, '/tmp/session.doh.2', '/tmp/session.doh.2', allowNoTicket=True)) class TestNoTLSSessionResumptionDOT(DNSDistTLSSessionResumptionTest): From e80c3b09f318380b6536cfdd83c07b1c8a84edd7 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 21 Jun 2023 10:55:28 +0200 Subject: [PATCH 629/909] dnsdist: Implement read-ahead support for incoming TLS connections Read-ahead instructs OpenSSL to read more than the number of bytes we requested from the incoming connection, if possible, and to buffer it. This provides a huge performance boost by reducing the number of syscalls because in most cases the data is already available on the socket to be read even if we cannot know that yet without reading the data length. There are two drawbacks: - we can keep reading on a connection in a loop as long as there is data available, which should be prevented by our number of concurrent requests limit ; - we need to always try to read all the data available before asking the kernel to wake us up when the socket is readable, because the data buffered by OpenSSL is obviously not visible to the kernel so we could wait forever. --- pdns/dnsdist-lua.cc | 1 + pdns/dnsdist-tcp.cc | 2 +- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 31 ++++++++++++++++---------- pdns/dnsdistdist/dnsdist-nghttp2-in.hh | 4 +++- pdns/libssl.hh | 2 ++ pdns/tcpiohandler.cc | 4 ++++ 6 files changed, 30 insertions(+), 14 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index fedd9c5d868a..c09ff65aead4 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -226,6 +226,7 @@ static void parseTLSConfig(TLSConfig& config, const std::string& context, boost: getOptionalValue(vars, "enableRenegotiation", config.d_enableRenegotiation); getOptionalValue(vars, "tlsAsyncMode", config.d_asyncMode); getOptionalValue(vars, "ktls", config.d_ktls); + getOptionalValue(vars, "readAhead", config.d_readAhead); } #endif // defined(HAVE_DNS_OVER_TLS) || defined(HAVE_DNS_OVER_HTTPS) diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 751ba986722a..8d10e492575b 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -375,7 +375,7 @@ void IncomingTCPConnectionState::terminateClientConnection() void IncomingTCPConnectionState::queueResponse(std::shared_ptr& state, const struct timeval& now, TCPResponse&& response) { // queue response - state->d_queuedResponses.push_back(std::move(response)); + state->d_queuedResponses.emplace_back(std::move(response)); DEBUGLOG("queueing response, state is "<<(int)state->d_state<<", queue size is now "<d_queuedResponses.size()); // when the response comes from a backend, there is a real possibility that we are currently diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 95b5705fd142..8b4f237c9f15 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -274,6 +274,7 @@ void IncomingHTTP2Connection::handleConnectionReady() if (ret != 0) { throw std::runtime_error("Fatal error: " + std::string(nghttp2_strerror(ret))); } + d_needFlush = true; ret = nghttp2_session_send(d_session.get()); if (ret != 0) { throw std::runtime_error("Fatal error: " + std::string(nghttp2_strerror(ret))); @@ -334,7 +335,7 @@ void IncomingHTTP2Connection::handleIO() } } - if (d_state == State::waitingForQuery) { + if (d_state == State::waitingForQuery || d_state == State::idle) { readHTTPData(); } @@ -358,11 +359,11 @@ void IncomingHTTP2Connection::handleIO() ssize_t IncomingHTTP2Connection::send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data) { IncomingHTTP2Connection* conn = reinterpret_cast(user_data); - bool bufferWasEmpty = conn->d_out.empty(); conn->d_out.insert(conn->d_out.end(), data, data + length); - if (bufferWasEmpty) { + if (conn->d_connectionDied || conn->d_needFlush) { try { + conn->d_needFlush = false; auto state = conn->d_handler.tryWrite(conn->d_out, conn->d_outPos, conn->d_out.size()); if (state == IOState::Done) { conn->d_out.clear(); @@ -379,7 +380,7 @@ ssize_t IncomingHTTP2Connection::send_callback(nghttp2_session* session, const u } } catch (const std::exception& e) { - vinfolog("Exception while trying to write (send) to incoming HTTP connection: %s", e.what()); + vinfolog("Exception while trying to write (send) to incoming HTTP connection to %s: %s", conn->d_ci.remote.toStringWithPort(), e.what()); conn->handleIOError(); } } @@ -412,8 +413,7 @@ static const std::array(NGHTTP2Headers::H "dns-over-tcp", "dns-over-tls", "dns-over-http", - "dns-over-https" -}; + "dns-over-https"}; static const std::string s_authorityHeaderName(":authority"); static const std::string s_pathHeaderName(":path"); @@ -500,6 +500,7 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str if (obj.d_queryPos >= obj.d_buffer.size()) { *data_flags |= NGHTTP2_DATA_FLAG_EOF; obj.d_buffer.clear(); + connection->d_needFlush = true; } return toCopy; }; @@ -691,7 +692,7 @@ static std::optional getPayloadFromPath(const std::string_view& pa } sdns.reserve(payloadSize + neededPadding); sdns = path.substr(pos + 5); - for (auto &entry : sdns) { + for (auto& entry : sdns) { switch (entry) { case '-': entry = '+'; @@ -1079,12 +1080,15 @@ int IncomingHTTP2Connection::on_error_callback(nghttp2_session* session, int lib void IncomingHTTP2Connection::readHTTPData() { + IOState newState; IOStateGuard ioGuard(d_ioState); do { size_t got = 0; - d_in.resize(d_in.size() + 512); + if (d_in.size() < 128) { + d_in.resize(std::max(static_cast(128U), d_in.capacity())); + } try { - IOState newState = d_handler.tryRead(d_in, got, d_in.size(), true); + newState = d_handler.tryRead(d_in, got, d_in.size(), true); d_in.resize(got); if (got > 0) { @@ -1100,6 +1104,9 @@ void IncomingHTTP2Connection::readHTTPData() } if (newState == IOState::Done) { + if (nghttp2_session_want_read(d_session.get())) { + continue; + } if (isIdle()) { watchForRemoteHostClosingConnection(); ioGuard.release(); @@ -1115,11 +1122,11 @@ void IncomingHTTP2Connection::readHTTPData() } } catch (const std::exception& e) { - vinfolog("Exception while trying to read from HTTP backend connection: %s", e.what()); + vinfolog("Exception while trying to read from HTTP client connection to %s: %s", d_ci.remote.toStringWithPort(), e.what()); handleIOError(); break; } - } while (getConcurrentStreamsCount() > 0); + } while (newState == IOState::Done || !isIdle()); } void IncomingHTTP2Connection::handleReadableIOCallback(int fd, FDMultiplexer::funcparam_t& param) @@ -1151,7 +1158,7 @@ void IncomingHTTP2Connection::handleWritableIOCallback(int fd, FDMultiplexer::fu ioGuard.release(); } catch (const std::exception& e) { - vinfolog("Exception while trying to write (ready) to HTTP backend connection: %s", e.what()); + vinfolog("Exception while trying to write (ready) to HTTP client connection to %s: %s", conn->d_ci.remote.toStringWithPort(), e.what()); conn->handleIOError(); } } diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh index 1fa2b83a2ee5..8d828dbb9ac8 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -101,12 +101,14 @@ private: PacketBuffer d_in; size_t d_outPos{0}; bool d_connectionDied{false}; + bool d_needFlush{false}; }; class NGHTTP2Headers { public: - enum class HeaderConstantIndexes { + enum class HeaderConstantIndexes + { OK_200_VALUE = 0, METHOD_NAME, METHOD_VALUE, diff --git a/pdns/libssl.hh b/pdns/libssl.hh index a8c30bf25a6c..feb90cbea3bd 100644 --- a/pdns/libssl.hh +++ b/pdns/libssl.hh @@ -53,6 +53,8 @@ public: bool d_asyncMode{false}; /* enable kTLS mode, if supported */ bool d_ktls{false}; + /* set read ahead mode, if supported */ + bool d_readAhead{false}; }; struct TLSErrorCounters diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index 78f23f9df414..0b960134971b 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -629,6 +629,10 @@ class OpenSSLTLSIOCtx: public TLSCtx } #endif /* DISABLE_OCSP_STAPLING */ + if (fe.d_tlsConfig.d_readAhead) { + SSL_CTX_set_read_ahead(d_feContext->d_tlsCtx.get(), 1); + } + libssl_set_error_counters_callback(d_feContext->d_tlsCtx, &fe.d_tlsCounters); if (!fe.d_tlsConfig.d_keyLogFile.empty()) { From af1bc11b7b0a36a7f3996f9c0101439c6372a3e2 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 22 Jun 2023 12:26:04 +0200 Subject: [PATCH 630/909] dnsdist: Make clang-tidy happy --- pdns/dnsdistdist/dnsdist-doh-common.cc | 4 +- pdns/dnsdistdist/dnsdist-healthchecks.cc | 2 +- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 176 ++--- pdns/dnsdistdist/dnsdist-nghttp2-in.hh | 9 +- pdns/dnsdistdist/dnsdist-rules.hh | 2 +- pdns/dnsdistdist/dnsdist-tcp-downstream.cc | 3 +- pdns/dnsdistdist/doh.cc | 636 +++++++++--------- pdns/dnsdistdist/test-dnsdistasync.cc | 6 +- pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc | 1 + pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc | 4 +- pdns/doh.hh | 2 +- 11 files changed, 447 insertions(+), 398 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-doh-common.cc b/pdns/dnsdistdist/dnsdist-doh-common.cc index 15fcb9672a9d..7d994365a258 100644 --- a/pdns/dnsdistdist/dnsdist-doh-common.cc +++ b/pdns/dnsdistdist/dnsdist-doh-common.cc @@ -49,8 +49,8 @@ string HTTPHeaderRule::toString() const return d_visual; } -HTTPPathRule::HTTPPathRule(const std::string& path) : - d_path(path) +HTTPPathRule::HTTPPathRule(std::string path) : + d_path(std::move(path)) { } diff --git a/pdns/dnsdistdist/dnsdist-healthchecks.cc b/pdns/dnsdistdist/dnsdist-healthchecks.cc index 67b65796d429..37139e8661f4 100644 --- a/pdns/dnsdistdist/dnsdist-healthchecks.cc +++ b/pdns/dnsdistdist/dnsdist-healthchecks.cc @@ -168,7 +168,7 @@ class HealthCheckQuerySender : public TCPQuerySender throw std::runtime_error("Unexpected XFR reponse to a health check query"); } - void notifyIOError(const struct timeval& now, TCPResponse&&) override + void notifyIOError(const struct timeval& now, [[maybe_unused]] TCPResponse&& response) override { ++d_data->d_ds->d_healthCheckMetrics.d_networkErrors; d_data->d_ds->submitHealthCheckResult(d_data->d_initial, false); diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 8b4f237c9f15..21098ec96ec5 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -95,32 +95,38 @@ class IncomingDoHCrossProtocolContext : public CrossProtocolContext class IncomingDoHCrossProtocolContext : public DOHUnitInterface { public: - IncomingDoHCrossProtocolContext(IncomingHTTP2Connection::PendingQuery&& query, std::shared_ptr connection, IncomingHTTP2Connection::StreamID streamID) : - d_connection(std::move(connection)), d_query(std::move(query)), d_streamID(streamID) + IncomingDoHCrossProtocolContext(IncomingHTTP2Connection::PendingQuery&& query, const std::shared_ptr& connection, IncomingHTTP2Connection::StreamID streamID) : + d_connection(connection), d_query(std::move(query)), d_streamID(streamID) { } + IncomingDoHCrossProtocolContext(const IncomingDoHCrossProtocolContext&) = delete; + IncomingDoHCrossProtocolContext(IncomingDoHCrossProtocolContext&&) = delete; + IncomingDoHCrossProtocolContext& operator=(const IncomingDoHCrossProtocolContext&) = delete; + IncomingDoHCrossProtocolContext& operator=(IncomingDoHCrossProtocolContext&&) = delete; - std::string getHTTPPath() const override + ~IncomingDoHCrossProtocolContext() override = default; + + [[nodiscard]] std::string getHTTPPath() const override { return d_query.d_path; } - const std::string& getHTTPScheme() const override + [[nodiscard]] const std::string& getHTTPScheme() const override { return d_query.d_scheme; } - const std::string& getHTTPHost() const override + [[nodiscard]] const std::string& getHTTPHost() const override { return d_query.d_host; } - std::string getHTTPQueryString() const override + [[nodiscard]] std::string getHTTPQueryString() const override { return d_query.d_queryString; } - const HeadersMap& getHTTPHeaders() const override + [[nodiscard]] const HeadersMap& getHTTPHeaders() const override { if (!d_query.d_headers) { static const HeadersMap empty{}; @@ -136,7 +142,7 @@ class IncomingDoHCrossProtocolContext : public DOHUnitInterface d_query.d_contentTypeOut = contentType; } - void handleUDPResponse(PacketBuffer&& response, InternalQueryState&& state, const std::shared_ptr& ds) override + void handleUDPResponse(PacketBuffer&& response, InternalQueryState&& state, const std::shared_ptr& downstream) override { std::unique_ptr unit(this); auto conn = d_connection.lock(); @@ -147,8 +153,10 @@ class IncomingDoHCrossProtocolContext : public DOHUnitInterface state.du = std::move(unit); TCPResponse resp(std::move(response), std::move(state), nullptr, nullptr); - resp.d_ds = ds; - struct timeval now; + resp.d_ds = downstream; + struct timeval now + { + }; gettimeofday(&now, nullptr); conn->handleResponse(now, std::move(resp)); } @@ -161,17 +169,15 @@ class IncomingDoHCrossProtocolContext : public DOHUnitInterface /* the connection has been closed in the meantime */ return; } - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); TCPResponse resp; resp.d_idstate.d_streamID = d_streamID; conn->notifyIOError(now, std::move(resp)); } - ~IncomingDoHCrossProtocolContext() override - { - } - std::weak_ptr d_connection; IncomingHTTP2Connection::PendingQuery d_query; IncomingHTTP2Connection::StreamID d_streamID{-1}; @@ -186,26 +192,26 @@ void IncomingHTTP2Connection::handleResponse(const struct timeval& now, TCPRespo auto& state = response.d_idstate; if (state.forwardedOverUDP) { - dnsheader* responseDH = reinterpret_cast(response.d_buffer.data()); + dnsheader_aligned responseDH(response.d_buffer.data()); - if (responseDH->tc && state.d_packet && state.d_packet->size() > state.d_proxyProtocolPayloadSize && state.d_packet->size() - state.d_proxyProtocolPayloadSize > sizeof(dnsheader)) { + if (responseDH.get()->tc && state.d_packet && state.d_packet->size() > state.d_proxyProtocolPayloadSize && state.d_packet->size() - state.d_proxyProtocolPayloadSize > sizeof(dnsheader)) { vinfolog("Response received from backend %s via UDP, for query %d received from %s via DoH, is truncated, retrying over TCP", response.d_ds->getNameWithAddr(), state.d_streamID, state.origRemote.toStringWithPort()); auto& query = *state.d_packet; - dnsheader* queryDH = reinterpret_cast(query.data() + state.d_proxyProtocolPayloadSize); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + auto* queryDH = reinterpret_cast(&query.at(state.d_proxyProtocolPayloadSize)); /* restoring the original ID */ queryDH->id = state.origID; state.forwardedOverUDP = false; + bool proxyProtocolPayloadAdded = state.d_proxyProtocolPayloadSize > 0; auto cpq = getCrossProtocolQuery(std::move(query), std::move(state), response.d_ds); - cpq->query.d_proxyProtocolPayloadAdded = state.d_proxyProtocolPayloadSize > 0; + cpq->query.d_proxyProtocolPayloadAdded = proxyProtocolPayloadAdded; if (g_tcpclientthreads && g_tcpclientthreads->passCrossProtocolQueryToThread(std::move(cpq))) { return; } - else { - vinfolog("Unable to pass DoH query to a TCP worker thread after getting a TC response over UDP"); - notifyIOError(now, std::move(response)); - return; - } + vinfolog("Unable to pass DoH query to a TCP worker thread after getting a TC response over UDP"); + notifyIOError(now, std::move(response)); + return; } } @@ -214,7 +220,10 @@ void IncomingHTTP2Connection::handleResponse(const struct timeval& now, TCPRespo std::unique_ptr IncomingHTTP2Connection::getDOHUnit(uint32_t streamID) { - auto query = std::move(d_currentStreams.at(streamID)); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clang-tidy is getting confused by assert() + assert(streamID <= std::numeric_limits::max()); + // NOLINTNEXTLINE(*-narrowing-conversions): generic interface between DNS and DoH with different types + auto query = std::move(d_currentStreams.at(static_cast(streamID))); return std::make_unique(std::move(query), std::dynamic_pointer_cast(shared_from_this()), streamID); } @@ -224,13 +233,8 @@ void IncomingHTTP2Connection::restoreDOHUnit(std::unique_ptr&& d_currentStreams.at(context->d_streamID) = std::move(context->d_query); } -void IncomingHTTP2Connection::restoreContext(uint32_t streamID, IncomingHTTP2Connection::PendingQuery&& context) -{ - d_currentStreams.at(streamID) = std::move(context); -} - -IncomingHTTP2Connection::IncomingHTTP2Connection(ConnectionInfo&& ci, TCPClientThreadData& threadData, const struct timeval& now) : - IncomingTCPConnectionState(std::move(ci), threadData, now) +IncomingHTTP2Connection::IncomingHTTP2Connection(ConnectionInfo&& connectionInfo, TCPClientThreadData& threadData, const struct timeval& now) : + IncomingTCPConnectionState(std::move(connectionInfo), threadData, now) { nghttp2_session_callbacks* cbs = nullptr; if (nghttp2_session_callbacks_new(&cbs) != 0) { @@ -258,9 +262,9 @@ IncomingHTTP2Connection::IncomingHTTP2Connection(ConnectionInfo&& ci, TCPClientT bool IncomingHTTP2Connection::checkALPN() { - constexpr std::array h2{'h', '2'}; + constexpr std::array h2ALPN{'h', '2'}; auto protocols = d_handler.getNextProtocol(); - if (protocols.size() == h2.size() && memcmp(protocols.data(), h2.data(), h2.size()) == 0) { + if (protocols.size() == h2ALPN.size() && memcmp(protocols.data(), h2ALPN.data(), h2ALPN.size()) == 0) { return true; } vinfolog("DoH connection from %s expected ALPN value 'h2', got '%s'", d_ci.remote.toStringWithPort(), std::string(protocols.begin(), protocols.end())); @@ -269,8 +273,8 @@ bool IncomingHTTP2Connection::checkALPN() void IncomingHTTP2Connection::handleConnectionReady() { - constexpr std::array iv{{{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100U}}}; - auto ret = nghttp2_submit_settings(d_session.get(), NGHTTP2_FLAG_NONE, iv.data(), iv.size()); + constexpr std::array settings{{{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 100U}}}; + auto ret = nghttp2_submit_settings(d_session.get(), NGHTTP2_FLAG_NONE, settings.data(), settings.size()); if (ret != 0) { throw std::runtime_error("Fatal error: " + std::string(nghttp2_strerror(ret))); } @@ -284,7 +288,9 @@ void IncomingHTTP2Connection::handleConnectionReady() void IncomingHTTP2Connection::handleIO() { IOState iostate = IOState::Done; - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); try { @@ -341,10 +347,10 @@ void IncomingHTTP2Connection::handleIO() if (!d_connectionDied) { auto shared = std::dynamic_pointer_cast(shared_from_this()); - if (nghttp2_session_want_read(d_session.get())) { + if (nghttp2_session_want_read(d_session.get()) != 0) { d_ioState->add(IOState::NeedRead, &handleReadableIOCallback, shared, boost::none); } - if (nghttp2_session_want_write(d_session.get())) { + if (nghttp2_session_want_write(d_session.get()) != 0) { d_ioState->add(IOState::NeedWrite, &handleWritableIOCallback, shared, boost::none); } } @@ -358,7 +364,8 @@ void IncomingHTTP2Connection::handleIO() ssize_t IncomingHTTP2Connection::send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data) { - IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + auto* conn = static_cast(user_data); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API conn->d_out.insert(conn->d_out.end(), data, data + length); if (conn->d_connectionDied || conn->d_needFlush) { @@ -385,7 +392,7 @@ ssize_t IncomingHTTP2Connection::send_callback(nghttp2_session* session, const u } } - return length; + return static_cast(length); } static const std::array(NGHTTP2Headers::HeaderConstantIndexes::COUNT)> s_headerConstants{ @@ -426,11 +433,13 @@ void NGHTTP2Headers::addStaticHeader(std::vector& headers, NGHTTP2He const auto& name = s_headerConstants.at(static_cast(nameKey)); const auto& value = s_headerConstants.at(static_cast(valueKey)); + // NOLINTNEXTLINE nghttp2 API headers.push_back({const_cast(reinterpret_cast(name.c_str())), const_cast(reinterpret_cast(value.c_str())), name.size(), value.size(), NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE}); } void NGHTTP2Headers::addCustomDynamicHeader(std::vector& headers, const std::string& name, const std::string_view& value) { + // NOLINTNEXTLINE nghttp2 API headers.push_back({const_cast(reinterpret_cast(name.data())), const_cast(reinterpret_cast(value.data())), name.size(), value.size(), NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE}); } @@ -442,6 +451,7 @@ void NGHTTP2Headers::addDynamicHeader(std::vector& headers, NGHTTP2H IOState IncomingHTTP2Connection::sendResponse(const struct timeval& now, TCPResponse&& response) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clang-tidy is getting confused by assert() assert(response.d_idstate.d_streamID != -1); auto& context = d_currentStreams.at(response.d_idstate.d_streamID); @@ -473,6 +483,7 @@ void IncomingHTTP2Connection::notifyIOError(const struct timeval& now, TCPRespon return; } + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clang-tidy is getting confused by assert() assert(response.d_idstate.d_streamID != -1); auto& context = d_currentStreams.at(response.d_idstate.d_streamID); context.d_buffer = std::move(response.d_buffer); @@ -487,7 +498,7 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str data_provider.source.ptr = this; data_provider.read_callback = [](nghttp2_session*, IncomingHTTP2Connection::StreamID stream_id, uint8_t* buf, size_t length, uint32_t* data_flags, nghttp2_data_source* source, void* cb_data) -> ssize_t { - auto connection = reinterpret_cast(cb_data); + auto* connection = static_cast(cb_data); auto& obj = connection->d_currentStreams.at(stream_id); size_t toCopy = 0; if (obj.d_queryPos < obj.d_buffer.size()) { @@ -502,10 +513,10 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str obj.d_buffer.clear(); connection->d_needFlush = true; } - return toCopy; + return static_cast(toCopy); }; - const auto& df = d_ci.cs->dohFrontend; + const auto& dohFrontend = d_ci.cs->dohFrontend; auto& responseBody = context.d_buffer; std::vector headers; @@ -519,8 +530,8 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str if (responseCode == 200) { NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::STATUS_NAME, NGHTTP2Headers::HeaderConstantIndexes::OK_200_VALUE); - ++df->d_validresponses; - ++df->d_http2Stats.d_nb200Responses; + ++dohFrontend->d_validresponses; + ++dohFrontend->d_http2Stats.d_nb200Responses; if (addContentType) { if (contentType.empty()) { @@ -531,7 +542,8 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str } } - if (df->d_sendCacheControlHeaders && responseBody.size() > sizeof(dnsheader)) { + if (dohFrontend->d_sendCacheControlHeaders && responseBody.size() > sizeof(dnsheader)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): API uint32_t minTTL = getDNSPacketMinTTL(reinterpret_cast(responseBody.data()), responseBody.size()); if (minTTL != std::numeric_limits::max()) { cacheControlValue = "max-age=" + std::to_string(minTTL); @@ -544,6 +556,7 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::STATUS_NAME, responseCodeStr); if (responseCode >= 300 && responseCode < 400) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) location = std::string(reinterpret_cast(responseBody.data()), responseBody.size()); NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_TYPE_NAME, "text/html; charset=utf-8"); NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::LOCATION_NAME, location); @@ -552,25 +565,25 @@ bool IncomingHTTP2Connection::sendResponse(IncomingHTTP2Connection::StreamID str responseBody.reserve(s_redirectStart.size() + responseBody.size() + s_redirectEnd.size()); responseBody.insert(responseBody.begin(), s_redirectStart.begin(), s_redirectStart.end()); responseBody.insert(responseBody.end(), s_redirectEnd.begin(), s_redirectEnd.end()); - ++df->d_redirectresponses; + ++dohFrontend->d_redirectresponses; } else { - ++df->d_errorresponses; + ++dohFrontend->d_errorresponses; switch (responseCode) { case 400: - ++df->d_http2Stats.d_nb400Responses; + ++dohFrontend->d_http2Stats.d_nb400Responses; break; case 403: - ++df->d_http2Stats.d_nb403Responses; + ++dohFrontend->d_http2Stats.d_nb403Responses; break; case 500: - ++df->d_http2Stats.d_nb500Responses; + ++dohFrontend->d_http2Stats.d_nb500Responses; break; case 502: - ++df->d_http2Stats.d_nb502Responses; + ++dohFrontend->d_http2Stats.d_nb502Responses; break; default: - ++df->d_http2Stats.d_nbOtherResponses; + ++dohFrontend->d_http2Stats.d_nbOtherResponses; break; } @@ -633,12 +646,12 @@ static void processForwardedForHeader(const std::unique_ptr& headers return; } - auto it = headers->find(s_xForwardedForHeaderName); - if (it == headers->end()) { + auto headerIt = headers->find(s_xForwardedForHeaderName); + if (headerIt == headers->end()) { return; } - std::string_view value = it->second; + std::string_view value = headerIt->second; try { auto pos = value.rfind(','); if (pos != std::string_view::npos) { @@ -703,7 +716,7 @@ static std::optional getPayloadFromPath(const std::string_view& pa } } - if (neededPadding) { + if (neededPadding != 0) { // re-add padding that may have been missing sdns.append(neededPadding, '='); } @@ -782,7 +795,7 @@ void IncomingHTTP2Connection::handleIncomingQuery(IncomingHTTP2Connection::Pendi if (entry->matches(query.d_path)) { const auto& customHeaders = entry->getHeaders(); query.d_buffer = entry->getContent(); - if (entry->getStatusCode() >= 400 && query.d_buffer.size() >= 1) { + if (entry->getStatusCode() >= 400 && !query.d_buffer.empty()) { // legacy trailing 0 from the h2o era query.d_buffer.pop_back(); } @@ -813,7 +826,9 @@ void IncomingHTTP2Connection::handleIncomingQuery(IncomingHTTP2Connection::Pendi } try { - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); auto processingResult = handleQuery(std::move(query.d_buffer), now, streamID); @@ -848,7 +863,7 @@ void IncomingHTTP2Connection::handleIncomingQuery(IncomingHTTP2Connection::Pendi int IncomingHTTP2Connection::on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data) { - IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + auto* conn = static_cast(user_data); #if 0 switch (frame->hd.type) { case NGHTTP2_HEADERS: @@ -879,14 +894,14 @@ int IncomingHTTP2Connection::on_frame_recv_callback(nghttp2_session* session, co if (frame->hd.type == NGHTTP2_GOAWAY) { conn->stopIO(); if (conn->isIdle()) { - if (nghttp2_session_want_write(conn->d_session.get())) { + if (nghttp2_session_want_write(conn->d_session.get()) != 0) { conn->d_ioState->add(IOState::NeedWrite, &handleWritableIOCallback, conn, boost::none); } } } /* is this the last frame for this stream? */ - else if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { + else if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) != 0) { auto streamID = frame->hd.stream_id; auto stream = conn->d_currentStreams.find(streamID); if (stream != conn->d_currentStreams.end()) { @@ -907,7 +922,7 @@ int IncomingHTTP2Connection::on_frame_recv_callback(nghttp2_session* session, co int IncomingHTTP2Connection::on_stream_close_callback(nghttp2_session* session, IncomingHTTP2Connection::StreamID stream_id, uint32_t error_code, void* user_data) { - IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + auto* conn = static_cast(user_data); if (error_code == 0) { return 0; @@ -919,7 +934,9 @@ int IncomingHTTP2Connection::on_stream_close_callback(nghttp2_session* session, return 0; } - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); auto request = std::move(stream->second); conn->d_currentStreams.erase(stream->first); @@ -937,7 +954,7 @@ int IncomingHTTP2Connection::on_begin_headers_callback(nghttp2_session* session, return 0; } - IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + auto* conn = static_cast(user_data); auto insertPair = conn->d_currentStreams.emplace(frame->hd.stream_id, PendingQuery()); if (!insertPair.second) { /* there is a stream ID collision, something is very wrong! */ @@ -958,7 +975,7 @@ int IncomingHTTP2Connection::on_begin_headers_callback(nghttp2_session* session, static std::string::size_type getLengthOfPathWithoutParameters(const std::string_view& path) { - auto pos = path.find("?"); + auto pos = path.find('?'); if (pos == string::npos) { return path.size(); } @@ -968,7 +985,7 @@ static std::string::size_type getLengthOfPathWithoutParameters(const std::string int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const nghttp2_frame* frame, const uint8_t* name, size_t nameLen, const uint8_t* value, size_t valuelen, uint8_t flags, void* user_data) { - IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + auto* conn = static_cast(user_data); if (frame->hd.type == NGHTTP2_HEADERS && frame->headers.cat == NGHTTP2_HCAT_REQUEST) { if (nghttp2_check_header_name(name, nameLen) == 0) { @@ -993,6 +1010,7 @@ int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const return NGHTTP2_ERR_CALLBACK_FAILURE; } auto& query = stream->second; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): nghttp2 API auto valueView = std::string_view(reinterpret_cast(value), valuelen); if (headerMatches(s_pathHeaderName)) { #if HAVE_NGHTTP2_CHECK_PATH @@ -1038,6 +1056,7 @@ int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const if (!query.d_headers) { query.d_headers = std::make_unique(); } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): nghttp2 API query.d_headers->insert({std::string(reinterpret_cast(name), nameLen), std::string(valueView)}); } } @@ -1046,7 +1065,7 @@ int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const int IncomingHTTP2Connection::on_data_chunk_recv_callback(nghttp2_session* session, uint8_t flags, IncomingHTTP2Connection::StreamID stream_id, const uint8_t* data, size_t len, void* user_data) { - IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + auto* conn = static_cast(user_data); auto stream = conn->d_currentStreams.find(stream_id); if (stream == conn->d_currentStreams.end()) { vinfolog("Unable to match the stream ID %d to a known one!", stream_id); @@ -1057,6 +1076,7 @@ int IncomingHTTP2Connection::on_data_chunk_recv_callback(nghttp2_session* sessio return NGHTTP2_ERR_CALLBACK_FAILURE; } + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API stream->second.d_buffer.insert(stream->second.d_buffer.end(), data, data + len); return 0; @@ -1064,7 +1084,7 @@ int IncomingHTTP2Connection::on_data_chunk_recv_callback(nghttp2_session* sessio int IncomingHTTP2Connection::on_error_callback(nghttp2_session* session, int lib_error_code, const char* msg, size_t len, void* user_data) { - IncomingHTTP2Connection* conn = reinterpret_cast(user_data); + auto* conn = static_cast(user_data); vinfolog("Error in HTTP/2 connection from %d: %s", conn->d_ci.remote.toStringWithPort(), std::string(msg, len)); conn->d_connectionDied = true; @@ -1080,7 +1100,7 @@ int IncomingHTTP2Connection::on_error_callback(nghttp2_session* session, int lib void IncomingHTTP2Connection::readHTTPData() { - IOState newState; + IOState newState = IOState::Done; IOStateGuard ioGuard(d_ioState); do { size_t got = 0; @@ -1104,7 +1124,7 @@ void IncomingHTTP2Connection::readHTTPData() } if (newState == IOState::Done) { - if (nghttp2_session_want_read(d_session.get())) { + if (nghttp2_session_want_read(d_session.get()) != 0) { continue; } if (isIdle()) { @@ -1129,13 +1149,13 @@ void IncomingHTTP2Connection::readHTTPData() } while (newState == IOState::Done || !isIdle()); } -void IncomingHTTP2Connection::handleReadableIOCallback(int fd, FDMultiplexer::funcparam_t& param) +void IncomingHTTP2Connection::handleReadableIOCallback([[maybe_unused]] int descriptor, FDMultiplexer::funcparam_t& param) { auto conn = boost::any_cast>(param); conn->handleIO(); } -void IncomingHTTP2Connection::handleWritableIOCallback(int fd, FDMultiplexer::funcparam_t& param) +void IncomingHTTP2Connection::handleWritableIOCallback([[maybe_unused]] int descriptor, FDMultiplexer::funcparam_t& param) { auto conn = boost::any_cast>(param); IOStateGuard ioGuard(conn->d_ioState); @@ -1192,7 +1212,7 @@ boost::optional IncomingHTTP2Connection::getIdleClientReadTTD(st } auto remaining = g_maxTCPConnectionDuration - elapsed; if (idleTimeout == 0 || remaining <= static_cast(idleTimeout)) { - now.tv_sec += remaining; + now.tv_sec += static_cast(remaining); return now; } } @@ -1201,13 +1221,15 @@ boost::optional IncomingHTTP2Connection::getIdleClientReadTTD(st return now; } -void IncomingHTTP2Connection::updateIO(IOState newState, FDMultiplexer::callbackfunc_t callback) +void IncomingHTTP2Connection::updateIO(IOState newState, const FDMultiplexer::callbackfunc_t& callback) { boost::optional ttd{boost::none}; auto shared = std::dynamic_pointer_cast(shared_from_this()); if (shared) { - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); if (newState == IOState::NeedRead) { diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh index 8d828dbb9ac8..e68d2142085e 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -56,12 +56,11 @@ public: Method d_method{Method::Unknown}; }; - IncomingHTTP2Connection(ConnectionInfo&& ci, TCPClientThreadData& threadData, const struct timeval& now); + IncomingHTTP2Connection(ConnectionInfo&& connectionInfo, TCPClientThreadData& threadData, const struct timeval& now); ~IncomingHTTP2Connection() = default; void handleIO() override; void handleResponse(const struct timeval& now, TCPResponse&& response) override; void notifyIOError(const struct timeval& now, TCPResponse&& response) override; - void restoreContext(uint32_t streamID, PendingQuery&& context); private: static ssize_t send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data); @@ -71,8 +70,8 @@ private: static int on_header_callback(nghttp2_session* session, const nghttp2_frame* frame, const uint8_t* name, size_t namelen, const uint8_t* value, size_t valuelen, uint8_t flags, void* user_data); static int on_begin_headers_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data); static int on_error_callback(nghttp2_session* session, int lib_error_code, const char* msg, size_t len, void* user_data); - static void handleReadableIOCallback(int fd, FDMultiplexer::funcparam_t& param); - static void handleWritableIOCallback(int fd, FDMultiplexer::funcparam_t& param); + static void handleReadableIOCallback(int descriptor, FDMultiplexer::funcparam_t& param); + static void handleWritableIOCallback(int descriptor, FDMultiplexer::funcparam_t& param); IOState sendResponse(const struct timeval& now, TCPResponse&& response) override; bool forwardViaUDPFirst() const override @@ -85,7 +84,7 @@ private: void stopIO(); bool isIdle() const; uint32_t getConcurrentStreamsCount() const; - void updateIO(IOState newState, FDMultiplexer::callbackfunc_t callback); + void updateIO(IOState newState, const FDMultiplexer::callbackfunc_t& callback); void watchForRemoteHostClosingConnection(); void handleIOError(); bool sendResponse(StreamID streamID, PendingQuery& context, uint16_t responseCode, const HeadersMap& customResponseHeaders, const std::string& contentType = "", bool addContentType = true); diff --git a/pdns/dnsdistdist/dnsdist-rules.hh b/pdns/dnsdistdist/dnsdist-rules.hh index 5b4e80a3947f..c9b932c3dd7a 100644 --- a/pdns/dnsdistdist/dnsdist-rules.hh +++ b/pdns/dnsdistdist/dnsdist-rules.hh @@ -557,7 +557,7 @@ private: class HTTPPathRule : public DNSRule { public: - HTTPPathRule(const std::string& path); + HTTPPathRule(std::string path); bool matches(const DNSQuestion* dq) const override; string toString() const override; private: diff --git a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc index 43de71fc58f7..89b3a2e5d812 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc +++ b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc @@ -240,7 +240,8 @@ static void prepareQueryForSending(TCPQuery& query, uint16_t id, QueryState quer if (query.d_buffer.size() < query.d_idstate.d_proxyProtocolPayloadSize) { throw std::runtime_error("Trying to remove a proxy protocol payload of size " + std::to_string(query.d_proxyProtocolPayload.size()) + " from a buffer of size " + std::to_string(query.d_buffer.size())); } - query.d_buffer.erase(query.d_buffer.begin(), query.d_buffer.begin() + query.d_idstate.d_proxyProtocolPayloadSize); + // NOLINTNEXTLINE(*-narrowing-conversions): the size of the payload is limited to 2^16-1 + query.d_buffer.erase(query.d_buffer.begin(), query.d_buffer.begin() + static_cast(query.d_idstate.d_proxyProtocolPayloadSize)); query.d_proxyProtocolPayloadAdded = false; query.d_idstate.d_proxyProtocolPayloadSize = 0; } diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index a2747400f47b..4d7f53e92bbd 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -57,7 +57,7 @@ */ /* 'Intermediate' compatibility from https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29 */ -#define DOH_DEFAULT_CIPHERS "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS" +static constexpr string_view DOH_DEFAULT_CIPHERS = "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS"; class DOHAcceptContext { @@ -68,7 +68,9 @@ class DOHAcceptContext d_rotatingTicketsKey.clear(); } DOHAcceptContext(const DOHAcceptContext&) = delete; + DOHAcceptContext(DOHAcceptContext&&) = delete; DOHAcceptContext& operator=(const DOHAcceptContext&) = delete; + DOHAcceptContext& operator=(DOHAcceptContext&&) = delete; h2o_accept_ctx_t* get() { @@ -81,19 +83,19 @@ class DOHAcceptContext d_h2o_accept_ctx.ssl_ctx = nullptr; } - void decrementConcurrentConnections() + void decrementConcurrentConnections() const { if (d_cs != nullptr) { --d_cs->tcpCurrentConnections; } } - time_t getNextTicketsKeyRotation() const + [[nodiscard]] time_t getNextTicketsKeyRotation() const { return d_ticketsKeyNextRotation; } - size_t getTicketsKeysCount() const + [[nodiscard]] size_t getTicketsKeysCount() const { size_t res = 0; if (d_ticketKeys) { @@ -162,7 +164,7 @@ class DOHAcceptContext time_t d_ticketsKeyRotationDelay{0}; private: - h2o_accept_ctx_t d_h2o_accept_ctx; + h2o_accept_ctx_t d_h2o_accept_ctx{}; time_t d_ticketsKeyNextRotation{0}; std::atomic_flag d_rotatingTicketsKey; }; @@ -190,7 +192,7 @@ struct DOHServerConfig } h2o_config_init(&h2o_config); - h2o_config.http2.idle_timeout = idleTimeout * 1000; + h2o_config.http2.idle_timeout = static_cast(idleTimeout) * 1000; /* if you came here for a way to make the number of concurrent streams (concurrent requests per connection) configurable, or even just bigger, I have bad news for you. h2o_config.http2.max_concurrent_requests_per_connection (default of 100) is capped by @@ -200,15 +202,18 @@ struct DOHServerConfig */ } DOHServerConfig(const DOHServerConfig&) = delete; + DOHServerConfig(DOHServerConfig&&) = delete; DOHServerConfig& operator=(const DOHServerConfig&) = delete; + DOHServerConfig& operator=(DOHServerConfig&&) = delete; + ~DOHServerConfig() = default; LocalHolders holders; std::set> paths; - h2o_globalconf_t h2o_config; - h2o_context_t h2o_ctx; + h2o_globalconf_t h2o_config{}; + h2o_context_t h2o_ctx{}; std::shared_ptr accept_ctx{nullptr}; - ClientState* cs{nullptr}; - std::shared_ptr df{nullptr}; + ClientState* clientState{nullptr}; + std::shared_ptr dohFrontend{nullptr}; #ifndef USE_SINGLE_ACCEPTOR_THREAD pdns::channel::Sender d_querySender; pdns::channel::Receiver d_queryReceiver; @@ -219,19 +224,21 @@ struct DOHServerConfig struct DOHUnit : public DOHUnitInterface { - DOHUnit(PacketBuffer&& q, std::string&& p, std::string&& h): path(std::move(p)), host(std::move(h)), query(std::move(q)) + DOHUnit(PacketBuffer&& query_, std::string&& path_, std::string&& host_): path(std::move(path_)), host(std::move(host_)), query(std::move(query_)) { ids.ednsAdded = false; } - ~DOHUnit() + ~DOHUnit() override { - if (self) { + if (self != nullptr) { *self = nullptr; } } DOHUnit(const DOHUnit&) = delete; + DOHUnit(DOHUnit&&) = delete; DOHUnit& operator=(const DOHUnit&) = delete; + DOHUnit& operator=(DOHUnit&&) = delete; InternalQueryState ids; std::string sni; @@ -261,26 +268,26 @@ struct DOHUnit : public DOHUnitInterface bool tcp{false}; bool truncated{false}; - std::string getHTTPPath() const override; - std::string getHTTPQueryString() const override; - const std::string& getHTTPHost() const override; - const std::string& getHTTPScheme() const override; - const std::unordered_map& getHTTPHeaders() const override; + [[nodiscard]] std::string getHTTPPath() const override; + [[nodiscard]] std::string getHTTPQueryString() const override; + [[nodiscard]] const std::string& getHTTPHost() const override; + [[nodiscard]] const std::string& getHTTPScheme() const override; + [[nodiscard]] const std::unordered_map& getHTTPHeaders() const override; void setHTTPResponse(uint16_t statusCode, PacketBuffer&& body, const std::string& contentType="") override; - virtual void handleTimeout() override; - virtual void handleUDPResponse(PacketBuffer&& response, InternalQueryState&& state, const std::shared_ptr&) override; + void handleTimeout() override; + void handleUDPResponse(PacketBuffer&& response, InternalQueryState&& state, [[maybe_unused]] const std::shared_ptr& downstream) override; }; using DOHUnitUniquePtr = std::unique_ptr; /* This internal function sends back the object to the main thread to send a reply. The caller should NOT release or touch the unit after calling this function */ -static void sendDoHUnitToTheMainThread(DOHUnitUniquePtr&& du, const char* description) +static void sendDoHUnitToTheMainThread(DOHUnitUniquePtr&& dohUnit, const char* description) { - if (du->responseSender == nullptr) { + if (dohUnit->responseSender == nullptr) { return; } try { - if (!du->responseSender->send(std::move(du))) { + if (!dohUnit->responseSender->send(std::move(dohUnit))) { ++dnsdist::metrics::g_stats.dohResponsePipeFull; vinfolog("Unable to pass a %s to the DoH worker thread because the pipe is full", description); } @@ -311,10 +318,10 @@ static thread_local std::unordered_map t_conns; static void on_socketclose(void *data) { - auto conn = reinterpret_cast(data); + auto* conn = static_cast(data); if (conn != nullptr) { if (conn->d_acceptCtx) { - struct timeval now; + struct timeval now{}; gettimeofday(&now, nullptr); auto diff = now - conn->d_connectionStartTime; @@ -371,17 +378,15 @@ static const std::string& getReasonFromStatusCode(uint16_t statusCode) }; static const std::string unknown = "Unknown"; - const auto it = reasons.find(statusCode); - if (it == reasons.end()) { + const auto reasonIt = reasons.find(statusCode); + if (reasonIt == reasons.end()) { return unknown; } - else { - return it->second; - } + return reasonIt->second; } /* Always called from the main DoH thread */ -static void handleResponse(DOHFrontend& df, st_h2o_req_t* req, uint16_t statusCode, const PacketBuffer& response, const std::unordered_map& customResponseHeaders, const std::string& contentType, bool addContentType) +static void handleResponse(DOHFrontend& dohFrontend, st_h2o_req_t* req, uint16_t statusCode, const PacketBuffer& response, const std::unordered_map& customResponseHeaders, const std::string& contentType, bool addContentType) { constexpr int overwrite_if_exists = 1; constexpr int maybe_token = 1; @@ -390,7 +395,7 @@ static void handleResponse(DOHFrontend& df, st_h2o_req_t* req, uint16_t statusCo } if (statusCode == 200) { - ++df.d_validresponses; + ++dohFrontend.d_validresponses; req->res.status = 200; if (addContentType) { @@ -399,12 +404,14 @@ static void handleResponse(DOHFrontend& df, st_h2o_req_t* req, uint16_t statusCo } else { /* we need to duplicate the header content because h2o keeps a pointer and we will be deleted before the response has been sent */ - h2o_iovec_t ct = h2o_strdup(&req->pool, contentType.c_str(), contentType.size()); - h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, nullptr, ct.base, ct.len); + h2o_iovec_t contentTypeVect = h2o_strdup(&req->pool, contentType.c_str(), contentType.size()); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-array-to-pointer-decay,cppcoreguidelines-pro-bounds-pointer-arithmetic): h2o API + h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, nullptr, contentTypeVect.base, contentTypeVect.len); } } - if (df.d_sendCacheControlHeaders && response.size() > sizeof(dnsheader)) { + if (dohFrontend.d_sendCacheControlHeaders && response.size() > sizeof(dnsheader)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) uint32_t minTTL = getDNSPacketMinTTL(reinterpret_cast(response.data()), response.size()); if (minTTL != std::numeric_limits::max()) { std::string cacheControlValue = "max-age=" + std::to_string(minTTL); @@ -415,18 +422,21 @@ static void handleResponse(DOHFrontend& df, st_h2o_req_t* req, uint16_t statusCo } req->res.content_length = response.size(); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): h2o API h2o_send_inline(req, reinterpret_cast(response.data()), response.size()); } else if (statusCode >= 300 && statusCode < 400) { /* in that case the response is actually a URL */ /* we need to duplicate the URL because h2o uses it for the location header, keeping a pointer, and we will be deleted before the response has been sent */ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): h2o API h2o_iovec_t url = h2o_strdup(&req->pool, reinterpret_cast(response.data()), response.size()); h2o_send_redirect(req, statusCode, getReasonFromStatusCode(statusCode).c_str(), url.base, url.len); - ++df.d_redirectresponses; + ++dohFrontend.d_redirectresponses; } else { // we need to make sure it's null-terminated */ if (!response.empty() && response.at(response.size() - 1) == 0) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): h2o API h2o_send_error_generic(req, statusCode, getReasonFromStatusCode(statusCode).c_str(), reinterpret_cast(response.data()), H2O_SEND_ERROR_KEEP_HEADERS); } else { @@ -448,24 +458,27 @@ static void handleResponse(DOHFrontend& df, st_h2o_req_t* req, uint16_t statusCo } } - ++df.d_errorresponses; + ++dohFrontend.d_errorresponses; } } static std::unique_ptr getDUFromIDS(InternalQueryState& ids) { - auto du = std::unique_ptr(dynamic_cast(ids.du.release())); - return du; + auto dohUnit = std::unique_ptr(dynamic_cast(ids.du.release())); + return dohUnit; } -class DoHTCPCrossQuerySender : public TCPQuerySender +class DoHTCPCrossQuerySender final : public TCPQuerySender { public: - DoHTCPCrossQuerySender() - { - } - - bool active() const override + DoHTCPCrossQuerySender() = default; + DoHTCPCrossQuerySender(const DoHTCPCrossQuerySender&) = delete; + DoHTCPCrossQuerySender(DoHTCPCrossQuerySender&&) = delete; + DoHTCPCrossQuerySender& operator=(const DoHTCPCrossQuerySender&) = delete; + DoHTCPCrossQuerySender& operator=(DoHTCPCrossQuerySender&&) = delete; + ~DoHTCPCrossQuerySender() final = default; + + [[nodiscard]] bool active() const override { return true; } @@ -476,29 +489,29 @@ class DoHTCPCrossQuerySender : public TCPQuerySender return; } - auto du = getDUFromIDS(response.d_idstate); - if (du->responseSender == nullptr) { + auto dohUnit = getDUFromIDS(response.d_idstate); + if (dohUnit->responseSender == nullptr) { return; } - du->response = std::move(response.d_buffer); - du->ids = std::move(response.d_idstate); - DNSResponse dr(du->ids, du->response, du->downstream); + dohUnit->response = std::move(response.d_buffer); + dohUnit->ids = std::move(response.d_idstate); + DNSResponse dr(dohUnit->ids, dohUnit->response, dohUnit->downstream); - dnsheader cleartextDH; + dnsheader cleartextDH{}; memcpy(&cleartextDH, dr.getHeader(), sizeof(cleartextDH)); if (!response.isAsync()) { static thread_local LocalStateHolder> localRespRuleActions = g_respruleactions.getLocal(); static thread_local LocalStateHolder> localCacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal(); - dr.ids.du = std::move(du); + dr.ids.du = std::move(dohUnit); if (!processResponse(dynamic_cast(dr.ids.du.get())->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) { if (dr.ids.du) { - du = getDUFromIDS(dr.ids); - du->status_code = 503; - sendDoHUnitToTheMainThread(std::move(du), "Response dropped by rules"); + dohUnit = getDUFromIDS(dr.ids); + dohUnit->status_code = 503; + sendDoHUnitToTheMainThread(std::move(dohUnit), "Response dropped by rules"); } return; } @@ -507,26 +520,26 @@ class DoHTCPCrossQuerySender : public TCPQuerySender return; } - du = getDUFromIDS(dr.ids); + dohUnit = getDUFromIDS(dr.ids); } - if (!du->ids.selfGenerated) { - double udiff = du->ids.queryRealTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (https), took %f us", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); + if (!dohUnit->ids.selfGenerated) { + double udiff = dohUnit->ids.queryRealTime.udiff(); + vinfolog("Got answer from %s, relayed to %s (https), took %f us", dohUnit->downstream->d_config.remote.toStringWithPort(), dohUnit->ids.origRemote.toStringWithPort(), udiff); - auto backendProtocol = du->downstream->getProtocol(); - if (backendProtocol == dnsdist::Protocol::DoUDP && du->tcp) { + auto backendProtocol = dohUnit->downstream->getProtocol(); + if (backendProtocol == dnsdist::Protocol::DoUDP && dohUnit->tcp) { backendProtocol = dnsdist::Protocol::DoTCP; } - handleResponseSent(du->ids, udiff, du->ids.origRemote, du->downstream->d_config.remote, du->response.size(), cleartextDH, backendProtocol, true); + handleResponseSent(dohUnit->ids, udiff, dohUnit->ids.origRemote, dohUnit->downstream->d_config.remote, dohUnit->response.size(), cleartextDH, backendProtocol, true); } ++dnsdist::metrics::g_stats.responses; - if (du->ids.cs) { - ++du->ids.cs->responses; + if (dohUnit->ids.cs != nullptr) { + ++dohUnit->ids.cs->responses; } - sendDoHUnitToTheMainThread(std::move(du), "cross-protocol response"); + sendDoHUnitToTheMainThread(std::move(dohUnit), "cross-protocol response"); } void handleXFRResponse(const struct timeval& now, TCPResponse&& response) override @@ -541,39 +554,39 @@ class DoHTCPCrossQuerySender : public TCPQuerySender return; } - auto du = getDUFromIDS(query); - if (du->responseSender == nullptr) { + auto dohUnit = getDUFromIDS(query); + if (dohUnit->responseSender == nullptr) { return; } - du->ids = std::move(query); - du->status_code = 502; - sendDoHUnitToTheMainThread(std::move(du), "cross-protocol error response"); + dohUnit->ids = std::move(query); + dohUnit->status_code = 502; + sendDoHUnitToTheMainThread(std::move(dohUnit), "cross-protocol error response"); } }; class DoHCrossProtocolQuery : public CrossProtocolQuery { public: - DoHCrossProtocolQuery(DOHUnitUniquePtr&& du, bool isResponse) + DoHCrossProtocolQuery(DOHUnitUniquePtr&& dohUnit, bool isResponse) { if (isResponse) { /* happens when a response becomes async */ - query = InternalQuery(std::move(du->response), std::move(du->ids)); + query = InternalQuery(std::move(dohUnit->response), std::move(dohUnit->ids)); } else { /* we need to duplicate the query here because we might need the existing query later if we get a truncated answer */ - query = InternalQuery(PacketBuffer(du->query), std::move(du->ids)); + query = InternalQuery(PacketBuffer(dohUnit->query), std::move(dohUnit->ids)); } - /* it might have been moved when we moved du->ids */ - if (du) { - query.d_idstate.du = std::move(du); + /* it might have been moved when we moved dohUnit->ids */ + if (dohUnit) { + query.d_idstate.du = std::move(dohUnit); } /* we _could_ remove it from the query buffer and put in query's d_proxyProtocolPayload, - clearing query.d_proxyProtocolPayloadAdded and du->proxyProtocolPayloadSize. + clearing query.d_proxyProtocolPayloadAdded and dohUnit->proxyProtocolPayloadSize. Leave it for now because we know that the onky case where the payload has been added is when we tried over UDP, got a TC=1 answer and retried over TCP/DoT, and we know the TCP/DoT code can handle it. */ @@ -583,12 +596,12 @@ class DoHCrossProtocolQuery : public CrossProtocolQuery void handleInternalError() { - auto du = getDUFromIDS(query.d_idstate); - if (!du) { + auto dohUnit = getDUFromIDS(query.d_idstate); + if (dohUnit == nullptr) { return; } - du->status_code = 502; - sendDoHUnitToTheMainThread(std::move(du), "DoH internal error"); + dohUnit->status_code = 502; + sendDoHUnitToTheMainThread(std::move(dohUnit), "DoH internal error"); } std::shared_ptr getTCPQuerySender() override @@ -628,25 +641,25 @@ std::unique_ptr getDoHCrossProtocolQueryFromDQ(DNSQuestion& throw std::runtime_error("Trying to create a DoH cross protocol query without a valid DoH unit"); } - auto du = getDUFromIDS(dq.ids); - if (&dq.ids != &du->ids) { - du->ids = std::move(dq.ids); + auto dohUnit = getDUFromIDS(dq.ids); + if (&dq.ids != &dohUnit->ids) { + dohUnit->ids = std::move(dq.ids); } - du->ids.origID = dq.getHeader()->id; + dohUnit->ids.origID = dq.getHeader()->id; if (!isResponse) { - if (du->query.data() != dq.getMutableData().data()) { - du->query = std::move(dq.getMutableData()); + if (dohUnit->query.data() != dq.getMutableData().data()) { + dohUnit->query = std::move(dq.getMutableData()); } } else { - if (du->response.data() != dq.getMutableData().data()) { - du->response = std::move(dq.getMutableData()); + if (dohUnit->response.data() != dq.getMutableData().data()) { + dohUnit->response = std::move(dq.getMutableData()); } } - return std::make_unique(std::move(du), isResponse); + return std::make_unique(std::move(dohUnit), isResponse); } /* @@ -654,15 +667,15 @@ std::unique_ptr getDoHCrossProtocolQueryFromDQ(DNSQuestion& */ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) { - const auto handleImmediateResponse = [inMainThread](DOHUnitUniquePtr&& du, const char* reason) { + const auto handleImmediateResponse = [inMainThread](DOHUnitUniquePtr&& dohUnit, const char* reason) { if (inMainThread) { - handleResponse(*du->dsc->df, du->req, du->status_code, du->response, du->dsc->df->d_customResponseHeaders, du->contentType, true); + handleResponse(*dohUnit->dsc->dohFrontend, dohUnit->req, dohUnit->status_code, dohUnit->response, dohUnit->dsc->dohFrontend->d_customResponseHeaders, dohUnit->contentType, true); /* so the unique pointer is stored in the InternalState which itself is stored in the unique pointer itself. We likely need a better design, but for now let's just reset the internal one since we know it is no longer needed. */ - du->ids.du.reset(); + dohUnit->ids.du.reset(); } else { - sendDoHUnitToTheMainThread(std::move(du), reason); + sendDoHUnitToTheMainThread(std::move(dohUnit), reason); } }; @@ -671,9 +684,9 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) ComboAddress remote; try { - if (!unit->req) { + if (unit->req == nullptr) { // we got closed meanwhile. XXX small race condition here - // but we should be fine as long as we don't touch du->req + // but we should be fine as long as we don't touch dohUnit->req // outside of the main DoH thread unit->status_code = 500; handleImmediateResponse(std::move(unit), "DoH killed in flight"); @@ -683,47 +696,48 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) remote = ids.origRemote; DOHServerConfig* dsc = unit->dsc; auto& holders = dsc->holders; - ClientState& cs = *dsc->cs; + ClientState& clientState = *dsc->clientState; - if (unit->query.size() < sizeof(dnsheader)) { + if (unit->query.size() < sizeof(dnsheader) || unit->query.size() > std::numeric_limits::max()) { ++dnsdist::metrics::g_stats.nonCompliantQueries; - ++cs.nonCompliantQueries; + ++clientState.nonCompliantQueries; unit->status_code = 400; handleImmediateResponse(std::move(unit), "DoH non-compliant query"); return; } - ++cs.queries; + ++clientState.queries; ++dnsdist::metrics::g_stats.queries; ids.queryRealTime.start(); { /* don't keep that pointer around, it will be invalidated if the buffer is ever resized */ - struct dnsheader* dh = reinterpret_cast(unit->query.data()); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + auto* dnsHeader = reinterpret_cast(unit->query.data()); - if (!checkQueryHeaders(dh, cs)) { + if (!checkQueryHeaders(dnsHeader, clientState)) { unit->status_code = 400; handleImmediateResponse(std::move(unit), "DoH invalid headers"); return; } - if (dh->qdcount == 0) { - dh->rcode = RCode::NotImp; - dh->qr = true; + if (dnsHeader->qdcount == 0U) { + dnsHeader->rcode = RCode::NotImp; + dnsHeader->qr = true; unit->response = std::move(unit->query); handleImmediateResponse(std::move(unit), "DoH empty query"); return; } - queryId = ntohs(dh->id); + queryId = ntohs(dnsHeader->id); } { // if there was no EDNS, we add it with a large buffer size // so we can use UDP to talk to the backend. - auto dh = const_cast(reinterpret_cast(unit->query.data())); - if (!dh->arcount) { + dnsheader_aligned dnsHeader(unit->query.data()); + if (dnsHeader.get()->arcount == 0U) { if (addEDNS(unit->query, 4096, false, 4096, 0)) { ids.ednsAdded = true; } @@ -731,14 +745,15 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) } auto downstream = unit->downstream; - ids.qname = DNSName(reinterpret_cast(unit->query.data()), unit->query.size(), sizeof(dnsheader), false, &ids.qtype, &ids.qclass); - DNSQuestion dq(ids, unit->query); - const uint16_t* flags = getFlagsFromDNSHeader(dq.getHeader()); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + ids.qname = DNSName(reinterpret_cast(unit->query.data()), static_cast(unit->query.size()), static_cast(sizeof(dnsheader)), false, &ids.qtype, &ids.qclass); + DNSQuestion dnsQuestion(ids, unit->query); + const uint16_t* flags = getFlagsFromDNSHeader(dnsQuestion.getHeader()); ids.origFlags = *flags; - ids.cs = &cs; - dq.sni = std::move(unit->sni); + ids.cs = &clientState; + dnsQuestion.sni = std::move(unit->sni); ids.du = std::move(unit); - auto result = processQuery(dq, holders, downstream); + auto result = processQuery(dnsQuestion, holders, downstream); if (result == ProcessQueryResult::Drop) { unit = getDUFromIDS(ids); @@ -746,18 +761,17 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) handleImmediateResponse(std::move(unit), "DoH dropped query"); return; } - else if (result == ProcessQueryResult::Asynchronous) { + if (result == ProcessQueryResult::Asynchronous) { return; } - else if (result == ProcessQueryResult::SendAnswer) { + if (result == ProcessQueryResult::SendAnswer) { unit = getDUFromIDS(ids); if (unit->response.empty()) { unit->response = std::move(unit->query); } if (unit->response.size() >= sizeof(dnsheader) && unit->contentType.empty()) { - auto dh = reinterpret_cast(unit->response.data()); - - handleResponseSent(unit->ids.qname, QType(unit->ids.qtype), 0., unit->ids.origDest, ComboAddress(), unit->response.size(), *dh, dnsdist::Protocol::DoH, dnsdist::Protocol::DoH, false); + dnsheader_aligned dnsHeader(unit->response.data()); + handleResponseSent(unit->ids.qname, QType(unit->ids.qtype), 0., unit->ids.origDest, ComboAddress(), unit->response.size(), *(dnsHeader.get()), dnsdist::Protocol::DoH, dnsdist::Protocol::DoH, false); } handleImmediateResponse(std::move(unit), "DoH self-answered response"); return; @@ -783,7 +797,7 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) /* we need to do this _before_ creating the cross protocol query because after that the buffer will have been moved */ if (downstream->d_config.useProxyProtocol) { - proxyProtocolPayload = getProxyProtocolPayload(dq); + proxyProtocolPayload = getProxyProtocolPayload(dnsQuestion); } unit->ids.origID = htons(queryId); @@ -796,22 +810,22 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) if (downstream->passCrossProtocolQuery(std::move(cpq))) { return; } + + if (inMainThread) { + // NOLINTNEXTLINE(bugprone-use-after-move): cpq is not altered if the call fails + unit = cpq->releaseDU(); + unit->status_code = 502; + handleImmediateResponse(std::move(unit), "DoH internal error"); + } else { - if (inMainThread) { - unit = cpq->releaseDU(); - unit->status_code = 502; - handleImmediateResponse(std::move(unit), "DoH internal error"); - } - else { - cpq->handleInternalError(); - } - return; + cpq->handleInternalError(); } + return; } auto& query = unit->query; ids.du = std::move(unit); - if (!assignOutgoingUDPQueryToBackend(downstream, htons(queryId), dq, query)) { + if (!assignOutgoingUDPQueryToBackend(downstream, htons(queryId), dnsQuestion, query)) { unit = getDUFromIDS(ids); unit->status_code = 502; handleImmediateResponse(std::move(unit), "DoH internal error"); @@ -824,8 +838,6 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) handleImmediateResponse(std::move(unit), "DoH internal error"); return; } - - return; } /* called when a HTTP response is about to be sent, from the main DoH thread */ @@ -835,16 +847,17 @@ static void on_response_ready_cb(struct st_h2o_filter_t *self, h2o_req_t *req, h return; } - DOHServerConfig* dsc = reinterpret_cast(req->conn->ctx->storage.entries[0].data); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): h2o API + auto* dsc = static_cast(req->conn->ctx->storage.entries[0].data); DOHFrontend::HTTPVersionStats* stats = nullptr; if (req->version < 0x200) { /* HTTP 1.x */ - stats = &dsc->df->d_http1Stats; + stats = &dsc->dohFrontend->d_http1Stats; } else { /* HTTP 2.0 */ - stats = &dsc->df->d_http2Stats; + stats = &dsc->dohFrontend->d_http2Stats; } switch (req->res.status) { @@ -875,10 +888,10 @@ static void on_response_ready_cb(struct st_h2o_filter_t *self, h2o_req_t *req, h We use this to signal to the 'du' that this req is no longer alive */ static void on_generator_dispose(void *_self) { - DOHUnit** du = reinterpret_cast(_self); - if (*du) { // if 0, on_dnsdist cleaned up du already - (*du)->self = nullptr; - (*du)->req = nullptr; + auto* dohUnit = static_cast(_self); + if (*dohUnit != nullptr) { // if nullptr, on_dnsdist cleaned up dohUnit already + (*dohUnit)->self = nullptr; + (*dohUnit)->req = nullptr; } } @@ -889,6 +902,7 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re { try { /* we only parse it there as a sanity check, we will parse it again later */ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) DNSPacketMangler mangler(reinterpret_cast(query.data()), query.size()); mangler.skipDomainName(); mangler.skipBytes(4); @@ -896,23 +910,24 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re /* we are doing quite some copies here, sorry about that, but we can't keep accessing the req object once we are in a different thread because the request might get killed by h2o at pretty much any time */ - auto du = DOHUnitUniquePtr(new DOHUnit(std::move(query), std::move(path), std::string(req->authority.base, req->authority.len))); - du->dsc = dsc; - du->req = req; - du->ids.origDest = local; - du->ids.origRemote = remote; - du->ids.protocol = dnsdist::Protocol::DoH; - du->responseSender = &dsc->d_responseSender; + auto dohUnit = std::make_unique(std::move(query), std::move(path), std::string(req->authority.base, req->authority.len)); + dohUnit->dsc = dsc; + dohUnit->req = req; + dohUnit->ids.origDest = local; + dohUnit->ids.origRemote = remote; + dohUnit->ids.protocol = dnsdist::Protocol::DoH; + dohUnit->responseSender = &dsc->d_responseSender; if (req->scheme != nullptr) { - du->scheme = std::string(req->scheme->name.base, req->scheme->name.len); + dohUnit->scheme = std::string(req->scheme->name.base, req->scheme->name.len); } - du->query_at = req->query_at; + dohUnit->query_at = req->query_at; - if (dsc->df->d_keepIncomingHeaders) { - du->headers = std::make_unique>(); - du->headers->reserve(req->headers.size); + if (dsc->dohFrontend->d_keepIncomingHeaders) { + dohUnit->headers = std::make_unique>(); + dohUnit->headers->reserve(req->headers.size); for (size_t i = 0; i < req->headers.size; ++i) { - (*du->headers)[std::string(req->headers.entries[i].name->base, req->headers.entries[i].name->len)] = std::string(req->headers.entries[i].value.base, req->headers.entries[i].value.len); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): h2o API + (*dohUnit->headers)[std::string(req->headers.entries[i].name->base, req->headers.entries[i].name->len)] = std::string(req->headers.entries[i].value.base, req->headers.entries[i].value.len); } } @@ -920,17 +935,17 @@ static void doh_dispatch_query(DOHServerConfig* dsc, h2o_handler_t* self, h2o_re h2o_socket_t* sock = req->conn->callbacks->get_socket(req->conn); const char * sni = h2o_socket_get_ssl_server_name(sock); if (sni != nullptr) { - du->sni = sni; + dohUnit->sni = sni; } #endif /* HAVE_H2O_SOCKET_GET_SSL_SERVER_NAME */ - du->self = reinterpret_cast(h2o_mem_alloc_shared(&req->pool, sizeof(*self), on_generator_dispose)); - *(du->self) = du.get(); + dohUnit->self = static_cast(h2o_mem_alloc_shared(&req->pool, sizeof(*self), on_generator_dispose)); + *(dohUnit->self) = dohUnit.get(); #ifdef USE_SINGLE_ACCEPTOR_THREAD - processDOHQuery(std::move(du), true); + processDOHQuery(std::move(dohUnit), true); #else /* USE_SINGLE_ACCEPTOR_THREAD */ try { - if (!dsc->d_querySender.send(std::move(du))) { + if (!dsc->d_querySender.send(std::move(dohUnit))) { ++dnsdist::metrics::g_stats.dohQueryPipeFull; vinfolog("Unable to pass a DoH query to the DoH worker thread because the pipe is full"); h2o_send_error_500(req, "Internal Server Error", "Internal Server Error", 0); @@ -956,7 +971,9 @@ static bool getHTTPHeaderValue(const h2o_req_t* req, const std::string& headerNa std::string_view headerNameView(headerName); for (size_t i = 0; i < req->headers.size; ++i) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): h2o API if (std::string_view(req->headers.entries[i].name->base, req->headers.entries[i].name->len) == headerNameView) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): h2o API value = std::string_view(req->headers.entries[i].value.base, req->headers.entries[i].value.len); /* don't stop there, we might have more than one header with the same name, and we want the last one */ found = true; @@ -1006,10 +1023,11 @@ static std::optional processForwardedForHeader(const h2o_req_t* re static int doh_handler(h2o_handler_t *self, h2o_req_t *req) { try { - if (!req->conn->ctx->storage.size) { + if (req->conn->ctx->storage.size == 0) { return 0; // although we might was well crash on this } - DOHServerConfig* dsc = reinterpret_cast(req->conn->ctx->storage.entries[0].data); + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): h2o API + auto* dsc = static_cast(req->conn->ctx->storage.entries[0].data); h2o_socket_t* sock = req->conn->callbacks->get_socket(req->conn); const int descriptor = h2o_socket_get_fd(sock); @@ -1021,17 +1039,18 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) ++conn.d_nbQueries; if (conn.d_nbQueries == 1) { if (h2o_socket_get_ssl_session_reused(sock) == 0) { - ++dsc->cs->tlsNewSessions; + ++dsc->clientState->tlsNewSessions; } else { - ++dsc->cs->tlsResumptions; + ++dsc->clientState->tlsResumptions; } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): h2o API h2o_socket_getsockname(sock, reinterpret_cast(&conn.d_local)); } auto remote = conn.d_remote; - if (dsc->df->d_trustForwardedForHeader) { + if (dsc->dohFrontend->d_trustForwardedForHeader) { auto newRemote = processForwardedForHeader(req, remote); if (newRemote) { remote = *newRemote; @@ -1046,20 +1065,25 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) return 0; } - if (auto tlsversion = h2o_socket_get_ssl_protocol_version(sock)) { - if(!strcmp(tlsversion, "TLSv1.0")) - ++dsc->cs->tls10queries; - else if(!strcmp(tlsversion, "TLSv1.1")) - ++dsc->cs->tls11queries; - else if(!strcmp(tlsversion, "TLSv1.2")) - ++dsc->cs->tls12queries; - else if(!strcmp(tlsversion, "TLSv1.3")) - ++dsc->cs->tls13queries; - else - ++dsc->cs->tlsUnknownqueries; + if (const auto* tlsversion = h2o_socket_get_ssl_protocol_version(sock)) { + if (strcmp(tlsversion, "TLSv1.0") == 0) { + ++dsc->clientState->tls10queries; + } + else if (strcmp(tlsversion, "TLSv1.1") == 0) { + ++dsc->clientState->tls11queries; + } + else if (strcmp(tlsversion, "TLSv1.2") == 0) { + ++dsc->clientState->tls12queries; + } + else if (strcmp(tlsversion, "TLSv1.3") == 0) { + ++dsc->clientState->tls13queries; + } + else { + ++dsc->clientState->tlsUnknownqueries; + } } - if (dsc->df->d_exactPathMatching) { + if (dsc->dohFrontend->d_exactPathMatching) { const std::string_view pathOnly(req->path_normalized.base, req->path_normalized.len); if (dsc->paths.count(pathOnly) == 0) { h2o_send_error_404(req, "Not Found", "there is no endpoint configured for this path", 0); @@ -1072,25 +1096,27 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) string path(req->path.base, req->path.len); /* the responses map can be updated at runtime, so we need to take a copy of the shared pointer, increasing the reference counter */ - auto responsesMap = dsc->df->d_responsesMap; + auto responsesMap = dsc->dohFrontend->d_responsesMap; /* 1 byte for the root label, 2 type, 2 class, 4 TTL (fake), 2 record length, 2 option length, 2 option code, 2 family, 1 source, 1 scope, 16 max for a full v6 */ const size_t maxAdditionalSizeForEDNS = 35U; if (responsesMap) { for (const auto& entry : *responsesMap) { if (entry->matches(path)) { const auto& customHeaders = entry->getHeaders(); - handleResponse(*dsc->df, req, entry->getStatusCode(), entry->getContent(), customHeaders ? *customHeaders : dsc->df->d_customResponseHeaders, std::string(), false); + handleResponse(*dsc->dohFrontend, req, entry->getStatusCode(), entry->getContent(), customHeaders ? *customHeaders : dsc->dohFrontend->d_customResponseHeaders, std::string(), false); return 0; } } } - if (h2o_memis(req->method.base, req->method.len, H2O_STRLIT("POST"))) { - ++dsc->df->d_postqueries; - if(req->version >= 0x0200) - ++dsc->df->d_http2Stats.d_nbQueries; - else - ++dsc->df->d_http1Stats.d_nbQueries; + if (h2o_memis(req->method.base, req->method.len, H2O_STRLIT("POST")) != 0) { + ++dsc->dohFrontend->d_postqueries; + if (req->version >= 0x0200) { + ++dsc->dohFrontend->d_http2Stats.d_nbQueries; + } + else { + ++dsc->dohFrontend->d_http1Stats.d_nbQueries; + } PacketBuffer query; /* We reserve a few additional bytes to be able to add EDNS later */ @@ -1101,9 +1127,10 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) } else if(req->query_at != SIZE_MAX && (req->path.len - req->query_at > 5)) { auto pos = path.find("?dns="); - if(pos == string::npos) + if (pos == string::npos) { pos = path.find("&dns="); - if(pos != string::npos) { + } + if (pos != string::npos) { // need to base64url decode this string sdns(path.substr(pos+5)); boost::replace_all(sdns,"-", "+"); @@ -1126,35 +1153,35 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) decoded.reserve(estimate + maxAdditionalSizeForEDNS); if(B64Decode(sdns, decoded) < 0) { h2o_send_error_400(req, "Bad Request", "Unable to decode BASE64-URL", 0); - ++dsc->df->d_badrequests; + ++dsc->dohFrontend->d_badrequests; return 0; } - else { - ++dsc->df->d_getqueries; - if(req->version >= 0x0200) - ++dsc->df->d_http2Stats.d_nbQueries; - else - ++dsc->df->d_http1Stats.d_nbQueries; - doh_dispatch_query(dsc, self, req, std::move(decoded), conn.d_local, remote, std::move(path)); + ++dsc->dohFrontend->d_getqueries; + if (req->version >= 0x0200) { + ++dsc->dohFrontend->d_http2Stats.d_nbQueries; } + else { + ++dsc->dohFrontend->d_http1Stats.d_nbQueries; + } + + doh_dispatch_query(dsc, self, req, std::move(decoded), conn.d_local, remote, std::move(path)); } else { vinfolog("HTTP request without DNS parameter: %s", req->path.base); h2o_send_error_400(req, "Bad Request", "Unable to find the DNS parameter", 0); - ++dsc->df->d_badrequests; + ++dsc->dohFrontend->d_badrequests; return 0; } } else { h2o_send_error_400(req, "Bad Request", "Unable to parse the request", 0); - ++dsc->df->d_badrequests; + ++dsc->dohFrontend->d_badrequests; } return 0; } - catch(const std::exception& e) - { + catch (const std::exception& e) { errlog("DOH Handler function failed with error %s", e.what()); return 0; } @@ -1174,9 +1201,7 @@ std::string DOHUnit::getHTTPPath() const if (query_at == SIZE_MAX) { return path; } - else { - return std::string(path, 0, query_at); - } + return {path, 0, query_at}; } const std::string& DOHUnit::getHTTPHost() const @@ -1192,11 +1217,9 @@ const std::string& DOHUnit::getHTTPScheme() const std::string DOHUnit::getHTTPQueryString() const { if (query_at == SIZE_MAX) { - return std::string(); - } - else { - return path.substr(query_at); + return {}; } + return path.substr(query_at); } void DOHUnit::setHTTPResponse(uint16_t statusCode, PacketBuffer&& body_, const std::string& contentType_) @@ -1227,18 +1250,18 @@ static void dnsdistclient(pdns::channel::Receiver&& receiver) if (!tmp) { continue; } - auto du = std::move(*tmp); + auto dohUnit = std::move(*tmp); /* we are not in the main DoH thread anymore, so there is a real risk of a race condition where h2o kills the query while we are processing it, - so we can't touch the content of du->req until we are back into the + so we can't touch the content of dohUnit->req until we are back into the main DoH thread */ - if (!du->req) { + if (dohUnit->req == nullptr) { // it got killed in flight already - du->self = nullptr; + dohUnit->self = nullptr; continue; } - processDOHQuery(std::move(du), false); + processDOHQuery(std::move(dohUnit), false); } catch (const std::exception& e) { errlog("Error while processing query received over DoH: %s", e.what()); @@ -1266,69 +1289,68 @@ static void on_dnsdist(h2o_socket_t *listener, const char *err) memory and likely coming up too late after the client has gone away */ auto* dsc = static_cast(listener->data); while (true) { - DOHUnitUniquePtr du{nullptr}; + DOHUnitUniquePtr dohUnit{nullptr}; try { auto tmp = dsc->d_responseReceiver.receive(); if (!tmp) { return; } - du = std::move(*tmp); + dohUnit = std::move(*tmp); } catch (const std::exception& e) { errlog("Error reading a DOH internal response: %s", e.what()); return; } - if (!du->req) { // it got killed in flight - du->self = nullptr; + if (dohUnit->req == nullptr) { // it got killed in flight + dohUnit->self = nullptr; continue; } - if (!du->tcp && - du->truncated && - du->query.size() > du->ids.d_proxyProtocolPayloadSize && - (du->query.size() - du->ids.d_proxyProtocolPayloadSize) > sizeof(dnsheader)) { + if (!dohUnit->tcp && + dohUnit->truncated && + dohUnit->query.size() > dohUnit->ids.d_proxyProtocolPayloadSize && + (dohUnit->query.size() - dohUnit->ids.d_proxyProtocolPayloadSize) > sizeof(dnsheader)) { /* restoring the original ID */ - dnsheader* queryDH = reinterpret_cast(du->query.data() + du->ids.d_proxyProtocolPayloadSize); - queryDH->id = du->ids.origID; - du->ids.forwardedOverUDP = false; - du->tcp = true; - du->truncated = false; - du->response.clear(); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + auto* queryDH = reinterpret_cast(&dohUnit->query.at(dohUnit->ids.d_proxyProtocolPayloadSize)); + queryDH->id = dohUnit->ids.origID; + dohUnit->ids.forwardedOverUDP = false; + dohUnit->tcp = true; + dohUnit->truncated = false; + dohUnit->response.clear(); - auto cpq = std::make_unique(std::move(du), false); + auto cpq = std::make_unique(std::move(dohUnit), false); if (g_tcpclientthreads && g_tcpclientthreads->passCrossProtocolQueryToThread(std::move(cpq))) { continue; } - else { - vinfolog("Unable to pass DoH query to a TCP worker thread after getting a TC response over UDP"); - continue; - } + vinfolog("Unable to pass DoH query to a TCP worker thread after getting a TC response over UDP"); + continue; } - if (du->self) { + if (dohUnit->self != nullptr) { // we are back in the h2o main thread now, so we don't risk - // a race (h2o killing the query) when accessing du->req anymore - *du->self = nullptr; // so we don't clean up again in on_generator_dispose - du->self = nullptr; + // a race (h2o killing the query) when accessing dohUnit->req anymore + *dohUnit->self = nullptr; // so we don't clean up again in on_generator_dispose + dohUnit->self = nullptr; } - handleResponse(*dsc->df, du->req, du->status_code, du->response, dsc->df->d_customResponseHeaders, du->contentType, true); + handleResponse(*dsc->dohFrontend, dohUnit->req, dohUnit->status_code, dohUnit->response, dsc->dohFrontend->d_customResponseHeaders, dohUnit->contentType, true); } } /* called when a TCP connection has been accepted, the TLS session has not been established */ static void on_accept(h2o_socket_t *listener, const char *err) { - DOHServerConfig* dsc = reinterpret_cast(listener->data); - h2o_socket_t *sock = nullptr; + auto* dsc = static_cast(listener->data); if (err != nullptr) { return; } - if ((sock = h2o_evloop_socket_accept(listener)) == nullptr) { + h2o_socket_t* sock = h2o_evloop_socket_accept(listener); + if (sock == nullptr) { return; } @@ -1339,18 +1361,19 @@ static void on_accept(h2o_socket_t *listener, const char *err) } ComboAddress remote; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): h2o API if (h2o_socket_getpeername(sock, reinterpret_cast(&remote)) == 0) { vinfolog("Dropping DoH connection because we could not retrieve the remote host"); h2o_socket_close(sock); return; } - if (dsc->df->d_earlyACLDrop && !dsc->df->d_trustForwardedForHeader && !dsc->holders.acl->match(remote)) { + if (dsc->dohFrontend->d_earlyACLDrop && !dsc->dohFrontend->d_trustForwardedForHeader && !dsc->holders.acl->match(remote)) { ++dnsdist::metrics::g_stats.aclDrops; - vinfolog("Dropping DoH connection from %s because of ACL", remote.toStringWithPort()); - h2o_socket_close(sock); - return; - } + vinfolog("Dropping DoH connection from %s because of ACL", remote.toStringWithPort()); + h2o_socket_close(sock); + return; + } if (!dnsdist::IncomingConcurrentTCPConnectionsManager::accountNewTCPConnection(remote)) { vinfolog("Dropping DoH connection from %s because we have too many from this client already", remote.toStringWithPort()); @@ -1358,15 +1381,15 @@ static void on_accept(h2o_socket_t *listener, const char *err) return; } - auto concurrentConnections = ++dsc->cs->tcpCurrentConnections; - if (dsc->cs->d_tcpConcurrentConnectionsLimit > 0 && concurrentConnections > dsc->cs->d_tcpConcurrentConnectionsLimit) { - --dsc->cs->tcpCurrentConnections; + auto concurrentConnections = ++dsc->clientState->tcpCurrentConnections; + if (dsc->clientState->d_tcpConcurrentConnectionsLimit > 0 && concurrentConnections > dsc->clientState->d_tcpConcurrentConnectionsLimit) { + --dsc->clientState->tcpCurrentConnections; h2o_socket_close(sock); return; } - if (concurrentConnections > dsc->cs->tcpMaxConcurrentConnections.load()) { - dsc->cs->tcpMaxConcurrentConnections.store(concurrentConnections); + if (concurrentConnections > dsc->clientState->tcpMaxConcurrentConnections.load()) { + dsc->clientState->tcpMaxConcurrentConnections.store(concurrentConnections); } auto& conn = t_conns[descriptor]; @@ -1381,14 +1404,14 @@ static void on_accept(h2o_socket_t *listener, const char *err) sock->on_close.data = &conn; sock->data = dsc; - ++dsc->df->d_httpconnects; + ++dsc->dohFrontend->d_httpconnects; h2o_accept(conn.d_acceptCtx->get(), sock); } -static int create_listener(std::shared_ptr& dsc, int fd) +static int create_listener(std::shared_ptr& dsc, int descriptor) { - auto* sock = h2o_evloop_socket_create(dsc->h2o_ctx.loop, fd, H2O_SOCKET_FLAG_DONT_READ); + auto* sock = h2o_evloop_socket_create(dsc->h2o_ctx.loop, descriptor, H2O_SOCKET_FLAG_DONT_READ); sock->data = dsc.get(); h2o_socket_read_start(sock, on_accept); @@ -1401,25 +1424,27 @@ static int ocsp_stapling_callback(SSL* ssl, void* arg) if (ssl == nullptr || arg == nullptr) { return SSL_TLSEXT_ERR_NOACK; } - const auto ocspMap = reinterpret_cast*>(arg); + const auto* ocspMap = static_cast*>(arg); return libssl_ocsp_stapling_callback(ssl, *ocspMap); } #endif /* DISABLE_OCSP_STAPLING */ #if OPENSSL_VERSION_MAJOR >= 3 -static int ticket_key_callback(SSL *s, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char *iv, EVP_CIPHER_CTX *ectx, EVP_MAC_CTX *hctx, int enc) +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays): OpenSSL API +static int ticket_key_callback(SSL* sslContext, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* ivector, EVP_CIPHER_CTX* ectx, EVP_MAC_CTX* hctx, int enc) #else -static int ticket_key_callback(SSL *s, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char *iv, EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc) +// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,modernize-avoid-c-arrays): OpenSSL API +static int ticket_key_callback(SSL *sslContext, unsigned char keyName[TLS_TICKETS_KEY_NAME_SIZE], unsigned char* ivector, EVP_CIPHER_CTX* ectx, HMAC_CTX* hctx, int enc) #endif { - DOHAcceptContext* ctx = reinterpret_cast(libssl_get_ticket_key_callback_data(s)); + auto* ctx = static_cast(libssl_get_ticket_key_callback_data(sslContext)); if (ctx == nullptr || !ctx->d_ticketKeys) { return -1; } ctx->handleTicketsKeyRotation(); - auto ret = libssl_ticket_key_callback(s, *ctx->d_ticketKeys, keyName, iv, ectx, hctx, enc); + auto ret = libssl_ticket_key_callback(sslContext, *ctx->d_ticketKeys, keyName, ivector, ectx, hctx, enc); if (enc == 0) { if (ret == 0) { ++ctx->d_cs->tlsUnknownTicketKey; @@ -1437,7 +1462,7 @@ static void setupTLSContext(DOHAcceptContext& acceptCtx, TLSErrorCounters& counters) { if (tlsConfig.d_ciphers.empty()) { - tlsConfig.d_ciphers = DOH_DEFAULT_CIPHERS; + tlsConfig.d_ciphers = DOH_DEFAULT_CIPHERS.data(); } auto [ctx, warnings] = libssl_init_server_context(tlsConfig, acceptCtx.d_ocspResponses); @@ -1478,29 +1503,29 @@ static void setupTLSContext(DOHAcceptContext& acceptCtx, acceptCtx.loadTicketsKeys(tlsConfig.d_ticketKeyFile); } - auto nativeCtx = acceptCtx.get(); + auto* nativeCtx = acceptCtx.get(); nativeCtx->ssl_ctx = ctx.release(); } static void setupAcceptContext(DOHAcceptContext& ctx, DOHServerConfig& dsc, bool setupTLS) { - auto nativeCtx = ctx.get(); + auto* nativeCtx = ctx.get(); nativeCtx->ctx = &dsc.h2o_ctx; nativeCtx->hosts = dsc.h2o_config.hosts; - auto df = std::atomic_load_explicit(&dsc.df, std::memory_order_acquire); - ctx.d_ticketsKeyRotationDelay = df->d_tlsContext.d_tlsConfig.d_ticketsKeyRotationDelay; + auto dohFrontend = std::atomic_load_explicit(&dsc.dohFrontend, std::memory_order_acquire); + ctx.d_ticketsKeyRotationDelay = dohFrontend->d_tlsContext.d_tlsConfig.d_ticketsKeyRotationDelay; - if (setupTLS && df->isHTTPS()) { + if (setupTLS && dohFrontend->isHTTPS()) { try { setupTLSContext(ctx, - df->d_tlsContext.d_tlsConfig, - df->d_tlsContext.d_tlsCounters); + dohFrontend->d_tlsContext.d_tlsConfig, + dohFrontend->d_tlsContext.d_tlsCounters); } catch (const std::runtime_error& e) { - throw std::runtime_error("Error setting up TLS context for DoH listener on '" + df->d_tlsContext.d_addr.toStringWithPort() + "': " + e.what()); + throw std::runtime_error("Error setting up TLS context for DoH listener on '" + dohFrontend->d_tlsContext.d_addr.toStringWithPort() + "': " + e.what()); } } - ctx.d_cs = dsc.cs; + ctx.d_cs = dsc.clientState; } static h2o_pathconf_t *register_handler(h2o_hostconf_t *hostconf, const char *path, int (*on_req)(h2o_handler_t *, h2o_req_t *)) @@ -1510,7 +1535,7 @@ static h2o_pathconf_t *register_handler(h2o_hostconf_t *hostconf, const char *pa return pathconf; } h2o_filter_t *filter = h2o_create_filter(pathconf, sizeof(*filter)); - if (filter) { + if (filter != nullptr) { filter->on_setup_ostream = on_response_ready_cb; } @@ -1523,14 +1548,14 @@ static h2o_pathconf_t *register_handler(h2o_hostconf_t *hostconf, const char *pa } // this is the entrypoint from dnsdist.cc -void dohThread(ClientState* cs) +void dohThread(ClientState* clientState) { try { - std::shared_ptr& df = cs->dohFrontend; - auto& dsc = df->d_dsc; - dsc->cs = cs; - std::atomic_store_explicit(&dsc->df, cs->dohFrontend, std::memory_order_release); - dsc->h2o_config.server_name = h2o_iovec_init(df->d_serverTokens.c_str(), df->d_serverTokens.size()); + std::shared_ptr& dohFrontend = clientState->dohFrontend; + auto& dsc = dohFrontend->d_dsc; + dsc->clientState = clientState; + std::atomic_store_explicit(&dsc->dohFrontend, clientState->dohFrontend, std::memory_order_release); + dsc->h2o_config.server_name = h2o_iovec_init(dohFrontend->d_serverTokens.c_str(), dohFrontend->d_serverTokens.size()); #ifndef USE_SINGLE_ACCEPTOR_THREAD std::thread dnsdistThread(dnsdistclient, std::move(dsc->d_queryReceiver)); @@ -1540,9 +1565,9 @@ void dohThread(ClientState* cs) setThreadName("dnsdist/doh"); // I wonder if this registers an IP address.. I think it does // this may mean we need to actually register a site "name" here and not the IP address - h2o_hostconf_t *hostconf = h2o_config_register_host(&dsc->h2o_config, h2o_iovec_init(df->d_tlsContext.d_addr.toString().c_str(), df->d_tlsContext.d_addr.toString().size()), 65535); + h2o_hostconf_t *hostconf = h2o_config_register_host(&dsc->h2o_config, h2o_iovec_init(dohFrontend->d_tlsContext.d_addr.toString().c_str(), dohFrontend->d_tlsContext.d_addr.toString().size()), 65535); - dsc->paths = df->d_urls; + dsc->paths = dohFrontend->d_urls; for (const auto& url : dsc->paths) { register_handler(hostconf, url.c_str(), doh_handler); } @@ -1551,6 +1576,7 @@ void dohThread(ClientState* cs) // in this complicated way we insert the DOHServerConfig pointer in there h2o_vector_reserve(nullptr, &dsc->h2o_ctx.storage, 1); + // NOLINTNEXTLINE: h2o API dsc->h2o_ctx.storage.entries[0].data = dsc.get(); ++dsc->h2o_ctx.storage.size; @@ -1562,12 +1588,12 @@ void dohThread(ClientState* cs) setupAcceptContext(*dsc->accept_ctx, *dsc, false); - if (create_listener(dsc, cs->tcpFD) != 0) { - throw std::runtime_error("DOH server failed to listen on " + df->d_tlsContext.d_addr.toStringWithPort() + ": " + strerror(errno)); + if (create_listener(dsc, clientState->tcpFD) != 0) { + throw std::runtime_error("DOH server failed to listen on " + dohFrontend->d_tlsContext.d_addr.toStringWithPort() + ": " + stringerror(errno)); } - for (const auto& [addr, fd] : cs->d_additionalAddresses) { - if (create_listener(dsc, fd) != 0) { - throw std::runtime_error("DOH server failed to listen on additional address " + addr.toStringWithPort() + " for DOH local" + df->d_tlsContext.d_addr.toStringWithPort() + ": " + strerror(errno)); + for (const auto& [addr, descriptor] : clientState->d_additionalAddresses) { + if (create_listener(dsc, descriptor) != 0) { + throw std::runtime_error("DOH server failed to listen on additional address " + addr.toStringWithPort() + " for DOH local" + dohFrontend->d_tlsContext.d_addr.toStringWithPort() + ": " + stringerror(errno)); } } @@ -1576,12 +1602,12 @@ void dohThread(ClientState* cs) int result = h2o_evloop_run(dsc->h2o_ctx.loop, INT32_MAX); if (result == -1) { if (errno != EINTR) { - errlog("Error in the DoH event loop: %s", strerror(errno)); + errlog("Error in the DoH event loop: %s", stringerror(errno)); stop = true; } } } - while (stop == false); + while (!stop); } catch (const std::exception& e) { @@ -1592,53 +1618,53 @@ void dohThread(ClientState* cs) } } -void DOHUnit::handleUDPResponse(PacketBuffer&& udpResponse, InternalQueryState&& state, const std::shared_ptr&) +void DOHUnit::handleUDPResponse(PacketBuffer&& udpResponse, InternalQueryState&& state, [[maybe_unused]] const std::shared_ptr& downstream) { - auto du = std::unique_ptr(this); - du->ids = std::move(state); + auto dohUnit = std::unique_ptr(this); + dohUnit->ids = std::move(state); { - const dnsheader* dh = reinterpret_cast(udpResponse.data()); - if (dh->tc) { - du->truncated = true; + dnsheader_aligned dnsHeader(udpResponse.data()); + if (dnsHeader.get()->tc) { + dohUnit->truncated = true; } } - if (!du->truncated) { + if (!dohUnit->truncated) { static thread_local LocalStateHolder> localRespRuleActions = g_respruleactions.getLocal(); static thread_local LocalStateHolder> localCacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal(); - DNSResponse dr(du->ids, udpResponse, du->downstream); - dnsheader cleartextDH; - memcpy(&cleartextDH, dr.getHeader(), sizeof(cleartextDH)); + DNSResponse dnsResponse(dohUnit->ids, udpResponse, dohUnit->downstream); + dnsheader cleartextDH{}; + memcpy(&cleartextDH, dnsResponse.getHeader(), sizeof(cleartextDH)); - dr.ids.du = std::move(du); - if (!processResponse(udpResponse, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) { - if (dr.ids.du) { - du = getDUFromIDS(dr.ids); - du->status_code = 503; - sendDoHUnitToTheMainThread(std::move(du), "Response dropped by rules"); + dnsResponse.ids.du = std::move(dohUnit); + if (!processResponse(udpResponse, *localRespRuleActions, *localCacheInsertedRespRuleActions, dnsResponse, false)) { + if (dnsResponse.ids.du) { + dohUnit = getDUFromIDS(dnsResponse.ids); + dohUnit->status_code = 503; + sendDoHUnitToTheMainThread(std::move(dohUnit), "Response dropped by rules"); } return; } - if (dr.isAsynchronous()) { + if (dnsResponse.isAsynchronous()) { return; } - du = getDUFromIDS(dr.ids); - du->response = std::move(udpResponse); - double udiff = du->ids.queryRealTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (https), took %f us", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); + dohUnit = getDUFromIDS(dnsResponse.ids); + dohUnit->response = std::move(udpResponse); + double udiff = dohUnit->ids.queryRealTime.udiff(); + vinfolog("Got answer from %s, relayed to %s (https), took %f us", dohUnit->downstream->d_config.remote.toStringWithPort(), dohUnit->ids.origRemote.toStringWithPort(), udiff); - handleResponseSent(du->ids, udiff, dr.ids.origRemote, du->downstream->d_config.remote, du->response.size(), cleartextDH, du->downstream->getProtocol(), true); + handleResponseSent(dohUnit->ids, udiff, dnsResponse.ids.origRemote, dohUnit->downstream->d_config.remote, dohUnit->response.size(), cleartextDH, dohUnit->downstream->getProtocol(), true); ++dnsdist::metrics::g_stats.responses; - if (du->ids.cs) { - ++du->ids.cs->responses; + if (dohUnit->ids.cs != nullptr) { + ++dohUnit->ids.cs->responses; } } - sendDoHUnitToTheMainThread(std::move(du), "DoH response"); + sendDoHUnitToTheMainThread(std::move(dohUnit), "DoH response"); } void H2ODOHFrontend::rotateTicketsKey(time_t now) @@ -1667,7 +1693,7 @@ std::string H2ODOHFrontend::getNextTicketsKeyRotation() const if (d_dsc && d_dsc->accept_ctx) { return std::to_string(d_dsc->accept_ctx->getNextTicketsKeyRotation()); } - return 0; + return {}; } size_t H2ODOHFrontend::getTicketsKeysCount() diff --git a/pdns/dnsdistdist/test-dnsdistasync.cc b/pdns/dnsdistdist/test-dnsdistasync.cc index 65a9c4a53fba..d74d2e64b5d6 100644 --- a/pdns/dnsdistdist/test-dnsdistasync.cc +++ b/pdns/dnsdistdist/test-dnsdistasync.cc @@ -36,15 +36,15 @@ class DummyQuerySender : public TCPQuerySender return true; } - void handleResponse(const struct timeval&, TCPResponse&&) override + void handleResponse([[maybe_unused]] const struct timeval& now, [[maybe_unused]] TCPResponse&& response) override { } - void handleXFRResponse(const struct timeval&, TCPResponse&&) override + void handleXFRResponse([[maybe_unused]] const struct timeval& now, [[maybe_unused]] TCPResponse&& response) override { } - void notifyIOError(const struct timeval&, TCPResponse&&) override + void notifyIOError([[maybe_unused]] const struct timeval& now, [[maybe_unused]] TCPResponse&& response) override { errorRaised = true; } diff --git a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc index 19cafc004ce2..9d437578f77f 100644 --- a/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistlbpolicies_cc.cc @@ -34,6 +34,7 @@ std::vector> g_frontends; /* add stub implementations, we don't want to include the corresponding object files and their dependencies */ +// NOLINTNEXTLINE(readability-convert-member-functions-to-static): this is a stub, the real one is not that simple.. bool TLSFrontend::setupTLS() { return true; diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc index c43297b53e5f..d10e85ef13f5 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc @@ -626,11 +626,11 @@ class MockupQuerySender : public TCPQuerySender d_valid = true; } - void handleXFRResponse(const struct timeval&, TCPResponse&&) override + void handleXFRResponse([[maybe_unused]] const struct timeval& now, [[maybe_unused]] TCPResponse&& response) override { } - void notifyIOError(const struct timeval&, TCPResponse&&) override + void notifyIOError([[maybe_unused]] const struct timeval& now, [[maybe_unused]] TCPResponse&& response) override { d_error = true; } diff --git a/pdns/doh.hh b/pdns/doh.hh index c482b7a0fa2a..58a26f16918f 100644 --- a/pdns/doh.hh +++ b/pdns/doh.hh @@ -51,7 +51,7 @@ public: size_t getTicketsKeysCount() override; }; -void dohThread(ClientState* cs); +void dohThread(ClientState* clientState); #endif /* HAVE_LIBH2OEVLOOP */ #endif /* HAVE_DNS_OVER_HTTPS */ From c02b7e139240e28260dea2313e8af933e5dda332 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 30 Jun 2023 17:49:35 +0200 Subject: [PATCH 631/909] dnsdist: Add unit and regression tests for incoming DoH w/ nghttp2 It is quite likely that the underlying TLS layer has buffered some data already, so we need to consume it before trying to poll the socket. --- pdns/dnsdist-doh-common.hh | 4 + pdns/dnsdistdist/Makefile.am | 2 + pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 271 ++++--- pdns/dnsdistdist/dnsdist-nghttp2-in.hh | 20 +- pdns/dnsdistdist/dnsdist-nghttp2.cc | 3 +- pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc | 727 ++++++++++++++++++ pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc | 135 +--- .../dnsdistdist/test-dnsdistnghttp2_common.hh | 157 ++++ pdns/dnsdistdist/test-dnsdisttcp_cc.cc | 2 +- pdns/test-dnsdist_cc.cc | 2 +- regression-tests.dnsdist/dnsdisttests.py | 32 +- regression-tests.dnsdist/test_DOH.py | 170 +++- 12 files changed, 1228 insertions(+), 297 deletions(-) create mode 100644 pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc create mode 100644 pdns/dnsdistdist/test-dnsdistnghttp2_common.hh diff --git a/pdns/dnsdist-doh-common.hh b/pdns/dnsdist-doh-common.hh index 41166de9f302..f0a1adc76744 100644 --- a/pdns/dnsdist-doh-common.hh +++ b/pdns/dnsdist-doh-common.hh @@ -77,6 +77,10 @@ struct DOHFrontend DOHFrontend() { } + DOHFrontend(std::shared_ptr tlsCtx): + d_tlsContext(std::move(tlsCtx)) + { + } virtual ~DOHFrontend() { diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index e4f30eaa83ab..0c07520108a9 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -332,7 +332,9 @@ testrunner_SOURCES = \ test-dnsdistkvs_cc.cc \ test-dnsdistlbpolicies_cc.cc \ test-dnsdistluanetwork.cc \ + test-dnsdistnghttp2-in_cc.cc \ test-dnsdistnghttp2_cc.cc \ + test-dnsdistnghttp2_common.hh \ test-dnsdistpacketcache_cc.cc \ test-dnsdistrings_cc.cc \ test-dnsdistrules_cc.cc \ diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 21098ec96ec5..b71601a916d4 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -142,7 +142,7 @@ class IncomingDoHCrossProtocolContext : public DOHUnitInterface d_query.d_contentTypeOut = contentType; } - void handleUDPResponse(PacketBuffer&& response, InternalQueryState&& state, const std::shared_ptr& downstream) override + void handleUDPResponse(PacketBuffer&& response, InternalQueryState&& state, const std::shared_ptr& downstream_) override { std::unique_ptr unit(this); auto conn = d_connection.lock(); @@ -153,7 +153,7 @@ class IncomingDoHCrossProtocolContext : public DOHUnitInterface state.du = std::move(unit); TCPResponse resp(std::move(response), std::move(state), nullptr, nullptr); - resp.d_ds = downstream; + resp.d_ds = downstream_; struct timeval now { }; @@ -263,7 +263,7 @@ IncomingHTTP2Connection::IncomingHTTP2Connection(ConnectionInfo&& connectionInfo bool IncomingHTTP2Connection::checkALPN() { constexpr std::array h2ALPN{'h', '2'}; - auto protocols = d_handler.getNextProtocol(); + const auto protocols = d_handler.getNextProtocol(); if (protocols.size() == h2ALPN.size() && memcmp(protocols.data(), h2ALPN.data(), h2ALPN.size()) == 0) { return true; } @@ -285,6 +285,11 @@ void IncomingHTTP2Connection::handleConnectionReady() } } +bool IncomingHTTP2Connection::hasPendingWrite() const +{ + return d_pendingWrite; +} + void IncomingHTTP2Connection::handleIO() { IOState iostate = IOState::Done; @@ -297,7 +302,7 @@ void IncomingHTTP2Connection::handleIO() if (maxConnectionDurationReached(g_maxTCPConnectionDuration, now)) { vinfolog("Terminating DoH connection from %s because it reached the maximum TCP connection duration", d_ci.remote.toStringWithPort()); stopIO(); - d_connectionDied = true; + d_connectionClosing = true; return; } @@ -341,56 +346,94 @@ void IncomingHTTP2Connection::handleIO() } } - if (d_state == State::waitingForQuery || d_state == State::idle) { - readHTTPData(); + if (active() && !d_connectionClosing && (d_state == State::waitingForQuery || d_state == State::idle)) { + do { + iostate = readHTTPData(); + } while (active() && !d_connectionClosing && iostate == IOState::Done); } - if (!d_connectionDied) { - auto shared = std::dynamic_pointer_cast(shared_from_this()); + if (!active()) { + stopIO(); + return; + } + /* + So: + - if we have a pending write, we need to wait until the socket becomes writable + and then call handleWritableCallback + - if we have NeedWrite but no pending write, we need to wait until the socket + becomes writable but for handleReadableIOCallback + - if we have NeedRead, or nghttp2_session_want_read, wait until the socket + becomes readable and call handleReadableIOCallback + */ + if (hasPendingWrite()) { + updateIO(IOState::NeedWrite, handleWritableIOCallback); + } + else if (iostate == IOState::NeedWrite) { + updateIO(IOState::NeedWrite, handleReadableIOCallback); + } + else if (!d_connectionClosing) { if (nghttp2_session_want_read(d_session.get()) != 0) { - d_ioState->add(IOState::NeedRead, &handleReadableIOCallback, shared, boost::none); + updateIO(IOState::NeedRead, handleReadableIOCallback); } - if (nghttp2_session_want_write(d_session.get()) != 0) { - d_ioState->add(IOState::NeedWrite, &handleWritableIOCallback, shared, boost::none); + else { + if (isIdle()) { + watchForRemoteHostClosingConnection(); + } } } } catch (const std::exception& e) { - vinfolog("Exception when processing IO for incoming DoH connection from %s: %s", d_ci.remote.toStringWithPort(), e.what()); + infolog("Exception when processing IO for incoming DoH connection from %s: %s", d_ci.remote.toStringWithPort(), e.what()); d_connectionDied = true; stopIO(); } } -ssize_t IncomingHTTP2Connection::send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data) +void IncomingHTTP2Connection::writeToSocket(bool socketReady) { - auto* conn = static_cast(user_data); - // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API - conn->d_out.insert(conn->d_out.end(), data, data + length); - - if (conn->d_connectionDied || conn->d_needFlush) { - try { - conn->d_needFlush = false; - auto state = conn->d_handler.tryWrite(conn->d_out, conn->d_outPos, conn->d_out.size()); - if (state == IOState::Done) { - conn->d_out.clear(); - conn->d_outPos = 0; - if (!conn->isIdle()) { - conn->updateIO(IOState::NeedRead, handleReadableIOCallback); + try { + d_needFlush = false; + IOState newState = d_handler.tryWrite(d_out, d_outPos, d_out.size()); + + if (newState == IOState::Done) { + d_pendingWrite = false; + d_out.clear(); + d_outPos = 0; + if (active() && !d_connectionClosing) { + if (!isIdle()) { + updateIO(IOState::NeedRead, handleReadableIOCallback); } else { - conn->watchForRemoteHostClosingConnection(); + watchForRemoteHostClosingConnection(); } } else { - conn->updateIO(state, handleWritableIOCallback); + stopIO(); } } - catch (const std::exception& e) { - vinfolog("Exception while trying to write (send) to incoming HTTP connection to %s: %s", conn->d_ci.remote.toStringWithPort(), e.what()); - conn->handleIOError(); + else { + updateIO(newState, handleWritableIOCallback); + d_pendingWrite = true; } } + catch (const std::exception& e) { + vinfolog("Exception while trying to write (%s) to HTTP client connection to %s: %s", (socketReady ? "ready" : "send"), d_ci.remote.toStringWithPort(), e.what()); + handleIOError(); + } +} + +ssize_t IncomingHTTP2Connection::send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data) +{ + auto* conn = static_cast(user_data); + if (conn->d_connectionDied) { + return static_cast(length); + } + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API + conn->d_out.insert(conn->d_out.end(), data, data + length); + + if (conn->d_connectionClosing || conn->d_needFlush) { + conn->writeToSocket(false); + } return static_cast(length); } @@ -471,7 +514,7 @@ IOState IncomingHTTP2Connection::sendResponse(const struct timeval& now, TCPResp sendResponse(response.d_idstate.d_streamID, context, statusCode, d_ci.cs->dohFrontend->d_customResponseHeaders, contentType, sendContentType); handleResponseSent(response); - return IOState::Done; + return hasPendingWrite() ? IOState::NeedWrite : IOState::Done; } void IncomingHTTP2Connection::notifyIOError(const struct timeval& now, TCPResponse&& response) @@ -748,6 +791,12 @@ void IncomingHTTP2Connection::handleIncomingQuery(IncomingHTTP2Connection::Pendi sendResponse(streamID, query, code, d_ci.cs->dohFrontend->d_customResponseHeaders); }; + if (query.d_method == PendingQuery::Method::Unknown || + query.d_method == PendingQuery::Method::Unsupported) { + handleImmediateResponse(400, "DoH query not allowed because of unsupported HTTP method"); + return; + } + ++d_ci.cs->dohFrontend->d_http2Stats.d_nbQueries; if (d_ci.cs->dohFrontend->d_trustForwardedForHeader) { @@ -864,44 +913,8 @@ void IncomingHTTP2Connection::handleIncomingQuery(IncomingHTTP2Connection::Pendi int IncomingHTTP2Connection::on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data) { auto* conn = static_cast(user_data); -#if 0 - switch (frame->hd.type) { - case NGHTTP2_HEADERS: - cerr<<"got headers"<headers.cat == NGHTTP2_HCAT_RESPONSE) { - cerr<<"All headers received"<headers.cat == NGHTTP2_HCAT_REQUEST) { - cerr<<"All headers received - query"<settings.niv<settings.niv; idx++) { - cerr<<"- "<settings.iv[idx].settings_id<<" "<settings.iv[idx].value<hd.type == NGHTTP2_GOAWAY) { - conn->stopIO(); - if (conn->isIdle()) { - if (nghttp2_session_want_write(conn->d_session.get()) != 0) { - conn->d_ioState->add(IOState::NeedWrite, &handleWritableIOCallback, conn, boost::none); - } - } - } - /* is this the last frame for this stream? */ - else if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) != 0) { + if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) != 0) { auto streamID = frame->hd.stream_id; auto stream = conn->d_currentStreams.find(streamID); if (stream != conn->d_currentStreams.end()) { @@ -959,7 +972,8 @@ int IncomingHTTP2Connection::on_begin_headers_callback(nghttp2_session* session, if (!insertPair.second) { /* there is a stream ID collision, something is very wrong! */ vinfolog("Stream ID collision (%d) on connection from %d", frame->hd.stream_id, conn->d_ci.remote.toStringWithPort()); - conn->d_connectionDied = true; + conn->d_connectionClosing = true; + conn->d_needFlush = true; nghttp2_session_terminate_session(conn->d_session.get(), NGHTTP2_NO_ERROR); auto ret = nghttp2_session_send(conn->d_session.get()); if (ret != 0) { @@ -1047,8 +1061,9 @@ int IncomingHTTP2Connection::on_header_callback(nghttp2_session* session, const query.d_method = PendingQuery::Method::Post; } else { + query.d_method = PendingQuery::Method::Unsupported; vinfolog("Unsupported method value"); - return NGHTTP2_ERR_CALLBACK_FAILURE; + return 0; } } @@ -1087,7 +1102,8 @@ int IncomingHTTP2Connection::on_error_callback(nghttp2_session* session, int lib auto* conn = static_cast(user_data); vinfolog("Error in HTTP/2 connection from %d: %s", conn->d_ci.remote.toStringWithPort(), std::string(msg, len)); - conn->d_connectionDied = true; + conn->d_connectionClosing = true; + conn->d_needFlush = true; nghttp2_session_terminate_session(conn->d_session.get(), NGHTTP2_NO_ERROR); auto ret = nghttp2_session_send(conn->d_session.get()); if (ret != 0) { @@ -1098,55 +1114,35 @@ int IncomingHTTP2Connection::on_error_callback(nghttp2_session* session, int lib return 0; } -void IncomingHTTP2Connection::readHTTPData() +IOState IncomingHTTP2Connection::readHTTPData() { IOState newState = IOState::Done; - IOStateGuard ioGuard(d_ioState); - do { - size_t got = 0; - if (d_in.size() < 128) { - d_in.resize(std::max(static_cast(128U), d_in.capacity())); - } - try { - newState = d_handler.tryRead(d_in, got, d_in.size(), true); - d_in.resize(got); - - if (got > 0) { - /* we got something */ - auto readlen = nghttp2_session_mem_recv(d_session.get(), d_in.data(), d_in.size()); - /* as long as we don't require a pause by returning nghttp2_error.NGHTTP2_ERR_PAUSE from a CB, - all data should be consumed before returning */ - if (readlen < 0 || static_cast(readlen) < d_in.size()) { - throw std::runtime_error("Fatal error while passing received data to nghttp2: " + std::string(nghttp2_strerror((int)readlen))); - } - - nghttp2_session_send(d_session.get()); + size_t got = 0; + if (d_in.size() < s_initialReceiveBufferSize) { + d_in.resize(std::max(s_initialReceiveBufferSize, d_in.capacity())); + } + try { + newState = d_handler.tryRead(d_in, got, d_in.size(), true); + d_in.resize(got); + + if (got > 0) { + /* we got something */ + auto readlen = nghttp2_session_mem_recv(d_session.get(), d_in.data(), d_in.size()); + /* as long as we don't require a pause by returning nghttp2_error.NGHTTP2_ERR_PAUSE from a CB, + all data should be consumed before returning */ + if (readlen < 0 || static_cast(readlen) < d_in.size()) { + throw std::runtime_error("Fatal error while passing received data to nghttp2: " + std::string(nghttp2_strerror((int)readlen))); } - if (newState == IOState::Done) { - if (nghttp2_session_want_read(d_session.get()) != 0) { - continue; - } - if (isIdle()) { - watchForRemoteHostClosingConnection(); - ioGuard.release(); - break; - } - } - else { - if (newState == IOState::NeedWrite) { - updateIO(IOState::NeedWrite, handleReadableIOCallback); - } - ioGuard.release(); - break; - } + nghttp2_session_send(d_session.get()); } - catch (const std::exception& e) { - vinfolog("Exception while trying to read from HTTP client connection to %s: %s", d_ci.remote.toStringWithPort(), e.what()); - handleIOError(); - break; - } - } while (newState == IOState::Done || !isIdle()); + } + catch (const std::exception& e) { + vinfolog("Exception while trying to read from HTTP client connection to %s: %s", d_ci.remote.toStringWithPort(), e.what()); + handleIOError(); + return IOState::Done; + } + return newState; } void IncomingHTTP2Connection::handleReadableIOCallback([[maybe_unused]] int descriptor, FDMultiplexer::funcparam_t& param) @@ -1158,29 +1154,7 @@ void IncomingHTTP2Connection::handleReadableIOCallback([[maybe_unused]] int desc void IncomingHTTP2Connection::handleWritableIOCallback([[maybe_unused]] int descriptor, FDMultiplexer::funcparam_t& param) { auto conn = boost::any_cast>(param); - IOStateGuard ioGuard(conn->d_ioState); - - try { - IOState newState = conn->d_handler.tryWrite(conn->d_out, conn->d_outPos, conn->d_out.size()); - if (newState == IOState::NeedRead) { - conn->updateIO(IOState::NeedRead, handleWritableIOCallback); - } - else if (newState == IOState::Done) { - conn->d_out.clear(); - conn->d_outPos = 0; - if (!conn->isIdle()) { - conn->updateIO(IOState::NeedRead, handleReadableIOCallback); - } - else { - conn->watchForRemoteHostClosingConnection(); - } - } - ioGuard.release(); - } - catch (const std::exception& e) { - vinfolog("Exception while trying to write (ready) to HTTP client connection to %s: %s", conn->d_ci.remote.toStringWithPort(), e.what()); - conn->handleIOError(); - } + conn->writeToSocket(true); } bool IncomingHTTP2Connection::isIdle() const @@ -1250,14 +1224,31 @@ void IncomingHTTP2Connection::updateIO(IOState newState, const FDMultiplexer::ca void IncomingHTTP2Connection::watchForRemoteHostClosingConnection() { - updateIO(IOState::NeedRead, handleReadableIOCallback); + if (d_connectionDied) { + return; + } + + if (hasPendingWrite()) { + updateIO(IOState::NeedWrite, &handleWritableIOCallback); + } + else if (!d_connectionClosing) { + updateIO(IOState::NeedRead, handleReadableIOCallback); + } } void IncomingHTTP2Connection::handleIOError() { d_connectionDied = true; + d_out.clear(); + d_outPos = 0; nghttp2_session_terminate_session(d_session.get(), NGHTTP2_PROTOCOL_ERROR); d_currentStreams.clear(); stopIO(); } + +bool IncomingHTTP2Connection::active() const +{ + return !d_connectionDied && d_ioState != nullptr; +} + #endif /* HAVE_NGHTTP2 */ diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh index e68d2142085e..3db7473a8e3d 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -39,7 +39,8 @@ public: { Unknown, Get, - Post + Post, + Unsupported }; PacketBuffer d_buffer; @@ -61,6 +62,7 @@ public: void handleIO() override; void handleResponse(const struct timeval& now, TCPResponse&& response) override; void notifyIOError(const struct timeval& now, TCPResponse&& response) override; + bool active() const override; private: static ssize_t send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data); @@ -73,6 +75,8 @@ private: static void handleReadableIOCallback(int descriptor, FDMultiplexer::funcparam_t& param); static void handleWritableIOCallback(int descriptor, FDMultiplexer::funcparam_t& param); + static constexpr size_t s_initialReceiveBufferSize{256U}; + IOState sendResponse(const struct timeval& now, TCPResponse&& response) override; bool forwardViaUDPFirst() const override { @@ -90,8 +94,10 @@ private: bool sendResponse(StreamID streamID, PendingQuery& context, uint16_t responseCode, const HeadersMap& customResponseHeaders, const std::string& contentType = "", bool addContentType = true); void handleIncomingQuery(PendingQuery&& query, StreamID streamID); bool checkALPN(); - void readHTTPData(); + IOState readHTTPData(); void handleConnectionReady(); + bool hasPendingWrite() const; + void writeToSocket(bool socketReady); boost::optional getIdleClientReadTTD(struct timeval now) const; std::unique_ptr d_session{nullptr, nghttp2_session_del}; @@ -99,8 +105,18 @@ private: PacketBuffer d_out; PacketBuffer d_in; size_t d_outPos{0}; + /* this connection is done, the remote end has closed the connection + or something like that. We do not want to try to write to it. */ bool d_connectionDied{false}; + /* we are done reading from this connection, but we might still want to + write to it to close it properly */ + bool d_connectionClosing{false}; + /* Whether we are still waiting for more data to be buffered + before writing to the socket (false) or not. */ bool d_needFlush{false}; + /* Whether we have data that we want to write to the socket, + but the socket is full. */ + bool d_pendingWrite{false}; }; class NGHTTP2Headers diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 03fa0bfca5a6..9b774f0ed4c1 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -300,10 +300,9 @@ void DoHConnectionToBackend::queueQuery(std::shared_ptr& sender, */ nghttp2_data_provider data_provider; - /* we will not use this pointer */ data_provider.source.ptr = this; data_provider.read_callback = [](nghttp2_session* session, int32_t stream_id, uint8_t* buf, size_t length, uint32_t* data_flags, nghttp2_data_source* source, void* user_data) -> ssize_t { - auto conn = reinterpret_cast(user_data); + auto conn = static_cast(user_data); auto& request = conn->d_currentStreams.at(stream_id); size_t toCopy = 0; if (request.d_queryPos < request.d_query.d_buffer.size()) { diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc new file mode 100644 index 000000000000..0ac62b3c3b6d --- /dev/null +++ b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc @@ -0,0 +1,727 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_MAIN + +#include + +#include "dnswriter.hh" +#include "dnsdist.hh" +#include "dnsdist-proxy-protocol.hh" +#include "dnsdist-nghttp2-in.hh" + +#ifdef HAVE_NGHTTP2 +#include + +extern std::function& selectedBackend)> s_processQuery; + +BOOST_AUTO_TEST_SUITE(test_dnsdistnghttp2_in_cc) + +struct ExpectedStep +{ +public: + enum class ExpectedRequest + { + handshakeClient, + readFromClient, + writeToClient, + closeClient, + }; + + ExpectedStep(ExpectedRequest r, IOState n, size_t b = 0, std::function fn = nullptr) : + cb(fn), request(r), nextState(n), bytes(b) + { + } + + std::function cb{nullptr}; + ExpectedRequest request; + IOState nextState; + size_t bytes{0}; +}; + +struct ExpectedData +{ + PacketBuffer d_proxyProtocolPayload; + std::vector d_queries; + std::vector d_responses; + std::vector d_responseCodes; +}; + +class DOHConnection; + +static std::deque s_steps; +static std::map s_connectionContexts; +static std::map> s_connectionBuffers; +static uint64_t s_connectionID{0}; + +std::ostream& operator<<(std::ostream& os, const ExpectedStep::ExpectedRequest d); + +std::ostream& operator<<(std::ostream& os, const ExpectedStep::ExpectedRequest d) +{ + static const std::vector requests = {"handshake with client", "read from client", "write to client", "close connection to client", "connect to the backend", "read from the backend", "write to the backend", "close connection to backend"}; + os << requests.at(static_cast(d)); + return os; +} + +class DOHConnection +{ +public: + DOHConnection(uint64_t connectionID) : + d_session(std::unique_ptr(nullptr, nghttp2_session_del)), d_connectionID(connectionID) + { + const auto& context = s_connectionContexts.at(connectionID); + d_clientOutBuffer.insert(d_clientOutBuffer.begin(), context.d_proxyProtocolPayload.begin(), context.d_proxyProtocolPayload.end()); + + nghttp2_session_callbacks* cbs = nullptr; + nghttp2_session_callbacks_new(&cbs); + std::unique_ptr callbacks(cbs, nghttp2_session_callbacks_del); + cbs = nullptr; + nghttp2_session_callbacks_set_send_callback(callbacks.get(), send_callback); + nghttp2_session_callbacks_set_on_frame_recv_callback(callbacks.get(), on_frame_recv_callback); + nghttp2_session_callbacks_set_on_header_callback(callbacks.get(), on_header_callback); + nghttp2_session_callbacks_set_on_data_chunk_recv_callback(callbacks.get(), on_data_chunk_recv_callback); + nghttp2_session_callbacks_set_on_stream_close_callback(callbacks.get(), on_stream_close_callback); + nghttp2_session* sess = nullptr; + nghttp2_session_client_new(&sess, callbacks.get(), this); + d_session = std::unique_ptr(sess, nghttp2_session_del); + + nghttp2_settings_entry iv[] = { + /* rfc7540 section-8.2.2: + "Advertising a SETTINGS_MAX_CONCURRENT_STREAMS value of zero disables + server push by preventing the server from creating the necessary + streams." + */ + {NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0}, + {NGHTTP2_SETTINGS_ENABLE_PUSH, 0}, + /* we might want to make the initial window size configurable, but 16M is a large enough default */ + {NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, 16 * 1024 * 1024}}; + /* client 24 bytes magic string will be sent by nghttp2 library */ + auto result = nghttp2_submit_settings(d_session.get(), NGHTTP2_FLAG_NONE, iv, sizeof(iv) / sizeof(*iv)); + if (result != 0) { + throw std::runtime_error("Error submitting settings:" + std::string(nghttp2_strerror(result))); + } + + const std::string host("unit-tests"); + const std::string path("/dns-query"); + for (const auto& query : context.d_queries) { + const auto querySize = std::to_string(query.size()); + std::vector headers; + /* Pseudo-headers need to come first (rfc7540 8.1.2.1) */ + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::METHOD_NAME, NGHTTP2Headers::HeaderConstantIndexes::METHOD_VALUE); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::SCHEME_NAME, NGHTTP2Headers::HeaderConstantIndexes::SCHEME_VALUE); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::AUTHORITY_NAME, host); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::PATH_NAME, path); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::ACCEPT_NAME, NGHTTP2Headers::HeaderConstantIndexes::ACCEPT_VALUE); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_TYPE_NAME, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_TYPE_VALUE); + NGHTTP2Headers::addStaticHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::USER_AGENT_NAME, NGHTTP2Headers::HeaderConstantIndexes::USER_AGENT_VALUE); + NGHTTP2Headers::addDynamicHeader(headers, NGHTTP2Headers::HeaderConstantIndexes::CONTENT_LENGTH_NAME, querySize); + + d_position = 0; + d_currentQuery = query; + nghttp2_data_provider data_provider; + data_provider.source.ptr = this; + data_provider.read_callback = [](nghttp2_session* session, int32_t stream_id, uint8_t* buf, size_t length, uint32_t* data_flags, nghttp2_data_source* source, void* user_data) -> ssize_t { + auto* conn = static_cast(user_data); + auto& pos = conn->d_position; + const auto& currentQuery = conn->d_currentQuery; + size_t toCopy = 0; + if (pos < currentQuery.size()) { + size_t remaining = currentQuery.size() - pos; + toCopy = length > remaining ? remaining : length; + memcpy(buf, ¤tQuery.at(pos), toCopy); + pos += toCopy; + } + + if (pos >= currentQuery.size()) { + *data_flags |= NGHTTP2_DATA_FLAG_EOF; + } + return toCopy; + }; + + auto newStreamId = nghttp2_submit_request(d_session.get(), nullptr, headers.data(), headers.size(), &data_provider, this); + if (newStreamId < 0) { + throw std::runtime_error("Error submitting HTTP request:" + std::string(nghttp2_strerror(newStreamId))); + } + + result = nghttp2_session_send(d_session.get()); + if (result != 0) { + throw std::runtime_error("Error in nghttp2_session_send:" + std::to_string(result)); + } + } + } + + std::map d_responses; + std::map d_responseCodes; + std::unique_ptr d_session; + PacketBuffer d_currentQuery; + PacketBuffer d_clientOutBuffer; + uint64_t d_connectionID{0}; + size_t d_position{0}; + + size_t submitIncoming(const PacketBuffer& data, size_t pos, size_t toWrite) + { + ssize_t readlen = nghttp2_session_mem_recv(d_session.get(), &data.at(pos), toWrite); + if (readlen < 0) { + throw("Fatal error while submitting line " + std::to_string(__LINE__) + ": " + std::string(nghttp2_strerror(static_cast(readlen)))); + } + + /* just in case, see if we have anything to send */ + int rv = nghttp2_session_send(d_session.get()); + if (rv != 0) { + throw("Fatal error while sending: " + std::string(nghttp2_strerror(rv))); + } + + return readlen; + } + +private: + static ssize_t send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data) + { + DOHConnection* conn = static_cast(user_data); + conn->d_clientOutBuffer.insert(conn->d_clientOutBuffer.end(), data, data + length); + return static_cast(length); + } + + static int on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data) + { + DOHConnection* conn = static_cast(user_data); + if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { + const auto& response = conn->d_responses.at(frame->hd.stream_id); + if (conn->d_responseCodes.at(frame->hd.stream_id) != 200U) { + return 0; + } + + BOOST_REQUIRE_GT(response.size(), sizeof(dnsheader)); + const auto* dh = reinterpret_cast(response.data()); + uint16_t id = ntohs(dh->id); + + const auto& expected = s_connectionContexts.at(conn->d_connectionID).d_responses.at(id); + BOOST_REQUIRE_EQUAL(expected.size(), response.size()); + for (size_t idx = 0; idx < response.size(); idx++) { + if (expected.at(idx) != response.at(idx)) { + cerr << "Mismatch at offset " << idx << ", expected " << std::to_string(response.at(idx)) << " got " << std::to_string(expected.at(idx)) << endl; + BOOST_CHECK(false); + } + } + } + + return 0; + } + + static int on_data_chunk_recv_callback(nghttp2_session* session, uint8_t flags, int32_t stream_id, const uint8_t* data, size_t len, void* user_data) + { + DOHConnection* conn = static_cast(user_data); + auto& response = conn->d_responses[stream_id]; + response.insert(response.end(), data, data + len); + return 0; + } + + static int on_header_callback(nghttp2_session* session, const nghttp2_frame* frame, const uint8_t* name, size_t namelen, const uint8_t* value, size_t valuelen, uint8_t flags, void* user_data) + { + DOHConnection* conn = static_cast(user_data); + + const std::string status(":status"); + if (frame->hd.type == NGHTTP2_HEADERS && frame->headers.cat == NGHTTP2_HCAT_RESPONSE) { + if (namelen == status.size() && memcmp(status.data(), name, status.size()) == 0) { + try { + uint16_t responseCode{0}; + auto expected = s_connectionContexts.at(conn->d_connectionID).d_responseCodes.at((frame->hd.stream_id - 1) / 2); + pdns::checked_stoi_into(responseCode, std::string(reinterpret_cast(value), valuelen)); + conn->d_responseCodes[frame->hd.stream_id] = responseCode; + if (responseCode != expected) { + cerr << "Mismatch response code, expected " << std::to_string(expected) << " got " << std::to_string(responseCode) << endl; + BOOST_CHECK(false); + } + } + catch (const std::exception& e) { + infolog("Error parsing the status header for stream ID %d: %s", frame->hd.stream_id, e.what()); + return NGHTTP2_ERR_CALLBACK_FAILURE; + } + } + } + return 0; + } + + static int on_stream_close_callback(nghttp2_session* session, int32_t stream_id, uint32_t error_code, void* user_data) + { + return 0; + } +}; + +class MockupTLSConnection : public TLSConnection +{ +public: + MockupTLSConnection(int descriptor, [[maybe_unused]] bool client = false, [[maybe_unused]] bool needProxyProtocol = false) : + d_descriptor(descriptor) + { + auto connectionID = s_connectionID++; + auto conn = std::make_unique(connectionID); + s_connectionBuffers[d_descriptor] = std::move(conn); + } + + ~MockupTLSConnection() {} + + IOState tryHandshake() override + { + auto step = getStep(); + BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::handshakeClient); + + return step.nextState; + } + + IOState tryWrite(const PacketBuffer& buffer, size_t& pos, size_t toWrite) override + { + auto& conn = s_connectionBuffers.at(d_descriptor); + auto step = getStep(); + BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::writeToClient); + + if (step.bytes == 0) { + if (step.nextState == IOState::NeedWrite) { + return step.nextState; + } + throw std::runtime_error("Remote host closed the connection"); + } + + toWrite -= pos; + BOOST_REQUIRE_GE(buffer.size(), pos + toWrite); + + if (step.bytes < toWrite) { + toWrite = step.bytes; + } + + conn->submitIncoming(buffer, pos, toWrite); + pos += toWrite; + + return step.nextState; + } + + IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead, bool allowIncomplete = false) override + { + auto& conn = s_connectionBuffers.at(d_descriptor); + auto step = getStep(); + BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::readFromClient); + + if (step.bytes == 0) { + if (step.nextState == IOState::NeedRead) { + return step.nextState; + } + throw std::runtime_error("Remote host closed the connection"); + } + + auto& externalBuffer = conn->d_clientOutBuffer; + toRead -= pos; + + if (step.bytes < toRead) { + toRead = step.bytes; + } + if (allowIncomplete) { + if (toRead > externalBuffer.size()) { + toRead = externalBuffer.size(); + } + } + else { + BOOST_REQUIRE_GE(externalBuffer.size(), toRead); + } + + BOOST_REQUIRE_GE(buffer.size(), toRead); + + std::copy(externalBuffer.begin(), externalBuffer.begin() + toRead, buffer.begin() + pos); + pos += toRead; + externalBuffer.erase(externalBuffer.begin(), externalBuffer.begin() + toRead); + + return step.nextState; + } + + IOState tryConnect(bool fastOpen, const ComboAddress& remote) override + { + throw std::runtime_error("Should not happen"); + } + + void close() override + { + auto step = getStep(); + BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::closeClient); + } + + bool hasBufferedData() const override + { + return false; + } + + bool isUsable() const override + { + return true; + } + + std::string getServerNameIndication() const override + { + return ""; + } + + std::vector getNextProtocol() const override + { + return std::vector{'h', '2'}; + } + + LibsslTLSVersion getTLSVersion() const override + { + return LibsslTLSVersion::TLS13; + } + + bool hasSessionBeenResumed() const override + { + return false; + } + + std::vector> getSessions() override + { + return {}; + } + + void setSession(std::unique_ptr& session) override + { + } + + std::vector getAsyncFDs() override + { + return {}; + } + + /* unused in that context, don't bother */ + void doHandshake() override + { + } + + void connect(bool fastOpen, const ComboAddress& remote, const struct timeval& timeout) override + { + } + + size_t read(void* buffer, size_t bufferSize, const struct timeval& readTimeout, const struct timeval& totalTimeout = {0, 0}, bool allowIncomplete = false) override + { + return 0; + } + + size_t write(const void* buffer, size_t bufferSize, const struct timeval& writeTimeout) override + { + return 0; + } + +private: + ExpectedStep getStep() const + { + BOOST_REQUIRE(!s_steps.empty()); + auto step = s_steps.front(); + s_steps.pop_front(); + + if (step.cb) { + step.cb(d_descriptor); + } + + return step; + } + + const int d_descriptor; +}; + +#include "test-dnsdistnghttp2_common.hh" + +struct TestFixture +{ + TestFixture() + { + s_steps.clear(); + s_connectionContexts.clear(); + s_connectionBuffers.clear(); + s_connectionID = 0; + s_mplexer = std::make_unique(); + } + ~TestFixture() + { + s_steps.clear(); + s_connectionContexts.clear(); + s_connectionBuffers.clear(); + s_connectionID = 0; + s_mplexer.reset(); + } +}; + +BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) +{ + auto local = getBackendAddress("1", 80); + ClientState localCS(local, true, false, false, "", {}); + localCS.dohFrontend = std::make_shared(std::make_shared()); + localCS.dohFrontend->d_urls.insert("/dns-query"); + + TCPClientThreadData threadData; + threadData.mplexer = std::make_unique(); + + struct timeval now; + gettimeofday(&now, nullptr); + + size_t counter = 0; + DNSName name("powerdns.com."); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, name, QType::A, QClass::IN, 0); + pwQ.getHeader()->rd = 1; + pwQ.getHeader()->id = htons(counter); + + PacketBuffer response; + GenericDNSPacketWriter pwR(response, name, QType::A, QClass::IN, 0); + pwR.getHeader()->qr = 1; + pwR.getHeader()->rd = 1; + pwR.getHeader()->ra = 1; + pwR.getHeader()->id = htons(counter); + pwR.startRecord(name, QType::A, 7200, QClass::IN, DNSResourceRecord::ANSWER); + pwR.xfr32BitInt(0x01020304); + pwR.commit(); + + { + /* dnsdist drops the query right away after receiving it, client closes the connection */ + s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, {403U}}; + s_steps = { + /* opening */ + { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + /* settings server -> client */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + /* settings + headers + data client -> server.. */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128 }, + /* .. continued */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60 }, + /* headers + data */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, std::numeric_limits::max() }, + /* wait for next query, but the client closes the connection */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 }, + /* server close */ + { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + }; + + auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); + state->handleIO(); + } + + { + /* client closes the connection right in the middle of sending the query */ + s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, { 403U }}; + s_steps = { + /* opening */ + { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + /* settings server -> client */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + /* client sends one byte */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 1 }, + /* then closes the connection */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 }, + /* server close */ + { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + }; + + /* mark the incoming FD as always ready */ + dynamic_cast(threadData.mplexer.get())->setReady(-1); + + auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); + state->handleIO(); + while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { + threadData.mplexer->run(&now); + } + } + + { + /* dnsdist sends a response right away, client closes the connection after getting the response */ + s_processQuery = [response](DNSQuestion& dq, std::shared_ptr& selectedBackend) -> ProcessQueryResult { + /* self answered */ + dq.getMutableData() = response; + return ProcessQueryResult::SendAnswer; + }; + + s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, {200U}}; + + s_steps = { + /* opening */ + { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + /* settings server -> client */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + /* settings + headers + data client -> server.. */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128 }, + /* .. continued */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60 }, + /* headers + data */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, std::numeric_limits::max() }, + /* wait for next query, but the client closes the connection */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 }, + /* server close */ + { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + }; + + auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); + state->handleIO(); + } + + { + /* dnsdist sends a response right away, but the client closes the connection without even reading the response */ + s_processQuery = [response](DNSQuestion& dq, std::shared_ptr& selectedBackend) -> ProcessQueryResult { + /* self answered */ + dq.getMutableData() = response; + return ProcessQueryResult::SendAnswer; + }; + + s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, {200U}}; + + s_steps = { + /* opening */ + { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + /* settings server -> client */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + /* settings + headers + data client -> server.. */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128 }, + /* .. continued */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60 }, + /* we want to send the response but the client closes the connection */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 0 }, + /* server close */ + { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + }; + + /* mark the incoming FD as always ready */ + dynamic_cast(threadData.mplexer.get())->setReady(-1); + + auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); + state->handleIO(); + while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { + threadData.mplexer->run(&now); + } + } + + { + /* dnsdist sends a response right away, client closes the connection while getting the response */ + s_processQuery = [response](DNSQuestion& dq, std::shared_ptr& selectedBackend) -> ProcessQueryResult { + /* self answered */ + dq.getMutableData() = response; + return ProcessQueryResult::SendAnswer; + }; + + s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, {200U}}; + + s_steps = { + /* opening */ + { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + /* settings server -> client */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + /* settings + headers + data client -> server.. */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128 }, + /* .. continued */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60 }, + /* headers + data (partial write) */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::NeedWrite, 1 }, + /* nothing to read after that */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 0 }, + /* then the client closes the connection before we are done */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 0 }, + /* server close */ + { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + }; + + /* mark the incoming FD as always ready */ + dynamic_cast(threadData.mplexer.get())->setReady(-1); + + auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); + state->handleIO(); + while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { + threadData.mplexer->run(&now); + } + } +} + +BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_BackendTimeout, TestFixture) +{ + auto local = getBackendAddress("1", 80); + ClientState localCS(local, true, false, false, "", {}); + localCS.dohFrontend = std::make_shared(std::make_shared()); + localCS.dohFrontend->d_urls.insert("/dns-query"); + + TCPClientThreadData threadData; + threadData.mplexer = std::make_unique(); + + auto backend = std::make_shared(getBackendAddress("42", 53)); + + struct timeval now; + gettimeofday(&now, nullptr); + + size_t counter = 0; + DNSName name("powerdns.com."); + PacketBuffer query; + GenericDNSPacketWriter pwQ(query, name, QType::A, QClass::IN, 0); + pwQ.getHeader()->rd = 1; + pwQ.getHeader()->id = htons(counter); + + PacketBuffer response; + GenericDNSPacketWriter pwR(response, name, QType::A, QClass::IN, 0); + pwR.getHeader()->qr = 1; + pwR.getHeader()->rd = 1; + pwR.getHeader()->ra = 1; + pwR.getHeader()->id = htons(counter); + pwR.startRecord(name, QType::A, 7200, QClass::IN, DNSResourceRecord::ANSWER); + pwR.xfr32BitInt(0x01020304); + pwR.commit(); + + { + /* dnsdist forwards the query to the backend, which does not answer -> timeout */ + s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr& selectedBackend) -> ProcessQueryResult { + selectedBackend = backend; + return ProcessQueryResult::PassToBackend; + }; + s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, {502U}}; + s_steps = { + /* opening */ + { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + /* settings server -> client */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + /* settings + headers + data client -> server.. */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128 }, + /* .. continued */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60 }, + /* trying to read a new request while processing the first one */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead }, + /* headers + data */ + { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, std::numeric_limits::max(), [&threadData](int desc) { + /* set the incoming descriptor as ready */ + dynamic_cast(threadData.mplexer.get())->setReady(desc); + } + }, + /* wait for next query, but the client closes the connection */ + { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 }, + /* server close */ + { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + }; + + auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); + state->handleIO(); + TCPResponse resp; + resp.d_idstate.d_streamID = 1; + state->notifyIOError(now, std::move(resp)); + while (threadData.mplexer->getWatchedFDCount(false) != 0 || threadData.mplexer->getWatchedFDCount(true) != 0) { + threadData.mplexer->run(&now); + } + } +} + +BOOST_AUTO_TEST_SUITE_END(); +#endif /* HAVE_NGHTTP2 */ diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc index d10e85ef13f5..3e5bb1631221 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc @@ -486,110 +486,7 @@ class MockupTLSConnection : public TLSConnection bool d_client{false}; }; -class MockupTLSCtx : public TLSCtx -{ -public: - ~MockupTLSCtx() - { - } - - std::unique_ptr getConnection(int socket, const struct timeval& timeout, time_t now) override - { - return std::make_unique(socket); - } - - std::unique_ptr getClientConnection(const std::string& host, bool hostIsAddr, int socket, const struct timeval& timeout) override - { - return std::make_unique(socket, true, d_needProxyProtocol); - } - - void rotateTicketsKey(time_t now) override - { - } - - size_t getTicketsKeysCount() override - { - return 0; - } - - std::string getName() const override - { - return "Mockup TLS"; - } - - bool d_needProxyProtocol{false}; -}; - -class MockupFDMultiplexer : public FDMultiplexer -{ -public: - MockupFDMultiplexer() - { - } - - ~MockupFDMultiplexer() - { - } - - int run(struct timeval* tv, int timeout = 500) override - { - int ret = 0; - - gettimeofday(tv, nullptr); // MANDATORY - - /* 'ready' might be altered by a callback while we are iterating */ - const auto readyFDs = ready; - for (const auto fd : readyFDs) { - { - const auto& it = d_readCallbacks.find(fd); - - if (it != d_readCallbacks.end()) { - it->d_callback(it->d_fd, it->d_parameter); - } - } - - { - const auto& it = d_writeCallbacks.find(fd); - - if (it != d_writeCallbacks.end()) { - it->d_callback(it->d_fd, it->d_parameter); - } - } - } - - return ret; - } - - void getAvailableFDs(std::vector& fds, int timeout) override - { - } - - void addFD(int fd, FDMultiplexer::EventKind kind) override - { - } - - void removeFD(int fd, FDMultiplexer::EventKind) override - { - } - - string getName() const override - { - return "mockup"; - } - - void setReady(int fd) - { - ready.insert(fd); - } - - void setNotReady(int fd) - { - ready.erase(fd); - } - -private: - std::set ready; -}; +#include "test-dnsdistnghttp2_common.hh" class MockupQuerySender : public TCPQuerySender { @@ -641,36 +538,6 @@ class MockupQuerySender : public TCPQuerySender bool d_error{false}; }; -static bool isIPv6Supported() -{ - try { - ComboAddress addr("[2001:db8:53::1]:53"); - auto socket = std::make_unique(addr.sin4.sin_family, SOCK_STREAM, 0); - socket->setNonBlocking(); - int res = SConnectWithTimeout(socket->getHandle(), addr, timeval{0, 0}); - if (res == 0 || res == EINPROGRESS) { - return true; - } - return false; - } - catch (const std::exception& e) { - return false; - } -} - -static ComboAddress getBackendAddress(const std::string& lastDigit, uint16_t port) -{ - static const bool useV6 = isIPv6Supported(); - - if (useV6) { - return ComboAddress("2001:db8:53::" + lastDigit, port); - } - - return ComboAddress("192.0.2." + lastDigit, port); -} - -static std::unique_ptr s_mplexer; - struct TestFixture { TestFixture() diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2_common.hh b/pdns/dnsdistdist/test-dnsdistnghttp2_common.hh new file mode 100644 index 000000000000..5c79679aba0f --- /dev/null +++ b/pdns/dnsdistdist/test-dnsdistnghttp2_common.hh @@ -0,0 +1,157 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +class MockupTLSCtx : public TLSCtx +{ +public: + ~MockupTLSCtx() + { + } + + std::unique_ptr getConnection(int socket, const struct timeval& timeout, time_t now) override + { + return std::make_unique(socket); + } + + std::unique_ptr getClientConnection(const std::string& host, bool hostIsAddr, int socket, const struct timeval& timeout) override + { + return std::make_unique(socket, true, d_needProxyProtocol); + } + + void rotateTicketsKey(time_t now) override + { + } + + size_t getTicketsKeysCount() override + { + return 0; + } + + std::string getName() const override + { + return "Mockup TLS"; + } + + bool d_needProxyProtocol{false}; +}; + +class MockupFDMultiplexer : public FDMultiplexer +{ +public: + MockupFDMultiplexer() + { + } + + ~MockupFDMultiplexer() + { + } + + int run(struct timeval* tv, int timeout = 500) override + { + int ret = 0; + + gettimeofday(tv, nullptr); // MANDATORY + + /* 'ready' might be altered by a callback while we are iterating */ + const auto readyFDs = ready; + for (const auto fd : readyFDs) { + { + const auto& it = d_readCallbacks.find(fd); + + if (it != d_readCallbacks.end()) { + it->d_callback(it->d_fd, it->d_parameter); + } + } + + { + const auto& it = d_writeCallbacks.find(fd); + + if (it != d_writeCallbacks.end()) { + it->d_callback(it->d_fd, it->d_parameter); + } + } + } + + return ret; + } + + void getAvailableFDs(std::vector& fds, int timeout) override + { + } + + void addFD(int fd, FDMultiplexer::EventKind kind) override + { + } + + void removeFD(int fd, FDMultiplexer::EventKind) override + { + } + + string getName() const override + { + return "mockup"; + } + + void setReady(int fd) + { + ready.insert(fd); + } + + void setNotReady(int fd) + { + ready.erase(fd); + } + +private: + std::set ready; +}; + +static bool isIPv6Supported() +{ + try { + ComboAddress addr("[2001:db8:53::1]:53"); + auto socket = std::make_unique(addr.sin4.sin_family, SOCK_STREAM, 0); + socket->setNonBlocking(); + int res = SConnectWithTimeout(socket->getHandle(), addr, timeval{0, 0}); + if (res == 0 || res == EINPROGRESS) { + return true; + } + return false; + } + catch (const std::exception& e) { + return false; + } +} + +static ComboAddress getBackendAddress(const std::string& lastDigit, uint16_t port) +{ + static const bool useV6 = isIPv6Supported(); + + if (useV6) { + return ComboAddress("2001:db8:53::" + lastDigit, port); + } + + return ComboAddress("192.0.2." + lastDigit, port); +} + +static std::unique_ptr s_mplexer; diff --git a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc index 22e137c24b3b..dedfd97d2b33 100644 --- a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc +++ b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc @@ -62,7 +62,7 @@ void handleResponseSent(const InternalQueryState& ids, double udiff, const Combo { } -static std::function& selectedBackend)> s_processQuery; +std::function& selectedBackend)> s_processQuery; ProcessQueryResult processQuery(DNSQuestion& dq, LocalHolders& holders, std::shared_ptr& selectedBackend) { diff --git a/pdns/test-dnsdist_cc.cc b/pdns/test-dnsdist_cc.cc index 850273eb8a67..c51a930c04f8 100644 --- a/pdns/test-dnsdist_cc.cc +++ b/pdns/test-dnsdist_cc.cc @@ -56,7 +56,7 @@ bool sendUDPResponse(int origFD, const PacketBuffer& response, const int delayMs bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint16_t queryID, DNSQuestion& dq, PacketBuffer& query) { - return false; + return true; } namespace dnsdist { diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 1e7968aa3d2d..75068bea027d 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -987,21 +987,32 @@ def openDOHConnection(cls, port, caFile, timeout=2.0): return conn @classmethod - def sendDOHQuery(cls, port, servername, baseurl, query, response=None, timeout=2.0, caFile=None, useQueue=True, rawQuery=False, rawResponse=False, customHeaders=[], useHTTPS=True, fromQueue=None, toQueue=None): + def sendDOHQuery(cls, port, servername, baseurl, query, response=None, timeout=2.0, caFile=None, useQueue=True, rawQuery=False, rawResponse=False, customHeaders=[], useHTTPS=True, fromQueue=None, toQueue=None, useProxyProtocol=False, conn=None): url = cls.getDOHGetURL(baseurl, query, rawQuery) - conn = cls.openDOHConnection(port, caFile=caFile, timeout=timeout) - response_headers = BytesIO() - #conn.setopt(pycurl.VERBOSE, True) - conn.setopt(pycurl.URL, url) - conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (servername, port)]) - # this means "really do HTTP/2, not HTTP/1 with Upgrade headers" - conn.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) + + if not conn: + print('creating a new connection') + conn = cls.openDOHConnection(port, caFile=caFile, timeout=timeout) + # this means "really do HTTP/2, not HTTP/1 with Upgrade headers" + conn.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) + if useHTTPS: + print("disabling verify") conn.setopt(pycurl.SSL_VERIFYPEER, 1) conn.setopt(pycurl.SSL_VERIFYHOST, 2) if caFile: conn.setopt(pycurl.CAINFO, caFile) + if useProxyProtocol: + print('enabling PP') + # 274 is CURLOPT_HAPROXYPROTOCOL + conn.setopt(274, 1) + + response_headers = BytesIO() + #conn.setopt(pycurl.VERBOSE, True) + conn.setopt(pycurl.URL, url) + conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (servername, port)]) + conn.setopt(pycurl.HTTPHEADER, customHeaders) conn.setopt(pycurl.HEADERFUNCTION, response_headers.write) @@ -1014,6 +1025,7 @@ def sendDOHQuery(cls, port, servername, baseurl, query, response=None, timeout=2 receivedQuery = None message = None cls._response_headers = '' + print('performing') data = conn.perform_rb() cls._rcode = conn.getinfo(pycurl.RESPONSE_CODE) if cls._rcode == 200 and not rawResponse: @@ -1076,8 +1088,8 @@ def sendDOHPostQuery(cls, port, servername, baseurl, query, response=None, timeo cls._response_headers = response_headers.getvalue() return (receivedQuery, message) - def sendDOHQueryWrapper(self, query, response, useQueue=True): - return self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) + def sendDOHQueryWrapper(self, query, response, useQueue=True, useProxyProtocol=False): + return self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue, useProxyProtocol=useProxyProtocol) def sendDOHWithNGHTTP2QueryWrapper(self, query, response, useQueue=True): return self.sendDOHQuery(self._dohWithNGHTTP2ServerPort, self._serverName, self._dohWithNGHTTP2BaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) diff --git a/regression-tests.dnsdist/test_DOH.py b/regression-tests.dnsdist/test_DOH.py index ae6aac46a44f..f9fce6be567d 100644 --- a/regression-tests.dnsdist/test_DOH.py +++ b/regression-tests.dnsdist/test_DOH.py @@ -1,5 +1,6 @@ #!/usr/bin/env python +import base64 import dns import os import time @@ -32,6 +33,7 @@ class DOHTests(object): addAction(HTTPPathRegexRule("^/PowerDNS-[0-9]"), SpoofAction("6.7.8.9")) addAction("http-status-action.doh.tests.powerdns.com.", HTTPStatusAction(200, "Plaintext answer", "text/plain")) addAction("http-status-action-redirect.doh.tests.powerdns.com.", HTTPStatusAction(307, "https://doh.powerdns.org")) + addAction("no-backend.doh.tests.powerdns.com.", PoolAction('this-pool-has-no-backend')) function dohHandler(dq) if dq:getHTTPScheme() == 'https' and dq:getHTTPHost() == '%s:%d' and dq:getHTTPPath() == '/' and dq:getHTTPQueryString() == '' then @@ -235,9 +237,133 @@ def testSpoof(self): (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, caFile=self._caCert, query=query, response=None, useQueue=False) self.assertEqual(receivedResponse, expectedResponse) + def testDOHWithoutQuery(self): + """ + DOH: Empty GET query + """ + name = 'empty-get.doh.tests.powerdns.com.' + url = self._dohBaseURL + conn = self.openDOHConnection(self._dohServerPort, self._caCert, timeout=2.0) + conn.setopt(pycurl.URL, url) + conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (self._serverName, self._dohServerPort)]) + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) + conn.setopt(pycurl.CAINFO, self._caCert) + data = conn.perform_rb() + rcode = conn.getinfo(pycurl.RESPONSE_CODE) + self.assertEqual(rcode, 400) + + def testDOHShortPath(self): + """ + DOH: Short path in GET query + """ + name = 'short-path-get.doh.tests.powerdns.com.' + url = self._dohBaseURL + '/AA' + conn = self.openDOHConnection(self._dohServerPort, self._caCert, timeout=2.0) + conn.setopt(pycurl.URL, url) + conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (self._serverName, self._dohServerPort)]) + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) + conn.setopt(pycurl.CAINFO, self._caCert) + data = conn.perform_rb() + rcode = conn.getinfo(pycurl.RESPONSE_CODE) + self.assertEqual(rcode, 404) + + def testDOHQueryNoParameter(self): + """ + DOH: No parameter GET query + """ + name = 'no-parameter-get.doh.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN', use_edns=False) + wire = query.to_wire() + b64 = base64.urlsafe_b64encode(wire).decode('UTF8').rstrip('=') + url = self._dohBaseURL + '?not-dns=' + b64 + conn = self.openDOHConnection(self._dohServerPort, self._caCert, timeout=2.0) + conn.setopt(pycurl.URL, url) + conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (self._serverName, self._dohServerPort)]) + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) + conn.setopt(pycurl.CAINFO, self._caCert) + data = conn.perform_rb() + rcode = conn.getinfo(pycurl.RESPONSE_CODE) + self.assertEqual(rcode, 400) + + def testDOHQueryInvalidBase64(self): + """ + DOH: Invalid Base64 GET query + """ + name = 'invalid-b64-get.doh.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN', use_edns=False) + wire = query.to_wire() + url = self._dohBaseURL + '?dns=' + '_-~~~~-_' + conn = self.openDOHConnection(self._dohServerPort, self._caCert, timeout=2.0) + conn.setopt(pycurl.URL, url) + conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (self._serverName, self._dohServerPort)]) + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) + conn.setopt(pycurl.CAINFO, self._caCert) + data = conn.perform_rb() + rcode = conn.getinfo(pycurl.RESPONSE_CODE) + self.assertEqual(rcode, 400) + + def testDOHInvalidDNSHeaders(self): + """ + DOH: Invalid DNS headers + """ + name = 'invalid-dns-headers.doh.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN', use_edns=False) + query.flags |= dns.flags.QR + wire = query.to_wire() + b64 = base64.urlsafe_b64encode(wire).decode('UTF8').rstrip('=') + url = self._dohBaseURL + '?dns=' + b64 + conn = self.openDOHConnection(self._dohServerPort, self._caCert, timeout=2.0) + conn.setopt(pycurl.URL, url) + conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (self._serverName, self._dohServerPort)]) + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) + conn.setopt(pycurl.CAINFO, self._caCert) + data = conn.perform_rb() + rcode = conn.getinfo(pycurl.RESPONSE_CODE) + self.assertEqual(rcode, 400) + + def testDOHQueryInvalidMethod(self): + """ + DOH: Invalid method + """ + if self._dohLibrary == 'h2o': + raise unittest.SkipTest('h2o does not check the HTTP method') + name = 'invalid-method.doh.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN', use_edns=False) + wire = query.to_wire() + b64 = base64.urlsafe_b64encode(wire).decode('UTF8').rstrip('=') + url = self._dohBaseURL + '?dns=' + b64 + conn = self.openDOHConnection(self._dohServerPort, self._caCert, timeout=2) + conn.setopt(pycurl.URL, url) + conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (self._serverName, self._dohServerPort)]) + conn.setopt(pycurl.SSL_VERIFYPEER, 1) + conn.setopt(pycurl.SSL_VERIFYHOST, 2) + conn.setopt(pycurl.CAINFO, self._caCert) + conn.setopt(pycurl.CUSTOMREQUEST, 'PATCH') + data = conn.perform_rb() + rcode = conn.getinfo(pycurl.RESPONSE_CODE) + self.assertEqual(rcode, 400) + + def testDOHQueryInvalidALPN(self): + """ + DOH: Invalid ALPN + """ + alpn = ['bogus-alpn'] + conn = self.openTLSConnection(self._dohServerPort, self._serverName, self._caCert, alpn=alpn) + try: + conn.send('AAAA') + response = conn.recv(65535) + self.assertFalse(response) + except: + pass + def testDOHInvalid(self): """ - DOH: Invalid query + DOH: Invalid DNS query """ name = 'invalid.doh.tests.powerdns.com.' invalidQuery = dns.message.make_query(name, 'A', 'IN', use_edns=False) @@ -268,13 +394,43 @@ def testDOHInvalid(self): self.checkQueryEDNSWithoutECS(expectedQuery, receivedQuery) self.assertEqual(response, receivedResponse) - def testDOHWithoutQuery(self): + def testDOHInvalidHeaderName(self): """ - DOH: Empty GET query + DOH: Invalid HTTP header name query """ - name = 'empty-get.doh.tests.powerdns.com.' - url = self._dohBaseURL - conn = self.openDOHConnection(self._dohServerPort, self._caCert, timeout=2.0) + name = 'invalid-header-name.doh.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN', use_edns=False) + query.id = 0 + expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096) + expectedQuery.id = 0 + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 3600, + dns.rdataclass.IN, + dns.rdatatype.A, + '127.0.0.1') + response.answer.append(rrset) + # this header is invalid, see rfc9113 section 8.2.1. Field Validity + customHeaders = ['{}: test'] + try: + (receivedQuery, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert, customHeaders=customHeaders) + self.assertFalse(receivedQuery) + self.assertFalse(receivedResponse) + except pycurl.error: + pass + + def testDOHNoBackend(self): + """ + DOH: No backend + """ + if self._dohLibrary == 'h2o': + raise unittest.SkipTest('h2o does not check the HTTP method') + name = 'no-backend.doh.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN', use_edns=False) + wire = query.to_wire() + b64 = base64.urlsafe_b64encode(wire).decode('UTF8').rstrip('=') + url = self._dohBaseURL + '?dns=' + b64 + conn = self.openDOHConnection(self._dohServerPort, self._caCert, timeout=2) conn.setopt(pycurl.URL, url) conn.setopt(pycurl.RESOLVE, ["%s:%d:127.0.0.1" % (self._serverName, self._dohServerPort)]) conn.setopt(pycurl.SSL_VERIFYPEER, 1) @@ -282,7 +438,7 @@ def testDOHWithoutQuery(self): conn.setopt(pycurl.CAINFO, self._caCert) data = conn.perform_rb() rcode = conn.getinfo(pycurl.RESPONSE_CODE) - self.assertEqual(rcode, 400) + self.assertEqual(rcode, 403) def testDOHEmptyPOST(self): """ From 0b324960cd299e0ea6f162dfa7778f6fac134690 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 12 Jul 2023 14:40:34 +0200 Subject: [PATCH 632/909] dnsdist: Fix timeout handling for incoming H2 w/ nghttp2 --- pdns/dnsdist-tcp.cc | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 8d10e492575b..08ecf1d4fcaa 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -1361,6 +1361,16 @@ static void tcpClientThread(pdns::channel::Receiver&& queryRecei state->handleTimeout(state, false); } } +#ifdef HAVE_NGHTTP2 + else if (cbData.second.type() == typeid(std::shared_ptr)) { + auto state = boost::any_cast>(cbData.second); + if (cbData.first == state->d_handler.getDescriptor()) { + vinfolog("Timeout (read) from remote H2 client %s", state->d_ci.remote.toStringWithPort()); + std::shared_ptr parentState = state; + state->handleTimeout(parentState, false); + } + } +#endif /* HAVE_NGHTTP2 */ else if (cbData.second.type() == typeid(std::shared_ptr)) { auto conn = boost::any_cast>(cbData.second); vinfolog("Timeout (read) from remote backend %s", conn->getBackendName()); @@ -1377,6 +1387,16 @@ static void tcpClientThread(pdns::channel::Receiver&& queryRecei state->handleTimeout(state, true); } } +#ifdef HAVE_NGHTTP2 + else if (cbData.second.type() == typeid(std::shared_ptr)) { + auto state = boost::any_cast>(cbData.second); + if (cbData.first == state->d_handler.getDescriptor()) { + vinfolog("Timeout (write) from remote H2 client %s", state->d_ci.remote.toStringWithPort()); + std::shared_ptr parentState = state; + state->handleTimeout(parentState, true); + } + } +#endif /* HAVE_NGHTTP2 */ else if (cbData.second.type() == typeid(std::shared_ptr)) { auto conn = boost::any_cast>(cbData.second); vinfolog("Timeout (write) from remote backend %s", conn->getBackendName()); @@ -1407,6 +1427,12 @@ static void tcpClientThread(pdns::channel::Receiver&& queryRecei auto state = boost::any_cast>(param); errlog(" - %s", state->toString()); } +#ifdef HAVE_NGHTTP2 + else if (param.type() == typeid(std::shared_ptr)) { + auto state = boost::any_cast>(param); + errlog(" - %s", state->toString()); + } +#endif /* HAVE_NGHTTP2 */ else if (param.type() == typeid(std::shared_ptr)) { auto conn = boost::any_cast>(param); errlog(" - %s", conn->toString()); @@ -1506,7 +1532,7 @@ static void acceptNewConnection(const TCPAcceptorParam& param, TCPClientThreadDa gettimeofday(&now, nullptr); if (ci.cs->dohFrontend) { -#ifdef HAVE_NGHTTP2 +#ifdef HAVE_NGHTTP2 auto state = std::make_shared(std::move(ci), *threadData, now); state->handleIO(); #endif /* HAVE_NGHTTP2 */ From 67b9320ece9845521a1e877b96181c8f373eed98 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 12 Jul 2023 14:41:31 +0200 Subject: [PATCH 633/909] dnsdist: Simplify I/O handling for incoming H2 w/ nghttp2 --- pdns/dnsdist-doh-common.hh | 2 +- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 37 +------- pdns/dnsdistdist/dnsdist-nghttp2-in.hh | 1 - pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc | 95 +++++++++---------- 4 files changed, 50 insertions(+), 85 deletions(-) diff --git a/pdns/dnsdist-doh-common.hh b/pdns/dnsdist-doh-common.hh index f0a1adc76744..6e0cc86e03e9 100644 --- a/pdns/dnsdist-doh-common.hh +++ b/pdns/dnsdist-doh-common.hh @@ -77,7 +77,7 @@ struct DOHFrontend DOHFrontend() { } - DOHFrontend(std::shared_ptr tlsCtx): + DOHFrontend(std::shared_ptr tlsCtx) : d_tlsContext(std::move(tlsCtx)) { } diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index b71601a916d4..7945a2544f30 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -375,11 +375,6 @@ void IncomingHTTP2Connection::handleIO() if (nghttp2_session_want_read(d_session.get()) != 0) { updateIO(IOState::NeedRead, handleReadableIOCallback); } - else { - if (isIdle()) { - watchForRemoteHostClosingConnection(); - } - } } } catch (const std::exception& e) { @@ -400,12 +395,7 @@ void IncomingHTTP2Connection::writeToSocket(bool socketReady) d_out.clear(); d_outPos = 0; if (active() && !d_connectionClosing) { - if (!isIdle()) { - updateIO(IOState::NeedRead, handleReadableIOCallback); - } - else { - watchForRemoteHostClosingConnection(); - } + updateIO(IOState::NeedRead, handleReadableIOCallback); } else { stopIO(); @@ -791,8 +781,7 @@ void IncomingHTTP2Connection::handleIncomingQuery(IncomingHTTP2Connection::Pendi sendResponse(streamID, query, code, d_ci.cs->dohFrontend->d_customResponseHeaders); }; - if (query.d_method == PendingQuery::Method::Unknown || - query.d_method == PendingQuery::Method::Unsupported) { + if (query.d_method == PendingQuery::Method::Unknown || query.d_method == PendingQuery::Method::Unsupported) { handleImmediateResponse(400, "DoH query not allowed because of unsupported HTTP method"); return; } @@ -919,10 +908,6 @@ int IncomingHTTP2Connection::on_frame_recv_callback(nghttp2_session* session, co auto stream = conn->d_currentStreams.find(streamID); if (stream != conn->d_currentStreams.end()) { conn->handleIncomingQuery(std::move(stream->second), streamID); - - if (conn->isIdle()) { - conn->watchForRemoteHostClosingConnection(); - } } else { vinfolog("Stream %d NOT FOUND", streamID); @@ -954,10 +939,6 @@ int IncomingHTTP2Connection::on_stream_close_callback(nghttp2_session* session, auto request = std::move(stream->second); conn->d_currentStreams.erase(stream->first); - if (conn->isIdle()) { - conn->watchForRemoteHostClosingConnection(); - } - return 0; } @@ -1222,20 +1203,6 @@ void IncomingHTTP2Connection::updateIO(IOState newState, const FDMultiplexer::ca } } -void IncomingHTTP2Connection::watchForRemoteHostClosingConnection() -{ - if (d_connectionDied) { - return; - } - - if (hasPendingWrite()) { - updateIO(IOState::NeedWrite, &handleWritableIOCallback); - } - else if (!d_connectionClosing) { - updateIO(IOState::NeedRead, handleReadableIOCallback); - } -} - void IncomingHTTP2Connection::handleIOError() { d_connectionDied = true; diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh index 3db7473a8e3d..32af8d3087d4 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -89,7 +89,6 @@ private: bool isIdle() const; uint32_t getConcurrentStreamsCount() const; void updateIO(IOState newState, const FDMultiplexer::callbackfunc_t& callback); - void watchForRemoteHostClosingConnection(); void handleIOError(); bool sendResponse(StreamID streamID, PendingQuery& context, uint16_t responseCode, const HeadersMap& customResponseHeaders, const std::string& contentType = "", bool addContentType = true); void handleIncomingQuery(PendingQuery&& query, StreamID streamID); diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc index 0ac62b3c3b6d..48d2f6eeeb36 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc @@ -90,7 +90,7 @@ class DOHConnection { const auto& context = s_connectionContexts.at(connectionID); d_clientOutBuffer.insert(d_clientOutBuffer.begin(), context.d_proxyProtocolPayload.begin(), context.d_proxyProtocolPayload.end()); - + nghttp2_session_callbacks* cbs = nullptr; nghttp2_session_callbacks_new(&cbs); std::unique_ptr callbacks(cbs, nghttp2_session_callbacks_del); @@ -499,19 +499,19 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, {403U}}; s_steps = { /* opening */ - { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done}, /* settings server -> client */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15}, /* settings + headers + data client -> server.. */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128}, /* .. continued */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60}, /* headers + data */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, std::numeric_limits::max() }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, std::numeric_limits::max()}, /* wait for next query, but the client closes the connection */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0}, /* server close */ - { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::closeClient, IOState::Done}, }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); @@ -520,18 +520,18 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) { /* client closes the connection right in the middle of sending the query */ - s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, { 403U }}; + s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, {403U}}; s_steps = { /* opening */ - { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done}, /* settings server -> client */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15}, /* client sends one byte */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 1 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 1}, /* then closes the connection */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0}, /* server close */ - { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::closeClient, IOState::Done}, }; /* mark the incoming FD as always ready */ @@ -556,19 +556,19 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) s_steps = { /* opening */ - { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done}, /* settings server -> client */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15}, /* settings + headers + data client -> server.. */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128}, /* .. continued */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60}, /* headers + data */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, std::numeric_limits::max() }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, std::numeric_limits::max()}, /* wait for next query, but the client closes the connection */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0}, /* server close */ - { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::closeClient, IOState::Done}, }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); @@ -587,17 +587,17 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) s_steps = { /* opening */ - { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done}, /* settings server -> client */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15}, /* settings + headers + data client -> server.. */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128}, /* .. continued */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60}, /* we want to send the response but the client closes the connection */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 0 }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 0}, /* server close */ - { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::closeClient, IOState::Done}, }; /* mark the incoming FD as always ready */ @@ -622,21 +622,21 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) s_steps = { /* opening */ - { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done}, /* settings server -> client */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15}, /* settings + headers + data client -> server.. */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128}, /* .. continued */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60}, /* headers + data (partial write) */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::NeedWrite, 1 }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::NeedWrite, 1}, /* nothing to read after that */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 0 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead, 0}, /* then the client closes the connection before we are done */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 0 }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 0}, /* server close */ - { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::closeClient, IOState::Done}, }; /* mark the incoming FD as always ready */ @@ -691,25 +691,24 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_BackendTimeout, TestFixture) s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, {502U}}; s_steps = { /* opening */ - { ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::handshakeClient, IOState::Done}, /* settings server -> client */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15 }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, 15}, /* settings + headers + data client -> server.. */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 128}, /* .. continued */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60 }, - /* trying to read a new request while processing the first one */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 60}, + /* trying to read a new request while processing the first one */ + {ExpectedStep::ExpectedRequest::readFromClient, IOState::NeedRead}, /* headers + data */ - { ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, std::numeric_limits::max(), [&threadData](int desc) { - /* set the incoming descriptor as ready */ - dynamic_cast(threadData.mplexer.get())->setReady(desc); - } - }, + {ExpectedStep::ExpectedRequest::writeToClient, IOState::Done, std::numeric_limits::max(), [&threadData](int desc) { + /* set the incoming descriptor as ready */ + dynamic_cast(threadData.mplexer.get())->setReady(desc); + }}, /* wait for next query, but the client closes the connection */ - { ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0 }, + {ExpectedStep::ExpectedRequest::readFromClient, IOState::Done, 0}, /* server close */ - { ExpectedStep::ExpectedRequest::closeClient, IOState::Done }, + {ExpectedStep::ExpectedRequest::closeClient, IOState::Done}, }; auto state = std::make_shared(ConnectionInfo(&localCS, getBackendAddress("84", 4242)), threadData, now); From 9f433af44e2bf4e2f1edb00affc76a362c38eee1 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 12 Jul 2023 17:46:57 +0200 Subject: [PATCH 634/909] dnsdist: Add support for incoming proxy protocol outside the TLS layer --- pdns/dnsdist-lua.cc | 2 + pdns/dnsdist-tcp.cc | 140 +++++++++++++---------- pdns/dnsdist.hh | 11 ++ pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 77 +++++++++---- pdns/dnsdistdist/dnsdist-nghttp2-in.hh | 1 + pdns/dnsdistdist/dnsdist-tcp-upstream.hh | 13 ++- pdns/tcpiohandler.hh | 6 +- 7 files changed, 164 insertions(+), 86 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index c09ff65aead4..d5c27f4de39b 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2409,6 +2409,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) getOptionalValue(vars, "serverTokens", frontend->d_serverTokens); getOptionalValue(vars, "provider", frontend->d_tlsContext.d_provider); boost::algorithm::to_lower(frontend->d_tlsContext.d_provider); + getOptionalValue(vars, "proxyProtocolOutsideTLS", frontend->d_tlsContext.d_proxyProtocolOutsideTLS); LuaAssociativeTable customResponseHeaders; if (getOptionalValue(vars, "customResponseHeaders", customResponseHeaders) > 0) { @@ -2647,6 +2648,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) getOptionalValue(vars, "provider", frontend->d_provider); boost::algorithm::to_lower(frontend->d_provider); + getOptionalValue(vars, "proxyProtocolOutsideTLS", frontend->d_proxyProtocolOutsideTLS); LuaArray addresses; if (getOptionalValue(vars, "additionalAddresses", addresses) > 0) { diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 08ecf1d4fcaa..2f78c22dad7a 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -299,7 +299,7 @@ void IncomingTCPConnectionState::registerOwnedDownstreamConnection(std::shared_p /* called when the buffer has been set and the rules have been processed, and only from handleIO (sometimes indirectly via handleQuery) */ IOState IncomingTCPConnectionState::sendResponse(const struct timeval& now, TCPResponse&& response) { - d_state = IncomingTCPConnectionState::State::sendingResponse; + d_state = State::sendingResponse; uint16_t responseSize = static_cast(response.d_buffer.size()); const uint8_t sizeBytes[] = { static_cast(responseSize / 256), static_cast(responseSize % 256) }; @@ -382,18 +382,18 @@ void IncomingTCPConnectionState::queueResponse(std::shared_ptrd_state == IncomingTCPConnectionState::State::idle || - state->d_state == IncomingTCPConnectionState::State::waitingForQuery) { + if (state->d_state == State::idle || + state->d_state == State::waitingForQuery) { auto iostate = sendQueuedResponses(state, now); if (iostate == IOState::Done && state->active()) { if (state->canAcceptNewQueries(now)) { state->resetForNewQuery(); - state->d_state = IncomingTCPConnectionState::State::waitingForQuery; + state->d_state = State::waitingForQuery; iostate = IOState::NeedRead; } else { - state->d_state = IncomingTCPConnectionState::State::idle; + state->d_state = State::idle; } } @@ -649,7 +649,7 @@ IncomingTCPConnectionState::QueryProcessingResult IncomingTCPConnectionState::ha auto dnsCryptResponse = checkDNSCryptQuery(*d_ci.cs, query, ids.dnsCryptQuery, ids.queryRealTime.d_start.tv_sec, true); if (dnsCryptResponse) { TCPResponse response; - d_state = IncomingTCPConnectionState::State::idle; + d_state = State::idle; ++d_currentQueriesCount; queueResponse(state, now, std::move(response)); return QueryProcessingResult::SelfAnswered; @@ -668,7 +668,7 @@ IncomingTCPConnectionState::QueryProcessingResult IncomingTCPConnectionState::ha dh->qr = true; response.d_idstate.selfGenerated = true; response.d_buffer = std::move(query); - d_state = IncomingTCPConnectionState::State::idle; + d_state = State::idle; ++d_currentQueriesCount; queueResponse(state, now, std::move(response)); return QueryProcessingResult::Empty; @@ -749,7 +749,7 @@ IncomingTCPConnectionState::QueryProcessingResult IncomingTCPConnectionState::ha response.d_idstate.cs = d_ci.cs; response.d_buffer = std::move(query); - d_state = IncomingTCPConnectionState::State::idle; + d_state = State::idle; ++d_currentQueriesCount; queueResponse(state, now, std::move(response)); return QueryProcessingResult::SelfAnswered; @@ -849,7 +849,7 @@ IncomingTCPConnectionState::ProxyProtocolResult IncomingTCPConnectionState::hand { do { DEBUGLOG("reading proxy protocol header"); - auto iostate = d_handler.tryRead(d_buffer, d_currentPos, d_proxyProtocolNeed); + auto iostate = d_handler.tryRead(d_buffer, d_currentPos, d_proxyProtocolNeed, false, isProxyPayloadOutsideTLS()); if (iostate == IOState::Done) { d_buffer.resize(d_currentPos); ssize_t remaining = isProxyHeaderComplete(d_buffer); @@ -887,6 +887,30 @@ IncomingTCPConnectionState::ProxyProtocolResult IncomingTCPConnectionState::hand return ProxyProtocolResult::Reading; } +IOState IncomingTCPConnectionState::handleHandshake(const struct timeval& now) +{ + DEBUGLOG("doing handshake"); + auto iostate = d_handler.tryHandshake(); + if (iostate == IOState::Done) { + DEBUGLOG("handshake done"); + handleHandshakeDone(now); + + if (!isProxyPayloadOutsideTLS() && expectProxyProtocolFrom(d_ci.remote)) { + d_state = State::readingProxyProtocolHeader; + d_buffer.resize(s_proxyProtocolMinimumHeaderSize); + d_proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; + } + else { + d_state = State::readingQuerySize; + } + } + else { + d_lastIOBlocked = true; + } + + return iostate; +} + void IncomingTCPConnectionState::handleIO() { // why do we loop? Because the TLS layer does buffering, and thus can have data ready to read @@ -909,34 +933,34 @@ void IncomingTCPConnectionState::handleIO() d_lastIOBlocked = false; try { - if (d_state == IncomingTCPConnectionState::State::doingHandshake) { - DEBUGLOG("doing handshake"); - iostate = d_handler.tryHandshake(); - if (iostate == IOState::Done) { - DEBUGLOG("handshake done"); - handleHandshakeDone(now); - - if (expectProxyProtocolFrom(d_ci.remote)) { - d_state = IncomingTCPConnectionState::State::readingProxyProtocolHeader; - d_buffer.resize(s_proxyProtocolMinimumHeaderSize); - d_proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; - } - else { - d_state = IncomingTCPConnectionState::State::readingQuerySize; - } + if (d_state == State::starting) { + if (isProxyPayloadOutsideTLS() && expectProxyProtocolFrom(d_ci.remote)) { + d_state = State::readingProxyProtocolHeader; + d_buffer.resize(s_proxyProtocolMinimumHeaderSize); + d_proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; } else { - d_lastIOBlocked = true; + d_state = State::doingHandshake; } } - if (!d_lastIOBlocked && d_state == IncomingTCPConnectionState::State::readingProxyProtocolHeader) { + if (d_state == State::doingHandshake) { + iostate = handleHandshake(now); + } + + if (!d_lastIOBlocked && d_state == State::readingProxyProtocolHeader) { auto status = handleProxyProtocolPayload(); if (status == ProxyProtocolResult::Done) { - d_state = IncomingTCPConnectionState::State::readingQuerySize; - d_buffer.resize(sizeof(uint16_t)); - d_currentPos = 0; - d_proxyProtocolNeed = 0; + if (isProxyPayloadOutsideTLS()) { + d_state = State::doingHandshake; + iostate = handleHandshake(now); + } + else { + d_state = State::readingQuerySize; + d_buffer.resize(sizeof(uint16_t)); + d_currentPos = 0; + d_proxyProtocolNeed = 0; + } } else if (status == ProxyProtocolResult::Error) { iostate = IOState::Done; @@ -946,19 +970,19 @@ void IncomingTCPConnectionState::handleIO() } } - if (!d_lastIOBlocked && (d_state == IncomingTCPConnectionState::State::waitingForQuery || - d_state == IncomingTCPConnectionState::State::readingQuerySize)) { + if (!d_lastIOBlocked && (d_state == State::waitingForQuery || + d_state == State::readingQuerySize)) { DEBUGLOG("reading query size"); d_buffer.resize(sizeof(uint16_t)); iostate = d_handler.tryRead(d_buffer, d_currentPos, sizeof(uint16_t)); if (d_currentPos > 0) { /* if we got at least one byte, we can't go around sending responses */ - d_state = IncomingTCPConnectionState::State::readingQuerySize; + d_state = State::readingQuerySize; } if (iostate == IOState::Done) { DEBUGLOG("query size received"); - d_state = IncomingTCPConnectionState::State::readingQuery; + d_state = State::readingQuery; d_querySizeReadTime = now; if (d_queriesCount == 0) { d_firstQuerySizeReadTime = now; @@ -980,14 +1004,14 @@ void IncomingTCPConnectionState::handleIO() } } - if (!d_lastIOBlocked && d_state == IncomingTCPConnectionState::State::readingQuery) { + if (!d_lastIOBlocked && d_state == State::readingQuery) { DEBUGLOG("reading query"); iostate = d_handler.tryRead(d_buffer, d_currentPos, d_querySize); if (iostate == IOState::Done) { DEBUGLOG("query received"); d_buffer.resize(d_querySize); - d_state = IncomingTCPConnectionState::State::idle; + d_state = State::idle; auto processingResult = handleQuery(std::move(d_buffer), now, std::nullopt); switch (processingResult) { case QueryProcessingResult::TooSmall: @@ -1005,7 +1029,7 @@ void IncomingTCPConnectionState::handleIO() /* the state might have been updated in the meantime, we don't want to override it in that case */ - if (active() && d_state != IncomingTCPConnectionState::State::idle) { + if (active() && d_state != State::idle) { if (d_ioState->isWaitingForRead()) { iostate = IOState::NeedRead; } @@ -1022,13 +1046,13 @@ void IncomingTCPConnectionState::handleIO() } } - if (!d_lastIOBlocked && d_state == IncomingTCPConnectionState::State::sendingResponse) { + if (!d_lastIOBlocked && d_state == State::sendingResponse) { DEBUGLOG("sending response"); iostate = d_handler.tryWrite(d_currentResponse.d_buffer, d_currentPos, d_currentResponse.d_buffer.size()); if (iostate == IOState::Done) { DEBUGLOG("response sent from "<<__PRETTY_FUNCTION__); handleResponseSent(d_currentResponse); - d_state = IncomingTCPConnectionState::State::idle; + d_state = State::idle; } else { d_lastIOBlocked = true; @@ -1038,8 +1062,8 @@ void IncomingTCPConnectionState::handleIO() if (active() && !d_lastIOBlocked && iostate == IOState::Done && - (d_state == IncomingTCPConnectionState::State::idle || - d_state == IncomingTCPConnectionState::State::waitingForQuery)) + (d_state == State::idle || + d_state == State::waitingForQuery)) { // try sending queued responses DEBUGLOG("send responses, if any"); @@ -1054,19 +1078,19 @@ void IncomingTCPConnectionState::handleIO() iostate = IOState::NeedRead; } else { - d_state = IncomingTCPConnectionState::State::idle; + d_state = State::idle; iostate = IOState::Done; } } } - if (d_state != IncomingTCPConnectionState::State::idle && - d_state != IncomingTCPConnectionState::State::doingHandshake && - d_state != IncomingTCPConnectionState::State::readingProxyProtocolHeader && - d_state != IncomingTCPConnectionState::State::waitingForQuery && - d_state != IncomingTCPConnectionState::State::readingQuerySize && - d_state != IncomingTCPConnectionState::State::readingQuery && - d_state != IncomingTCPConnectionState::State::sendingResponse) { + if (d_state != State::idle && + d_state != State::doingHandshake && + d_state != State::readingProxyProtocolHeader && + d_state != State::waitingForQuery && + d_state != State::readingQuerySize && + d_state != State::readingQuery && + d_state != State::sendingResponse) { vinfolog("Unexpected state %d in handleIOCallback", static_cast(d_state)); } } @@ -1075,18 +1099,18 @@ void IncomingTCPConnectionState::handleIO() but it might also be a real IO error or something else. Let's just drop the connection */ - if (d_state == IncomingTCPConnectionState::State::idle || - d_state == IncomingTCPConnectionState::State::waitingForQuery) { + if (d_state == State::idle || + d_state == State::waitingForQuery) { /* no need to increase any counters in that case, the client is simply done with us */ } - else if (d_state == IncomingTCPConnectionState::State::doingHandshake || - d_state != IncomingTCPConnectionState::State::readingProxyProtocolHeader || - d_state == IncomingTCPConnectionState::State::waitingForQuery || - d_state == IncomingTCPConnectionState::State::readingQuerySize || - d_state == IncomingTCPConnectionState::State::readingQuery) { + else if (d_state == State::doingHandshake || + d_state != State::readingProxyProtocolHeader || + d_state == State::waitingForQuery || + d_state == State::readingQuerySize || + d_state == State::readingQuery) { ++d_ci.cs->tcpDiedReadingQuery; } - else if (d_state == IncomingTCPConnectionState::State::sendingResponse) { + else if (d_state == State::sendingResponse) { /* unlikely to happen here, the exception should be handled in sendResponse() */ ++d_ci.cs->tcpDiedSendingResponse; } @@ -1180,7 +1204,7 @@ void IncomingTCPConnectionState::handleTimeout(std::shared_ptrd_state = IncomingTCPConnectionState::State::idle; + state->d_state = State::idle; state->d_ioState->update(IOState::Done, handleIOCallback, state); } } diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index a9ecef017080..694dab3a6cbe 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -529,6 +529,17 @@ struct ClientState return tlsFrontend != nullptr || (dohFrontend != nullptr && dohFrontend->isHTTPS()); } + const TLSFrontend& getTLSFrontend() const + { + if (tlsFrontend != nullptr) { + return *tlsFrontend; + } + if (dohFrontend) { + return dohFrontend->d_tlsContext; + } + throw std::runtime_error("Trying to get a TLS frontend from a non-TLS ClientState"); + } + dnsdist::Protocol getProtocol() const { if (dnscryptCtx) { diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 7945a2544f30..b22da0c39715 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -290,6 +290,32 @@ bool IncomingHTTP2Connection::hasPendingWrite() const return d_pendingWrite; } +IOState IncomingHTTP2Connection::handleHandshake(const struct timeval& now) +{ + auto iostate = d_handler.tryHandshake(); + if (iostate == IOState::Done) { + handleHandshakeDone(now); + if (d_handler.isTLS()) { + if (!checkALPN()) { + d_connectionDied = true; + stopIO(); + return iostate; + } + } + + if (!isProxyPayloadOutsideTLS() && expectProxyProtocolFrom(d_ci.remote)) { + d_state = State::readingProxyProtocolHeader; + d_buffer.resize(s_proxyProtocolMinimumHeaderSize); + d_proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; + } + else { + d_state = State::waitingForQuery; + handleConnectionReady(); + } + } + return iostate; +} + void IncomingHTTP2Connection::handleIO() { IOState iostate = IOState::Done; @@ -306,39 +332,42 @@ void IncomingHTTP2Connection::handleIO() return; } + if (d_state == State::starting) { + if (isProxyPayloadOutsideTLS() && expectProxyProtocolFrom(d_ci.remote)) { + d_state = State::readingProxyProtocolHeader; + d_buffer.resize(s_proxyProtocolMinimumHeaderSize); + d_proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; + } + else { + d_state = State::doingHandshake; + } + } + if (d_state == State::doingHandshake) { - iostate = d_handler.tryHandshake(); - if (iostate == IOState::Done) { - handleHandshakeDone(now); - if (d_handler.isTLS()) { - if (!checkALPN()) { - d_connectionDied = true; - stopIO(); + iostate = handleHandshake(now); + if (d_connectionDied) { + return; + } + } + + if (d_state == State::readingProxyProtocolHeader) { + auto status = handleProxyProtocolPayload(); + if (status == ProxyProtocolResult::Done) { + if (isProxyPayloadOutsideTLS()) { + d_state = State::doingHandshake; + iostate = handleHandshake(now); + if (d_connectionDied) { return; } } - - if (expectProxyProtocolFrom(d_ci.remote)) { - d_state = IncomingTCPConnectionState::State::readingProxyProtocolHeader; - d_buffer.resize(s_proxyProtocolMinimumHeaderSize); - d_proxyProtocolNeed = s_proxyProtocolMinimumHeaderSize; - } else { + d_currentPos = 0; + d_proxyProtocolNeed = 0; + d_buffer.clear(); d_state = State::waitingForQuery; handleConnectionReady(); } } - } - - if (d_state == IncomingTCPConnectionState::State::readingProxyProtocolHeader) { - auto status = handleProxyProtocolPayload(); - if (status == ProxyProtocolResult::Done) { - d_currentPos = 0; - d_proxyProtocolNeed = 0; - d_buffer.clear(); - d_state = State::waitingForQuery; - handleConnectionReady(); - } else if (status == ProxyProtocolResult::Error) { d_connectionDied = true; stopIO(); diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh index 32af8d3087d4..a648a5027b3f 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -95,6 +95,7 @@ private: bool checkALPN(); IOState readHTTPData(); void handleConnectionReady(); + IOState handleHandshake(const struct timeval& now) override; bool hasPendingWrite() const; void writeToSocket(bool socketReady); boost::optional getIdleClientReadTTD(struct timeval now) const; diff --git a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh index 4318892659f6..f1c49e93e4e2 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh +++ b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh @@ -138,6 +138,7 @@ public: virtual IOState sendResponse(const struct timeval& now, TCPResponse&& response); void handleResponseSent(TCPResponse& currentResponse); + virtual IOState handleHandshake(const struct timeval& now); void handleHandshakeDone(const struct timeval& now); ProxyProtocolResult handleProxyProtocolPayload(); void handleCrossProtocolResponse(const struct timeval& now, TCPResponse&& response); @@ -150,6 +151,14 @@ public: { return d_ioState != nullptr; } + bool isProxyPayloadOutsideTLS() const + { + if (!d_ci.cs->hasTLS()) { + return false; + } + return d_ci.cs->getTLSFrontend().d_proxyProtocolOutsideTLS; + } + virtual bool forwardViaUDPFirst() const { return false; @@ -174,7 +183,7 @@ public: dnsdist::Protocol getProtocol() const; - enum class State : uint8_t { doingHandshake, readingProxyProtocolHeader, waitingForQuery, readingQuerySize, readingQuery, sendingResponse, idle /* in case of XFR, we stop processing queries */ }; + enum class State : uint8_t { starting, doingHandshake, readingProxyProtocolHeader, waitingForQuery, readingQuerySize, readingQuery, sendingResponse, idle /* in case of XFR, we stop processing queries */ }; TCPResponse d_currentResponse; std::map, std::deque>> d_ownedConnectionsToBackend; @@ -199,7 +208,7 @@ public: size_t d_currentQueriesCount{0}; std::thread::id d_creatorThreadID; uint16_t d_querySize{0}; - State d_state{State::doingHandshake}; + State d_state{State::starting}; bool d_isXFR{false}; bool d_proxyProtocolPayloadHasTLV{false}; bool d_lastIOBlocked{false}; diff --git a/pdns/tcpiohandler.hh b/pdns/tcpiohandler.hh index 5e1d23e737c6..3cf674ca1656 100644 --- a/pdns/tcpiohandler.hh +++ b/pdns/tcpiohandler.hh @@ -226,6 +226,8 @@ public: ComboAddress d_addr; std::string d_provider; ALPN d_alpn{ALPN::Unset}; + /* whether the proxy protocol is inside or outside the TLS layer */ + bool d_proxyProtocolOutsideTLS{false}; protected: std::shared_ptr d_ctx{nullptr}; }; @@ -365,13 +367,13 @@ public: return Done when toRead bytes have been read, needRead or needWrite if the IO operation would block. */ - IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead, bool allowIncomplete=false) + IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead, bool allowIncomplete=false, bool bypassFilters=false) { if (buffer.size() < toRead || pos >= toRead) { throw std::out_of_range("Calling tryRead() with a too small buffer (" + std::to_string(buffer.size()) + ") for a read of " + std::to_string(toRead - pos) + " bytes starting at " + std::to_string(pos)); } - if (d_conn) { + if (!bypassFilters && d_conn) { return d_conn->tryRead(buffer, pos, toRead, allowIncomplete); } From 41f3676508f033cc0b0a5fb456cce0f917c7149a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 13 Jul 2023 14:45:38 +0200 Subject: [PATCH 635/909] dnsdist: Add a test for DoH incoming proxy protocol outside of TLS --- regression-tests.dnsdist/dnsdisttests.py | 11 +- .../test_ProxyProtocol.py | 152 +++++++++++++++++- 2 files changed, 151 insertions(+), 12 deletions(-) diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 75068bea027d..e2787d577fd8 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -987,7 +987,7 @@ def openDOHConnection(cls, port, caFile, timeout=2.0): return conn @classmethod - def sendDOHQuery(cls, port, servername, baseurl, query, response=None, timeout=2.0, caFile=None, useQueue=True, rawQuery=False, rawResponse=False, customHeaders=[], useHTTPS=True, fromQueue=None, toQueue=None, useProxyProtocol=False, conn=None): + def sendDOHQuery(cls, port, servername, baseurl, query, response=None, timeout=2.0, caFile=None, useQueue=True, rawQuery=False, rawResponse=False, customHeaders=[], useHTTPS=True, fromQueue=None, toQueue=None, conn=None): url = cls.getDOHGetURL(baseurl, query, rawQuery) if not conn: @@ -1003,11 +1003,6 @@ def sendDOHQuery(cls, port, servername, baseurl, query, response=None, timeout=2 if caFile: conn.setopt(pycurl.CAINFO, caFile) - if useProxyProtocol: - print('enabling PP') - # 274 is CURLOPT_HAPROXYPROTOCOL - conn.setopt(274, 1) - response_headers = BytesIO() #conn.setopt(pycurl.VERBOSE, True) conn.setopt(pycurl.URL, url) @@ -1088,8 +1083,8 @@ def sendDOHPostQuery(cls, port, servername, baseurl, query, response=None, timeo cls._response_headers = response_headers.getvalue() return (receivedQuery, message) - def sendDOHQueryWrapper(self, query, response, useQueue=True, useProxyProtocol=False): - return self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue, useProxyProtocol=useProxyProtocol) + def sendDOHQueryWrapper(self, query, response, useQueue=True): + return self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) def sendDOHWithNGHTTP2QueryWrapper(self, query, response, useQueue=True): return self.sendDOHQuery(self._dohWithNGHTTP2ServerPort, self._serverName, self._dohWithNGHTTP2BaseURL, query, response=response, caFile=self._caCert, useQueue=useQueue) diff --git a/regression-tests.dnsdist/test_ProxyProtocol.py b/regression-tests.dnsdist/test_ProxyProtocol.py index 2ff4a2d74100..744d6a7c79e2 100644 --- a/regression-tests.dnsdist/test_ProxyProtocol.py +++ b/regression-tests.dnsdist/test_ProxyProtocol.py @@ -2,6 +2,7 @@ import copy import dns +import selectors import socket import struct import sys @@ -141,6 +142,80 @@ def ProxyProtocolTCPResponder(port, fromQueue, toQueue): tcpResponder.daemon = True tcpResponder.start() +backgroundThreads = {} + +def MockTCPReverseProxyAddingProxyProtocol(listeningPort, forwardingPort): + # this responder accepts TCP connections on the listening port, + # and relay the raw content to a second TCP connection to the + # forwarding port, after adding a Proxy Protocol v2 payload + # containing the initial source IP and port, destination IP + # and port. + backgroundThreads[threading.get_native_id()] = True + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) + sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + try: + sock.bind(("127.0.0.1", listeningPort)) + except socket.error as e: + print("Error binding in the Mock TCP reverse proxy: %s" % str(e)) + sys.exit(1) + sock.settimeout(0.5) + sock.listen(100) + while True: + try: + (incoming, _) = sock.accept() + except socket.timeout: + if backgroundThreads.get(threading.get_native_id(), False) == False: + del backgroundThreads[threading.get_native_id()] + break + else: + continue + + incoming.settimeout(5.0) + payload = ProxyProtocol.getPayload(False, True, False, '127.0.0.1', '127.0.0.1', incoming.getpeername()[1], listeningPort, [ [ 2, b'foo'], [ 3, b'proxy'] ]) + + outgoing = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + outgoing.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + outgoing.settimeout(2.0) + outgoing.connect(('127.0.0.1', forwardingPort)) + + outgoing.send(payload) + + sel = selectors.DefaultSelector() + def readFromClient(conn): + data = conn.recv(512) + if not data or len(data) == 0: + return False + outgoing.send(data) + return True + + def readFromBackend(conn): + data = conn.recv(512) + if not data or len(data) == 0: + return False + incoming.send(data) + return True + + sel.register(incoming, selectors.EVENT_READ, readFromClient) + sel.register(outgoing, selectors.EVENT_READ, readFromBackend) + done = False + while not done: + try: + events = sel.select() + for key, mask in events: + if not (key.data)(key.fileobj): + done = True + break + except socket.timeout: + break + except: + break + + incoming.close() + outgoing.close() + + sock.close() + class ProxyProtocolTest(DNSDistTest): _proxyResponderPort = proxyResponderPort _config_params = ['_proxyResponderPort'] @@ -398,6 +473,7 @@ class TestProxyProtocolIncoming(ProxyProtocolTest): """ _config_template = """ + addDOHLocal("127.0.0.1:%s", "%s", "%s", {"/"}, {library='nghttp2', proxyProtocolOutsideTLS=true}) setProxyProtocolACL( { "127.0.0.1/32" } ) newServer{address="127.0.0.1:%d", useProxyProtocol=true} @@ -434,8 +510,13 @@ class TestProxyProtocolIncoming(ProxyProtocolTest): -- override all existing values addAction("override.proxy-protocol-incoming.tests.powerdns.com.", SetProxyProtocolValuesAction({["50"]="overridden"})) """ - _config_params = ['_proxyResponderPort'] - _verboseMode = True + _serverKey = 'server.key' + _serverCert = 'server.chain' + _serverName = 'tls.tests.dnsdist.org' + _caCert = 'ca.pem' + _dohServerPort = 8443 + _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) + _config_params = ['_dohServerPort', '_serverCert', '_serverKey', '_proxyResponderPort'] def testNoHeader(self): """ @@ -445,9 +526,12 @@ def testNoHeader(self): name = 'no-header.incoming-proxy-protocol.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') - for method in ("sendUDPQuery", "sendTCPQuery"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOHQueryWrapper"): sender = getattr(self, method) - (_, receivedResponse) = sender(query, response=None) + try: + (_, receivedResponse) = sender(query, response=None) + except Exception: + receivedResponse = None self.assertEqual(receivedResponse, None) def testIncomingProxyDest(self): @@ -656,6 +740,66 @@ def testProxyTCPSeveralQueriesOverConnection(self): self.assertEqual(receivedResponse, response) self.checkMessageProxyProtocol(receivedProxyPayload, srcAddr, destAddr, True, [ [0, b'foo'], [1, b'dnsdist'], [ 2, b'foo'], [3, b'proxy'], [ 42, b'bar'], [255, b'proxy-protocol'] ], True, srcPort, destPort) + def testProxyDoHSeveralQueriesOverConnection(self): + """ + Incoming Proxy Protocol: Several queries over the same connection (DoH) + """ + name = 'several-queries.proxy-protocol-incoming.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + + toProxyQueue.put(response, True, 2.0) + + wire = query.to_wire() + + reverseProxyPort = 13053 + reverseProxy = threading.Thread(name='Mock Proxy Protocol Reverse Proxy', target=MockTCPReverseProxyAddingProxyProtocol, args=[reverseProxyPort, self._dohServerPort]) + reverseProxy.start() + + receivedResponse = None + conn = self.openDOHConnection(reverseProxyPort, self._caCert, timeout=2.0) + + reverseProxyBaseURL = ("https://%s:%d/" % (self._serverName, reverseProxyPort)) + (receivedQuery, receivedResponse) = self.sendDOHQuery(reverseProxyPort, self._serverName, reverseProxyBaseURL, query, response=response, caFile=self._caCert, useQueue=True, conn=conn) + (receivedProxyPayload, receivedDNSData) = fromProxyQueue.get(True, 2.0) + self.assertTrue(receivedProxyPayload) + self.assertTrue(receivedDNSData) + self.assertTrue(receivedResponse) + + receivedQuery = dns.message.from_wire(receivedDNSData) + receivedQuery.id = query.id + receivedResponse.id = response.id + self.assertEqual(receivedQuery, query) + self.assertEqual(receivedResponse, response) + self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.1', '127.0.0.1', True, [ [0, b'foo'], [1, b'dnsdist'], [ 2, b'foo'], [3, b'proxy'], [ 42, b'bar'], [255, b'proxy-protocol'] ], v6=False, sourcePort=None, destinationPort=reverseProxyPort) + + for idx in range(5): + receivedResponse = None + toProxyQueue.put(response, True, 2.0) + (receivedQuery, receivedResponse) = self.sendDOHQuery(reverseProxyPort, self._serverName, reverseProxyBaseURL, query, response=response, caFile=self._caCert, useQueue=True, conn=conn) + (receivedProxyPayload, receivedDNSData) = fromProxyQueue.get(True, 2.0) + self.assertTrue(receivedProxyPayload) + self.assertTrue(receivedDNSData) + self.assertTrue(receivedResponse) + + receivedQuery = dns.message.from_wire(receivedDNSData) + receivedQuery.id = query.id + receivedResponse.id = response.id + self.assertEqual(receivedQuery, query) + print(receivedResponse) + print(response) + self.assertEqual(receivedResponse, response) + self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.1', '127.0.0.1', True, [ [0, b'foo'], [1, b'dnsdist'], [ 2, b'foo'], [3, b'proxy'], [ 42, b'bar'], [255, b'proxy-protocol'] ], v6=False, sourcePort=None, destinationPort=reverseProxyPort) + + @classmethod + def tearDownClass(cls): + cls._sock.close() + for backgroundThread in cls._backgroundThreads: + cls._backgroundThreads[backgroundThread] = False + for backgroundThread in backgroundThreads: + backgroundThreads[backgroundThread] = False + cls.killProcess(cls._dnsdist) + class TestProxyProtocolNotExpected(DNSDistTest): """ dnsdist is configured to expect a Proxy Protocol header on incoming queries but not from 127.0.0.1 From 8e5da829565750d80d2032e2f1deb5a00c108f7f Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 13 Jul 2023 16:15:48 +0200 Subject: [PATCH 636/909] dnsdist: Add a test for DoH incoming proxy protocol inside of TLS --- regression-tests.dnsdist/dnsdisttests.py | 6 -- .../test_ProxyProtocol.py | 90 ++++++++++++++++--- 2 files changed, 79 insertions(+), 17 deletions(-) diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index e2787d577fd8..c82f2b9ac9dd 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -657,7 +657,6 @@ def sendTCPQueryOverConnection(cls, sock, query, rawQuery=False, response=None, @classmethod def recvTCPResponseOverConnection(cls, sock, useQueue=False, timeout=2.0): - print("reading data") message = None data = sock.recv(2) if data: @@ -671,7 +670,6 @@ def recvTCPResponseOverConnection(cls, sock, useQueue=False, timeout=2.0): print(useQueue) if useQueue and not cls._fromResponderQueue.empty(): receivedQuery = cls._fromResponderQueue.get(True, timeout) - print("Got from queue") print(receivedQuery) return (receivedQuery, message) else: @@ -707,7 +705,6 @@ def sendTCPQuery(cls, query, response, useQueue=True, timeout=2.0, rawQuery=Fals receivedQuery = None print(useQueue) if useQueue and not cls._fromResponderQueue.empty(): - print("Got from queue") print(receivedQuery) receivedQuery = cls._fromResponderQueue.get(True, timeout) else: @@ -991,13 +988,11 @@ def sendDOHQuery(cls, port, servername, baseurl, query, response=None, timeout=2 url = cls.getDOHGetURL(baseurl, query, rawQuery) if not conn: - print('creating a new connection') conn = cls.openDOHConnection(port, caFile=caFile, timeout=timeout) # this means "really do HTTP/2, not HTTP/1 with Upgrade headers" conn.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_2_PRIOR_KNOWLEDGE) if useHTTPS: - print("disabling verify") conn.setopt(pycurl.SSL_VERIFYPEER, 1) conn.setopt(pycurl.SSL_VERIFYHOST, 2) if caFile: @@ -1020,7 +1015,6 @@ def sendDOHQuery(cls, port, servername, baseurl, query, response=None, timeout=2 receivedQuery = None message = None cls._response_headers = '' - print('performing') data = conn.perform_rb() cls._rcode = conn.getinfo(pycurl.RESPONSE_CODE) if cls._rcode == 200 and not rawResponse: diff --git a/regression-tests.dnsdist/test_ProxyProtocol.py b/regression-tests.dnsdist/test_ProxyProtocol.py index 744d6a7c79e2..ee730eacb3dc 100644 --- a/regression-tests.dnsdist/test_ProxyProtocol.py +++ b/regression-tests.dnsdist/test_ProxyProtocol.py @@ -4,6 +4,7 @@ import dns import selectors import socket +import ssl import struct import sys import threading @@ -144,16 +145,21 @@ def ProxyProtocolTCPResponder(port, fromQueue, toQueue): backgroundThreads = {} -def MockTCPReverseProxyAddingProxyProtocol(listeningPort, forwardingPort): +def MockTCPReverseProxyAddingProxyProtocol(listeningPort, forwardingPort, serverCtx=None, ca=None, sni=None): # this responder accepts TCP connections on the listening port, # and relay the raw content to a second TCP connection to the # forwarding port, after adding a Proxy Protocol v2 payload # containing the initial source IP and port, destination IP # and port. backgroundThreads[threading.get_native_id()] = True + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) + + if serverCtx is not None: + sock = serverCtx.wrap_socket(sock, server_side=True) + try: sock.bind(("127.0.0.1", listeningPort)) except socket.error as e: @@ -161,6 +167,7 @@ def MockTCPReverseProxyAddingProxyProtocol(listeningPort, forwardingPort): sys.exit(1) sock.settimeout(0.5) sock.listen(100) + while True: try: (incoming, _) = sock.accept() @@ -177,6 +184,15 @@ def MockTCPReverseProxyAddingProxyProtocol(listeningPort, forwardingPort): outgoing = socket.socket(socket.AF_INET, socket.SOCK_STREAM) outgoing.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) outgoing.settimeout(2.0) + if sni: + if hasattr(ssl, 'create_default_context'): + sslctx = ssl.create_default_context(cafile=ca) + if hasattr(sslctx, 'set_alpn_protocols'): + sslctx.set_alpn_protocols(['h2']) + outgoing = sslctx.wrap_socket(outgoing, server_hostname=sni) + else: + outgoing = ssl.wrap_socket(outgoing, ca_certs=ca, cert_reqs=ssl.CERT_REQUIRED) + outgoing.connect(('127.0.0.1', forwardingPort)) outgoing.send(payload) @@ -473,7 +489,8 @@ class TestProxyProtocolIncoming(ProxyProtocolTest): """ _config_template = """ - addDOHLocal("127.0.0.1:%s", "%s", "%s", {"/"}, {library='nghttp2', proxyProtocolOutsideTLS=true}) + addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library='nghttp2', proxyProtocolOutsideTLS=true}) + addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library='nghttp2', proxyProtocolOutsideTLS=false}) setProxyProtocolACL( { "127.0.0.1/32" } ) newServer{address="127.0.0.1:%d", useProxyProtocol=true} @@ -514,9 +531,9 @@ class TestProxyProtocolIncoming(ProxyProtocolTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPort = 8443 - _dohBaseURL = ("https://%s:%d/" % (_serverName, _dohServerPort)) - _config_params = ['_dohServerPort', '_serverCert', '_serverKey', '_proxyResponderPort'] + _dohServerPPOutsidePort = 8443 + _dohServerPPInsidePort = 9443 + _config_params = ['_dohServerPPOutsidePort', '_serverCert', '_serverKey', '_dohServerPPInsidePort', '_serverCert', '_serverKey', '_proxyResponderPort'] def testNoHeader(self): """ @@ -740,11 +757,11 @@ def testProxyTCPSeveralQueriesOverConnection(self): self.assertEqual(receivedResponse, response) self.checkMessageProxyProtocol(receivedProxyPayload, srcAddr, destAddr, True, [ [0, b'foo'], [1, b'dnsdist'], [ 2, b'foo'], [3, b'proxy'], [ 42, b'bar'], [255, b'proxy-protocol'] ], True, srcPort, destPort) - def testProxyDoHSeveralQueriesOverConnection(self): + def testProxyDoHSeveralQueriesOverConnectionPPOutside(self): """ - Incoming Proxy Protocol: Several queries over the same connection (DoH) + Incoming Proxy Protocol: Several queries over the same connection (DoH, PP outside TLS) """ - name = 'several-queries.proxy-protocol-incoming.tests.powerdns.com.' + name = 'several-queries.doh-outside.proxy-protocol-incoming.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') response = dns.message.make_response(query) @@ -753,10 +770,63 @@ def testProxyDoHSeveralQueriesOverConnection(self): wire = query.to_wire() reverseProxyPort = 13053 - reverseProxy = threading.Thread(name='Mock Proxy Protocol Reverse Proxy', target=MockTCPReverseProxyAddingProxyProtocol, args=[reverseProxyPort, self._dohServerPort]) + reverseProxy = threading.Thread(name='Mock Proxy Protocol Reverse Proxy', target=MockTCPReverseProxyAddingProxyProtocol, args=[reverseProxyPort, self._dohServerPPOutsidePort]) + reverseProxy.start() + + receivedResponse = None + conn = self.openDOHConnection(reverseProxyPort, self._caCert, timeout=2.0) + + reverseProxyBaseURL = ("https://%s:%d/" % (self._serverName, reverseProxyPort)) + (receivedQuery, receivedResponse) = self.sendDOHQuery(reverseProxyPort, self._serverName, reverseProxyBaseURL, query, response=response, caFile=self._caCert, useQueue=True, conn=conn) + (receivedProxyPayload, receivedDNSData) = fromProxyQueue.get(True, 2.0) + self.assertTrue(receivedProxyPayload) + self.assertTrue(receivedDNSData) + self.assertTrue(receivedResponse) + + receivedQuery = dns.message.from_wire(receivedDNSData) + receivedQuery.id = query.id + receivedResponse.id = response.id + self.assertEqual(receivedQuery, query) + self.assertEqual(receivedResponse, response) + self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.1', '127.0.0.1', True, [ [0, b'foo'], [1, b'dnsdist'], [ 2, b'foo'], [3, b'proxy'], [ 42, b'bar'], [255, b'proxy-protocol'] ], v6=False, sourcePort=None, destinationPort=reverseProxyPort) + + for idx in range(5): + receivedResponse = None + toProxyQueue.put(response, True, 2.0) + (receivedQuery, receivedResponse) = self.sendDOHQuery(reverseProxyPort, self._serverName, reverseProxyBaseURL, query, response=response, caFile=self._caCert, useQueue=True, conn=conn) + (receivedProxyPayload, receivedDNSData) = fromProxyQueue.get(True, 2.0) + self.assertTrue(receivedProxyPayload) + self.assertTrue(receivedDNSData) + self.assertTrue(receivedResponse) + + receivedQuery = dns.message.from_wire(receivedDNSData) + receivedQuery.id = query.id + receivedResponse.id = response.id + self.assertEqual(receivedQuery, query) + self.assertEqual(receivedResponse, response) + self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.1', '127.0.0.1', True, [ [0, b'foo'], [1, b'dnsdist'], [ 2, b'foo'], [3, b'proxy'], [ 42, b'bar'], [255, b'proxy-protocol'] ], v6=False, sourcePort=None, destinationPort=reverseProxyPort) + + def testProxyDoHSeveralQueriesOverConnectionPPInside(self): + """ + Incoming Proxy Protocol: Several queries over the same connection (DoH, PP inside TLS) + """ + name = 'several-queries.doh-inside.proxy-protocol-incoming.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + + toProxyQueue.put(response, True, 2.0) + + wire = query.to_wire() + + reverseProxyPort = 14053 + tlsContext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) + tlsContext.load_cert_chain(self._serverCert, self._serverKey) + tlsContext.set_alpn_protocols(['h2']) + reverseProxy = threading.Thread(name='Mock Proxy Protocol Reverse Proxy', target=MockTCPReverseProxyAddingProxyProtocol, args=[reverseProxyPort, self._dohServerPPInsidePort, tlsContext, self._caCert, self._serverName]) reverseProxy.start() receivedResponse = None + time.sleep(1) conn = self.openDOHConnection(reverseProxyPort, self._caCert, timeout=2.0) reverseProxyBaseURL = ("https://%s:%d/" % (self._serverName, reverseProxyPort)) @@ -786,8 +856,6 @@ def testProxyDoHSeveralQueriesOverConnection(self): receivedQuery.id = query.id receivedResponse.id = response.id self.assertEqual(receivedQuery, query) - print(receivedResponse) - print(response) self.assertEqual(receivedResponse, response) self.checkMessageProxyProtocol(receivedProxyPayload, '127.0.0.1', '127.0.0.1', True, [ [0, b'foo'], [1, b'dnsdist'], [ 2, b'foo'], [3, b'proxy'], [ 42, b'bar'], [255, b'proxy-protocol'] ], v6=False, sourcePort=None, destinationPort=reverseProxyPort) From 0ee9fa391fbed622c56fd4d6e5ac3a03d21edf72 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 18 Jul 2023 14:37:16 +0200 Subject: [PATCH 637/909] dnsdist: Give the mock Proxy Protocol proxy some time to start --- regression-tests.dnsdist/test_ProxyProtocol.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/regression-tests.dnsdist/test_ProxyProtocol.py b/regression-tests.dnsdist/test_ProxyProtocol.py index ee730eacb3dc..dd4ca4fbefb9 100644 --- a/regression-tests.dnsdist/test_ProxyProtocol.py +++ b/regression-tests.dnsdist/test_ProxyProtocol.py @@ -531,8 +531,8 @@ class TestProxyProtocolIncoming(ProxyProtocolTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _dohServerPPOutsidePort = 8443 - _dohServerPPInsidePort = 9443 + _dohServerPPOutsidePort = pickAvailablePort() + _dohServerPPInsidePort = pickAvailablePort() _config_params = ['_dohServerPPOutsidePort', '_serverCert', '_serverKey', '_dohServerPPInsidePort', '_serverCert', '_serverKey', '_proxyResponderPort'] def testNoHeader(self): @@ -769,9 +769,10 @@ def testProxyDoHSeveralQueriesOverConnectionPPOutside(self): wire = query.to_wire() - reverseProxyPort = 13053 + reverseProxyPort = pickAvailablePort() reverseProxy = threading.Thread(name='Mock Proxy Protocol Reverse Proxy', target=MockTCPReverseProxyAddingProxyProtocol, args=[reverseProxyPort, self._dohServerPPOutsidePort]) reverseProxy.start() + time.sleep(1) receivedResponse = None conn = self.openDOHConnection(reverseProxyPort, self._caCert, timeout=2.0) @@ -818,7 +819,7 @@ def testProxyDoHSeveralQueriesOverConnectionPPInside(self): wire = query.to_wire() - reverseProxyPort = 14053 + reverseProxyPort = pickAvailablePort() tlsContext = ssl.SSLContext(ssl.PROTOCOL_TLS_SERVER) tlsContext.load_cert_chain(self._serverCert, self._serverKey) tlsContext.set_alpn_protocols(['h2']) From 383f129049c7c04e38dcbcf4f3f3fd6d357ea211 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 13 Jul 2023 17:23:00 +0200 Subject: [PATCH 638/909] dnsdist: Document the new options to add{DOH,TLS}Local --- pdns/dnsdistdist/docs/reference/config.rst | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 36e147dcc428..8dfa212fae88 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -122,6 +122,9 @@ Listen Sockets ``certFile`` now accepts a TLSCertificate object or a list of such objects (see :func:`newTLSCertificate`) ``additionalAddresses``, ``ignoreTLSConfigurationErrors`` and ``keepIncomingHeaders`` options added. + .. versionchanged:: 1.9.0 + ``library``, ``readAhead`` and ``proxyProtocolOutsideTLS`` options added. + Listen on the specified address and TCP port for incoming DNS over HTTPS connections, presenting the specified X.509 certificate. If no certificate (or key) files are specified, listen for incoming DNS over HTTP connections instead. @@ -164,6 +167,9 @@ Listen Sockets * ``keepIncomingHeaders``: bool - Whether to retain the incoming headers in memory, to be able to use :func:`HTTPHeaderRule` or :meth:`DNSQuestion.getHTTPHeaders`. Default is false. Before 1.8.0 the headers were always kept in-memory. * ``additionalAddresses``: list - List of additional addresses (with port) to listen on. Using this option instead of creating a new frontend for each address avoids the creation of new thread and Frontend objects, reducing the memory usage. The drawback is that there will be a single set of metrics for all addresses. * ``ignoreTLSConfigurationErrors=false``: bool - Ignore TLS configuration errors (such as invalid certificate path) and just issue a warning instead of aborting the whole process + * ``library``: str - Which underlying HTTP2 library should be used, either h2o or nghttp2. Until 1.9.0 only h2o was available, but the use of this library is now deprecated as it is no longer maintained. nghttp2 is the new default since 1.9.0. + * ``readAhead``: bool - When the TLS provider is set to OpenSSL, whether we tell the library to read as many input bytes as possible, which leads to better performance by reducing the number of syscalls. Default is true. + * ``proxyProtocolOutsideTLS``: bool - When the use of incoming proxy protocol is enabled, whether the payload is prepended after the start of the TLS session (so inside, meaning it is protected by the TLS layer providing encryption and authentication) or not (outside, meaning it is in clear-text). Default is false which means inside. Note that most third-party software like HAproxy expect the proxy protocol payload to be outside, in clear-text. .. function:: addTLSLocal(address, certFile(s), keyFile(s) [, options]) @@ -178,6 +184,8 @@ Listen Sockets .. versionchanged:: 1.8.0 ``certFile`` now accepts a TLSCertificate object or a list of such objects (see :func:`newTLSCertificate`). ``additionalAddresses``, ``ignoreTLSConfigurationErrors`` and ``ktls`` options added. + .. versionchanged:: 1.9.0 + ``readAhead`` and ``proxyProtocolOutsideTLS`` options added. Listen on the specified address and TCP port for incoming DNS over TLS connections, presenting the specified X.509 certificate. @@ -215,6 +223,8 @@ Listen Sockets * ``additionalAddresses``: list - List of additional addresses (with port) to listen on. Using this option instead of creating a new frontend for each address avoids the creation of new thread and Frontend objects, reducing the memory usage. The drawback is that there will be a single set of metrics for all addresses. * ``ignoreTLSConfigurationErrors=false``: bool - Ignore TLS configuration errors (such as invalid certificate path) and just issue a warning instead of aborting the whole process * ``ktls=false``: bool - Whether to enable the experimental kernel TLS support on Linux, if both the kernel and the OpenSSL library support it. Default is false. + * ``readAhead``: bool - When the TLS provider is set to OpenSSL, whether we tell the library to read as many input bytes as possible, which leads to better performance by reducing the number of syscalls. Default is true. + * ``proxyProtocolOutsideTLS``: bool - When the use of incoming proxy protocol is enabled, whether the payload is prepended after the start of the TLS session (so inside, meaning it is protected by the TLS layer providing encryption and authentication) or not (outside, meaning it is in clear-text). Default is false which means inside. Note that most third-party software like HAproxy expect the proxy protocol payload to be outside, in clear-text. .. function:: setLocal(address[, options]) From 65454336750ae3053318ab2762007bd11019c7ad Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 13 Jul 2023 17:23:22 +0200 Subject: [PATCH 639/909] dnsdist: Enable readAhead by default for TLS and DOH frontends --- pdns/libssl.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/libssl.hh b/pdns/libssl.hh index feb90cbea3bd..327fed32a677 100644 --- a/pdns/libssl.hh +++ b/pdns/libssl.hh @@ -54,7 +54,7 @@ public: /* enable kTLS mode, if supported */ bool d_ktls{false}; /* set read ahead mode, if supported */ - bool d_readAhead{false}; + bool d_readAhead{true}; }; struct TLSErrorCounters From 920894c0960283508be51c641250c6c9d7c5a1da Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 17 Jul 2023 16:58:25 +0200 Subject: [PATCH 640/909] dnsdist: Fix incoming DoT when OpenSSL's read-ahead mode is enabled --- pdns/dnsdist-tcp.cc | 23 ++++++++++++++++------ pdns/dnsdistdist/dnsdist-tcp-downstream.cc | 12 +++++++---- pdns/dnsdistdist/dnsdist-tcp-upstream.hh | 2 +- pdns/tcpiohandler.cc | 1 + 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 2f78c22dad7a..c55574ef27d4 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -372,7 +372,7 @@ void IncomingTCPConnectionState::terminateClientConnection() } } -void IncomingTCPConnectionState::queueResponse(std::shared_ptr& state, const struct timeval& now, TCPResponse&& response) +void IncomingTCPConnectionState::queueResponse(std::shared_ptr& state, const struct timeval& now, TCPResponse&& response, bool fromBackend) { // queue response state->d_queuedResponses.emplace_back(std::move(response)); @@ -400,6 +400,17 @@ void IncomingTCPConnectionState::queueResponse(std::shared_ptractive()) { updateIO(state, iostate, now); + // if we have not finished reading every available byte, we _need_ to do an actual read + // attempt before waiting for the socket to become readable again, because if there is + // buffered data available the socket might never become readable again. + // This is true as soon as we deal with TLS because TLS records are processed one by + // one and might not match what we see at the application layer, so data might already + // be available in the TLS library's buffers. This is especially true when OpenSSL's + // read-ahead mode is enabled because then it buffers even more than one SSL record + // for performance reasons. + if (fromBackend && !state->d_lastIOBlocked) { + state->handleIO(); + } } } } @@ -522,7 +533,7 @@ void IncomingTCPConnectionState::handleResponse(const struct timeval& now, TCPRe ++dnsdist::metrics::g_stats.responses; ++state->d_ci.cs->responses; - queueResponse(state, now, std::move(response)); + queueResponse(state, now, std::move(response), true); } struct TCPCrossProtocolResponse @@ -651,7 +662,7 @@ IncomingTCPConnectionState::QueryProcessingResult IncomingTCPConnectionState::ha TCPResponse response; d_state = State::idle; ++d_currentQueriesCount; - queueResponse(state, now, std::move(response)); + queueResponse(state, now, std::move(response), false); return QueryProcessingResult::SelfAnswered; } @@ -670,7 +681,7 @@ IncomingTCPConnectionState::QueryProcessingResult IncomingTCPConnectionState::ha response.d_buffer = std::move(query); d_state = State::idle; ++d_currentQueriesCount; - queueResponse(state, now, std::move(response)); + queueResponse(state, now, std::move(response), false); return QueryProcessingResult::Empty; } } @@ -751,7 +762,7 @@ IncomingTCPConnectionState::QueryProcessingResult IncomingTCPConnectionState::ha d_state = State::idle; ++d_currentQueriesCount; - queueResponse(state, now, std::move(response)); + queueResponse(state, now, std::move(response), false); return QueryProcessingResult::SelfAnswered; } @@ -1188,7 +1199,7 @@ void IncomingTCPConnectionState::handleXFRResponse(const struct timeval& now, TC } std::shared_ptr state = shared_from_this(); - queueResponse(state, now, std::move(response)); + queueResponse(state, now, std::move(response), true); } void IncomingTCPConnectionState::handleTimeout(std::shared_ptr& state, bool write) diff --git a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc index 89b3a2e5d812..8dc6cc0a99ad 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc +++ b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc @@ -362,7 +362,7 @@ void TCPConnectionToBackend::handleIO(std::shared_ptr& c iostate = conn->handleResponse(conn, now); } catch (const std::exception& e) { - vinfolog("Got an exception while handling TCP response from %s (client is %s): %s", conn->d_ds ? conn->d_ds->getName() : "unknown", conn->d_currentQuery.d_query.d_idstate.origRemote.toStringWithPort(), e.what()); + vinfolog("Got an exception while handling TCP response from %s (client is %s): %s", conn->d_ds ? conn->d_ds->getNameWithAddr() : "unknown", conn->d_currentQuery.d_query.d_idstate.origRemote.toStringWithPort(), e.what()); ioGuard.release(); conn->release(); return; @@ -726,7 +726,14 @@ IOState TCPConnectionToBackend::handleResponse(std::shared_ptractive()) { DEBUGLOG("passing response to client connection for "<& state, IOState newState, const struct timeval& now); - static void queueResponse(std::shared_ptr& state, const struct timeval& now, TCPResponse&& response); + static void queueResponse(std::shared_ptr& state, const struct timeval& now, TCPResponse&& response, bool fromBackend); static void handleTimeout(std::shared_ptr& state, bool write); virtual void handleIO(); diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index 0b960134971b..6be1eea47680 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -435,6 +435,7 @@ class OpenSSLTLSConnection: public TLSConnection bool hasBufferedData() const override { if (d_conn) { + /* this is broken when read-ahead is set, unfortunately */ return SSL_pending(d_conn.get()) > 0; } From c2410e5997b840e8654b96ac40b83999f13e3ab6 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 17 Jul 2023 16:59:48 +0200 Subject: [PATCH 641/909] dnsdist: Remove TCPIOHandler::hasBufferedData() since we cannot rely on it --- pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc | 5 ----- pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc | 5 ----- pdns/dnsdistdist/test-dnsdisttcp_cc.cc | 5 ----- pdns/tcpiohandler.cc | 19 ------------------- pdns/tcpiohandler.hh | 9 --------- 5 files changed, 43 deletions(-) diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc index 48d2f6eeeb36..e3e9dedd9eda 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc @@ -362,11 +362,6 @@ class MockupTLSConnection : public TLSConnection BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::closeClient); } - bool hasBufferedData() const override - { - return false; - } - bool isUsable() const override { return true; diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc index 3e5bb1631221..a7afea2063e1 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc @@ -405,11 +405,6 @@ class MockupTLSConnection : public TLSConnection BOOST_REQUIRE_EQUAL(step.request, !d_client ? ExpectedStep::ExpectedRequest::closeClient : ExpectedStep::ExpectedRequest::closeBackend); } - bool hasBufferedData() const override - { - return false; - } - bool isUsable() const override { return true; diff --git a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc index dedfd97d2b33..296cd44cb62e 100644 --- a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc +++ b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc @@ -208,11 +208,6 @@ class MockupTLSConnection : public TLSConnection BOOST_REQUIRE_EQUAL(step.request, !d_client ? ExpectedStep::ExpectedRequest::closeClient : ExpectedStep::ExpectedRequest::closeBackend); } - bool hasBufferedData() const override - { - return false; - } - bool isUsable() const override { return true; diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index 6be1eea47680..db12a7f4b959 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -432,16 +432,6 @@ class OpenSSLTLSConnection: public TLSConnection return got; } - bool hasBufferedData() const override - { - if (d_conn) { - /* this is broken when read-ahead is set, unfortunately */ - return SSL_pending(d_conn.get()) > 0; - } - - return false; - } - bool isUsable() const override { if (!d_conn) { @@ -1445,15 +1435,6 @@ class GnuTLSConnection: public TLSConnection return got; } - bool hasBufferedData() const override - { - if (d_conn) { - return gnutls_record_check_pending(d_conn.get()) > 0; - } - - return false; - } - bool isUsable() const override { if (!d_conn) { diff --git a/pdns/tcpiohandler.hh b/pdns/tcpiohandler.hh index 3cf674ca1656..3f68828163de 100644 --- a/pdns/tcpiohandler.hh +++ b/pdns/tcpiohandler.hh @@ -32,7 +32,6 @@ public: virtual size_t write(const void* buffer, size_t bufferSize, const struct timeval& writeTimeout) = 0; virtual IOState tryWrite(const PacketBuffer& buffer, size_t& pos, size_t toWrite) = 0; virtual IOState tryRead(PacketBuffer& buffer, size_t& pos, size_t toRead, bool allowIncomplete=false) = 0; - virtual bool hasBufferedData() const = 0; virtual std::string getServerNameIndication() const = 0; virtual std::vector getNextProtocol() const = 0; virtual LibsslTLSVersion getTLSVersion() const = 0; @@ -476,14 +475,6 @@ public: return writen2WithTimeout(d_socket, buffer, bufferSize, writeTimeout); } - bool hasBufferedData() const - { - if (d_conn) { - return d_conn->hasBufferedData(); - } - return false; - } - std::string getServerNameIndication() const { if (d_conn) { From cc4c7911e862cc768e5f72c81899eb33ae32ba3e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 20 Jul 2023 10:07:38 +0200 Subject: [PATCH 642/909] dnsdist: Better logging of backend server identity --- pdns/dnsdistdist/dnsdist-tcp-downstream.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc index 8dc6cc0a99ad..35a2befffbae 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-downstream.cc +++ b/pdns/dnsdistdist/dnsdist-tcp-downstream.cc @@ -118,7 +118,7 @@ bool ConnectionToBackend::reconnect() return true; } catch (const std::runtime_error& e) { - vinfolog("Connection to downstream server %s failed: %s", d_ds->getName(), e.what()); + vinfolog("Connection to downstream server %s failed: %s", d_ds->getNameWithAddr(), e.what()); d_downstreamFailures++; if (d_downstreamFailures >= d_ds->d_config.d_retries) { throw; @@ -269,7 +269,7 @@ IOState TCPConnectionToBackend::queueNextQuery(std::shared_ptr& conn, const struct timeval& now) { - DEBUGLOG("sending query to backend "<getDS()->getName()<<" over FD "<d_handler->getDescriptor()); + DEBUGLOG("sending query to backend "<getDS()->getNameWithAddr()<<" over FD "<d_handler->getDescriptor()); IOState state = conn->d_handler->tryWrite(conn->d_currentQuery.d_query.d_buffer, conn->d_currentPos, conn->d_currentQuery.d_query.d_buffer.size()); @@ -555,16 +555,16 @@ void TCPConnectionToBackend::handleTimeout(const struct timeval& now, bool write if (write) { if (isFresh() && d_queries == 0) { ++d_ds->tcpConnectTimeouts; - vinfolog("Timeout while connecting to TCP backend %s", d_ds->getName()); + vinfolog("Timeout while connecting to TCP backend %s", d_ds->getNameWithAddr()); } else { ++d_ds->tcpWriteTimeouts; - vinfolog("Timeout while writing to TCP backend %s", d_ds->getName()); + vinfolog("Timeout while writing to TCP backend %s", d_ds->getNameWithAddr()); } } else { ++d_ds->tcpReadTimeouts; - vinfolog("Timeout while reading from TCP backend %s", d_ds->getName()); + vinfolog("Timeout while reading from TCP backend %s", d_ds->getNameWithAddr()); } try { From 5ff1d0052bf301be5d76f3be89034d267a22e385 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 7 Jul 2023 17:16:02 +0200 Subject: [PATCH 643/909] dnsdist: Remove unused function in outgoing DoH --- pdns/dnsdistdist/dnsdist-nghttp2.cc | 32 ----------------------------- 1 file changed, 32 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 9b774f0ed4c1..0aad8712081e 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -94,7 +94,6 @@ class DoHConnectionToBackend : public ConnectionToBackend uint16_t d_responseCode{0}; bool d_finished{false}; }; - void addToIOState(IOState state, FDMultiplexer::callbackfunc_t callback); void updateIO(IOState newState, FDMultiplexer::callbackfunc_t callback, bool noTTD = false); void watchForRemoteHostClosingConnection(); void handleResponse(PendingRequest&& request); @@ -512,37 +511,6 @@ void DoHConnectionToBackend::watchForRemoteHostClosingConnection() } } -void DoHConnectionToBackend::addToIOState(IOState state, FDMultiplexer::callbackfunc_t callback) -{ - struct timeval now - { - .tv_sec = 0, .tv_usec = 0 - }; - - gettimeofday(&now, nullptr); - boost::optional ttd{boost::none}; - if (state == IOState::NeedRead) { - ttd = getBackendReadTTD(now); - } - else if (isFresh() && d_firstWrite == 0) { - /* first write just after the non-blocking connect */ - ttd = getBackendConnectTTD(now); - } - else { - ttd = getBackendWriteTTD(now); - } - - auto shared = std::dynamic_pointer_cast(shared_from_this()); - if (shared) { - if (state == IOState::NeedRead) { - d_ioState->add(state, callback, shared, ttd); - } - else if (state == IOState::NeedWrite) { - d_ioState->add(state, callback, shared, ttd); - } - } -} - ssize_t DoHConnectionToBackend::send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data) { DoHConnectionToBackend* conn = reinterpret_cast(user_data); From 6e38689a8a2ce17d89a2c800c3e6dea892694afe Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 21 Jul 2023 17:53:34 +0200 Subject: [PATCH 644/909] dnsdist: Document the h2o -> nghttp2 upgrade path --- pdns/dnsdistdist/docs/guides/dns-over-https.rst | 12 +++++++++++- pdns/dnsdistdist/docs/install.rst | 2 +- pdns/dnsdistdist/docs/reference/config.rst | 2 +- pdns/dnsdistdist/docs/rules-actions.rst | 3 ++- pdns/dnsdistdist/docs/upgrade_guide.rst | 10 ++++++++++ 5 files changed, 25 insertions(+), 4 deletions(-) diff --git a/pdns/dnsdistdist/docs/guides/dns-over-https.rst b/pdns/dnsdistdist/docs/guides/dns-over-https.rst index 5df4d7f05352..1367a99c7cd2 100644 --- a/pdns/dnsdistdist/docs/guides/dns-over-https.rst +++ b/pdns/dnsdistdist/docs/guides/dns-over-https.rst @@ -3,7 +3,7 @@ DNS-over-HTTPS (DoH) :program:`dnsdist` supports DNS-over-HTTPS (DoH, standardized in RFC 8484) for incoming queries since 1.4.0, and for outgoing queries since 1.7.0. To see if the installation supports this, run ``dnsdist --version``. -If the output shows ``dns-over-https(DOH)``, incoming DNS-over-HTTPS is supported. If ``outgoing-dns-over-https(nghttp2)`` shows up then outgoing DNS-over-HTTPS is supported. +If the output shows ``dns-over-https(DOH)`` (``dns-over-https(h2o nghttp2)``, ``dns-over-https(h2o)`` or ``dns-over-https(nghttp2)`` since 1.9.0) , incoming DNS-over-HTTPS is supported. If ``outgoing-dns-over-https(nghttp2)`` shows up then outgoing DNS-over-HTTPS is supported. Incoming -------- @@ -54,6 +54,16 @@ To let dnsdist listen for DoH queries over HTTP on localhost at port 8053 add on addDOHLocal("127.0.0.1:8053") addDOHLocal("127.0.0.1:8053", nil, nil, "/", { reusePort=true }) +HTTP/1 support +^^^^^^^^^^^^^^ + +dnsdist initially relied on the ``h2o`` library to support incoming DNS over HTTPS. Since 1.9.0, ``h2o`` has been deprecated and ``nghttp2`` is the +preferred library for incoming DoH support, because ``h2o`` has unfortunately really never been maintained in a way that is suitable for use as a library +(see https://github.com/h2o/h2o/issues/3230). While we took great care to make the migration as painless as possible, ``h2o`` supported HTTP/1 while ``nghttp2`` +does not. This is not an issue for actual DNS over HTTPS clients that support HTTP/2, but might be one in setups running dnsdist behind a reverse-proxy that +does not support HTTP/1, like nginx. We do not plan on implementing HTTP/1, and recommend using HTTP/2 between the reverse-proxy and dnsdist for performance reasons. +For nginx in particular, a possible work-around is to use the `gprc_pass `_ directive as suggested in their `bugtracker `_. + Internal design ^^^^^^^^^^^^^^^ diff --git a/pdns/dnsdistdist/docs/install.rst b/pdns/dnsdistdist/docs/install.rst index 54194b729e84..9d24c03dcbef 100644 --- a/pdns/dnsdistdist/docs/install.rst +++ b/pdns/dnsdistdist/docs/install.rst @@ -50,7 +50,7 @@ dnsdist depends on the following libraries: * `Editline (libedit) `_ * `libfstrm `_ (optional, dnstap support) * `GnuTLS `_ (optional, DoT and outgoing DoH support) -* `libh2o `_ (optional, incoming DoH support) +* `libh2o `_ (optional, incoming DoH support, deprecated in 1.9.0 in favor of ``nghttp2``) * `libcap `_ (optional, capabilities support) * `libsodium `_ (optional, DNSCrypt and console encryption support) * `LMDB `_ (optional, LMDB support) diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 8dfa212fae88..1b1743664654 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -144,7 +144,7 @@ Listen Sockets * ``idleTimeout=30``: int - Set the idle timeout, in seconds. * ``ciphers``: str - The TLS ciphers to use, in OpenSSL format. Ciphers for TLS 1.3 must be specified via ``ciphersTLS13``. * ``ciphersTLS13``: str - The TLS ciphers to use for TLS 1.3, in OpenSSL format. - * ``serverTokens``: str - The content of the Server: HTTP header returned by dnsdist. The default is "h2o/dnsdist". + * ``serverTokens``: str - The content of the Server: HTTP header returned by dnsdist. The default is "h2o/dnsdist" when ``h2o`` is used, "nghttp2-/dnsdist" when ``nghttp2`` is. * ``customResponseHeaders={}``: table - Set custom HTTP header(s) returned by dnsdist. * ``ocspResponses``: list - List of files containing OCSP responses, in the same order than the certificates and keys, that will be used to provide OCSP stapling responses. * ``minTLSVersion``: str - Minimum version of the TLS protocol to support. Possible values are 'tls1.0', 'tls1.1', 'tls1.2' and 'tls1.3'. Default is to require at least TLS 1.0. diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index 41f531c5e591..2dae14279294 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -831,7 +831,8 @@ These ``DNSRule``\ s be one of the following items: sense for DoT or DoH, and for that last one matching on the HTTP Host header using :func:`HTTPHeaderRule` might provide more consistent results. As of the version 2.3.0-beta of h2o, it is unfortunately not possible to extract the SNI value from DoH - connections, and it is therefore necessary to use the HTTP Host header until version 2.3.0 is released. + connections, and it is therefore necessary to use the HTTP Host header until version 2.3.0 is released, + or ``nghttp2`` is used for incoming DoH instead (1.9.0+). :param str name: The exact SNI name to match. diff --git a/pdns/dnsdistdist/docs/upgrade_guide.rst b/pdns/dnsdistdist/docs/upgrade_guide.rst index d089a9d0f7c8..7f58f3270ee0 100644 --- a/pdns/dnsdistdist/docs/upgrade_guide.rst +++ b/pdns/dnsdistdist/docs/upgrade_guide.rst @@ -1,6 +1,16 @@ Upgrade Guide ============= +1.8.x to 1.9.0 +-------------- + +dnsdist now supports a new library for dealing with incoming DNS over HTTPS queries: ``nghttp2``. The previously used library, ``h2o``, can still be used +but is now deprecated and will be removed in the future, as it is unfortunately no longer maintained in a way that is suitable for use as a library +(see https://github.com/h2o/h2o/issues/3230). See the ``library`` parameter on the :func:`addDOHLocal` directive for more information on how to select +the library used when dnsdist is built with support for both ``h2o`` and ``nghttp2``. The default is now ``nghttp2`` whenever possible. +Note that ``nghttp2`` only supports HTTP/2, and not HTTP/1, while ``h2o`` supported both. This is not an issue for actual DNS over HTTPS clients that +support HTTP/2, but might be one in setups running dnsdist behind a reverse-proxy that does not support HTTP/1. See :doc:`guides/dns-over-https` for some work-arounds. + 1.7.x to 1.8.0 -------------- From 24edf3f5b9d2ae3a21b74ace6594ce9910a3837e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 21 Jul 2023 19:19:15 +0200 Subject: [PATCH 645/909] dnsdist: Fix spelling issues --- .github/actions/spell-check/expect.txt | 1 + pdns/dnsdistdist/docs/guides/dns-over-https.rst | 2 +- pdns/dnsdistdist/docs/upgrade_guide.rst | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index b451e038dc8e..052d5d20efbe 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -511,6 +511,7 @@ gpgsqlbackend gprof gpsqlbackend grepq +grpc GSQ gsql gsqlite diff --git a/pdns/dnsdistdist/docs/guides/dns-over-https.rst b/pdns/dnsdistdist/docs/guides/dns-over-https.rst index 1367a99c7cd2..226dbc49fad6 100644 --- a/pdns/dnsdistdist/docs/guides/dns-over-https.rst +++ b/pdns/dnsdistdist/docs/guides/dns-over-https.rst @@ -62,7 +62,7 @@ preferred library for incoming DoH support, because ``h2o`` has unfortunately re (see https://github.com/h2o/h2o/issues/3230). While we took great care to make the migration as painless as possible, ``h2o`` supported HTTP/1 while ``nghttp2`` does not. This is not an issue for actual DNS over HTTPS clients that support HTTP/2, but might be one in setups running dnsdist behind a reverse-proxy that does not support HTTP/1, like nginx. We do not plan on implementing HTTP/1, and recommend using HTTP/2 between the reverse-proxy and dnsdist for performance reasons. -For nginx in particular, a possible work-around is to use the `gprc_pass `_ directive as suggested in their `bugtracker `_. +For nginx in particular, a possible work-around is to use the `grpc_pass `_ directive as suggested in their `bug tracker `_. Internal design ^^^^^^^^^^^^^^^ diff --git a/pdns/dnsdistdist/docs/upgrade_guide.rst b/pdns/dnsdistdist/docs/upgrade_guide.rst index 7f58f3270ee0..575dd56faeaa 100644 --- a/pdns/dnsdistdist/docs/upgrade_guide.rst +++ b/pdns/dnsdistdist/docs/upgrade_guide.rst @@ -9,7 +9,7 @@ but is now deprecated and will be removed in the future, as it is unfortunately (see https://github.com/h2o/h2o/issues/3230). See the ``library`` parameter on the :func:`addDOHLocal` directive for more information on how to select the library used when dnsdist is built with support for both ``h2o`` and ``nghttp2``. The default is now ``nghttp2`` whenever possible. Note that ``nghttp2`` only supports HTTP/2, and not HTTP/1, while ``h2o`` supported both. This is not an issue for actual DNS over HTTPS clients that -support HTTP/2, but might be one in setups running dnsdist behind a reverse-proxy that does not support HTTP/1. See :doc:`guides/dns-over-https` for some work-arounds. +support HTTP/2, but might be one in setups running dnsdist behind a reverse-proxy that does not support HTTP/1. See :doc:`guides/dns-over-https` for some work-around. 1.7.x to 1.8.0 -------------- From 061405361016e93fea54818d97d7a0bf6776bafe Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 11:26:30 +0200 Subject: [PATCH 646/909] dnsdist: Delint test-dnsdistnghttp2-in_cc.cc and dnsdist-nghttp2.cc --- pdns/dnsdistdist/dnsdist-nghttp2.cc | 2 +- pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc | 111 ++++++++++-------- 2 files changed, 63 insertions(+), 50 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 0aad8712081e..352e864decd5 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -301,7 +301,7 @@ void DoHConnectionToBackend::queueQuery(std::shared_ptr& sender, data_provider.source.ptr = this; data_provider.read_callback = [](nghttp2_session* session, int32_t stream_id, uint8_t* buf, size_t length, uint32_t* data_flags, nghttp2_data_source* source, void* user_data) -> ssize_t { - auto conn = static_cast(user_data); + auto* conn = static_cast(user_data); auto& request = conn->d_currentStreams.at(stream_id); size_t toCopy = 0; if (request.d_queryPos < request.d_query.d_buffer.size()) { diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc index e3e9dedd9eda..741ec74e699e 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc @@ -32,7 +32,7 @@ #ifdef HAVE_NGHTTP2 #include -extern std::function& selectedBackend)> s_processQuery; +extern std::function& selectedBackend)> s_processQuery; BOOST_AUTO_TEST_SUITE(test_dnsdistnghttp2_in_cc) @@ -47,8 +47,8 @@ struct ExpectedStep closeClient, }; - ExpectedStep(ExpectedRequest r, IOState n, size_t b = 0, std::function fn = nullptr) : - cb(fn), request(r), nextState(n), bytes(b) + ExpectedStep(ExpectedRequest req, IOState next, size_t bytes_ = 0, std::function func = nullptr) : + cb(std::move(func)), request(req), nextState(next), bytes(bytes_) { } @@ -73,13 +73,13 @@ static std::map s_connectionContexts; static std::map> s_connectionBuffers; static uint64_t s_connectionID{0}; -std::ostream& operator<<(std::ostream& os, const ExpectedStep::ExpectedRequest d); +std::ostream& operator<<(std::ostream& outs, ExpectedStep::ExpectedRequest step); -std::ostream& operator<<(std::ostream& os, const ExpectedStep::ExpectedRequest d) +std::ostream& operator<<(std::ostream& outs, ExpectedStep::ExpectedRequest step) { static const std::vector requests = {"handshake with client", "read from client", "write to client", "close connection to client", "connect to the backend", "read from the backend", "write to the backend", "close connection to backend"}; - os << requests.at(static_cast(d)); - return os; + outs << requests.at(static_cast(step)); + return outs; } class DOHConnection @@ -104,18 +104,18 @@ class DOHConnection nghttp2_session_client_new(&sess, callbacks.get(), this); d_session = std::unique_ptr(sess, nghttp2_session_del); - nghttp2_settings_entry iv[] = { + std::array settings{ /* rfc7540 section-8.2.2: "Advertising a SETTINGS_MAX_CONCURRENT_STREAMS value of zero disables server push by preventing the server from creating the necessary streams." */ - {NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0}, - {NGHTTP2_SETTINGS_ENABLE_PUSH, 0}, + nghttp2_settings_entry{NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS, 0}, + nghttp2_settings_entry{NGHTTP2_SETTINGS_ENABLE_PUSH, 0}, /* we might want to make the initial window size configurable, but 16M is a large enough default */ - {NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, 16 * 1024 * 1024}}; + nghttp2_settings_entry{NGHTTP2_SETTINGS_INITIAL_WINDOW_SIZE, 16 * 1024 * 1024}}; /* client 24 bytes magic string will be sent by nghttp2 library */ - auto result = nghttp2_submit_settings(d_session.get(), NGHTTP2_FLAG_NONE, iv, sizeof(iv) / sizeof(*iv)); + auto result = nghttp2_submit_settings(d_session.get(), NGHTTP2_FLAG_NONE, settings.data(), settings.size()); if (result != 0) { throw std::runtime_error("Error submitting settings:" + std::string(nghttp2_strerror(result))); } @@ -154,7 +154,7 @@ class DOHConnection if (pos >= currentQuery.size()) { *data_flags |= NGHTTP2_DATA_FLAG_EOF; } - return toCopy; + return static_cast(toCopy); }; auto newStreamId = nghttp2_submit_request(d_session.get(), nullptr, headers.data(), headers.size(), &data_provider, this); @@ -177,7 +177,7 @@ class DOHConnection uint64_t d_connectionID{0}; size_t d_position{0}; - size_t submitIncoming(const PacketBuffer& data, size_t pos, size_t toWrite) + void submitIncoming(const PacketBuffer& data, size_t pos, size_t toWrite) const { ssize_t readlen = nghttp2_session_mem_recv(d_session.get(), &data.at(pos), toWrite); if (readlen < 0) { @@ -185,36 +185,35 @@ class DOHConnection } /* just in case, see if we have anything to send */ - int rv = nghttp2_session_send(d_session.get()); - if (rv != 0) { - throw("Fatal error while sending: " + std::string(nghttp2_strerror(rv))); + int got = nghttp2_session_send(d_session.get()); + if (got != 0) { + throw("Fatal error while sending: " + std::string(nghttp2_strerror(got))); } - - return readlen; } private: static ssize_t send_callback(nghttp2_session* session, const uint8_t* data, size_t length, int flags, void* user_data) { - DOHConnection* conn = static_cast(user_data); + auto* conn = static_cast(user_data); + //NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API conn->d_clientOutBuffer.insert(conn->d_clientOutBuffer.end(), data, data + length); return static_cast(length); } static int on_frame_recv_callback(nghttp2_session* session, const nghttp2_frame* frame, void* user_data) { - DOHConnection* conn = static_cast(user_data); - if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && frame->hd.flags & NGHTTP2_FLAG_END_STREAM) { + auto* conn = static_cast(user_data); + if ((frame->hd.type == NGHTTP2_HEADERS || frame->hd.type == NGHTTP2_DATA) && (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) != 0) { const auto& response = conn->d_responses.at(frame->hd.stream_id); if (conn->d_responseCodes.at(frame->hd.stream_id) != 200U) { return 0; } BOOST_REQUIRE_GT(response.size(), sizeof(dnsheader)); - const auto* dh = reinterpret_cast(response.data()); - uint16_t id = ntohs(dh->id); + const dnsheader_aligned dnsHeader(response.data()); + uint16_t queryID = ntohs(dnsHeader.get()->id); - const auto& expected = s_connectionContexts.at(conn->d_connectionID).d_responses.at(id); + const auto& expected = s_connectionContexts.at(conn->d_connectionID).d_responses.at(queryID); BOOST_REQUIRE_EQUAL(expected.size(), response.size()); for (size_t idx = 0; idx < response.size(); idx++) { if (expected.at(idx) != response.at(idx)) { @@ -229,22 +228,23 @@ class DOHConnection static int on_data_chunk_recv_callback(nghttp2_session* session, uint8_t flags, int32_t stream_id, const uint8_t* data, size_t len, void* user_data) { - DOHConnection* conn = static_cast(user_data); + auto* conn = static_cast(user_data); auto& response = conn->d_responses[stream_id]; + //NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): nghttp2 API response.insert(response.end(), data, data + len); return 0; } static int on_header_callback(nghttp2_session* session, const nghttp2_frame* frame, const uint8_t* name, size_t namelen, const uint8_t* value, size_t valuelen, uint8_t flags, void* user_data) { - DOHConnection* conn = static_cast(user_data); - + auto* conn = static_cast(user_data); const std::string status(":status"); if (frame->hd.type == NGHTTP2_HEADERS && frame->headers.cat == NGHTTP2_HCAT_RESPONSE) { if (namelen == status.size() && memcmp(status.data(), name, status.size()) == 0) { try { uint16_t responseCode{0}; auto expected = s_connectionContexts.at(conn->d_connectionID).d_responseCodes.at((frame->hd.stream_id - 1) / 2); + //NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast): nghttp2 API pdns::checked_stoi_into(responseCode, std::string(reinterpret_cast(value), valuelen)); conn->d_responseCodes[frame->hd.stream_id] = responseCode; if (responseCode != expected) { @@ -277,8 +277,11 @@ class MockupTLSConnection : public TLSConnection auto conn = std::make_unique(connectionID); s_connectionBuffers[d_descriptor] = std::move(conn); } - - ~MockupTLSConnection() {} + MockupTLSConnection(const MockupTLSConnection&) = delete; + MockupTLSConnection(MockupTLSConnection&&) = delete; + MockupTLSConnection& operator=(const MockupTLSConnection&) = delete; + MockupTLSConnection& operator=(MockupTLSConnection&&) = delete; + ~MockupTLSConnection() override = default; IOState tryHandshake() override { @@ -344,8 +347,10 @@ class MockupTLSConnection : public TLSConnection BOOST_REQUIRE_GE(buffer.size(), toRead); + //NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) std::copy(externalBuffer.begin(), externalBuffer.begin() + toRead, buffer.begin() + pos); pos += toRead; + //NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) externalBuffer.erase(externalBuffer.begin(), externalBuffer.begin() + toRead); return step.nextState; @@ -362,32 +367,32 @@ class MockupTLSConnection : public TLSConnection BOOST_REQUIRE_EQUAL(step.request, ExpectedStep::ExpectedRequest::closeClient); } - bool isUsable() const override + [[nodiscard]] bool isUsable() const override { return true; } - std::string getServerNameIndication() const override + [[nodiscard]] std::string getServerNameIndication() const override { return ""; } - std::vector getNextProtocol() const override + [[nodiscard]] std::vector getNextProtocol() const override { return std::vector{'h', '2'}; } - LibsslTLSVersion getTLSVersion() const override + [[nodiscard]] LibsslTLSVersion getTLSVersion() const override { return LibsslTLSVersion::TLS13; } - bool hasSessionBeenResumed() const override + [[nodiscard]] bool hasSessionBeenResumed() const override { return false; } - std::vector> getSessions() override + [[nodiscard]] std::vector> getSessions() override { return {}; } @@ -396,7 +401,7 @@ class MockupTLSConnection : public TLSConnection { } - std::vector getAsyncFDs() override + [[nodiscard]] std::vector getAsyncFDs() override { return {}; } @@ -421,7 +426,7 @@ class MockupTLSConnection : public TLSConnection } private: - ExpectedStep getStep() const + [[nodiscard]] ExpectedStep getStep() const { BOOST_REQUIRE(!s_steps.empty()); auto step = s_steps.front(); @@ -449,6 +454,10 @@ struct TestFixture s_connectionID = 0; s_mplexer = std::make_unique(); } + TestFixture(const TestFixture&) = delete; + TestFixture(TestFixture&&) = delete; + TestFixture& operator=(const TestFixture&) = delete; + TestFixture& operator=(TestFixture&&) = delete; ~TestFixture() { s_steps.clear(); @@ -462,14 +471,16 @@ struct TestFixture BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) { auto local = getBackendAddress("1", 80); - ClientState localCS(local, true, false, false, "", {}); + ClientState localCS(local, true, false, 0, "", {}); localCS.dohFrontend = std::make_shared(std::make_shared()); localCS.dohFrontend->d_urls.insert("/dns-query"); TCPClientThreadData threadData; threadData.mplexer = std::make_unique(); - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); size_t counter = 0; @@ -541,9 +552,9 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) { /* dnsdist sends a response right away, client closes the connection after getting the response */ - s_processQuery = [response](DNSQuestion& dq, std::shared_ptr& selectedBackend) -> ProcessQueryResult { + s_processQuery = [response](DNSQuestion& dnsQuestion, std::shared_ptr& selectedBackend) -> ProcessQueryResult { /* self answered */ - dq.getMutableData() = response; + dnsQuestion.getMutableData() = response; return ProcessQueryResult::SendAnswer; }; @@ -572,9 +583,9 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) { /* dnsdist sends a response right away, but the client closes the connection without even reading the response */ - s_processQuery = [response](DNSQuestion& dq, std::shared_ptr& selectedBackend) -> ProcessQueryResult { + s_processQuery = [response](DNSQuestion& dnsQuestion, std::shared_ptr& selectedBackend) -> ProcessQueryResult { /* self answered */ - dq.getMutableData() = response; + dnsQuestion.getMutableData() = response; return ProcessQueryResult::SendAnswer; }; @@ -607,9 +618,9 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) { /* dnsdist sends a response right away, client closes the connection while getting the response */ - s_processQuery = [response](DNSQuestion& dq, std::shared_ptr& selectedBackend) -> ProcessQueryResult { + s_processQuery = [response](DNSQuestion& dnsQuestion, std::shared_ptr& selectedBackend) -> ProcessQueryResult { /* self answered */ - dq.getMutableData() = response; + dnsQuestion.getMutableData() = response; return ProcessQueryResult::SendAnswer; }; @@ -648,7 +659,7 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_BackendTimeout, TestFixture) { auto local = getBackendAddress("1", 80); - ClientState localCS(local, true, false, false, "", {}); + ClientState localCS(local, true, false, 0, "", {}); localCS.dohFrontend = std::make_shared(std::make_shared()); localCS.dohFrontend->d_urls.insert("/dns-query"); @@ -657,7 +668,9 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_BackendTimeout, TestFixture) auto backend = std::make_shared(getBackendAddress("42", 53)); - struct timeval now; + struct timeval now + { + }; gettimeofday(&now, nullptr); size_t counter = 0; @@ -679,7 +692,7 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_BackendTimeout, TestFixture) { /* dnsdist forwards the query to the backend, which does not answer -> timeout */ - s_processQuery = [backend](DNSQuestion& dq, std::shared_ptr& selectedBackend) -> ProcessQueryResult { + s_processQuery = [backend](DNSQuestion& dnsQuestion, std::shared_ptr& selectedBackend) -> ProcessQueryResult { selectedBackend = backend; return ProcessQueryResult::PassToBackend; }; From c750de7f1047136e8f180c94c2c2eff98e88547a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 1 Aug 2023 11:32:38 +0200 Subject: [PATCH 647/909] dnsdist: Fix formatting in test-dnsdistnghttp2-in_cc.cc --- pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc index 741ec74e699e..b02b86d67ecc 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc @@ -104,7 +104,7 @@ class DOHConnection nghttp2_session_client_new(&sess, callbacks.get(), this); d_session = std::unique_ptr(sess, nghttp2_session_del); - std::array settings{ + std::array settings{ /* rfc7540 section-8.2.2: "Advertising a SETTINGS_MAX_CONCURRENT_STREAMS value of zero disables server push by preventing the server from creating the necessary From 7191b41a22b799e20970a3f44ef15209707b2f51 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 14 Aug 2023 11:21:39 +0200 Subject: [PATCH 648/909] dnsdist: Fix a typo (HTTP/1->2) in the DoH doc, as reported by Frank Louwers (thanks!) --- pdns/dnsdistdist/docs/guides/dns-over-https.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/guides/dns-over-https.rst b/pdns/dnsdistdist/docs/guides/dns-over-https.rst index 226dbc49fad6..6f4e5d16b682 100644 --- a/pdns/dnsdistdist/docs/guides/dns-over-https.rst +++ b/pdns/dnsdistdist/docs/guides/dns-over-https.rst @@ -61,7 +61,7 @@ dnsdist initially relied on the ``h2o`` library to support incoming DNS over HTT preferred library for incoming DoH support, because ``h2o`` has unfortunately really never been maintained in a way that is suitable for use as a library (see https://github.com/h2o/h2o/issues/3230). While we took great care to make the migration as painless as possible, ``h2o`` supported HTTP/1 while ``nghttp2`` does not. This is not an issue for actual DNS over HTTPS clients that support HTTP/2, but might be one in setups running dnsdist behind a reverse-proxy that -does not support HTTP/1, like nginx. We do not plan on implementing HTTP/1, and recommend using HTTP/2 between the reverse-proxy and dnsdist for performance reasons. +does not support HTTP/2, like nginx. We do not plan on implementing HTTP/1, and recommend using HTTP/2 between the reverse-proxy and dnsdist for performance reasons. For nginx in particular, a possible work-around is to use the `grpc_pass `_ directive as suggested in their `bug tracker `_. Internal design From 2d068b483428bae2fde71b5c861cd4e8d59366f4 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 18 Aug 2023 08:53:16 +0200 Subject: [PATCH 649/909] dnsdist: Apply suggestions from Charles-Henri Bruyand's review (thanks!) --- pdns/dnsdist-lua.cc | 1 - pdns/dnsdist.cc | 8 ++++---- pdns/dnsdistdist/doh.cc | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index d5c27f4de39b..4dd374f94cc0 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2348,7 +2348,6 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) if (frontend->d_library == "h2o") { #ifdef HAVE_LIBH2OEVLOOP frontend = std::make_shared(); - frontend->d_library = "h2o"; #else /* HAVE_LIBH2OEVLOOP */ errlog("DOH bind %s is configured to use libh2o but the library is not available", addr); return; diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 19e477ce798f..a23c03f0485b 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -2584,13 +2584,13 @@ int main(int argc, char** argv) cout<<"dns-over-https("; #ifdef HAVE_LIBH2OEVLOOP cout<<"h2o"; -#ifdef HAVE_NGHTTP2 - cout<<" "; -#endif #endif /* HAVE_LIBH2OEVLOOP */ +#if defined(HAVE_LIBH2OEVLOOP) && defined(HAVE_NGHTTP2) + cout<<" "; +#endif /* defined(HAVE_LIBH2OEVLOOP) && defined(HAVE_NGHTTP2) */ #ifdef HAVE_NGHTTP2 cout<<"nghttp2"; -#endif +#endif /* HAVE_NGHTTP2 */ cout<<") "; #endif /* HAVE_DNS_OVER_HTTPS */ #ifdef HAVE_DNSCRYPT diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 4d7f53e92bbd..3111274e2653 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -1618,7 +1618,7 @@ void dohThread(ClientState* clientState) } } -void DOHUnit::handleUDPResponse(PacketBuffer&& udpResponse, InternalQueryState&& state, [[maybe_unused]] const std::shared_ptr& downstream) +void DOHUnit::handleUDPResponse(PacketBuffer&& udpResponse, InternalQueryState&& state, [[maybe_unused]] const std::shared_ptr& downstream_) { auto dohUnit = std::unique_ptr(this); dohUnit->ids = std::move(state); From 0cf94587ebb35f4b9d3642596e176bce19b33932 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 18 Aug 2023 10:47:47 +0200 Subject: [PATCH 650/909] dnsdist: Unbreak incoming DoH w/ h2o --- pdns/dnsdist-lua.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 4dd374f94cc0..a3a9bf3bdc8d 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2348,6 +2348,8 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) if (frontend->d_library == "h2o") { #ifdef HAVE_LIBH2OEVLOOP frontend = std::make_shared(); + // we _really_ need to set it again, as we just replaced the generic frontend by a new one + frontend->d_library = "h2o"; #else /* HAVE_LIBH2OEVLOOP */ errlog("DOH bind %s is configured to use libh2o but the library is not available", addr); return; From 4742aeb4b98b1c14f49d5398578c39c165432f54 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 7 Sep 2023 11:30:17 +0200 Subject: [PATCH 651/909] tcpiohandler: Make it clearer which TLS implementation is preferred --- pdns/tcpiohandler.cc | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index db12a7f4b959..d0c82b69c95d 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -1826,25 +1826,25 @@ bool TLSFrontend::setupTLS() #if defined(HAVE_DNS_OVER_TLS) || defined(HAVE_DNS_OVER_HTTPS) std::shared_ptr newCtx{nullptr}; /* get the "best" available provider */ -#ifdef HAVE_GNUTLS +#if defined(HAVE_GNUTLS) if (d_provider == "gnutls") { newCtx = std::make_shared(*this); } #endif /* HAVE_GNUTLS */ -#ifdef HAVE_LIBSSL +#if defined(HAVE_LIBSSL) if (d_provider == "openssl") { newCtx = std::make_shared(*this); } #endif /* HAVE_LIBSSL */ if (!newCtx) { -#ifdef HAVE_LIBSSL +#if defined(HAVE_LIBSSL) newCtx = std::make_shared(*this); -#else /* HAVE_LIBSSL */ -#ifdef HAVE_GNUTLS +#elif defined(HAVE_GNUTLS) newCtx = std::make_shared(*this); -#endif /* HAVE_GNUTLS */ -#endif /* HAVE_LIBSSL */ +#else +#error "TLS support needed but neither libssl nor GnuTLS were selected" +#endif } if (d_alpn == ALPN::DoT) { @@ -1864,25 +1864,25 @@ std::shared_ptr getTLSContext([[maybe_unused]] const TLSContextParameter #ifdef HAVE_DNS_OVER_TLS /* get the "best" available provider */ if (!params.d_provider.empty()) { -#ifdef HAVE_GNUTLS +#if defined(HAVE_GNUTLS) if (params.d_provider == "gnutls") { return std::make_shared(params); } #endif /* HAVE_GNUTLS */ -#ifdef HAVE_LIBSSL +#if defined(HAVE_LIBSSL) if (params.d_provider == "openssl") { return std::make_shared(params); } #endif /* HAVE_LIBSSL */ } -#ifdef HAVE_LIBSSL +#if defined(HAVE_LIBSSL) return std::make_shared(params); -#else /* HAVE_LIBSSL */ -#ifdef HAVE_GNUTLS +#elif defined(HAVE_GNUTLS) return std::make_shared(params); -#endif /* HAVE_GNUTLS */ -#endif /* HAVE_LIBSSL */ +#else +#error "DNS over TLS support needed but neither libssl nor GnuTLS were selected" +#endif #endif /* HAVE_DNS_OVER_TLS */ return nullptr; From df5a4ff151620e9c05c7683dbe4997394dcbe25e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 7 Sep 2023 11:31:24 +0200 Subject: [PATCH 652/909] dnsdist: Only compile and link doh.cc when h2o support is enabled --- pdns/dnsdistdist/Makefile.am | 3 ++- pdns/dnsdistdist/doh.cc | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 0c07520108a9..47686dedf018 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -207,7 +207,7 @@ dnsdist_SOURCES = \ dnsparser.hh dnsparser.cc \ dnstap.cc dnstap.hh \ dnswriter.cc dnswriter.hh \ - doh.hh doh.cc \ + doh.hh \ dolog.hh \ ednscookies.cc ednscookies.hh \ ednsoptions.cc ednsoptions.hh \ @@ -424,6 +424,7 @@ dnsdist_LDADD += -lgnutls endif if HAVE_LIBH2OEVLOOP +dnsdist_SOURCES += doh.cc dnsdist_LDADD += $(LIBH2OEVLOOP_LIBS) endif diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 3111274e2653..8a9f5fef2ae5 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -1731,4 +1731,4 @@ void H2ODOHFrontend::setup() } #endif /* HAVE_LIBH2OEVLOOP */ -#endif /* HAVE_LIBH2OEVLOOP */ +#endif /* HAVE_DNS_OVER_HTTPS */ From a2e1991b33732f00008cff483267571c86b8b8e3 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 7 Sep 2023 11:51:50 +0200 Subject: [PATCH 653/909] dnsdist: Remove the fuzz_target_dnsdistcache binary --- pdns/dnsdistdist/fuzz_target_dnsdistcache | Bin 10957216 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100755 pdns/dnsdistdist/fuzz_target_dnsdistcache diff --git a/pdns/dnsdistdist/fuzz_target_dnsdistcache b/pdns/dnsdistdist/fuzz_target_dnsdistcache deleted file mode 100755 index 8eb51b815d0b178f871190daa9ec08073bfdba34..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10957216 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�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%0D>LvI~@nQsUzL0>;248O@U@t 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�IvJg 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 z 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%0DBu&GtP4{jY>c%& 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 z

      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%0D&WeQ^fC8q#*5Fkv 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

      c4KH%8>P~Kh8FS>6= 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 T@ilqGeSOva<0uy$|!=le8atAEph;3gBKq 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�{oL9AoLf21Pj^C=YhgV$v+wq{)k7Y7Q?o{D!Jue7g_>VvZN{x;TQ4X*dQWDS1hXAGXI;&_J>GcioQ%N9s_E$8!!pHPdF zE91|x#mTKbD>l);`5XrV^Y_ECX||uEy<01bU-YanM{_*|3WW@Z;?Of$K%KDy*5*YL z*Lgc_x`nqh^9fz=m2Ezeh*E^!%Xp`nOxqGjcgQAlJ2iJN z@g~#bpzhcW@geTkpt_&FR4y7;W=`Nb777KX>L34S%1nWs4_T9gFzG%84V$`8;RJvt zeT$yaqhRe@qxnzy9xd3Zi({DCTL_+IpAv^LA~yjVEqQAA`rF zH%ns$8cBf<0M+(>v#e@+zn?AjqZw2YPXi8K#<7pA<4|Rrw=`uwlzhFDpJnAYlAV7@ zUOF~;>~)@W3;U!^dUxg8NI+XWU6syT)RyF0wg4yBvITgOYv;?_9l6%L!uOk$*{Z&9 zU51GZtWAD(w)EZ<7uYqnz}n>ZvF}P$I>|Q=Vk~$H$HxAdch$)Hexh$)ll+4^@)`bW zf?v!3`RdnL!#e!DxgSlW1%3gQgceiTrnt((J3ZA(CI70CbXwq>)1W&&m7gX5>LcL; z2=1~%MXO|7Q>kr4@HsTkd#`z+DLJi)gq>2pX$^H%b=8&s1CD>YDS!!;y(bXW?M}=$ zM*|rF1*&o`g*gxEr~1R`ct$!c#^(n^k*?(SJ;JL-`3&X*;SXg6_0S}YBf#fBRT_*# zT9W6R0w@@bXIGe>P-W@b`~=_FOaot3ZUudCrURTL&00KhIB zeA6O>@XU|O+D#3gP}VNv&PEJukj2~Z_yxZC6Hn!%IXb?ne*^JhQsWdUy~V8vTr((G zgQp`*2gp?FVYf{}Y9=kutGY&7dfI&e?Id8evfBXz(;)^{hRR->t;0YK5z_R0nAfRu zV$*S%2V?60lD|pjUj}s~3P(t(Yr&^1(aq=>(+l(U*EQ(KClIvc&KY1%gMvnQ&ViXB zrJkRX6sP1ToEHDGhD!Ce&JdH+i>eyKu=rXKvLj< z_00(x;5ldTu^-2+;82`*K)wY9`{G#-^EuS&q@`KSFtK5iic|Dh=WqsyU=q%+;5SKU z*Xy%7MO*0<-dY`w01@nmQ@@b12~x84R=7x(nn`i8JKaen?OV|tSW`hu2UE&8pqFq- zoSOT6KatWQz&fJP!76pjQ3|$JBHxycN2xEcJ}B%2wYr>w!v(}3U-G8JL8Xrz5X=QJ z4CoN3DmSkf=G_9GH<;aZ%B+!K4}(HwTAj?Iv$KT~nH4Cr#)2Os9c7w+r4yTG%lqQ3 z^zZcrpxr0&x$}rPBQp&l51K zpnh-6%r~o(urK75X>oITupa4q+PEpuNWbRxS5VglO$ri-Z?3}% zvqI-7)^~A-gI~>NU{!s|%J-7MvRs_dq9#G(U@stP@NJ=1dO{B6C0r(7Owsb=35ydVi6L#%}U_oAGEqvi+uvCvA&(3K#4~ zGZ=pQM(NpvV_QrM2CI4cm)d0mC#kW?44L|&Nr$xXiYX0@R+HB(KBs{x>6~hR6)H88 zI+V%N-+Jn^exhW%RLN=?i*6#2eX$jcz{v?@r}_kP8?vM+>HSl0m8PWHP4QR&O-bun ze*ptNG$rLR(MI~CD-_D(E)?4tO`pcVd+;N&xVg-*^-Ow^NlW`@x{*msySoPIqxHD{ znbc)%aBO_9i2I$R%(2~DPK6(+iJD`(cjUh&8HAVdRy$Rg?!b42LMex#oW?jNTEs-a zesKP=IM$##wK+XdY3)6`!i?uS8486q(Fy2X1m|CgljxaRK~8_W)ZD^#2^0!s(r+;J z7`zQ@+pOxKy17To+hOqeJ#4=?z4!yL_0P)5m3iQkTxrkkBv+2d!&vKkDfY+_nQd`w zWYitbNrbGe_`JgO=DG_M3T@K!)h!+li#?Ud?@BSS42HQJ)qS%%z5 zji#3;H*aEE-!w1}o^hn-c`dt7=H1`l=+MeTY_Au8FZCRa*Z0ai<9#=tsgJSdmBrpj zby}BuaA$ZHz-p{(I6ra~i>!l#V>6P!i>gXuJODRV+>m zZbC+G#r?uH2j)DN{@hNU%QQSD>dHjfQWX4Gouv=ZAXDwzx*FcStp{mJtyacY^)5G` zaQy)ar5rvW=P4XMB&OlKDHyE4u~F0LL(YSi)`9#hNDcS5g+ifCv>d&jaQ*Cl`U*gYo)Zqg)at&Gn)yWD)n^(QEla`>Q}XK+lk)AvMSDh3B4y_qAf2?g_8V=3dEw8=evye~pc!0q;92;r-iKf3&e3l^VGjil;V;77RKD`^& zB!AF+$f6I6&5hjarT>6dmQbR6UvDQnB$R$g`S}xf>*nVg;q8|hzfu1sKjZH=da5H) zIGd<7!?97@n46#XbK68iank~Ap9?bSb|K2skR`QRoS$D&lW#FVLVijb*J|Xa_1Ic1 z$L1819WZ*s4f{v$e@Z}AY-7aF4aox5>< zQbNCErzLJ;tf>BUQrH^DW`o9x?0XpO;I}x9+svopZYR)gTZ2yWt1T$~v!2W}0Lhb? z<7tZPpC8D}zFu&XepRWuAI-uwsY;_AN0>Mzo(i%PaD%-jlGcQS3r*QzuT4B^m?}ao zZ^l*+;crH%cnH~1Djq_1lqz`$yJF4T4r}%yCOxeSYePeELIrUd5m~itT2d&#nPq$ z);`M()5cnnvcW}HGd}hM_k$|h$M!+5VB9Po7oODYQSRD54LEhC$BSa>&1$?qX(ch$ zlXY zrucV5?%1aAuBlFH3J5!)pbPiF(jVe-)AcnUkwMpHrP%JcmjA%>Cb?P-qif#Nzw< z=b=}HW5YkauAZ=cIM}W;_q#!%&?dSay+LsPK{yLNjrt_o-W{y-GPOdFd%E0=;W{xv zh0+T5!7=F}WK*yRc8kXReJ!(%`TKg>#(Z=EyLOfV4c@}BL4D;K^ICB6+J~7YQ+C0{ zW@fBD1ML6eG-lUr%*)cvoQPR?KI@L4P-v4Lt625JpHwoQt(*^HQ_vhwwR2pDd{eJ` z+{$00R{p^##PSASG~G7yD>Yp*Hdh`NDDOT<2WARl|9l*ql>73L*9!X1PnG6cuJfQ! zAf{0ipO;~`h>w~FTf`^sFKkeMVLb{-e152>aIYE|n4b~*=7LPPofOYnLCboUnNq}! zp->>!pH=a;;`O(~vC+IyW@-g_n`21(aor6H1v1f-%&r^{7o3liom5kk?|)3Hoy{so zCaa>~v2cSd+?};x!*w%p>GHTNucqLAO~4_H9T;Dzg+1tI%m*Ia zhGVlp>kdsco!-p~ME>(mu6|I?S1$a3BP-4OTt9|Fp-uEA8-q5&`N2gQd#mc|30wYk zrK#Y4Gbj|=L_ed~8L!_5C+91dcIGP=`d7C9@6UB)f(oS-_P{aG9M)x?3>S>Yv5C>5 zP!qjKN97zu{xwdnE=^8igzwIu9{ii@T~H{riTbj1_F*{xWgKg-PhCA>kDFa))^Ys; z3WYY&;plCK^Xp$+Co$5_Bu40$8&;auAUY=vY@p5Ez1P!~E>-7eC> zhZ@sxhrFF-q^4aJo*sES%44D;bgzL6ZoG+!X2vh9+zeayZ8-}`Zg1_s zye)BWE&YMg_yKD6>8mre)zeQ=ivG>hZ&-rnwwG@8^krk~r!Q&p^sT4v)8AXxhG5M; zeG70;UmlY;4M6%Fq0R%f#S@u`sF(U`xm`4#$c_cdtVg7^B3CP}ch#NSqMnQUZr|OV zGEajKUdFMH@S>r5w4ZAJU-F-vJlm%m@3)M*YY*N-gS)|O`$|oK3!3WK36uUo@|r|m z88ox5ACzgJT2J`ZZH4=&@&1nqge`heCl!jGp`~*yPFQ_6Gm%fzunLcrbbD zL#4l0Uc899eclpn^}J>LZ=QFXQZ$=iw$<~Njjf-zq{;KPp1RNb7+LF$HT%3Rz&&qy zO!@)=F3b%sZa1sI+hQc3CTJyT99&J%$$D&XH9=2#O!_%lyWIt60WP>0ut9(qasiYG zqfNuc`L>5>()XQ7zJCWGE-8k1O)}*$%S?uN?cU_JNq19My^yJt7&OOgp{|@smz81t zXypIYi@Uj9wikEv&e>kv!scrC&-A`}huMNV%T%M!^j>+Wo+(*wJ*>v`c&)B-L8d0= zw?B0Vouv`Qg(fv6zahh|ETg|YG^uH^$3$N;{jd-Pe8>^ISEP6iOky1IMI))kwL21&Prv9mUU$lv_SCQf~Vz(cyHnN`MC2>$ZL9C1<31T8|!j$@r9AQy6z1$EUWn z^C;=#)DONJ%kiUG=e5c#0_6Fv^R~N|+a~&Hb6{2}x~pAuN0XT*s{B1LZ%MwcuKW)o z{fp$qbM!%G79ekt&PVN9L6g2jX&V7>i=JTIm1K#o?LE5c(t2!9km}NU+y^9&Nw1N$ z$yl==kOjCmItCn~{Rr0!pvR;RpO-i$J@{$%BfQAnI6IiwN#E&)Nm)Ym;!`>M5sJW4 zawx#UD>L@gcd{jrRt+ZW>m{{MM4PDO@vg%$(IX$RUmn$ zJg225e2X?^WXBNU z;3fP?J>uD#{V_znnik@yPo}(Ki1d$oEgnE*(kDo(@TwdwWBYGXu!Dq~rJkcnM=tKL zEtckhtu>S3#qQk8t-H{SyL5TX=op5{2!ow@D`g#yvVUs>6OI7nTVUud!b_Wha(n~$x%y;`=hU3-w#n3iWF!U&Dc9?N3 z0VfvYPe1Y+WqTBnXRFf8;NwBkExdNiNPMhFsKfieBVkeO4PZ_$sF9)l%~17&$C`(t zo@HmKAUjI;`p5S)W5{~ghud|qlQZd=x_4N7uWwzwvu1wA;Qs^R1>D`_ebcGb)I3zR zoHiCgs7LLok8K^o7!4@6E4E|%#=Q#L%b%ov1kXP5AizdONj@f4~_54WXvb8l9aZen;VdN(3*WCDfFP< zugdnI-|r~-t8A({+JqnVziE}4J=@E|$yoTO{_|MBIEi7|SigA^Lp<%`{_|+rxKXii z{dkw(0^11!9;o)A%zm3}AHFWZ%VH`O!lO3x$ypP&_dgJYjZy(xN6 zpN#^uS@OIaGV-CeqPR-&>WZvz)X~P+Oh30(fyw)iU!~lv`SRXSo{sXEXfJxt{Q(C@ zJ1g1V^Q7ue!NlWcsVR+~n5Gi;k0Q^E1M6Sl6ed6Gy3)=4HXUqNTE<55-?P_oT?B>F z2+zb}z?r`IGPvMj9Gjj-(n&u^yuG$JW}d1#q5tLeu^m?T`dH8Z{q-@8$e`ov1hnPr zlkI|U@%o%8U6(aB9TshSr z{qu|Ro2uV#_vlPyxpjU++l{9$K)?KX@cxHRN&WJi2BwU?HLKiw%k?KH6xu|ymoZ2_ zAH4=RHWF(}k=F{c>G29qFyOyTp->wZuukV(Hu z#(Hbzhlziv+SFscKiN5zsv*p;2zAfQYjx}n`Ln~a6 zdE;$4sjkD{6qpxyJ#4XP-}no?=GJ51_=~(M>#+sq#c?N@GQ1HdB4IcfgkuvqC?4+` zV^YWDw>Y4I?QNVY&vvR2h88S0CUru7*-_jv=|hQ_cejg}#s{*g*Mhn_CAl3-aG#>} z{NF#t`O1MG>IAgqr8rWueDSnNLx{Z~ZAIG1RA+#4!6QrkY^mOlgs%gzegCfSdtt2~U8%ElYAp^mg<|CD8u^#zE=yA@4q$rlU($t z8Fb|Hr5*`5n22LPrOePVpVD}*+4)q(99lx`&f~s+qXQ|{gv*H5w|Uz<%WYFD1D&2` z288QMD3nGx8;5BuKG@)ESacYZW>jfkKG^>^ z6s+DTJ8-5E6q>P?&%9CMGu75dH>J!?;QbXiHvbHUsAEXxr8RjnS}S|6>{D)5bJaTR zPzvGgIE(`-Kz4*=lV@My7WcJOQf)J<#eH@(id@u~)AnF(q;=>+cH=37EW^2N)22fo z;sL0q56mrp=A>1{nKq*Fih*L*gN?H8rYLkief=_$eEss6Xb=yy3awxmj!m3K*Wv)E1u{?fZ)$-SJa-ed}E!ALU3E=`B&x^Unh>KR>_|3A#BX4%l?lQmFdTgnDncv)cl;35S`R(Lk+1~Ix(-IRwdmNhskJzk#i(Ku2 z$RFn9cf~ow_u4Jh;a-7irStFhjm$`{CqSVz!hSd=UD}MuT?K1DI*s$Wx6<;85^tq= zHq3t+n1w)tXK`#KuI_9f!&svQ52at&kBl!aImF}6o`HE2u>YmgXu%LnPE$yhmcCnI ze&cHXO{|0_qyhXpG~S>Ijt%Jv^h{oNVw>)-DDTIOWY{U5UE3AWKaRoWou+A^Nm8A) zwdypfZaEEghTaG7FIa@$ss_YwW$m{~MrP+(es@Y6WfHpwSp{LTw$)}dIJ;+#NinXP2CRX zFUPTP4P}{HK`z^++&suQhl+TF(dhy9ZA?C_>0 zL!y(}P+D|50aWAI0A3*gThcPm@TLt+2KQQDVY&k83x!e$D{(jiMx#&X!6pM%_FF#! zN$wEX-%WXCX2jzmu;|-eIGPQuU>=T*NcUk1;5h~GVr~F&+BncLo3`^Z>-^H+3f*YQ zmeKiE(a9MM`!CUn2g9Q3{&}VicKn@iY;@WZ9fFQO_H7lnS_QO2H+DdAJqQY=5q82c z(OvYBkAd^g#IXi8@F-jr_JjJ-wbGe&M5Vcy>(x*wg>VcGqvykclr|{172o}kHKC<2 zo}I0#6@F90M&?{>CakavfB4XDyqF<~CR22^P+xgEa-RB4Cf;RuTw z3S<<5fjBlOjTh8B%Mya3OT1=(QDE2XG}U^xm1k(D{&+6+8fdc1L^m@0wXf7iIQ2mq zL`#<~{!tkXENW?OGyC;S|m1bUj#7uG>Xi|=IqU-Fxre3BiCI}iC%$ye5qr`Kx# z!CGXQ(ZoF%FkIK!4H&NLW(N$T8pho=0P<6JW|EfO5OLj(c0)w1jHF-8GnGJEL7^1F zO*kCRMr=DH3wCt+8rn0_#SG=`CiwwQuAw~dYmMhc5219FZl3IJ#!3sGX8cd`*-m~9 z#xx4KJnX;Ma^+4Qsl8E=a1K~!m-c)r{nd83i9WGO4FIEwjYNAne>5e zdBKi_weM8XYhIOx7HbZ_f|ueouY>g*6?=A+$E3ejS*$&UwvQlL+^LvjHRFM=Io)II zJ9>R@18bWmd3*W;?0S!=QCDMDAP#=Uv61|p*E)VlXBRZJFKHvrdoG$?&_Ny|cd9&n z)myD;t~-|%lxPOI-@y&P~DFUKgujQ}DJoP#%-6Xif_DN5iH-GM56&+eYl1 z?iL%(+{TzAfd<+ZnS4$rYRUJcosa%(ClAiBL$Y>Ow*cPMN`(_p%>u4VAiGu4?ld*& zx9GS8Pavcmv7@i+Z9iuvJNw^7>RoYnrg5PWL>sQg*=jC1yVMkK^jpnr$Z~EqgYfjR zqmznt@ppbRJK}gDvCABTQv8$ONZtB%-Y`rKy>Z`iQ~ax6F453N_i$?LZ+_U5LA_Il zE*w;5it7hWWC8V|yL9zUajU@IjiIeG9t{^1Zxh5unpf2~#Wk5b9iQO@#0P% zy-I0Ohf-!Z+oM zTGbFOWWmlj$+N1lFVYOJwSBAXyEDV9&AwGLyaDl}?omViFZF|*`czfu(UClpVFm+3Qq5Y?v=m*pmq2V3AEb}Nen)g2*r69Hkp+{*) z|Niz-HpS%sxS!N{b$)EW1Z(`OKrVAx39*3CuM>gPU+{lIN-^6&15$ zcB$kmom?Z1w55+F7b;ED zmrKsm*k!b=HZbkL`h9Ws`R?{Sqa{c-I_INlOT4Ciyvm`(mR2F4kNB(0gSj4+s}RaY z*ae5W{ENq>R#C&H zIn8=0{MfqOyu$S@C={B}yd|uEhVy^Hv3eS^%+V9}^2rsZa5?Lrp-^a+m~*U36<)s` zj@3IHJyR>lOFLAU9l7>}LV-;54Y@D`E;ta!!sBQ5BV!XsOMa1)+mc8PiqwU?{wh1- z6PH+7S)#E;W6tq^sr1b4D7?%$|N5mQ=I71*^#M*W@^wzN>>OO*H+w_3*kjL%&-7c% z!i7ktK!eIIH)g~j{sysls$Zcp>p7&4LnEG_SkDws^NR(q9})<(*y|5|ApwlAh1cbN ziJ~`k|;1A)zhQu8xtHA~*+H?A?s@CHM2`?Xj|m zo|fN0*6*_8!@5;`m)|Aatij_Aa@NUt9p^4jV{k&0TCBv^UI+@ z0(HI~$)EUsgig8@kEB&%x+MqR(zEv zy`2Rw;hcp$4r~u50~vwBa9KD3&sdl-vY@H(DlHRt7W{-uEY$Z(gEN85L}9ut{0q-D zFjvWf7L~hSrN+I}nbdgZAm!dwe#5~l$PkTO--*I)vd{_7voKG}(+bbeFdLykqm)&> zkTh%Hn?_LOXQ=|yEy|>}!T& zliYZit=rg7duFP2F}F>0InBkiK-)Wz@`aU@0~lNhPQt<%ZrI^PS-u<39KBL4{|FNh-=H}ABw(9}xjn*lp)|tfI3_xVr~ETq(CwkjQ`V$I@|0~qI5o7Mtw7=-*^r z?p?1)Ww%M+tE@g8gUP7JJ|zd0*r^W;618-`J-?CNKBb;H31DyrPELAlFW14`*H#!Q882`OK>#o@JE_*#!dB-xbFOm>F@7m%(>Z^lD{m#fWlqAlFe) zD2=cO4r^Z6#CQsvKM}_o(5SDe6>j2%mF7aOv!PHRj>C(H+Y7M&Fg3xdMLUXbQ>i74 z8u^W9BchAg7Wgiz!KXM$TupQ!qvqdB-sq7Wxoyg6G<81H4e^VRjHX^pq}u@YdpHe6 zI;Z(0OS|37pCxl028BYKs2!$8!1>4G*cg0a6D!Eg)630xu9KlqAUgYh2IeBT;7S|| z*VCjWbUn{|HL{Y`aoznmlR^4w^tlK%`>2d2w>T4+qUw{s_{k})M>YaZJ zOwVFYdx7Qz#gBO18?WMTY66Y3k4AO?bY-9c_YdJ7hcXSEr@h8{VMa8hxdp}Tqi4N_ znwVHw!VzOo+&)?z3qL^cmV_C^Seqo%Esd8`sBXsO7|QOJHOsP-fOHjavdcDp0iqW?|%FDAN*n^~LzfBrSn+ zkIJ?L-exXkLdF!O4W`J9t}_&tN1TEmxxWxw^C43?;pZ&cGuy`KUT-SkbGh|Apl6`! zPu|Spe2YsR7nB6QAzsh@PoeNTJebrBlZ!w-(?=$s_c~5_43kfBt3f$Co}oZ@PpNn%U(+WxHXdnAB6HmR(mnRSUJS-Hy?nUoBO+4F?l37ISd?>8O6EwtGhVOPL z@bP>A^A=RC$tq{YGcuFc)GrOLL2N2{`@n=(DC4K&)F7#X0?kP61+xd#Z}hiW6P!bc ziFyyFf_X^Car-1Fyc|z(0nXL~ReD;#Nf?W}+Z_Aeh7X<`v-zyaua;(=l<|fN2exYK=%a zV9KnEfvp0KK5Y-6i$L*dX)d0D`A(?0eqr$wnA2%#{Xy+4Wa*Ve!U4U6%RDV9?KVJ4 zHv`)jg}tRzsUy~$5=#MQ$JWi00CmLLC_p12d(_%km@)F`sI{pulOcQ5nzK+Zv6Te- zSZ8~B*leJ)q^mKsc`!FfSIY~XZkBVpg_%>tmIA#~y88iN1@kb(uTHUSmAF`mc^cptyO#{f3>ZrWO5(|z?BEG~AH^_pH&1;213#+6<3mr5_ zxFq5zb$JRU9bmW}3Y{Q(fZ@(CeXNB>WW-ZRu#QWDy~A&Kj4bH2+8c#oR!RBgph3bV z!J@QSO3JU1C>#da{2BvulC_`{8doR5I<8?R+@d@E%26sbbX? zFNmf3HjcAioT3GOqpK9Kp3`$^JS#1G*rkI8rc|HQe7~_h?D8`JZ$b93%WazYrX>{U zu*+RwdO`MAsZ|JXC(&((iQ=_hb&EBGHJ@Am0ytWlSKzr3<|=v4#q&JO6Y@;N^9#&I zs9KwYoH;f|VlMTY*DRQVxTYxuDir(+&%Q8w%5yZHsW9W^IS9`Zn1xWa4yJIX7;M8- z$yuq^LH~2u0nhzcq|gmdy=EM>DNj2*UGZ!S1V9i(e3x zQYEWNn~JuF!9NJaMVo{2=riicr;5_PQqrfo289B2a^PaV!qV31z#dDl%9I0rV zBMU0pHlXmeEU0Mv6XthoK}DO%B$WPElH^RpDWz7+f*TVvWS4(DFXPH zfcmJb0kweaN8Jl%M`@L+I4ekka$Fn`7ATpzJ%5+a+S`IlJaN- z3d13rM<>IaXf3EXa~ARvF0nvywn7$EoJ~RDELl)-HVfurS+ED7x|bm^OO#xy^mQ(> z^8npofogI%V4-9|CRLjNKu=?xx@!f{fvg}#FZ=4)k>EA*!Wm;l*A|6!Qr z@~F`N2Ie!!{;IU>%Dq=v&V^gjBh@5a1th!&r%D?o9k?Lj95}C&-!Sy%0M_owRys`7 zfwP_zhFL11mc zw}Il*NS#uHzf+1&BkcjWJ7iBIb$I?9a?9c*a~kO&pu5R_&d*k&FDDB1E~66t%&QLQ zwb)AZFz^RKp(;^Zd7h2$OvqNAi(uwKw(@jl_?KABB$elC?mq#AsyuC_`3=4=AX{mc zw&E6KD@|vDe?i7XQfYSQ{&vEt(zKQ3A^7%#Y-M>i%y?*!lx$^r7ruW(wzAB7-le&P zjMk|v-vIO?WGltZS znn`6j8PMs{Qf0XqW}dW?%F<~CR?AhEuYg%CB~_N2VSa#YW!XGQ+HgW~m1Rve%@xR2 zmIuM?1=-4See$HUT>Lhuvh4FRX;Wo61N_-gTvCEWV~7)bjln<{KM?D#_oIARLzjK_$5l7D82$ah^Cxkf`N? zX9%o32^-;#3@u|7*~SsAv2Pu+30=gKA z``r#$Xs#EKN^tb6096UL2GkO=m0-)vTf)Ar3@Xy>Kq?dnhpQ^N-@g&I5!@ic&frg+-H)IjZLWx{pShLbaiOE1>i@y?7B z)?J9Mk;9yUb4LDIPyS#2a4Kgxdh{~O<9nm;?TeEP*blTL?e{g-Ks(#jS?GTRw}bHx zqx}JPfhDOdfnqCoSyYBsW7Pik-NVnkF0JQF%B(om=UPS&gx$>O(7~ya3T4vtn`XLkw&C;7!Fqk^0 z_*;Db+ZmG+F`1((`1t+HOgZ>qSn&92g{mBLx~mYW>_^sWO6rN|+H974D!TyO-ARlKxbHaR+F!bGE4AU8&s2@Z3j zP3FH@x__?Zvz^>7-H%dx2If{o{yjKbMC&$XZmkr)9#(E%)`zV z;Miz=XVW9_oSQ1m@4ELc87Gj5+H4b;W_bNJI9r6+Tyd=x`1$QC%+6eQtpf_B$PTng zw722>!*FbfT1L;-cf9+xYGlT6Jq-#4GSQ}KEOmkNFUGNOZJ;)_f;4=m)ZD=JW+)WM zL_c8bZaDuz91GV%a8oPDx{^xs0#_~R2nAvf&P>W!xFGdj2AlGn)Wz_m9N3T>jnWuDm+E*OPlBc>Gs@l@(jsmLztif#sU zia_T&P?+ee52&QIl0|D9!>3NOu_re^}k3q_F7MD(pR%0G#H4CgdA=7i=xI_ zmyCzi#PhrkUr~OglL}gd< zPl#9Y$0?cMby7-9bV#Q>(-3gb)M@;sMYGYxEY@s?$nWdqnKQ!UTH`0XvQ|1z@y`%@ zaUBkY(g?fYnDlmQ$dxl-S)XqY4H;|RZq>=I@s0}b;*czE1^40Dytk{_Pn~31f8zDk z8unNH{3Z>|)7*Z=zj0+l)A}>7#co{3Ykm6>^%xe^y;0gReY?q*nP}i0)PFF+Cpgw< zymY<|^6wyI==y5PO~I8UMS%>&J@cUuB8^K&f8g zR2Bak`!@?4ytW77S?8U?z3JX*C$qf&d#~azMSPt%1L4rOUm!u7yhKe5ipL_zX+LPcpA{@2#Ns7zZ~@ocH=1l+(995BLqhcI!cA|G|1T5qyFy zX!p^U+54`yb2fW>aJx~#@&eQPeXmM&dcKb&li?qDElVC}gcV7g;X>OCUt;oQIQrza zJhLZEa3oHWfz!R?j~-`QH}onlQ1YU?K#dh@l0zx4O!OF=A=Ogl$ zIl1sTufFgF&lQ>{xjqMlLYrvVzd8RO&i@!Ed8bURARiuIVt(NID-;T3qPO`{^4Ai4 zDUOBP&p+C?H@S+))88f)E@9QWUfBdN@NE{**MGN_gacQw$)WzcUB!D^XfxAWHV?@M zMf!-FUHT9OO#StR`fIq`J^4ylnKcR9`ky#|Do(va719Mbd9!fx3V%7>ffbo{L=N(ymN!OZTB;!NAu|0KUzPG8fG5*r7?w6WqLo%sJ>e19b3=z?070Dnv{+uFHClu0mIC($g zcvqyM|8=_hR+2H%b{M~zY?%l@h$i2ODf%!6@eE@aeGlhR9uhJMaCPJaY37g>X zo+-R#3ynEXGTF^}&usjn$Jj@sfu2BU^HkJXyPV|+3N@}zgESVKX~sn92IE3B*75YSX1&SO8maM5bMm)&!3TbPBK9A(y7ogUdbHgK`fO{ZzV|fNd2!W>i%`npp>i}7WTNZ% zk~EeQXnZ`04Cmz|*Kk1aR9*R=MBp_<{!dPxjle@W5qPL$yva!Fv#;d)XOK*Td!dxW z_vNg|p;16eHG&rC|I>0Ja0gpf^oMEwUQVt9rm~N}R`{umG#`_kh(0N~|2f}`+Z|*9$(r5NGkHz! zaXX#xbk##7fIu$T#dK@nVDA| z7a;$p2enk7l@1hdF=~wbS;=3mEB~R`GixQ!`yvzVOskx&N1Od-+IsY{ckhkmCiRD3 z8gJnAn|f?zMrAlovQ_7Q5^&-F(fvj)rCWD`oBkSyko=}B<_BHq8(=5*MI67EM zC13WNc1ktjf7+1z#%({fJ`<+8)}~e}CvgUTCF15#D3FOZb0krFyna^)w?`G#3UbTA zWo97PJ)uw_b7Sg>yBKe}$}c<&uRj*YCQJKgay}3#%wJq;&gOa^6bjAhVv72Guu0VG zj~qDG?mgn2nZS@k(DC*H%J63ORT52N{qU2ZgZFTf+^boDFZF%UB<^|j;;DWwP?s+= zPgU!*vuKT4ZS}PXk~~#;>OR%<(TeCEGN=bCfM<6@M-5pPegtxVyt}DxoDD6zcY3E( zKYPkdtt`ylxzb#wYpy~l8{udi%3D6;+u(wGagunmJhqBHl;?RzPGh&@o_6EV5@5GV-~JCk z@nF0D`*{RUL0z>i!I_}TcM0RBd)6HF74g-sgfD@70hz8^lfEbuRKD3!xC7f<_cb`J zO#cPU&rsO(Arf9B=P$&AgzMZEZ-chJ$%E|v5@)Bt4Ca1n?|SLp|3O3hOG52086>gY zSK^R`F;WXQwXY<*pTq(9zg~2b{UluosxuU7KS{igWNs$%ZXd}Raeh^4hmx~WlyEIF zxtZFp-Zp{uE%n1%UntQ2rF~$A%ALR`Z!1g5_NE%J+elg4n|i|Z zkVo5_hQbVn>^3K7i9hVj#LmSj&uw!W0d}~QwasZP%ousJ&1ojgbSU%dsT~V0Lv=ON-OdAQbA<1cbW{Tc>HYC;Z-3Qu~ z)E!J$DQR=ko-l*t(P6TOz#Igb-fuk{KO#*x=+{#lK~BpEJ#$=!D~TVIDIV1H44Kz1 zkmE6MEM(dTne|c0>hUv@)#K3=3b*-ExgW=tdf5T9Gu)`!fL~ch$$kGz2h!4is*00L z>Sll2_3U`S!yb)=ew96isaDpGIH=70#qZuP=S^D@`9e`_XG5O$?@sI}XSKa)`#;Cydm zCRNI)Y=!)-CqwV9t1vYH);<$I++#9N&zpPpkEC1%rt;uUhf1|M#o=gaWi&DhCiQ_I z9fzer8&Pfpf2$sNsdl(*NT81El+jAP?>D^g2b7)$_8fpgvaLu1?qdZlIX*l?UrK8@R)8SnBOi~(T5>V94D?8wObkxf`5&US#&hx!K*Pbez$}ESb)1V+_RU8Z z(}`@&nxjpKALRaWDSU z-B;mde%1QYS|*wHE$L2up(6OJtfwZSf1K-DT=YABzUaeV*^ zg=YWi{FHeH&VLuj>Z$n6(G#}cfO7L6uHQkS&?b6{Eoy(k`Gr4a^mMqMsTHL1mrBzN zaVsbki1TmQiM9(~Zv>9rcqU)Y{J9NUW$F^Ycx-bocecD`Cu2?k9h{A0aT+h7OlSON zW2zz^c&T8z{8E9gbs)`7o9NQN0<&21N1R-N*uzXxoAaWR?Ogkl!}H7=-1oo6u{{!P z2ed)m1)89kt)SCk54Wq8r3rVJnR-7n>e_g^3E9iXgXttjAEE?Jt=(1;kDmzU79J_7#FfX>akz2DFdx|8Jj_+nxc0& zn!ZV?9&4x`+inv&nvU-azBgn_wF1CF8J5^miF#~`l+Fh>6otW1a3-D+FvH~;gXbie z6ChKiX?tgcQ=T&BTE$U_zkf~SPXjy&s@Cy&%aTB+Ow4@$D-kc`{#+=y1J8e8K9fg> z=!Ko=KtY3quh!pftVm2;CKFn!vI=o0K<%L59z4gujFM*&o+&VsplbcEqto_`wC(q= ze{sB)`&UX~9-jMPmdbMlo((WxK^whiG6B2BBk$YNMht)H;arPjUy!5iG~vj>y#I*& z)lROp1<3@|}JW?CuS4F!?^mr5p(BAAz&=aVe%&daqYinn_%z zB? z_hsfiuIr#sAQMe(!}Qw_Wu6iWF{--F%V$HC-Y zLs|9#>kr4ViPj&A*r@0k#bY$JQhuzgkvWa))LdXF-Ee;#l0TpI4kUjzzUv@sWSyR9 zt#mG&TxM?PdN&jb!(r;X@c%b({%RZxw`)sk1v!&{s(6>{S|}8VUHmMD*Z}AMfn(uX z43UYVaCXmvot4gA2aGvG8n{>9$lwJREi<3m<;rzVH8@0qICSQ!AbSTvl$%5jTZG zflT!J3DZ0YFvrNF-tP>U$NF zp-uW)H6s?o+GfO8RDy*^_RIW#yj%095%OfsUp!o1&@s;}M=Mx`V{=TaF*s0z5%m`( zf6K}3>W%dC3a0q4e-4J$N;Vi;D{(MwJ75#7pe>FKCZ6H?g1qY{dEdJ7&scvkMDnAY zJTtXR3vX!3PN14-(GE=i3UsCe#YRtgB+pzR`4vtcF97IuZ=P8o`LDV1P7_S)IYE!b ztOYoA=(okiruDT!Ga-f!|AD;**JV7n`4y)1^+9Fw$EvMw2--ei!jN%J9 z1gh5J1c&2{k8#Gd9vkEZTB2|X_s@ZP_Rhih2|8ocw4T!RRxAcuS+NZG-H_?26C=lF z!snFr4Cgwbt*177UphKD@^SEwTAk-VU}P$T^b#&dr$o`$l9^Y)za*VjI(BkGqT@I> znngH)PN7^2_CqLm4$t>68|7Jr$Lm602TxVw>nOaE2s@5RKl^Ka7+u<4KuW+DLqTUe zEn%vlP=CF%(K|n*?pjOHDLk_WiL?I{PV%@+tsXKGmO$hWbaI`JnSDuWg+GK!>;SHZ zLZQ$mI-cN1!}-&2lHlXny{3NJ&hFI;KjlGVF5@~E3Z)T_!!haeG}rPzY~d9b7`uk5 zkRd&eGo#QLb+j>drI`wiq7lVCRDRh)qv){WMk-fWpUDz~uTb}^f}9A@DPkqtc)wa8 zJfr04u8HAOhiXAf(GYG}Hecjc}L!iGW6v|rogB*kRPQL-}?!`DdwB!I5L7V`; z^eKhTvIXnvGkKB2v*H6vw2Y${Pq-u0PwPP(*fZz-izq)61zPuUCbv(9y1ub=7Rrl=N=$;LcvFP*1$XmT^H=lzBs4kCtM~r=E$DEfPNxl)JwR+44~?$ zcDpEmVyvvk-scLy$MY-9Ca7~WJoRfCRDevYPQqoZu?Z-{xq<(xV_F3RKr{v07z%pe z=>U_KvgxWkcsohpQYCOn{z`?feApRKPiTJXvkZoVv4Weu1ITaBB~fQ(ovO&s_s(3z zA3&k3Q_bufXP3>SAJ>ai&LJjtc2R5Q>~k;kyo!})+aCFm22UG#%nbiOz+ZmVlSz{w zUwDYShyV3OJlMX7!-}i)?i@v&4}}iaU;GyBRoq2y=OqZvfhx5E=Z%bguqOf8ySUB2 z>XGQytQc7a<}N6xz_S|W8F{o$=RKIWpvnu#L}!7c1Z81Cexn~qVQ>YvegN|=)c&(f zDBB-X-ySKZnX77@E&FZe29wYk0m?=GT)jk6Q~`l-DW=)^SOGu_y5rS#hfYPLSPocLL1u@@VV%6qpGRzZrhp7I|jx z*kcNX$ zj*^1-px2^-#SI4#jT1m00aY%g06jDl8)Nnc3#9rlCHxU?%>#1-R2PVD46IETWq@}A zT4I4(?>RQHI99-2i(5V^pjLN24Cq0qS`$nTM<-Xf^HLSIsCj|=&q4NdCx_wS6=5h| zZjdb%FYkeQ2Z~R3a=?_iB?iVt%2xo^3q&Fmx2Z|o?u+Br=ZFTGxcvca6J+D&aGrTN zH*T$HYBz&y+#H56)J)uZ%9i5RA50%L%k9Zi4wy2(<;LxB0K*01b=1n*Uy`^v&b76Q zb}QbdV==b(19m1V|$a3S)qCBmD-1yrl zZz>=+9s_dY-xB*J(k01il~cfZi4L5yRB8hjJIZJuaN|@?ew1Zv@5bxzzyf{5yYZGN z6^M7^MqyWrK+dR;Swef2Dnf32Q}CUT%#9l~7fEppz>RMZNu%HP5W0Jk+<0+FpQn#O zi=GV9;--+~#`l7-2jboMAd~?L$c>Le8G(2=ZfS5Iy|&%Kjh_f~oVar1(^001D>rV8 zG-_66bK`S>UMQ~I_*E#25q{o{*N+7;Ee^uC@f{ceeBW9LO99N|}?7fUY7CLsD8rGC zdP~(vMHy*kaocnp(epTdp$MZ0+={YX0lmZeF3PJ&h4#xgcIvt+%j=8FXDiEXIaIn6 z6J{jsL|_M$?h3RdFaTwL1+=^VIFw_ME<@>I`o$Mt?ipd{v&)^KWR19AlwIZ=2+~iO z?NH)+Wrg0-_q2;ia*p!Qgn1>(4T$e)M!>np!N+Ipds_WwY67(KwcytvSx+-)E|Ovs zpwsLsl6u-p5MJ~o^|X8A`7o`prh-r4$M|&k)tAc34 z+!xBei0^5Jq$34(EId7JoH*)fhk_rftb9*o??&ei7VqptpJ-@4yiAz)lWsohZD!uhNB9Z0JNfLy2anEz*}}m7 z!2H6%b-eJ838|*vc@us(1^y1Ll+|7bub1ArluKrPspACKd{>{>*-4*u9O=2yd7#ct zHd#nuw-DH0M|y3n3BGH4ILT-VpK3BzaFcdt>Q`Q%=xdA5Ki#>as49DZP@Gf7I`&p#Dd7t_G_-RG7A@kB=jmfe1w3Jwv}AcN|8GaK zjZ50*;H@TDw4Oha=e8B(k_Vl8ga7X#r2_G}2u^F-t4-l)4eimN;{V_6aVC?M14up{ z!XIx=_Hb*j3dc5;m^sVh_oH}w>1kut{LOTabT4(ss`)#<)q>jJR`g2`Y~(KI{|!i~ z$fe`-XEJ}>lH7@pl(-kTKc6fvVXuZESKnRclEZV|_It zd`84OihQ|Q3q>Au@{D5Fv6|~VWXPlkeB>xyP9H?X0m!gl_pWfs$XpY3wF`)tflNI0 zwdU@~T+=fyVL|k~x26s|a(OeC9F?mt=92&(KxQSQk9NoB>NjY@ZKhqhOhA?=+g-wg zzfSetW69_f-RZgJZ{DpW-kVzSN4JJ<+#KqFU*d)WOHR*KT~OyLYtXxZngKiZOjUMo2t$SkCzULi3U+b9BSy={_9^&-h) zjxR!b>Aexd@O4IEzTZ66%OkgN_+~-06NW)@8RV9FsW!oQn8Obt9rcAugA{wn#_fxn zrut6hiyVI*sn~Nt9@D_hA*YR7CzY4V>H!@32+Riv?~fJ$OJcIVy7(hfIvvO_fPX?N z$Ir?qoYx}$zq}$j6-fP_T$m!^*Im!SZitn*B&)=W+hL9#h_wOP3i10p8;mz`fHf*A zYOt=7rm2~&pV4jwa0|rGXm>@~1@SXlW9GB6{2M*e)qmK`&t&_7-(MVEGa9Es)QrPS zwsaT>KZ6|!{&0j}xw^m6xDE)VGMWso+ysL)D74qALqnudGi-yUow8+!*+qc?i|YWD z=s*(nbE%WD<3!m~u5rsqrBSogMOrRPH1@UEa!JEBike{?tlBJFKk3S~aNU4SqGrHG zxuWK8$&z|3*Pe+LXUURE-NZCfS=5>YR-@vgrhZ;_8Q@D1KQCL3vJCO_G9#BqaswlC z1M^U|6wS;21O8qmpn2JPlqZmEUUo-pUZ&X-;F=pIzX{`Yv3S(2cZ#lwC(ty@nSQ=? z2Qt>HMPI@A0!h0O_ygsCNTuE>G8RiILQ2MOeKZ4r-ZE;k8+Y-M_IjzvP&{g@jb|{> zTSo1HZX&pLgE3GVwU|5ugEocP4rn)|QlEA;crI!N_k)B!_PQ6?J&^LHynthPHbRK? zkX5|;{;%yR{_VgH0)L?LXn9_qQ&N|s{@)qM(O{26I5(#hGXuyZ(5HEZ zKQnq?%m%sAsAZP<5!iLaG`&A|0i^ShRBx0mMp=YZY6l+UH;S6^+b>RbP2UG{3)q{H z_WFvh;TuOS;-B0l)n|1d2Ktba*XJq?-Xv-UZ+mZXi&P)5d=c#Ph<@$$mY#9SqGlW# zTdEiJJ_7y$lIqpHpHO~4D)ok*am%A-T;I_2&R$6`Zs#EF^@^V1n?)_+X=r+9uNBaZ z1lLAK2IteqwOT@J8k+Vy+5+h2NM%_;WwodS_YF2Xt;|p*_?hU!H6U)*`#4h9TwMbRtkj%7)d0~nKbZcqK zTSflXuIsX(;HaY5g~wHG8X~K%WAd9(czVl&T%NP*N$wf^9g=i&w-)sX$OA*d%x>J$ z-0%=PGZ|W$Jseb~I_4_$%G<>kWhG18r<%}>$~9XA-!B_|6q6rD_$&x-f!!8?zY2JK zZu>O?YT@(-K+k!gmJRm}t%EIGR96#o&93MS@EHz$3FuQK)q>&T-MROScr%Pt;@UyV z{gk%sAd+6Xs|2$#;>z`9zu~d%nP%fx?$@;WIU2ra4bgoC`RaQ%fo?7DWA`gG!7ACH$ESNKBkNR#ycEF#W12sQ& z)hk0{)jagCIx(Dp%?bQBV0l@hdP0a7$gNGznp5F+%9WJfS>ZIVeU+(svRLU~ueoco zQ?A1+OkU5&+F{6$UtTU(WY@EqQjge!2+5=$eB^$8dDr1mA}&NG9&%8H+a=euUvDl$ z=G``R*cB``P7cg9*lK-=TL<7#WO*|F9wyw|)prvw99!ac%Qch@>AZ`kPTaV>h3jSE zIa4RjZB*fQ&ow(|vS!kAr&e^|uAzJEA!|)nkxatjFE-?UZ4Plp%(nbq?CYD`X8ty0`#FbhAiZTssvRSqMp=jS z5v=Pk#C%TZW2B=#Z)?fmJ2=i>2W6#`iB3=8Pw`%iD@dx3-foW43GwOdGo6@dFdUw%xComXgkm!Q#a}Y7zf4-1cPGTu`6@7Zyn_XZxx`;{! zJWA}8zyy?25Vw=ss@Yr-H9McVsT(y__G-5?!Jj2gFJ)w$mhK>BG;JfF$>kis4Dp$) zK)GH7n$5C;qH+Bgtc=<4ZQqt#lFyyM9)NNmQmN0k8hog&9Rb#5^8wUOmgkSr@7TB~7EjM=~-}=UbJ|SbUx|k8!>aRR%vHqy|k5#O< zfwkA$^@eR0HN&bT{&oAT_gx#i&oOG%E9$kKy>;k)XOsC1#P_}hD3>681k3k6qtjYN zKeNS9vDN!-1iV6Q^}dHt9ze3P8;O}%t=3BK^JRY??6bmik6rKW-yE%+qik-hS1;Au z`=0>$04diVk%r+Sp?0b)TKhpLDtc?|Kp8yK7ST48H_ zM^hQ0-3{IX^O{InhgCX%g?l10WfgOZ#t2 ziPS9SK)ev~&BBmL0XrjUE#vR11vQIn!C$QmeX}r9T9-t#*tZ)bHH$kT+>WGb7Hd(~ zD4^!?3d&0eBOmR-k}HXt*&UnAr+`03{Bod!V>v%owP`K0n#*q-{}u7grMwT1%@E&Q zI-;~k`Uvlv%ZQl7&q~6YOAkQXiKXV!7iC`s)Le$69E$knVr?r}-)H>y@}a%?8cYC2^X! zRYp3^Z$o$!@u&G)l&=-=qrks;4~>B9a&X91%ffW2at7H~*i30D&snruro=zi=250VK#wsp`o2$v3Sd#uw9*>Y@X ziufC{hGT9{b?L6+(C+w!ctf^5z)cW;Lv|aKtr34i)|mOce1`m~aYMEz_-b)Fs>qW*^LFzh%) zw)h*ekH=~?%?cpWjy

      0hS(StHZs z!PBoAt#_f%6@I=4xtE~Wvj~wTnZs-Mt;DNKGR3kpVo8>c|7}U${tSX?f?(MAbu&7# z0abl;kMezVPa~b1o{Pzanu zat02ZAX+Z2xCL!Ej>BLF+Y;WekD;e!=7dpH;TT6p%^DEPkl|=C3Jw(FSiA)S1@k6c zWX7|HGhW9<2pkDZW_#p6$NhJdS1PWWrD#VQz0@qJ?%t=MDm z57s~}^UK$qzk_hh_sA9fy0S#EYvjn_r|8Ojaar|GKSkGZdl^XD(P7YV{tBEe8~7tS zwLdz<{{6<{9Q5c6^7+GNCh=%)<#_froErGI<7itK{n|g#X^UY#f8(=A+P~3poaxMG z{~i#YWcIH4`#PtJfaOV?Nm#X?VZc_7$w`QG{@Na}pXSMufn9tIFSe&Uj`iQbWQHe| zRwiFWD)ax%hELd&%@7gGG5GRCpsFX#RODyi^_@Vzry}h@n4gt}v;P}nPGe*gSk^KdV_cq&hzY$pc?U6rHXxLZ;AyLqZjqvWoWIJ>F4wu_ACJM%u~ zcd#+J+rfqFU5k6L51bt0r~PVVKGz-&)>$|Tq=TI;9L=PIoo(7hBjp_LrT@hQIbfU5KZZnhr(#}8?R4aN-Z224WX>(wo3B)w`D zE)Am^(INbQVRE!4w5&n6$N<<;s{n?3vfoDZ;g~4WhI?wVg~|6KOVdg`i6lXV`d2yYyg|BWo!X5EbT1CAQfF;qDk(ILW~VbDnX3E9XYAN^D} zai7$bV=M1{^%eHZRA6fXD~m()b!Hp+tmUtPNVkBubt^8BNQe9gwbZC2Bb})nwds&$ z1Cll@8^V7Biv!hHkQ&9zLc2H`;$SS~C&Ox(9y$z%O$GKk3s}e#OVnPe=HFh9rcGv?9^|GxuXZ3;m0< zzp{P^{>|v${&IhQD54krZ`S@C2?#$=7#~gl+1g)@Kk#kfz7R=_++M&Xb_=lKZ5OZqSpW!0Hvsj&)!c$eJ(Lw2^eIxsob z8}E}N1%!X+HdK3t|1B==IVm#okq7#>qAEv*DsM&AqeJ+4P{8ldGR=!la^=ik9xdI0 zSH+Xyoer`I68>iZuL`Hxu{=Cy!f;GP*K5le(xR{1W8uDDZ`sG@QT2r`A<+;2B_Ny1 zb}e3-;UexfGkXZ}5ZL%1*&5?P!IFQ%SiLr22>BRFvFZ{Rm|Upg4LSU-C7uI~Sv)I2 zr0y|t{_Kc#y7w%R0(#DXPyLUec8|%I?2RCdEV;IkD}{ThtBQeQLT zcy9;1Z;8I3>Y-;mBK5HHoC%Mq^vu35MWnv2)Yrq~5qf4~V3c}9A-{yjae5XUN*1Ya zD9_xZmPiK$IL;_=(uv$YjJO;!f|Y+qesVA|3Yh*NvmG3dgIP~UBRDRBxd5t1or*o+ zlly@sDuX=tBp9yE2#3WE`AaMIq#pkbx&0tuB2Y8O5S^R|7@{tWVN6mO%?Nabs1Xb{ z0NK~TA=3I^P`9LH2%g@J-Z9p^p{R4}7x)(ApplL#TeM+XUN`D?hbcP=@iU`w=>l8V zfka?Ky5XV?(O;pPY+%68Ky({G<3Wi=FoH8BF0I&#H`Cy~0`esw8?!lxLx7`09f4>u zh9-{~1vmczlgA)>8qmid# z%2cSSMkTuh-u3`o5;<$E0hRbLuwdWr76Z*;2qAx| zM~!g&-$=zNz@{M5lR@U&a4Y~bmyZ2#tOrvDO5g}o+lbiJ)}qtR1al1_F9Q1lm6yWt z2AJ3A;Arz}FsDFq`I!-Yq}Yj}wq(6%o7VvG51@Zhw=o=X$FR^0^1Ox#4XuI9a8sw! zWMrBxivL8KJ_M{P@VOx2dAgiZ)YVEEW=z9NP{Ipy3{u)9~m{X1vMnpck+`K(d2~<0HCO^17T>G9Sw^`M5q5_`%fS13Z6$ zW0+*tda+^&N|Avy3}PC-f@lK3<3Pd_RSxKPRg@K_l<*e{P&L5JFfOy8H3MWO!Lb6& zGEiLkv<0rV@^X>v=}h){>wqt#PWhw-uhK!%3b^@t1bIZdk?;wP#$urs=uC|#2v`VPR;)Eo>)jgKr*5oGhxEs=A`TGN!8vO%eV z$=3k@^#qxjaI6Bej9Q#BZho+?;c8h@i;c%8@O=}QSEzIpj@T2(a*&6&YMYz12q)yv z*k}ee{DV}oq}2z$F7-TzLlGs@Rfoh?`kG3g1J)i2Z9(QSIC_KWDJ^V-Yr7L{g!5<% zo6Ll2|H8s*Q-$250d%yKA3l5<~ zxp7!+wqHyO!vKr=7|W?3;bCgEQnbst`L)`N*-s^=HUx!aDh1fWzU^jF{Of420Gwd} z$W}EMpvoZGx;6k)j}Er3?ZC7F$<|d{FkM@2Twg9y9S5L2sLNJ%IGCZ-Wh<+7Etk`} zx&xU6=mhGrwVey56og;kJ7n62ZsaR6@@vf0j~Mw&5ZwpZ3Qz*;jmDWS=jMzT&v>je z8-ZOfP0N<_GuN`_bi|BxW+=#3fdzIaG@hka;^VIwLPIT4i_uwYrkZcV`&|GIfXw}H z#GkZ;7i8{$qZOEXApR0=!st_%J&()jU^5%qY34LQCIdeSWZw!$0_Re+lGo+5Qgopi zXD$U~J{0Csi8Cm1Pu7cs6myl5wLf6K2*iWHuLOC<;*RSuVqH#$VWe3}*=X&}X@G43 zeltiUT!+p}EBRfnoKmXU50G5|KM#sypQ!Nxmviwuf+oAeBY+;J{m3uCZl|p?fW-DC zL4_y-QzAtkau(&~m(cY7w2JyTtv3qdA(s2jm_ z2g#l)ksXy*HKnTCWtr@<<^egAs_eR+0JDJ(c3~fbc^_1d(Uo0T;8ROPfn*nUr<SnSFD~>{3Sslj# zKNh6AFby?@=5!ID(iSSQ3!4Rn86eptF9WkgT3{D8)Co4imG8pN(E_`$GAKMk3+%$S zf_YL}U>8>6TF{&>gY3f6Fj-@>MGygYT^eGEb;wHs+7rO;N_JCwV0O1O&4zn|Yg%)z zX>?N)smX?0<%NczS#-0~$v}WN63o1?*^LViyCaQ@ayi#Lx}(paA-khD5uYO@AiPJ51@N)|b^DGFmBP(^Sedz?-fd!u(Sp}f7K(ZsN1*V7& zc4RHVGzZC!Ok2RF%`0=(>BzbO+L^lS$OeKLKwWlZS_A#l6}q}38w==Y>aru70p>0c zezLn+>PB93ZbqZKxr+&5;aUQfMO2gBjfPr+XRNv1&Eo((0+QX$cVN!Y!R{vE3roa+ z_>CDA{U?pZs-g2`)cm&;t$4p)ki!9#-Q6uD6 z1CaS79NoZlp@W|q9tdUts2+6^xyJOqd+RH~E3MQ>GJl2lSb#=T>l--cftdrcKZYZb z+f}rdA*dB?o2fRprkJ1MazBvwQuTc}o&@taDDAWp4)+rC0c@g5kB1|Ok!ddIk`aCpFJ8-0#BSKxMZ+9L9079}Bu5ikEn-R=a7Pm-fIUuSjwa56IRlcT3ayOe z#I6Wkk1Bo#^diW^0m3*pvJpN$nJ5hU-fMwZuhbeus#2+(8@Zh;1K z2orf!mG@kWa07YI|1}a;`BB_>&*iu8rtbh4PY+~zHp zx4I7$deH)J^>8plX@R#~TkyD?w!qtO^7c;xb^^#|F_5>v6s}pIw7E|B`u0yp(t1TN z-!>zn)n{%6VlVVwqVD=~4uA@WI!P@=NiWoP zs?xF4k#N6#+5?WG|F7ycvqFS>_rYZUStQh5ER+-FoEKCR1b0aRlH$dMn1#@G|qXe{J}~>L`(3&#uvcpgihS>=hCX@z47rXJ&2A)rxT6 zVTj>$u;_^%1F2@?KCdtuT8oOvxS5iH&S1MIwL&=tQDvraIb2p{Wj zFu{))kO$6?9~U2;Vz+}{@9^ly&Bt!2D2J2@Nh38z3T%LZ(SOTNp4}1c%|B#I+ z5A@M|B=eIuJ&TC_m?-t~7=H9lyatT_r68N(*hRRAJqE-3vX1V8_D{Bq zUbyZk6gSR6%k{sg!Oi8;rvDWzBy!5x`WzQGr-lEvJj9XyiRdESY(%CH6-FRB4HA(r zR~zG^6GO;1>=ZVjQW5C3S7_iiJ+0PW<*K0ZY?RXQpF-F@0Jhk5xnYR#64qU=+PHNW z;i9ruH!~tzBdVLNWVZO9=p+Q!ZmdVO6}cnS&ksRvqyH}LFLyD8_dkH!{yF?oBYU8- z-91p*Y7bO+|9-^bFNI=a)gA)5$HCtb1tK;PmYd-s5nOGn?hNrtW6dsn zYvL;-yFLC7L8dlZQzkcBKQ4SUYVCa({BNiKtjqm3-;VO2= z{;vYRnf^~-?q3a&-b;Tg>B>l-Fj__;odj_m?+z@*o;0$;NV)G*XgSIF#HbLz-z(0+ zM(Gsue<^u1*88M?ayTQ8#!!(2*er5 zA2GxH?<~iWdIZfa4-)<#;D0auAJP8G=#Nifb&&o$v_BVlh5uUMUxAnTq4p;}Qs453 z_r4w@&fxz$kWIAkKfDYJjNr_uC4s{_TLGIwvYec18YZn4Lw?#>+r|YyzmCGMg?n`g!Up zje^QJ1&|sqX$`r1AUFz*W%wTUKUGrDTIOSG1NSh??Oew0KwZMq14Wqad?}E{=*rDJ z#-2c~l)R2(zm2_0B5S6xFHn67TG@OV{Hp=K+!5{np%5FO5P;PT7g-k6=7qHgz9+m4 zKA+0Anzl<0_PMg z4%ywv2!9>;^HI>6ce#HrMBqMnnLD+ABm%q3MPPS<+Q>uoWoS4L;h%FaHkIv1c-evr z_O>9UoU5?7@>VVa8)NbAI=swyOi4)p1G6q`If$QuXQfJzR|TnsIsa(r)rZq;Szb@% z5i;iuya0uN&T`lUVFMO|=LDEF78eXgBHRphxDYvfr`90Xb3ChA= z1Q*1B4n$QZBy%X)0(O#)2=5cg2X$f?}%z@K|3tlgLUSLulNKj3A4 zQrCGb~rh7;%#{az_n;;S1 z&j$T{u<`dUz^D~o@fbD9&ppKthU{yfZsKnWHso6=s#PBl49QL?{5SPE+4=v}KNHBJ ziqiikP*?Rf3vy8Wp>A=Pgp95#yc4o<_5{4lZrWdVhqA9oH>*kIJnBq;QHa6#9}Tjp zVRJVH3ITe@so<>TxJbiJaY6~YIVxS1pjX#m|2sijG)NBj{0$KLbMP`>*8Wr$d4#>5 zqlHJ370sj!ZtcsWWzlT1q2wvu3 z?eD}Hqv6}l9A=;DI&U}Yvu*01&z{bhZmQ3Qh(#t1u6h8=UikmDPfG-iqmUJON3qU5@)>U90q=T*P z7BHJZa?({>FkM?tL@@HGELRVo2XrTOIq7-`%mM0h(pBqXM#+hX*42})9|C%mx}0?V z3e0H`es>$pkdBCRMP|sK@ckJSh&ycHgH9@Q4AGBinr_xk$VQsdA*%JIB?>@kX%1%C zuWG_!8f+$Vj8oB7E}`-aGiXnOw>c7*&d_WNGH-%oHkj#ja2T`-%t}x_Dm`f2L5<}d zYI0DM&2dDYV-*`10Kfy?YQ~6TiD#ho6wPpS@iv$vAd$@uMJt(NF_kW)yhm{rRpV^&h{EMo1g;R0l&_G{AhRMIZNN0ABMFWnU~U2>^5r9KAW9lAP8jj#bMT%8 z`JGhw4;*X3tfJ!)IQD{h0pzKQJS}k3ra7;37mY`a)VUQ9mllAX0RA`))Q00Mm@^<1 zemB>`b|e7rHhE;S2qNR8Z3&oW(xk@YII zc>fOq^eTY~ya5_$xm>gk$}m!FX1>hy51{crwL~=zUt75LHRosv&+nd^Y@0Z)Jqv|1 zRLbT6^fpHaX9_bXz6cB>j>}bl19J%^m+t&$(1w9THI8hx5~dFw^%y54osG{BX+ zOyJW&a^)@`Om!MayH%@T_^77Jd5@N3X{ftVOPcXlU5)tL;tX@{_f9#sa@MRpMOHg*rt&sjkpfP+Y$LJcY z#s0no9z#F@KC6D<*camHAwaqXtL&X2a0G_<%~3Y*hWFP{`VwT`3CFKsF3>R+ z4*MH0q`~DKd~qNdzKNi;-yEB#3)JmqW$b0tl6Tu{^ib6@kz21c5_6TT9^HaPa_?0x ztW;tc+&mV;Rek{ztJVY+tRcsr|_ zYXMzDU3Rcr!8}P_cCcC(b<>HH*3}*C9zb_fmmTbzV2*(B^YB^nA2%VI^E>)n?0ta= z;WOn)sGI=F{Q(+jy4r5yvG6;eI&8wu0e_Z3B@`plcxy=-#&f>Ix!LSBDw=$K;!l8o zr-BM5*45CQ6Endb1>fsnV$LF3AhqqN&AEAZS@-xoG|p2?$QAuYjvBsh z>~bn(ZXoN*nDajU4UJ3Gl4B7K#XFm9l=KF&}Ee9v_3cT9~Ibng#u(v+&<$%RwP7 z6ygCvE&;R+#Q@pEywa04U zLVy-XAZI+sxfZ`5uwAf1Yzpe@EN`#jFw0jaoYpe=4GAGf9eG$aURk<-b)yK&Q; z9zhxHgOw-b!}bG!-2jzdAoCtL#)G+)4$e21f|&tIV85+xMC`iO`g^iuAHEvcRa9ml z{y3N|bg&QK1?G7=*oV6g_Tg{9_cc(OQC}5a)rafe8)->kzpbSa4y&;8hqM&RKKv_K zIn6NGhyMcRXOQf}wK6{1=mg^E%0B!{W`vx3{LT^vNcG_wYP(8q1Ay*0y#PvV`VyfK zFO}GbM>+N*oV*?b z?87zE6q<7rk9yXLIxNc%0sjDll6|<(4M=ltHtRn8F@QHwK{c_-u7>8^TtO5241-}4 z`y4cOP)jzk8jAf_tTMWZeGPzDL9&TG4dx3v*u?$<=0^~I0j}oU?^Gs3ET(}D!7ASr zA*A6DC4P@~8f0=I=Nd3gK#6>*RV(3HoJw<}!sae`kA=L13QxkZ2+SNh`18RTGyz5(V-D)oXR`3Dq1ka;Z}MPO>s!FR4ZgJ};+yRm_)T<+^? zJDp=I@vOAnNm&SsHh5OD)*HQ$XgONeB11f_5}hw=+BldT%`jNg?g29oBx{;hFoova zdxOz(mzpdBDF2TFzZRrwnugl0l3N5&Y48aaRnwk^!d9uon)aM~KQt%r6@p_;>s$*; ztZDn8um>b-+S_2>q=Pl>Q!pn%vZiSprfb)Yw^P%;1N0nqS=0Uk^Cxv#)3h$$t#lh) zrLAk4??-IF1Ie0}0VWNEpR8%S+=OT@-U*wdbPB49-(TiI0y%P|ytaJ2l9 zYe92v#4+&wfEL(9JPL)iQi-Ew4Ygd(%^xVG)`1eoj88*hD@cwRUk0;RTHt8;6E|4R zxxr%K+nE;FWxNB0x1$o&doDD zO13$3hqA%@ves?7HRom!n(i?SkoTnk_G>T<*>r0t-i~4;q?_*M05k^4ruzmkedu7* zJqpZl5PtqqIcQX2*Ww^T&eo`qws=XEfySMT!2bkCMMjrcNkO!r#SzyCJ!P024Ym;VQjz9DLM;K3a+ z1L7%|Jc=HlV5}W8C=M+i)&-Pnq;jc6yt@ICn=W1xe!B|30s^n z0USdzx$D+^t30UOBo~$2;huel|F1xDkFN0lURQ_motvZDy-uzF|(bG3|NI( zV%CU9Y}Ja!5>xFh%A=*%He=-x+T8GI)0X`gFEMn6a1ncrEm*`gc5tib7?4Z@S8>Zl zkIHQ@O*S3>b3k&pukiOqLFaoR=0;qk-Z!%@(X^N|MlajU-3Ge=22W+ zJ&{MqeJ^3D0RQJeHbEk6wZhz8hX&>E@z0YGPQx^LU;7>=pF0jWYres(iD@qHWrq%U zii>Fx;%)4Z{UG?3ioc%ztuos{0c(8dZu`KtH3%0O7g;hNGREWN-3#6eI2oW0aBYtu zk5

      gIAo5QDeo0j*s7sl_8Yw8K4EmkNH{P87d+m=BGAMlS_wHvHBR*g8kGhu~Zax~9$hL6P!jEE9DW?zic0 zP8u^#r2HM1-v~Lq{GI6yJK^}8b7s`6i670RP11Li_PzJIkod(6 zzbJhNY2QoOb@_+J_SL>?nuWyQ+P8=H?c5ssSuDry_1d>17ILF3Cl0M#-zFgutFcYA z?^MJrsD0~e-_spJB2oL+a(ufEy*?yDAuDkTa=_}k5;r)Ms$JdN!j-06qHFtW;mUAi zZGJ-$*xnICfQz^@p#m$KIX&!xg~L-Y-~DG#cotf5ERq-CagLt%AOfKxE65vA>ld`9 zpz2$(&>X6%klo@EfAvxOxeRKWqly(MxCdavehbOx4~mPD8LN`4>*MwCHGA%Yz2(O z0F0Q^AzBQ~0+7jF2AjY<3X%#aIR@`$3K7qo=w7_!*&V%`u7I^M}Ja0hjnO9lR=M7u}{tp`9ntAL+ zykZEF=M89GJUO|kQEA|L1IL;e>b!w;;8Q{Bya5f3x>^bE>ThleC7w4>4GMW6dES85 ziM~olpEuAD(E1>G-hhVVd*N5a%RO(PJ+N&-k@E&L)O(eZ9%1(ez9)6~EX$u<&(?ae z;v3w3o;UCg)4(yV!oBk-J)d3X-GA{!au4;f+hkMbA+ zjli?b71(me2yo?Ci*1*Saw5Y64SX#3e5%-mcs$Rz$RXWsHzu0X3Ej%&c1j@x<4Mh9ns6ZlrP%5|hI|>@b z)WR>o-8n0qQ3O6df)+U?#)#YA8X=TIG#j|dAd@?GUIOzRD3QC%wGt*jp=1n-N-%$e z_j$-arvkT|SN$C;aG-jGRJ0SYUl6YAKyp@Do4~<0G!Yk_`*2Hy%c1?Pz>EQ@3E9-KgkJjKbv$8Q3BgbL2B+U~}46Ky9(S01fxe+t-1LghvY4aAg+qvFoHCPt?` zMJ2A){{V&WKyuCA`U5kWAoU{XZbuKXcDQ&adPY)o%3R(*?n+37LJCM0#yl`pK(a7u zHB&s#xS}xTQi+AJAu#o+#KPDfOj{5R%0!F~I)Pz+ms%)SJ)srZSkM>9-bBlH^)))8 z=fqJKW0~i-06dBcB5m4ds_vh{BDbuR`&cQRT^L;W?ZL|pMr|6A1=svkX$Wx~u}QIw zxIt}^23c@nb1Fy{+-+d~1Cj+-D`B%0lb{Rk$B@5I1s2?xKXDiXs2(A*;MRew03-{p zHerfiX#xee*EI;21-CmeT|uhg`rQadv57#z{fj^r++hF>0?C4_aad;~P8ZzSkWUB6 zf~zs6s6`A4?qS+u!CeE)YLF_p8fXj6xw)7S?wGdK)AQ>sMe-Q%kU;8)TBhpk({Yz9S!ty&igc~@9*hpo>;VJ9tc*m@Yu zAzE;Uty&LF^%WNMu=P0bAJPDat!KfU0m)&j*1$rBn;Mk}4qKPBLmK$b((k}u1gT-G zhDKejgu&3w?V-eBYs_B=1SE&8S||D{9X)K#05lCGhpig!xeD$MTl0af4vGw0wUYNL zB|U6y27D9hTsCagda>d@mPMptKGVQq>-7M40;yrE2KuiGfJ%+7MFDn)tv5rfA4m>c zCxe*;lEYSQC2+Ns^264-z?V{o!&a>mbU9rCE*rMq2mA^Uesb7a?A%mCXilp!!iyPU zci5^C=2h4$hOHWCyTJ0p*8MOlE982_V;$onhpnUCm}t(835Kn|QHjIWXQA+nRN}Bz zL$UhdsFw>VSil;_CiVanUZGOqbO%;`*t*YY4X`%ha5`iTTQ}1PhpivNz)_GKwrZq# zwT>RPo&okNkRG-kbBtdxY_*r8r^Li62d`bwlt&ASH{sk+4g5wfok9HJH)(W%s8 zZgvIedIIIZRRb*%;Z*)zK5!ibjhm^3UpC*VNO7jS(5_)RCFK|Y-p&YsuU3o)Yz!!o z2cBw}DQ*EQtxa^AnfNPCU50!<$ma2rC&jaFN5M1osJ+Q zT)Go}czu#t2E==SzC$=Ce6`^S=fWQd$wPp?0Q57EJgq^)v6;q6ord$YhCVVM(Kh`E z{P)!1UJQ-2T+Z*r$jC4f@9u=W=c?Af!2b=By{gu+T^)7*P#`dZk%b}n4-WqTp)~MZ z+yeKeYA&Ed$;4yWN#b2__|6SyfBBJL@_ zX8Ny3)HxY_4&bvOc>s%sVTuDVBP}*n-h;m&|5F;x=BpIb9Amb4n8yB&o6!}<_)bOO zUo;XRc}|Ol#fqnB%rs+;BhX0yQ~|&&knEp|z!ZRF|D-j2ZcsWkM*04!74R*n!~RL@ z_+3uxT-HDJ0KOXtzW^W8wOW#Rm641xT=3DD`Bf{(BXpBKfwP5k`+-S z(d=ER<5a|WVT&LLHJvXw>d2Tbm*=E_Evh_HEeGg|AlaH~JQ`RhfFzAaYwBY{*qYV@ zz7BObSkXw^<=nvvTGNl15O%Nafo}^^&x02n^Vs=*WlHq(;0*xxp@M3H4R;n!b8ggh z6I=rHNRVuTr-7LYl1;EyF-3FES5-}gb)#eV z9(BT(h(jxtY9Xay+WJdj(_W31=&@z7J2J0J@0LO33l&ed+P zn)5n0n8E(bU|CXoA(S2BM#x%*+7E*goNg7vUnYeULhg?K0q(fMjen(h!<+ zg2Ae>IvB7F&__Ug%60{St;wfnIv{=) zcw$7k@EXUTAhi*M>*I1Gh+p`)H$Z;Ek;~)K6N?5b=~)?Yu8vDjukbw%K1k2y=2EP) zr)>59gbxyMLB7^;H9Ptg2Oanss~;HT>^Rt3hdU11B9ohe)Q*F#ZJObIqd@xaxzh8Pgdl+Ubiwf-^Va-atRO<=}a_<=_n5$3P8V#CC{O zGifu@7h^3eRgWbNXS556u$i=5`p(q8$6JO(B{S(=>Dx;ChHu0tel#{s`+Bewptkn) zYTwpa5}wat9>W+4T(FLbiv;HT0Bw32sryLGb7YYV#*TyyHf_m*93& z-p5i%?xKp^0x(5+Zi2@eddj^7cPP&f;qe|wwDBJlV!vx>i4y+|(Ru1fLraxsN;F0Y zAZ2Ko^6UVQwjhzsbu9l0RrYW;4dR#bR$SptXo0vIFansHL2@-<1(-!3xf-B#FnIwT zcQxQS$hT5~s{yCMd;+RRh+GZudJrZ^zAg~&20NN2Fv4FhHfNIl1CAa;u?pn8^`2*7xP(2{dht&?Yp z*9pT)#Xq$7e<*toFe!@X|G#H$@8-B=xx^s{$8m6QWR47q7(hiOD2jp#0uls4L_kms zAYc{+BMN2|F(*`1R1g&r%vn?f6|F!-P{XW0{K2PmbcfG5+x~Hep%=E}m zdM>az0@XWGRX!7rQzO!Ba7SvNV^ESs{zWKU3h5&MtuVKU1)XQLwibB5SCZl`)IVq? zWS*t-t5qN$fpkU5fkX49fSEBZ5wI-i>uhN~z~{uY4tqO!(~gr2%1>66UJ>VH*!wmL zZ;FzxDmiGDahw}|`Bf$R7-Rhzw$ZY8p4bJSra!Uh#@TXHc-K2my`-w0VVl7$Q%(&o zd7*Yfs+m@=FY(|LNUN8_(E);!>XneYq*|>~xpbpY7ZJrbnFzI(SUGi0l^LQ<%%2fX zf(vR0ZLt*2!QO2<}kszx_A!qvmw3V7dZVw)RIS2^2{16w6f zt(OiMdKEPyr=EKGjwngJ+J%vrnO$)?oB(+XPkOD9!)K+0+i}NalLdc#4S+&r}^cF>}0 zFX?rc)6qChw2aYJgTpME`;nG&XQ1SPI$uaya*bSw#`&VvQdY{2^-ej?rB(7^!+|5w zkyW#6z+VmNDy9R5UfHSm6|~#I-X>|pj*aq;InF!wP~*9hh&c8L3M)mazDuEhW&F0Y zyjraTKpE5MSg)2z%J@wqWk{oubxiUu7bznejoiZ|*SJU-j%Z{@lYGlX%4kF*3rzAW z_-lez40MJTA1%X@myLP(HBQ#j?pN|IUNE{Fl8*As;Y&EW4!Sn@k^#`rJ~GCvo0l*N zNQaBB2f@hgcK9a`s9qKX8(mn2i=%?z1{ap$;x9q?^ukPN9$Ov!NYJ3^ZzMjkGnT!%i$JXkwnE{A%bw3e3Qq}|Gho0UqKVNma$ zbevf`KVfpAc$|4upySNe zL^PF1eP;FO79Y|- z*N3MkDoHc7uEHKK>|OBp;b`U>;ZXX{NzH0}kbbbE`1^h@{qmzzZ=FnLfUyGA-puIF5nnz}0}TQOFeVPI9@n?cnh2$)E=(_HT} zoaSuS?+%)LD4MdxW>>U2LndnfgYinC=dxoRRy=}!#gYyAr00Gp^j4)on0We&_;jW@ ztHa`4w6w?@c z4h=dC-|HLN;0^+LI#_5ibtTB}xwrzJqZROE44ov#`W*8ns{qrenmc4NnJ`kdtHzrJVQv+Lg28e39M8Lj+RB zxkU++15s~fe=p~AU^a@$ZrM>N`+SvxD1nM(dsT-CW6aD%Stwhqc0=9?N=Yqr819UU zoee=*rDR@e-XJiCK(^*dC3?eW*m1rRZ3wyz6-}u`Bhfk*it9rcpE<|*%xwq`(fV)_ z;1fkbe&y1T%=IaKhhHTZHu~}ej7wuO7u*?;HYT^i+#~^MOxD1xhO{wp1~N^>_T?h~ z16MN|69>-9NH-1cJwftClkqOb-!JCxCwI5XKMc#FcU*_iwe{uf9a6Nk<* z#e$|WSuc5%#-wgBD-w`4CJq8QAeFicclV2nQa!L;XzaNy*m@M!G zo#t%TX-wLPM^aCZKdQzfb7&3!#^T$~Phr!l!w zl%%3hL*Zmm(#FI=*?7dN`^w`QlevKBhysntt=66YY)o3}TTyMf@bq_u=i+e5^!@`U z;)vXOT!hU_A-x6ZfV@(*iwd_OL)q@~7N9q&8|8A(WwnPj=j@hDAO5J=mD?|+L}Znq#2o`uIP0eLEO6a zZ0D>K@N&7el6H1@(TUdCmRPBR)Y&4RT$)Qe`}CKL}?X z#5wCr)(LoYpoX*ko^s9}ftAA{b+&;|F3qK#y+d@QWXFI%4pL_wGBA#dHR%6r$xZ`$ zGK8}Z;+&Ox7FrFQfQRpEINN{HWLvUxu`&lzXPbIw(_GrwA)+JBE&_ikq|Q1dTMK(_ zt7DzL5$N?0&N_&5R&HOkl$#(=^ zel_)6+QUbjhoixdg5vt+J*=T)J)8=33MBPwXAkw(vpVPmy!o#V_Md#REy8oqoDHdi z?YvuQF74n@(UBs&1^i8rI_Qvraa^pCzFJoTeGtMy2k}L?kRsF*e!kD=9Lw=$ul{JY z8&0*}K98AaA@z2F_ttTFRz*&Dj_8QDZ-IXUQg0oSR|BoK*RjR}J?}+D`p$U)%567o#eFw$^0l!h09rM(TtZ!!1@xZ?Jq@w(=+| zms_dxGUTS+O}51JeyEOt2l{#5RWg~ru+g`tP=YcBZbNZ2hja`)5awVB$Qbwpm~oJf zft>;F&U#bv>5#GMKO~3iU7G1E!O-jDhE3e2%0hW8lkR7D5?gV5gjIZvXcQ z^)29UfOHJ(&^hKYK{E#4D0!4I@MkBfy^=R?~(x- z1Ahnp8z^H8e3Z{{nzQA^7`R$Ik}>e#X#EMrV_*jjjpH)Mz+*&7#=xoFxN!}cNXEdo z+X=PF;A~2afv*uI83UK0&_I-Q4D6IbuT*0U+y-zfQQ#_`W^?nOW8iX`K<=<8J}<>m zM#-#}FV7%xnM3Z0ogR?RAssBCu#}ra9*O)gNDJO!SVQqfZKjw{P7}LQ@RPw$g5rWt z$$at;U+}GDJ%u^sQb9|(oeA=EC@z96ej&nf?(q?n;yL8SfG-pUJAp2kTs`l?ya}abIm#IbO+RstE2iU2cg3V+3CaNyX1E1R0-#sP zj~Mw*tjbkVRG-@)P{vi_RCCNpR&|$Ur_SK3A-zf*Ix=SqnyX}>Uu-5D|LM~_%oq+ed0S?mbHxIyb{$`tL!C!FBS!A zV3mdccMX&&eh-V{qbKC5WMQLCv+N1F2|G(5JweaGtd)SApsg?;LfX7J1DU2`zvN_n zNLDhMHwR`TS)Xni-260q;(o{YZ<3mvxV%#4KTyVrbIRG~)_*^7jlh>edg2^9$2?+B z+?|p~IdR>=bcXcAIb0Ou+=&~6d;p|ZnZxAz3}iNM?@9*bDw_cQcqpTJ>*F(==4{qE z<#og(IpwFKH3N#9HwO)k<1(AKKB6R->3Jxeqe{}ey<$^Jb8$LUF6zmtq9o1RRVZ8` zO4__RC7$KC>NT3TTLIr93RJG+Ea<;0m#pcX?eqMCRIVA7E6*VD>ySK*od+OY(|Z}_ zMW~CQQqnFuMb`TyiiNe$Pe)T4#?JwM0%^nOaAAyd4I}Hvyxhd;m&G-QVYgPXMPoQe zY{_Y=08errb*A zDS)Sm0-rRrYdZUUpf~+$Wu5MaT&#N(Y>OLt8LQ=W%jW&pT3J2p!)s{kQqJ-=Zt)|{ zA>+r0v-C`Sl%<^cBsUk*r5p!joy9B1DsCy~Dxg=Whq{#WiiefTTIBTM^Te(!<=g@2 zHb|Fp-hz1zs{F{}WhrMW(0^UZ`Q3tcTFNQ0BTQ1UTzblSYKOB(RhDwTC6TWoofI_k zDrqjxjZ6v}ijGVQ{sR98q>}=Nw6mv(j+E>W@JB%L$Xm>R4wl2f7HtSqE{> z`lTEvU@c%5D_ns~Bw?BJ-HeqRC1F|0aX=RAc2RM2zK4N6pb2YLbFdt*kS>t(4m{fy z$QvlU25Eux@|M$FxW1j(P;vyvku8Jnb)>D_Uv^9+8M%G2eHm( zEaf-}@A+!u*6-@MwmAEux<8~IKH}3zb7>FfijEZLk>CeI>Y+ojdK$GP59+QCZE5eKgVe+8rtI%HrR=XGom z-VXFO2nQX+7olIuX;AjJ_66|IL+Y(V z@>HeO_Bz(vcYwYH;jM$X;`B>7{jDw?y%y(rb>`dR+>Yj_qOD6g4#%fnyssGM$7MZL zbmX%B1^iEtUe*p6)=+Vmb#5bWVnQs0EVBKdEahB)IlGkOx@1|(xham0mvUBF{IfRl zUzT!QKP^i+J1k7UV^S+?*QK0X+d9ZnPFP5H1!1B#|Tl#(woI+a56*=r2B7Ka7d zg8KteD=;mfUJZZbT}*4bD8`Mg6}BR_2jXr5+4IXZq&S9rUK}1wY+uCtL)C{9;8%EE zMye&=uFCjJT@yA5*QsjvX zt0WfWC;2*4^7R{8Hifd5;2=E3`7dByQ`m|NTOgg9{s6NBil?Tgd;=w!WuGnM!&wwX z$%MMUNJ)H*B)go>MpWg?c+Chjh2jBpiNF7w=F~}3vb^`v=VL$y(4E0|gmeJyfV_Y1 zm17k*fZiWyA4wvZxwUAbe(BC?q zi2*6TJ+QD#wRjlx1EL|-!fAx&LeXH!q*T(BYVi`74Ukp~hs%m_u3CJCe5=@!X`I9G zsFK*?>72e75G&KTKf(MCWz4p7tgpPh=ef9aWP#-j(UfUZvT?%Hg5ue>gN9zo^+fV? z&i$e!bH4^C)K?{$ZSU_(#c^>u_{ePgGf|S+b}JNGh?35>9h5sGR^3k+-3|2~fV+tT z^}WJ^GV6Pdn(oeTXdLGq;Zz+jrz&039fW&gwp#eC0@j+|m&Esnw5AV%IRbJuUG6`% zvz>j8xmzmK@`?Q~BC|3#ngH^6NPF3?eoT<&V$Wnu&|P$7OmHgr8Ibm}4#_ChYg--L z%bo}H9Ej3!5ZBAjAX2A{Q~Zs@7u3PSAC|;q%D5QKD}@O z_RhufJJ8=Cip4=(vG}|HPQXKZE-$eW&f(z&3#_xXDsWWjV7z$NCzs~Z&i>(?tq;B) zq|Q2IruNRxwgB23!dVA)&iW~%6Yy<}8qV&!+Bw?|D_tOUc9VBD&83~aU38>m_Xpnx zQfD2KEyBI_&dv@7dKiSW4&t2kQ${CXFL-MuT@8AlaEUG1(O4M;sk3kT}VHsO4#L6X-uuK`93hVQ` zB<#kP%Yfdf3F|D(!E(GpxCT|fBJ9fN---biLPaa-(HxAMA;3~ova&<@YIsxR6;Qc!hz=8) zF9dT|>5zq(lK!wGkZK`)TDAO5`mFtYy8jdK>;|(1ybZ}d0QZ7Sx%6iJEsp2ic?}cX za=}Rlb_kdOg3JE~Er(;PU#n3a7r5wze}Fg^>@X7(8k9jSDWf`1s&O6QO)1zK&dWBaJ*fj$dS=^VsWIzJQq(K}m8 zfztqAcA0hXJv85d)WN^KgJ~|#lsI^X=!k>Af&T?k2OW}ore53XSO@c(a%%;`K?ku8 zW~@y(32PJT;l77cMJs>=E zU{{2GZNdpyn@|UPzv&ztfM#Dv9W3;2InJLiits7t;6(5fAa&3o*?8G%dmZcGnLtm6 zaL_?~5z5*`Wucu9R5Q!?jYMSJAWv5h4ref58N@!4l?giplUaEF6@C`(#`Q7_?+`~b z3r911(JN$V{U%CZAfKqexHTzIyYZw zF)}xQCC2PDH+K(F$=v+Q47sUvZI`@`p14wTteU3sbX!&BZT7NQBKzUCbCuaWYCjz&f%*lLJ4e5UzkF(?@`m~+;S?Jja+bV-Q*Ph(*)czU=5$EJ``h)J z6>r9YT3PS7*nzxTRIgRp_Zs`Oi@l&HvDFrPyNf;gFk-vd*u^fk%TQu>x3TBD*q3A@ z^u3C6)<|koT3l@h9Vu(i;`#$Fgq;#1;>$Zqt(g~58ZoIh0f=)zz# z{2<}Yg~3N%>zTt9!)rxN^o^knl;(O!UdwONDu>hc9-((6MqVpws-Q0jZkH%tE2`Aj zivA|_i^RxlMa}fJqAr!puc0A7@&bEFRe}2qfWFk!qQ0EeWr(kZ`rN_U&AOitEa@)z zC+G`B+Y!7E_0~=BC+hn|CpO~^8mPCvw?0WAOVv&6$Qmz4aBK(>1OW;notTuM(Z1amNup7BYSQ!OF?r z$|9AXh2&JxP%D>d+;xPnmN>O?xyC&~_)*Brn2Uw;g3+d=v%bT@J0AONi>qacoFaaA zfZ!#g?kax+rPoBUPvI-ZjK7{t=sOp0v0 zqF&Obs{eI#3bONPV;~J7-Fb9(n68lSJi6NI7~{C|*fAqJk3P2)1G4kzAn=EX0oi$U zB+RiAkPY)sf;kb=jq{xi=1zhczs@ zok;Hlxb>ks~5(UG0roK79jxgsZP3CWs%b?X@LM?w5_C$pDqIk3jH zONofXyHRD+JDE8|SOd%aAt8@bV^rQ$cff?_{6K^a^!v+oAg?o@fFI+<7u|{Ub?=Ge zTn1zV{j)_$b|O6ug_)`(DLE+nQ19wK8|XjmQaT@nb497$`xchD6Y2hb`83VNY0FNe z9p$>0ok*|7z?G2hMCy>t%)PeNaXXRT26h?bb|O960_{$udh;OOK0jaHLf>LN<0Dj- zE3^er(zZ(9Mt=ljE5!l*=#>Srb^I=H|7QAgVAnzVX8Kz&Z$R+}udE8I!-{=(|X$LQlm*q>tFSg)qF)l-~ki8f^PjrDK6lH=U- zNPc?>-Hf0ZjY84lSKfw>{T@3UG3G^jzmneN-!3D80Z7^ctAN6N2~2|-ErG5C*1|ji zmCMEu&Om5B6$5pOUKJ1Jb@Gpad<2>DMx2CaZ9-&Ma7Bd^ZveM1k{`i*4~1O_BwE1; zwINU!rU=r_L!1G=t4gOAtjjL%DHbH9Dlp9;Q-8Bf<&3s=*LF6&lF_y9*WQu)0?9>B zopnW!+oM@-k19Nq{)l0hmPcqxFg^x-YomHuciY<7dRKN=4+2Gahhj@98q?Urk# zHgJLd=twaj{n1?TXNdvnkFJGTECK0{R=_NWv_En-cqw%kYra2v4D7?AEd9}IFt12J z`lF9wK7zDAa{6HnORhiq0qD1)s~>b}&BPDV{>bTOd0m?&BmL3sH(_;*93n6{(aHesR?#^d1g43K^muK%gKW@!QTP?28x?t2drHq0a1DrrSz1* zwBvOVG_?t?PoN&8O|Y|)s%a&&32p(tx#&m}>~!jQ&Yh>7n&58WyFmQ33C^>#YTnwl zoKq8rTT^AzO|V0RHL$xh!4AkXqSmOtQfY!m$aNrB>i+oAM|{yHINy8XIPVEf@D-vY zP4EyDj!-3Of*q7SiLH8`)uP?5^MXrh0t&~AQoAM=me~Xw-vm3(r7TVGesbMQ6MQ-b zPJ^@wc1Xr)R@>{iCip_I=R>XuF8M#2VBMOk%KFCrG--0GtES&U(y}$x63kp9Ny}uw z!LmJ9qZz&%?46J{!>eH)hqM`X$~j&+vl)&gL1~6x2ER!RNHhEq%m+~13|IT}U{3vzP5N8vkB(q_1eS909HH^W)&c|0EC*GuLCBduPRnIlEgt6b*+^*|IrIuGaz zv%3Uj9&i!NIgsvs<&?9%nS6Vam=k;|j><^=4&b*#@toic@95Q%U{T@hJHg4E;0Z8~ zK{_Yc1oNTyTCfT`9WKA-xLo zGNc`n)6Md_?#h!n!4r3pC+U#3fd3GRJ0z!+T~mo>?&7;qk`C!R6uyD9LvlJfHFR8u z^f%ByA?=VHJgNcr9a5?TqbVreAvvYo8cME1Dg)m@bav{HoL-*UB(;n@tdu-Rhtvje zD=6-e9I$qc1Vm}vJ((TSo@n)ev_l#Ua~Px@lCzSkX(h8m8V!Dw=tzg;bn1A{ou{2T zq^aPiK>V~rde#rv9Ou-;;m5^cKPPaA&^XRvcj=Ivn8j~v-nUtFNINj9ZPwZNF@B^Zh=B`QPR%nN3Z0#fA5TXpwUgVN*(PNR1 zhRWH-&tr1Ud1B|H;%gI_`A*NA;qov;^(d0@|m^0Rgr56bbJgUj=o zg&-~ix=_r^Prsfr%jUemTq`+m((K>|a7Ffkyb0V5kbXVI!3q`T_kO$&`8{f{WigkG zLlt{2PDu^oe zKK>T_^319}tLm^hHL#RL=BGm(kR6n)ADKowKZqmJ`o4-2FH27K6T1$Y=aurUmU!|B zO6lpqr)Yf)Y3utp%%709zRpV0Tk%O}w!Q_Oc#Rm+*4OFOuA#G2>)RB31;kHV-$gcW zZ0hnax!nDs%+}W-!W!6&)>poD;(*+a+|?-GI+=`7{oY9z{OBaUXv5;5IbNxbD>}YV zqhF^v0Pud0HY`WN42HB}amtZb&TLq|krbt284rG(7?4r!sW3C3xQ)2h7lh+78kUT2 z#a@WU`JzR2l_yV)UH4COzPcU}40(iv`!sqg?z@y`#Va|Si* zPVg&4N4_-WkThIY$5$-AjnYDNt5V`8LX@QW6tCG3E#`hl|o20ux}y zN?W3mZ8gwFQR=~tg_Cw!AdJgon7IROLJ*wi$q79-2;3N zNS$>^ZiRU5ot-@hXkQ3t9mF{+53iO#!Kmybs~ec3sDvd)1b?h1u?mgnAafFF1t;f!_219#jyZkrS>Em zX%F=B+J^GSkX~L671qStw%`Y#J0!jMSNIbb&A#5YI1*;C1l}hw7G^Y5_yiY#)8`ZK)~2&0{ZzOC$aJt%MfoEF^I*=F!0QCA zhPe`IcZAh-=iy(S05KtB}?ThvbH=*S0#g zR%`{j1)^nikjzF`dx(ZsmrK-g$=C?a9&pf8*4gi|@*Skkx;z<^=F-k~5gl>XbWfPS z(NSj|GN`Fzoy`ZHf^gP>owH{Wsm{6+z(TflwzYHih~PKpY&llSAa!#V&q*lv^^^yo9XgKYC94+EF+WG4fPU>`mu zWuxU&QvKp+HwbArCVomZ^HWl8yrDawS$O(WQk$(Yc`)~EFE#B7Yyqev9c)0J(Y-AV zs+?uxUJpg^)RS%kp)X_yaN-q zHr`;PZ~lOnX5(o0P&<#jue4IBUR%7>R6cFvrAGahj<3Jo#!HQo@$(G)D!T<&vzp;q zQ+4dey~Hmwa~09<@$WWq26!@iJ-C(w*7Kf}HDx^KI;OmhrMG|zj{$WmS(^^!pOK-G zsT>neb-jgf5IW z?9=?G+O@P`X&(Nac+7oR>{d`X1>6ldx&&%f?`f$L1qBzL&7S*2JR*^&TubDh1$8AG zO?z-R6l#^blE_{K1roWGh$|%Wp96{9tDv?#IQ=#e&qArMXse&KKCs^Pl&9COyK_?r3jYRoJj_v0mj%Eo_{N0!iqHp8MWtZ(01H)A6Br9KTmn4_Tn}>FMH9FZnL5lV_h{Egm>$fNO(V*}O0yo1fhI%dg$@nB{nVF)wx-#)NvEc*!y$xoQ;AF+$xsqoV zgWGAHsk|2xc!*!+NLy+r@}rXsy2LpnHhOECD5=9OXX zfA}@9@cJ)(mxen-4jSwPH7VIx*d-pARgxD@S@=AqAh#5H$!l{?9;!UOkd->0f_K7f z^NJ|%UC@3w%Ha)&Mv=K=pztaJm%}W8bV<}HMdnvg`Z!Ub%PbEgzYpTQ0gNt zhbpdcc2~q-`LnG{@}4HqEw!|Dk!CM$T}F(UVv_gltFYQnk1|Hux^OIi+DBB-Seq(= zf4L^l%-|@^UqV2pc5UF&)`eH_r||bT3tS*i9LW5}!1Q{ADoW>XEWwk&9OVdo^ z@}RMpHDyOjyo`fN_n$}F6N1v^lJ>!Ipu=4PS{uC15c~F)0le*nIR;DR22l7LqBWHJ zDkzliZ+-%^6^fdbq?OW~+7R_`Q;nN$kO~9rH}JnedRx*Z#O9zjNw2dEgcU!Uoe7We@+mb0MKL^e>W1ozD8X-QFBI*XV6I6elH8|$y_{x`c zlhoR}JV$N?^nq6SHcBK>iwuQ-A|HtM!BF@efpIX$Nnk61IWV&%@Fsy9V6K6>h?VMk zXs6cmW~Z|rnTy2wx>W6pH)8!GMB!Wftw!Z>NWX~orgbIDTrc3lFn`XAcp+cv+X!X@ zq-)NbVcruZsR~=X|M!bh5R?o+Dg9-xuK<1lu{|JmToT-o6ST2kME?`O?~txY*WQQo z0#QKH(z`6=npZ`oPFQP&cqJ`;Lr|rHjHIP^z&y|SQ;yQnl5gMYw??Zaq^*8WnB5`0 z>)@;;Yg)_+{aHe{T?Tzmvb=QW7x%{+`rc@FMWYHNOldd z%c#3B;`=JDaxjzK#kf?(MdGi&tL+fkHL&UKNWYm}&?;_2sN$9@wxtlfkjma$+7p?g z&!pH+fpj8S-y)e8SWcQi`N>4GwdlyK_gwJvA)QD%WKdJbP9(1cdO3tu2X?dGX+&0j zYBMb#ZyQM((o^f3rrBqj8K$YJ{Luog;!>QS3DBA3AlbOReqbFIj5m_4QDjSxB%Msm!-#0_yeFQ#%c~1gQ5Xj$`m27Bnu!&H(XlV5^ z>QrJqf%30+81tw#$^-9QkkJRbPkI?~k_r|6gSZu{EudZI zU$`HCJpgutm{k>#$jjdJPh$G}#7&qE+aoy$(Ed=^oWMAk<3y`mZtysz&?Fd9Mn9Ik zAWCviX91WC6!#d8y=IN`HbaandlkPwL=wKr-(3K2gTi$LUW9oTD!Tm3v|^}=!5dti zj}ZMe@=rwJ4g&Rh^K2FrUPquSOf{rms(i=i$#HH4EVwz?ZSE`hDqpHR6#PIj(2>9h znBh>IzIi=9i+rj~hRipxx+UpP1u#i8B>gL47D+(TzZ+%+R3zgAr_D%Dw3h`X;mbrn zk9>_NtR?Uz%x4l5Q|~ZdIh7$WQu>$3;o*W*&gT zevtMZN5Tvi3;M)^ODfAa&Rd|LO7~G?(HJdSre#m6*SFq7$7!nkMZZN=asdqlbs7pY zMXCG+yr}f&XquG7$Ejlkw*|=pFc(4L+XR-vTq{Z~Z_Q8&y*fiO{Y6^~mx_TWK-~#` zg&25{z~eBh#6bNrn_?|y4D#~&qM`bF4XdW%|GqY+-x|tk=@(yMq<~L`y@SqrF;Yrk z&;3~Vg~Db8o`$&(s^~*tkNtUe9SY?$V+&v|kU&QQ&%)dfr4}(fo8WUhieys%%h~8yj=Q;Uxr@eeNc87-+`Sy|B2mE5yPp~3Z1a&< zvHg2a;oLW{{SBgJz;1-XZ3JF~c^>LDdTUxKOO@&zUKq|K_6Nk@3jRa_rG0rR1L{?4 zOB&B`jYR4kS~sj9b|1uhLg8)%j)xfy@tb@oMSmy2H#m_Mg9t1|a3NGNj6mu@9xIZ- z1OgWmI18$nLEsaZ4<#^k6z@Cj8cBybo^e+gViU@pv53EV;81DH)v>Mk;QwJ+$` zr7-@;>Amtzn#&gvC7$H3s3kdbAQra);^ooO8M8i;vPOVXTq} zx`%%e-RfW-Rf57F2@HTa2}!}CnG*l@RbCvgjodXFD2i2yTN+T ztU$c~Gp9@2w>XvZowwBhS3fMFdvE0BKdk>2V0#&(;^1O zyX*e};8y{e)MhTaJAATx2*j;eBMq(;s*YTM&iH#f6*vtNRUd*BsyHo-xQ2Yg2IalTnn>U0&@tgfLRW85v7V{ z#5_vqVW|2(0_6{5{#9R{<^U?#vtXj6{;H(@Jbxztu|kF`Z-?q=%w(u2NiLl2(5US}L0(uw^rgrz5`{Jd?tr;n0v!lE2eVcJdlL8t<_jp% zm_Qe?P;nq!-2sdmpz^CePN$G%9!6gG(njlXK5;ja#4`T6NNmL_xXx%)LzQ3HLXAG; zi=KcP9&!g`c8+P+yj7sZBFnYZt9CZn4q&@ZHqb%>d)Pn|0{l{^GM%Y-Gt_`FZ<1uH zC~7+OT|BuIQQ}$gNm&1!!Ni1-f+2gT&{ESgJc;Wq&KD! z_=ZsUGx&}$)e`uc!2U3Opu%6br7iK5HEYvb8cnt7{)sVz!5${cO$m&L87G0=2%G^k z3#vYZK;hagX>(x>bHyhIt;4^7T!g{}V&Q87H^5vcf$anygt;F|Y$c$-=uIkK3!hoX zHM8Q>-cjQ>-lsV0)5xzw^J&peO0)kris8@veNNP8P(^d1{|EE41UeCDbOv0 z_50b>Xa6i0#vo=)`irFAoZz$XxF)gGr1p&(zq^@=EVU_=TGWp0w1KoX?FqAo1f(|g zgE24TUuOC)q^Goaz6_ehu9JmHl18|C#-ZZ0c_CF7wVo@~tKLMGw$<+~fSHk&doeQO}1gFjeQM)9(b1{V5x6s+4dL`s*e$;`sX_-|_b8TIw_m8UbJ|fe5 z0ZT~_?69Hf@(k_Ff?&5EA0n4txJY{6yL|!fCvtk+gzVo2D`VeBd`g3@_6*UM@o$lA z?B?X5Q8}N1NXV{kT=cS?o0D>v$l7t+2a6vG+0RY)al4HiE`xL*x0NstLb{LJi{3lO zWxJfZecaZ8T`S76kK5}ouR`%YZm(Ev`@}_RE$zOG;{|NV(E(ADr=+}IL8PBzaq`e3 zZGtAXM^HLMu+lx4!UbH>>wRDCIPcz`LG#2CAQj8_+lotDpu*-Kr5l@B;6= zgMLHQe*#zkaBluV;dTO@VA@0V=h%vSzIIDTMAOWog|l;-$_!psR*J^ci!SjgyelbG zMh(O3i9QznBca410*U$j70C+xeZKI&67+Y;`stO8`M~Eu{3icG-S`8zX1JDw4@rB9Kqw3P#3{zT`pR?C9NN-zVGq0-c|u`3TeIF3uaF!U2je5SUQYV z-tDu+?Y2?lCZAC#ryx26ct6pfL|_8USV$Xnr^KCOudd~6Qf~zHyL^fPY1GdKKO17M zO_RCSLvNOp-VVy|5}-7b3jtjMX>)l4%ym!~fz=P+iAUi6vq!y;tF1|KaqRNhqt62U z?9q--lCdwGnENq)sP9xBl62o>&b*%Jdr0CgN%JWJt6?6OGzC(>$^UzrAI52p-0IUb zI+)z%GwZl=>r|?JR6L8TO{XTWk>&<*LI#yt+`tVW9aJ`fDV2Z>Di4D>6snL}$|#r- zP_@ifw58qQ6LVayOU$*jQ&5-;X?2_rGgkuA(k_O%3euL=>GJ@TwdpOnmUcPVTSZw~ z+Q(s5NkFRT%P^aubW7`ugf-0hmi9vwHj4#mX@7v(A%X1#a)wY_g|-rq-!N$g1A8`G z#BnCo!8U}YK#K*wb3<5Q@r+dD?C;bN_5j`m;-}ZbM&HD45p3tEY|ZEPS~v{YKuE8J zNigFfy%wBOXdGuf(`#WLF(B8%eDHH2-od55z2}=}#}&K$P(SC2lGM@5QCI|N9laUm zMzK&RS5r%0s~y+US>VdjtLlEh_lmX*LY{_sQnXE>jPt+oS#?~tQ|}U0g)+u}8T2Mm zm$Cjfn2#Z?Z%!rjX1uZ+>uWvx0fil6LF!q~P|gjc^~_nws%c@TCa?sBVo2*(E0`8g zx_&t`ys2#S;~d$!CG3G#H!-t)3&SUvgCSq9xZ-=;6%Ti}OnTkLp=<_w%XoJMQ1|R& zK(JJBVK2ldW9TTcd;o#3VBVL&;RFsmiZr1})&SivaE$R2z!Q?Cb-u!ytOs5N{t8If z106Ip7ra7kbnAh)BELm2G8=I}7Mca))&n0x{s5$lG7iHH1Hn8Tl)d+*t(4DzSp&uE zGP-)`(CMSp8Tt9u!`IMw1(M(7kz{ohcCY)1k>)4@pCb84Y)&FjaTV7=<|0+?Fk{!PnKV=1VcVL~NP*zgM!i<7+Mb#;>>!K*_w4!=8pwmQ4R#abyc|iiQ zqFOqP{6JkqNmo>lAv6GrS5#%O)cttP7Z59|o5UMgBz+Iu8;~xN)*a3xbdc#K%dqap z3kI=L#u6;D)XtcZ;_}2~RpW1%y0o=p@git>RRhsLQjfV)>=2iyaVZ4tFxIE+jMKKKOx@%C1kBt*H~*G%dTmV zuCca zYpnz26rQXR+(V*wK-%#* zT)MVq*(kYR_M{ZJbUe?2Uk7E}FLRp4ye}zmzihjp<$l?lAYX^#

      Alp-=(3uTp*j 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 pS9>%OCu@BO^OL>vs{%C9 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%0AjP!z~S;c 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�)n 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

      >o8 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%0Db9$Us~`@ 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

      DFP_Y7v@=%&c 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

      u~ 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
    1. 4`U+$$M8#2-8)P~Pw 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
        1fIFX_TyV)Q&@3T49 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

        $$66{ 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сxys6ZIi16JTpS!GhGWlU8~_u6BnuWEW~_a zoyzuBv+amXB~md0Z*V=p>N)K#ZXvoMKE&TW+eO~Y9_|({W=%isNl%+TZ*l+T?VVIZ zxn}~m8UxJh06#+gj5Vk|RNh@_uxfl+ewr5|t8Uht++f}!OD-zz$W?DT>}zErLNO%d ztaU2Jbz_bU7saz=)i(7x*t|N94;SpOyA=<#!B$aVb)yRh(HdNAk#C{4@|oC)nywwE z5ry|studgKW7G!^0+vYJe4lgG!;<#m_2ZMsa-=o5xYJF?{v{XG;$Xj#RXpq~bKNU| z{>IngiMACgl&$kl=;;e<#4dnv7p@cz*YejoCl*M_;y%cK}WQ&s?~za{M&LcXSKey5Bn8~ zirATRGVq6&|Xm&y_5sBwSZ|fR#bf35>FZ!Ku zN879hiB!UH7N?lvq9m8naDy7+=%QZ zBk|mN|Mspp-~10RbPue~gTOP5dAWMTl{{0B=H*_?Jk!mu#ZCtE&X%Lj7Po`1Xj&o} zHP{AwNYD=NnLv-b=o*Eqh^8~}!yktnKE>Fh-L~8=@MwieDol^8!iwiQg?UWBRh-OP z-I=#uRm7*{?y|i6EWGTkUlaR|y$9nG=m=WT6VQ*TVr{McicA>z?zch|9b73*w9<_I z)vd6V@cNAPl{MjY$T1t&UBujb*gp09t{~dXLZB&99;h>_y0-UNkzxz_izN>Y$wF1&3GbqUgqX`nn+Q6s-K&AyG6N)AP$!nwfcs&8 zzVy&n>|nlz2%3taCyh29zPck-$CL4{pIAxoRDNTcYX``rtI{RkOJVVG|*;8Cc1; zl?uZ&d@PRBV~=JZiGH-q;z2!Rw)Rt|~+N|3dYfp5LqIL53zJe_=byMA9c6SPaM{29QHQ+P{7?=6z6 z5z-0q8I%gq!!}zwQ*Ljior*&7|aZIXUuW7LaiUnU!5*5N5ej< zj645IeBMsMMpepP^=<|tPFK+>K^FF>2vYs-`)5lq|3EBX=->9*#R6Iljt6K2P~Y8* z&*N7k`!~PKZ`gl_-~IXc_~ocKzP#%Fi61($>*5ClyJ#sA)+v6l zb>Y$lX-oFx3{)$gLN*2r3u1Z&*q`Lpf=P zMrU?1*~-L7j-5!BK&aahugW(MVGTBv?{O`bCSZgXg(zYzdi_4K$S$DzhUmV>#IGC( za&g|7h+>T{!f2>j)np5Nn3?v_+LyT@A;0SX_3Q&Dhu&+)e&Y!u$jRQ`Nw*atPVW>g z7c;QcQ^i}me>*+@I2@C*B3Yt*tr~S2R~)-H8-+{I3It`*zx#-pRD%g>Jj+4o9y6a% zTlPnmMm>MqF7#@CxlESXO%XV&CXvc1db>&_005Q{A>#Q4W$fuWApPA?UQL)Gy9G01F$= zW2h>WoO@{dT%MSf$nGUE=RBvFAmJ*YP)N=^g{&!mn$IV1EM< z%o@u&=l@g0e|W!VtT|&U^?A2A|7-Hw^pp56?qy_kp9(L<_5c5eIH3BC+oPUA1^7`7$5}Sp#re+ zY&vxUjtSV5gfZ(Qu3&(rC1_3!T2K439)WWGvi<|wFPR+~JvdQTHm)}0OKWM_QeBVb z<1izKM1EtY2>>$e$WQ%YLr2irhv5zpo#Ji^M?#&d8781Q5`acDKJ8o;$?WrWfD8fe zt;y%F#%rh+gBrws2=_>)mxp&fL_4hpb!#O)@GU8HQVkGQU9U7~@QW!7M{O%YO3 zyYl$e&~N3(#k=*EH;nnP+=10T$g`Yd7I*e)qL7kXq`uc%jDja7)O}7mNuGtK@9a6% zpcRs)>9T2Z+|~Et-h)%7Ly4!+$Mx=SM$^kkKA7Ar+<`z`&uW_6W1w0GvgmlT<6~O` zPMA#ZFI`kBB=~*ZvA=&7QnGayvGVud39?;``UScS^+M1db2S}1EYY`r@s1r+rTzo| zNgmZ1lA-$^yCQ*{^&kE|AM|(rRYFdkacq_%HPAfMq{*Rd9-cdb3e=YelY;tzI9%GXZV7tziTa+o|Be>@kyk+_$b(GUElICYB8s zqdC+@@V4f6s7eUdghS@$zHc#rPGy^PGQ3Jc+KjRiXw>SQz8jwUX*J^1JfwigO1^og5V;+0jOLn;*jjA~XO{+Zx$-JL zv(*W-VajD&&;2}*f6Wms5T?wcLB(|N;B1dK53PK00{2iYp}-vd z7z%3@9>6PcUGQNJT6`+qmwOKXyktnlK z)et_C#8t2frTobxG{-D>JLRk+3^WjqDrOL!4f+V3=YP@w31TUi(^raPezz$>ASNnA zUiZ)c`4^XENN}2yHs!DeyJ>b7jh8g`o=9l0Ua-iL$m{`AWO%`$U^?D zj`&<4Rc72-fg>b^mby`^6$y5=j=1Sm5A)UJ>Te{d!YXXDr_RL1u7De#_>$i!UlQz@ zpP}Z4T#I@99H964iMkDa+ez3E$6(cA1|_fVS4-e&yg+i=2R4RL;itsbL#DKMwHURY z!!P*xt!@YmvX|=YU{s3cw^NK8K@8ZrC{BO)Abvy77!F$fq6F9yBs{|YcKkM*FM+V` z7x0O3Nla;7tulQGzWzjAeF!Wa%`nJC#ya)6F5g=L@Iv9vB2?T|oc(MhsX?I#k;f=T zgGmSRs0{|RgRh*nTnX#8Wqnhe9ZL?eMQ41scz7jKDosW_8%wVb%hO;RLP-b{nTHm` zD{Q0T;-Q@VifdBHn=AL3&xToV6!ZW6v&vj3zlCI^q##Hp0sU0pd8+RSfpoWv`cd2i z>ZzOophOyaz%h>*L4!)tj16A_FMPgQ3wihn@b^0xw*%ok(;i0I_SX9Dh|V{ap*plW z7Mn?V20{XojJkw{cm$m&oO#F}a-$`j*HHW(Eqj)QaBTDWmU2B!N7 zneLkbm?e-e6{0F7A}c>zNizw*lYtwIb_ORm(JHh|Ek2+VT)#BtEnbv|H=g$Fh z*oPRx9O4Ngmw&&*(a``(?pD^25>(*dwm>Dmze(LmU$jL>E`~d}=14^c9j=H7JkLQZ zO@gdEi9lSdl!fUs2-n;{sjwlz2>C;cKqMo0*Kk4MsTjzX0MjIs$IC z7<^fP20sIGNiP0Z`eTq+uZrc}&8&AdxR`$I{qq5Ehjmgo)BPQ2JKs}03d;c zE~=XLLt?{-ztk5#8NnK1nm|I!mTR7jActE5=*Sb9JI}|{tKs!Sp`8hVI2ed4-Shtj z=@SR2^tdskKS8*LF2;ZPUaIjD=FWQDF`NyKd|HfzwlS&*!=xLqX=smv008|NI0Ouz zME@n4U~I-qig^ciC9 z&EToxJ)R(Ud0?GgFDLA$udCX-BK^DROzZcqS`Q$HWzokg)NB1%SA0@C zBMmswZd^NMd`%-k!`Wj}m4lkrh?f3SA+7?DU zMyjCx*9@xF&Kc{|CN-yLI0~aM7+umB*azK)(m!T9wB0fGPi21sAJy_?w+egv|FQS3 zy=`2{*06qxAG|=242%b&Zk7a{0EtZ>GrmY8DLI4r(x6DnqQi@Zq-6WxL4NzYR@JV3 z>E2B?X=Nr(l#`ROC9>Jvy?0$!ty<+gn0_~$Qiz&j5~mT3AnJPs%Kso5cVJj8rzCoY z%j=y3y3j#C!qP5hpI=Q!5a|E?Cu<;3l+7Si{Vu2*?AWe@ZUVv~5zZU^ECc;DQ*)HBm^h zGk{yKCgju)-5Pwlr5J>4H?iF1kki@{7IwbW^-A8J8~HfSj(l8`%Be(5nST%*%L1{c z#|YevZ!6+2P;!b^(4J>k~bB*D1JL(K%eFAc8V4FZ;MtRkSuKRJ93 zY+Xn|vaF*00gKqY;w$oJdr0wQm9^mf;8UoiWUb6Lfw3R_10L>z>;-Z6Xe~2gHQldx zG9P-Sa-aKliXo*kAB3L>l3?}LpcC6gU0+|;#~kmPy=xw_l_`oQg+YhZwvhR#6Z&6~yNhCO;*zOst2j76xCBQCu@SKYUQtTEW zLln{m-5CNGHHXn*+RR5GdmtB*a%-QLqbCw|1mMKWN(hjRuTe?d=-`xG?;H3U^{C)l z4^c7)h-@WuRPXTgJaeAaJX%R}8?5oU0-p~~(wk^N!xv}2&nbWSwwcl7OG|)XXV)1| zPHX$kUH3U^bFlDO0`m!2zBI#I=BWfV@JwhqP}VE}GPoo(LE7(^;ozfmA64qnnb$}| z)<1DG-sfPiJBfxRQzD|;&yp!imXYwgP}=uFNB@1ZL-`%F_>u|aIeZCl!7c%Yg3 zWqVTh@(#~4?n8V(rCFo4#Vvd$HvR+~RD-fIT(RB$>C9*ixqB1)$mmF#K-6%cC*&Pt zC8XpUM(U;g9q&;E(7LpSvnbX(MW`<~i;v1H=6C^GB1T+(5&{)nT|a*eu;59g9qrZw zd9UcNcxAOp^5IjB2$E9RhXJCOe5;w;eS{rV+_MEyH+AsdE4$jbV%!vI1+?Us_~gPh zZ`N&b6TnH(20V~MLI0Lplm=8wCeABID;C#+H#n$qzeb+Zj>DS4N~w7*z;x@THDVLw zM2TSdD*g_X%6)KF`zV+!-2+emZ#ey(?Ogk>JEJMwxvjOLG{)Qr*rVc*+Da{%M9~II zC~>rbm$HcB;T3EW42H(ZzXW&I-6rs;kAv>7u$l<{I?Lr?BY4vu=_-2xQ*{vp^(Y0+ zwhE-xGQvK?DWu7 zaQo>KClU;nTM(Y~Y96hf5l79QE1wL8Bs)481c;x3tbV@*_GGsQPP6Ybv+%Jdj-Zvn zSX}%M{?!_bnrC<+6i4Oh!v5;>hIzn&=-+o|pz8xSydNMHn)IczC~`UA4IMf6lQo{Hw z$V7L|PhD=xvuyr0Hv=Bw1?rq1yPrY)_}5)mu;}xF1V@BUPo$e8;lv}vt?=Y4VQ=*% z83@24I`?kB7wX^4`^wx>=Gv8@(0xeZ!c4T)XX3-^i_T_XxWX#QikOy08OwNu+gea1 z#P+tFY{d*5a^S8^niV)vBc3cu`8V9+zhn2Leq1-kZUBHFRFY(@Cgoux{{rf1GN zoV~oK4P{~6x-8_>ni)1zkw*DpSY-1K6@&rIGh`!Xjb{Q=RKd7P4KT5nve=0;d}x@+ zKlO(i=I$=2yH#|Q9_Pf*?2rb!E#YNs`UhWr?H5fQYz8O`8RmL(kC=5vXt2*mKRi@E z>gywRR1Jr=%*yhF($FHNO`N&Y`rhj`efymr76FTMolVH;Dy`H)B#}h+`){nf`M^Im zD+u6bR^g9jx&B?q^-D*Vny$3I83Jm=UvU|{p7046zP&sQJ)%gn#H$Wz*d#n`JrfDG z>)~v^Am^%>UblPfEAxi8k9o_w&<+~%OU*sLzW$0k5-IECAwPhpjy}hE9&sisGPHw| zmP4Afv@jLJG(9Aw)L6)Na5e(5?R<252P{U|zj&+9xb3|*6xG=F?A|~u>cu`z#FyI4 z0Q^NKR2?5r1|P$$=@YRwx}P&-n>9w6G~Aq`T#8bXRz5&F`{QuY9&)X9w?A`Pc}MztqO38adQUpq zIgNiyNiYMVDJ}H=q}x&GiF<50m4L`jmBB{_bME>d2t~o?vc^_}!xG&zcIRbB!yhCcxl7(2DjG!tWQimxK`Y*2{H{qk!G|QiWMx zy<4Q`G2u_q3du?c0y&v*UfhWmWl$K;WelF&(d#P?#a?Oz`mGU7^EI=q3AUe+R zF}}(>fO9pKj)S^V2j7D#NG5^B=i_qE!nd%Hjt*S^AD{y|LXMC*s`~5zc5Sx~UcalcP~JbU?a zI0EJE_?UVM28^YjW&v-_wXGDIshsV^@`RyghKPHWu7eNYeOBA5tFpItj8%s{Gj5+< zF=QjtLl_q>YWued+T+I0z;Q#k4L-u`x_5ARwEq@a^_%I(!R$vAnMo&P3OgEn8uq5B zo7~=@gMq~p8O++TB%TTQXn4h3yrjbcWh)Tc_nEg?F-`}Lqu8wj#{o(d?JHF2pBG54 zE?yK!qfiSCB^~ijTkobFR9tn#0QvL11sa4@nhQ?ir>Tx>gmSG7Bv+n@Tkj;DW8(J{ za*Q%*2Cm2F79iA>X*wiT&Qz+6^kF`d zWhvK~#NOO>SxYo+sm@f5UX{?BFrxs~knY_lB-l$NPH_qL90~baO7YIJlmY+DZpaFB z1uNz8FkmPy-J;@TrDBckbQ&yL<_H*Mleq;cc`IYW+r-ip@)ov4H^i>a-gu>JMfbjM z4~@TAK(=zk7;Z~KcDXM>>ui)blbN!5$VU6b9RWe&sJkY^reWh^-Hr(UZa|vaW5i_6 zq6yBnf+?%u3t|GSMOH{$#yOs zg52XJEkpMW+9`gk!0TJTB`Eq9v?+8bF^XRE=^d0>P0%61BELF_jV=>H9MWL}{|RgF zusfPr`~Vc0AiW&AKZUVv;L88`uM=MnV2SUEyse}mm%L*Aa;!;D+X<{Y&3vqgC5VD* z2N8!5U|JMw#f0lL?DJ$jZs0sC8WTf%LdB9oxqYl97diD-e&%R^>_m;Vy=66t*Q}5p zyiD5rj+5P)bla*EwC;Z&#fOF*!7H|9$58R0Fz4#ewc6*F_%1Z!OhA?(T_ey}p9c;6|l4s$hY%BOYgKn$d0y}n=};9l_w8GFX?mZmJ3 z0eyh8h%Oc%&XgiXrd_4@F!w}h|D9iF?1_yv9Q}WigW}a``22?;`Pa8%WA%UyW#F{N zy)2;wO>2wiPB|*@^oN`yEYp*;ZJhIQjoJwW@UU)PKcy;V&$U|EzAvdq zihyG|C(Z|+x#!D`8l`5dq{t+H!4n|;7sr`Vh)ayAc!rLO^gy?2TE)`hz0ajmEUO;L zEr0OM7$GylE$t>)S|oKoI1r+izS^8e!rAc}KzoKd<9xZV-Y4=O{B@wDyVvY6i zO^=EnCZDBRMs|?4bm6;54XrmFVXP@C+4}iwuw(HYDbj{#2|xeiKBY?L+j;nr(8R523J#82SxU^jfD%uqD=x}MWy)6;z<3gglT^z{M~b0>E&4HNR7+A{XA9WTzVe2sE9r5eFk^%bJNoLbEu z&&ZYd;&;#sVsvKpm4|B1%6+l_Y`35`VnjWImOuzAIN;kznGM&YKZt(uB`q>Az1|h! zNHb?$YEYTgq;u1q@}8Q?7o3z^%H>x2M3g1Oz>5F1_uF@M(-u(Nm!bv4IB)m?yN4Cr zJWER#pdrE2A5O4I6zALam0K+k+yMd2sj+wjL(4wK0moZurd6dU#I@<%?5|BcRoG-5eeP6K0Wj9Eynm4S3+f1(k_O@j{m zQ%P5o{;*!O`A94$jL)g zXvEPH*{XIN?}W?_m%C8)L0PgPQ1j5%UYe4C=hmUHL&ad@#3}7VZwmXByAokW7I(Km zEsP@;GD_$?p|1n=_TA#m7>y3&9axJ3vIk5dp)}&ft9@dDbMAXHdL#6Rtp(dbzg!DH zMS(u77(sZ2B$fVHG6_pm~y`@IpQ`P2oim#4N`8s0fE(bv*77d$|IH+X_$ zdDKW=G|5-hCI91_Cj1~yu$LPP z?)vb4SMNMUOtIyc&y;~=Z~LFx9`*>!E8~vJG5(v6!H^&a&N*yaJ$*9`qkOx($)*Rm zdEEl*ZUkC4TpNuL7l)=RCY4%1$Tqh~{I^6UD}jd=Vrgp%l`c)vta=`k4W84Sak>sc z)+jACYP_<_1TG(d#sr&@VnLd?PV_h|TzIE7kC1R1aTS4ahkdkUr4&bli7?BD*MwG{ zq49XmaSix2{<;rs*zV^LIHC=lQLIIgs^rLMBF;%Say*tP!FcuVArEo!oqlUtDR6r$T-G8}H0$mN3#gCEOE%wle?Ph7ph4r<8^A?y+*j@(({)3y_ zP5Keq>)wxlJwNQnf(5DaP?TM4-2&V=#8G?^J~Ls;ArD)B8Soao4;z!=8Gr~WI%xV9 zV5CG}WyvGeAz5K2oD)9GY!^4$eFx}+%nSzq2_v;+ItNI8$}6i736c?Eq;sBg_!o=? z?^F(K%(G}VE~+p65FuLPrSyLH*aOu$_x6Rs=SroLC>uq6Z%zY0n@yqVj?4Zo9uc4N zcaEZQpJ2#Bn6z}Ni2*r3H9!-Xe0qEK=5ivM8hGQ9K&G~>R@MSb53)?b(?s8YV(3BmVA6%TMha8O7PO_^N$$Jy`T^IPk4~#b+4PIb`9w z;Mr+nlV+cs&m;+!kQnn(c=8e#oYbF}R-)&FH3}B2-q3o(wjUWb>}6djKuYmC4e``k zMMAhmpzx4{+gHWK`v2l4QBallEj7k%8e@=s%f@*9PYfTn3uC-rF~<9;F)q`Val;#Z zrW#{xUVhDD7x~+PcE5GNQGR#vbMegewsmlQXtjABu9v8CHW0k$0No>$*&3_(it-9D zqIxE*&>c@)CY-i0E(Xq|RHr^PAal@+${iUPIT*>TJI& zpbFEOzi-6K1h&9wCNmoUInuqM_OUc^Zo6>goUyuTjGGy%63ptB1aBb^8d}J0SjfB4 zNDydBe#QUt;L5zZ9koSNFDplK2dVMcFGX_k<>EiXI6S9ikU4j3GPeh`##!<3^2AX=9DLqIaf|WB z7`ufQF3WxG4C2|WZsFEA9gAC5R+`!!TKNPky? zr)9fs(?JtXHA!dz^W$SWNNe)2pUMB)4-<7UZ4fPsdDt0-d@{xZpsVTWlW&sRWssjc zJ{A-VnjWPWL~Wy9*~#w5hihNwZ-P==fH>{AvD;bYf>A;foq;vY9Va3`qNjKsDktLs{niV zIAZ^o!?YHk;Lzyalurl3M2-%QF zBv!wvI>#U=vD;saTF(%xu-iidd8<>i5jx!mY`Zw%S1uOMcX&xu#0|7_)nKlXPB{b9 z(xh@K8_J$-%H`uw48Ug>xZ`V=NmzVPUsdx_g2_)?J*~{(8j-;@+FA^Aqf?A{RUL4m zzp-x;C9usH6<8$8)XT`^!_tZ1MDSTZg!H!jpsNp4V=8QmA1I&$w%ZJk4l-SfArw-# zW`ip<(`iRS0g+j)h=u}b$!MD4t(sH+8*X8}D|qu|x?s1rR01zhZgZ-lVjwhPL~9bX zB*3O%5J?7cIttK4x|@EE%ZluTHg2M|{4UDaas(vOX{02gH*YFJN5Dn&u)ztFj(mA} zrj%qu_$%m_LytdAXTtSNz%I8kn`}<&6tBiJC6g$TN&ui}O`Jme`YQis2NPhwex`h- zRNl%nhxM7~m^nKM-ks?si@e!6teR_%eTdRTly+NEgt?hW={O|wD^Og9!-0q9SO+bu zA?F27RaXNd*;rxMvbEbN5#FE31Q3@$LNN24d~E8=uc4B+JPxhWaky5 zN|DooHyZ*y16oC+Gt;thdI9Za|C#knD2-v7XEa)C%l(XEShQ zZXlkybBH=pUzN#zyB&3VgPZ9HO*p#qLV1Nub@J*vud~B77$HYcq0IEaJEDObfWoMF zV0>lm8U7)f*VnF5IU$Iq=BpArHBepKm-rd0+Z~aMOSO5K_G_cp6H+nPp<|Q)e4|`N zj4-A^nUbe4to6X{38q!fwVBfs)C6NT!QqG#80RAv=E4Rpn=R$&y~gtW#{M7=)vXOT zw}>sY_T~${_Q94p!=5mJHa2z)1`;B&|DWenlcVN#417!yBYr_?NSJYL|=@tlxx0{oi-p8AZC|2}fzv z1;UPE28s)r(dD&+?}T_7ae+?yRwQJcRlHMRupFzGs1u$-qMIM*a zhEFxZvUw28Uu+{hLnSlU^^HA8Vm@dhs7@D3%&){?&lrwr{8e0cduVQl9Rz?|ip_W> z_sZ)j&XdfQhG#bu;B{$mP9ijEV;xMmfn7fP{h{Op8=U=iThPg zjm>7`>7-<>X~HUsjuPv%wexT|Z+}viO!uu@j{BE~SQR!7#D~VU9@uO4tUIGGF@=5* zl6-dgMBk)?!cp$F;RPf^i{qIxaAk-HXt@W z8K9+6LlE3>()bf&dDwRHRV*3nL;}eoVT_`_H6~BZ5 z^`+W_f#j6VU94+ks$+!_WXpCcC6g6dj~2Ixk}2FGc%yuuqIQ}Fxy*K7*n4J;njS54 zwCnF`6kOG8>>6Al-2kn9OeSOV^|{k-#clh5_NI=XI~MSz=C{wBdKj|N_WhYs0K+vy zM+nyD17ZgUqr?^&2}Ef!M-JumDJBFQeu7JbY3C5~7q_Gx=K6WEG!VnT7*`?*4Emp9 zP&CpEMN1hqZL)`A!vk30=;|v_Im?>74-d%Y7ZbyyGXU zD6cwioMo^<-?1N2 zQCun;HzZoS*>0xMUvTDC-Tg;Hn>49SXL_G-?am2`#k2sX&SzSUyIBO$+FL+0_Tvmr zNowY9!(iQFYMkvK{5Xe2=T&%Gr9g3CHmXDsFblX8hMHk^qI|4675uDPyRET9DLI7J z_zd#Fgft>i&rQ%CxIg4UMW>I}6@&>gg2=E2{7wQ1cFyQVL(OdEMvF2y!xLNE0fz|< zG;06hFxTS>N`K5gW|XQrshI*})OKg+E3^2k9Oq=7=!%k_qP0GDob#|@eA{F}asqB0 z5uXhI`YAN0pi@Q8PaE34$TfsqR$%PK81L$E5Oxsz!8mOBI@%|FE)(V;kl`)Vm*Af9 z@x^^)DhtV`Z^8%l5x9$o19Pg?peUrmudH_aCQhIXl1~QYx5@p1`fcU`Vy6Y|AVeI||5nt}Mf*^q$%f;~l+YUio^3vK=D z-o2-jEN-WxVed1(9o|yyZa~id7T=x!Amvg(XE`)L!`rAmppDCwRZ@VBs@Rp7Z%;cA zua6&C68xLr%nQmb+|>77j5%S6VaW;kiIJ zXwMlS#FNCOaeoJ+u%53Nin4YC@&U(WP`PX-3kyfr3*}qjKJ-Bjl)YJ zVn@bv3?XJ79w;V8ynLX|MO)B(SdJ?Ek+q+xfrr~a^n^Db0MMA_QrvR#WPD0E?$YoQ z^i@KR1{P8pgtX?OzByGzD0RxF&7BN_A{m3Ks(>k-LPPn2;fo^1xcQ`lhDBVTxI?%` z;4rftZeQxaZc?iXp;>+ZjXLD~^5?c@N@{Ht(&Pqr*4ln^*L|)^r#rjtPlMhaYl6Z! z232Wr%fA^yw<<()MAyuNL3ui>)QLObW6zd-tu~Y0Q0kDYQ$|qm>-k`fIVkyh zJr#ar~sFP#VyD6swO^`J| zbVBHMp+3cL&?xWWDIv4#!1c9IBE~OH8AQdcXBwceRiYD~3*ZgPFY!~nQzQ!o_aP6` z#z0_`*>1=gCcd6NGcI#Gt59(US4+6k6?z?JmRJSf#` zg*fx@FAD*>(JtkDPl*^zZL9~)KQxTO$7PUGi~oK<>YZV-zuzZmMCpuNrYzS=%W}ei zGZl?`S-Y~P(h5Pgimct^9O;)ub?!BeB4*q$E3W>o$xrY;*tx8J-D~LA{XNpJdx;MT z`gJ=S%#ns;%vwHvzMfrQV(x5Qc?6i@wEhaSoP(<>W37GSkS<%`GKd$@CuS}* zKyRhCjt?~B4fyoVx0XPv4U-kiPNmEo<*o8}Ytx8x0M?hsk!F%twf29J z_Myo+gh5bU`OM>4iGCSM3UJ`5I2N>Dwf9C-sM_(CDk`fybV-kIS$}>xr7|AE_1boH z>)^cm@lE$?Fq;1|oDb14u`g{<3JZ(WBi9O!}k2 z<&cES`Rl>w^C<_lBL8%u)dswR(lJ9Y%6kpr5h5v^>0~1J=JAqBJ8-vzhqXl5^Qxkh z>tl2~;C5!xMGXv7>&#j8jTrq)AU-~KQqb5wB^d_9(|C~@O#+k7JLJOQ>|w-qbJ z4)-Mbqn7`tPi{BS&cO{-EFLo)gO*Cq9e;fY5A}cz8+ZozzL-`$9!^f;CS-{wDk*;z z7Zo-_MuBJ-1476rA*I=)PZC=3uUd?!MZ~AunF-s=EOyfvqmf9J$^!1?kg~CE4PrE+BatfpzvUa5c|>@#61Uqc<916@!$bh4 zVP@!M7as-B*VbAmPva{VJU@`(e1-SczyrN{&qkrYIW-s9(*=KBBV0g7CwD-UfMQiH zsQ<}K8C@YMX7j6QW3Z#^mQ_HE$C^@kqs+QesG_%9O(QHz6`do|#yeL#`ecGr4mmWp zk!sO84*LX+)^BkMd@Yc0-Sl-Z!Wc%ERJ8VmhYjtWd%(?xJZTzM4I;78LbW7WU)xO^ zZAI)meL60dce(LwOhgEK0=u)9y~Oh%5NaMY4pj}^hpXUBQSA2J?2WjLyNILygk-J;{T zyfuME;U;>7ab=RT4EAB;F4}Z6$t5yZg+QgvlkvIK+rT^1XfKG9VMAYcF?pewG(j51 zZL~}7vfAP-X~HY0=@4QiQd1Ny`oWOc*WSpgI<$I-QQTXvI`3YdZpBkj-Hl<>McVri zjkdO%s0CS&v}Pqt-~w1g*RC5m3&%xKLpZpaI$ltRC^?=E3+7pO(jZCEPFV_9BT*Je zn-VQz0mKx$Dp0uvy&>W&{KVp@V|T3@d(y>xLIWz-=Vy7vRgl z&EZ#-44s&y!7KW7VjiszA=m4Pbr&p!1HP#O>ktS~X^-qd9Rup1zDrhqm7fEE%Qfqu zwOLr_uO$LhfA!4ig(kDmE(>%FtsI9&uvzk1zue zhoGxWD~a&C3NpCUs*ES%bj|j86~oM#sYYrAx}_A=hz!;jY*IrKoDVk>*g8s?VuJZ` z9}wkZPdE6Qtzl9OJnN04BeLEV#MdC4!Q+pxnFcx{dfy5D zY;>->yI~(v{QMtC=+Ev3`rin%TcO=N9#gv+wT?~Jq_qo0QVh);&gOvku8}9{^6;Eu zjtJCMZw4cX_(>xII5|JD9RhwI52}RMvghz8>^*cF(kAncoE2IwJ&oJ<;cUrS8wUuT z_|E4VRE-bMuual}1U0h+5yk1nBl_WPG2IGstmu(Nq3fh7KQ0T;Z&xZ>WyCO+*R9Hm zvE>DmS#9jz4A!qKV`5*ok*V^h7zR-4bN~fh-CG|-qSO4?AoXWxkb-i=Xn;0z6nz8; zntK4vr~}|xMf}<3bzU8|qy*)tGFess^HBgPVu;vqny-gYk^4Mf4739zv-@0If4No5 zb@VrxjcHKMKf3)lw8)PnqSF~WVfvRCAK8TOlYNbpAHEh6QIr$YUf1$7UN0=_A-e;+ z)D!!i;|YOIl=N(dh=yXJKY$O*I7Em>J$RIiojOUOS|u{ZfXh(Hkk(W_p!05XM)Mi= z0ljz$P;DK-nf^Tabu#@pQC0*<5k4OUPd=i0IGmGO>u#W~8BE^e zN1H}nF-r{BSZZGpAb<`cYQ3vj+DI5UGDdI$_L<Ivu~9itaadh-DmhD14F; zsd&+%`WIRhl7?4-?}0Ow%n1TvL&#JVzTy&LQzjYxu5AX^c$A99!Y^)df2ZsT6lTeDAXZaNRJl)-{G~yYRBx$#J_~h^Ro8xw6*Y7*mLTo}Uj! zBK*U&q}ck6;(Wz>FY_uEM|C%Xu$!IwEMpHXzHi1mZT^27xG$PmabXYuJUOvagEh3O zZjrFf*;26ujKr2GV+PAaaeJVzVJ*_E6I&-(u!rVjFiE@t8pm(#%J$LD&vBk!xAsWU zume7vMVk_v4%x9-t6L9W;g+MyQrZKc$$%xdsIK{R?6&)vHGQQ8jkqOFxu~*rmr`To zm5h<7Uk%U-c&gAMTxSpVd8ND)s3SS*p4UbdyKzkT=0v2Zxix?B_YRFgyVdnBYmgH!h-VLBWXRKq$ecOka2o!Pn$ zs->OAZ7s8Fhh{Or{B95;@GJSe{4{AVWfju#WzY-G9yq8l=ZVtyYO) z-hb#MT0&jvRZz>Gg!8*!{O`FernBo1B`nzWLzqh0`-MEUll0}&?h z>fT>IKSQ+PbZJF!%votWn|L-!w6jM2qB(I^210+BjZ7e6u3D`fHvs_tC~A%-BE0+3Ii zU>J@2aKAyI;7QM-6hhxFA4&HD_LElAxN>F>N5jgrE5YutHcrhd-%1X+1fqE4u^||L z)Tx@zwmTP;>P94?0I0!ZQ83z^(Eh`LG?wAJf@T^1F+FqN%G@>?YeAgTtp+CG84a14C#!XAm#G z?xX2n=7EGb+?X z(k7;sx-k#(Klp3;ab%psgMK2LTfb5!o=H0_MH_Yz*4v3Rc2A(|L*Pe&kyZ-Fw02PR zdjTCFC|qL<->F>-<*MqUiTu`eF2mvBA%bb52o-hZb(nL~p zZ)Hk(GAZjEtzUt8xj6f9?n;<}5@>)7c!gIVuC7GYTZ4yCNnTf54R8|%DPh=Bq4W7D zkHKys*EX*y(=y;|We)YCWVCZgn8AQYGB4-~!{dn47z~0q`QlbnHfVlJ|J3qN4OD_A zW|ce0D{AkLyNlipO3`T`hX|7%!wZWbB-a@l4n~B-IX;$_sUPpIUtrvyGby(B-Ms8o z?;-$zBk+7QMA#ofeg4c;zPHHs#4`9+D?do7K91Z;Tjlj|G*YmBhP1;8B5OI0=^w;6 zfP2m{fyM?#tx6*|aU8+Tv$q^)iH8vX+>UHoUk)Q=CalWoY;JOKK&31p$em$w5ngr3 zfe0iucV6BP?Evm}C!g`T`f@|IEaQsfg_tGFL8eP15KSVs1FnlCr!?J~pU4CpKkp*? zq2?$+U?K5JvTN+Sl?<7x4v>7hgD#rz0QE$Xfrrf#8ormN+?zdgcT+mI2N5L6i+S=J zUVz}SiD#uz37HW)}WoKU)0cm7JHx+KoF(_-WsX~fnM22{VpoGBU;VX81TOndak@~Bnrj5=U^cz1V0N9{s)k&t(aSZp$)qLtGzn(b7df;& zkZAWgrldEg6dnHesP>8LgMC@M_7nIPYRC49m(FsEe}3V{mpBsMhL%9a0V1E2!YcI< zFo7T)>Z(2|c#3icBzPx!^ErRG=-z!=NnvErAsog~gh34>D&W#eZwj%2HU>sKrh0%h z<9arfgzr4}PNcRDl5F%hHNQ55t8_=p0;=#*x_fnDybLuUP1HS9WuDzluIOVBd|5ei zvGto&jU;cvuwxy*scp9>J9|%`09p&Vw4PVjCGPVwMd2n>DN%L%-CIO3<&&Mf80Xm! z`71?GlBhk*2S_?CHPn+J@^^eJ-?Zb!D6I9pbRSFJ!5}Uyl(goY96o(=u=o8ID3%j~ z6aCZInz!UfUpk=swNNYRV;g(=<_*j!p`$S!bD?mnGCEW@VX6cvTy1n_4Ao72vAj~N z0MN9Dy}elU5zvp>MF+o~DoUbgqTEkZYlD!DrRb{ECsrl{l|X<{N&`M9PO`L(PwrmN z&EgP3K}jm01?p*)`VvbsX!Ll$H5**Pr|8zVNz=IDC`lnI^i>UsaD-vv8OFIysGg5x zJIZAd3f2DTY?ryx;g%xZ&)vx>6GwAuTv>Kq>4#qx+0IJK$f;UK8TIFS^!nm|1ZmF0 z)Tf$IwsjVs8+f-F8geex}M>61G$qHu2CFdb7R|L=B6kfKFaDFLEF z8(NNINcciqsPMszphz^*b?ff74`=cYi13^4|9(cZ*=TX|{ASSmmEfWjiltuS-L zU3agB_btRBMGs}C4 zh41IOSR@QwC4RqU0>j^a=d-ox{a`e_IzBFgA14fNG#~g|l!i2VIn1UTzvt)L@M%TN zq;iXHjSx+)X_p-*g_Ap7MmDvenH7^L*B0>7))GqF4$agU(pY0rXksAf>#VL=<>H#W zhl$_J;N8q`pdP-f$t3ZR}62r8d4|@2*b1*btOvl}!!)im?AWL3H`2hfjA_i$%1loinWt$0u7)Ap& zjrpBtZR<*U(E6CXH#aTPZ>A>TlzcNhV4^?x6uTjTIYCiW{Ut%n>>gaFUyl?3`G!^L zfX#K~<#xp2$fo6oaN}_nbS>!v?X_Y&bGdj(Z|gEW!kL*6RH_fy30xF*YLJmD>AHcJ z>m4Gc_tFkXF3t++TGLJNHoQeb(8{R;`|FfgfU03m2v4@^F*lNwj=iSNs z!TB9(NJvwix}|=v93UJkfMd^NongV0yQ1viw>H37B!(b^NIBXbY*11%;0Y4{6Ra-~gYBjac*myVa)-LV z>~Y3PVdSHM8O{ZuuH*ngMfePq^R7N*ypOTUgabior%nOZ)9mTxPdYE8BzSxrhP7tW zHe5f2e4VJU*`QX7iQj*-7h}+`;K8Zg!nKwaAIsH5lP}(#-^_*+)cU4K<3fW$dRui- z85~pD&m-?ld!Ud-Sz|-oxwPj7H3+3L4U#j0p3dniMN$H~&YxN8A_yT+1P$sKWxWV8 zM)BjAG77L$qf=X}fR$tCcwbf*XympJ*%?lj_)I9c3}YG!4I9aK!{Kf*6un^{9>zup z|3KCU!7u2x9v)rZm{Ml);;fRa_2b=egcejFLGiFCh*w-d^a#Jg$cP2vPOT^ZV4Wqo z)WflS5o}>X{X6IhAU;yY#NzYqfW(+n)gUl&?vMj-xF+ji6Rv#;TcZ&UZ4olQjRd|p z+DQBU&KbJ2g3`Jf;SEubwGJ-EHeG`!5I6rxsuA}JG|;Mu#5fjPKj0r{@$IC1Nyf4# zsf9C*Wv%B?yH?Rl-@`CZRDQMXP*P)8w{eDL@m{CAwDTm#`z^ z%4D4Q=;)(Rl?DCXG7L_%bd?xBY5`=@eQeYhqy>0_k@)Nx?rv+)pUg2CU?4Rl7jR`O z014R_=d?+qeHJap8P?<+x?`|NBDe=n2^lhyijO9Xn_|@cOxciOt1V|9Smm~a`lOG2 zmd|eOx)eYSvixipb$9#$^{MTbFMdS8ApPv`_BdW_XVPthg1y1NxJgivPci zZn}@oTz13VUE^KKjG~4;pm&AoHP}JI_YgMXS#PFV%Vs9Nm>H4AYzB`p&lg-eO9>eC z<{G$O4F6Z)`!dUObu;#T`}PfU`ErC=2O-JLlz{+GI4GlunYg5C=YndSHQw6Iz-LD_ z7Ix^T&D6`QB4+QRM{YhUHC&-fywvj^_R6X^D#%lnA0tOZFg=Ou(B7SlNTH`iIMYX` zzVlyA_@AHV~edJ8^N~$rkDcg#;J_1_d3eDu%EE zehT<=dN|S4+ITeq^b|_JQxdG-iku5=n8kim0EnwK<1fL;pA$ zjp;BM?;+06@)Nw<*^i3m@xh{3fC(+K(;66m@FN`&7aowDTu2=n9|A7}0EJQ{knn`G zEYsIg1&H-=xejtY$jZWa{p)TpL)p|=)@zL4vUV$%_oQvEi}s=Fhfim176~#!l$DxY zW}WK1tT-I$Y)5|zYst^qLsN>?UFvLck|F487jm@M?NlUaaF4N8VluyoZV*m#acDOt zF%OV=>kPso7nANih|ifr+aOzH90=)*Yp6G3SxcZ-CDft-vItq?=|UA7oCfSV_rc-h zVujc4absmGt~cQCFd>>t$)Dqz*=YK4fTRur1j4Fdy~uJg?nbGufo-usH8cLX>{6^I z(!+Aq$m$lbh9Hqo2D6&sytc?OV7FMnx-D2v_h%y%P7*tq4%-GSlIPl^^>n*<;RKy$ zEYh+q6V1R1)oiGsj5jbT6o z0;CyDECrs*J!<%nvTE({Oud{zwFydkIKP`52=25HWSd6#x;?c+@wMowbv#%zT+4Ep zc)qXiA1gW2O}>#Fao1}ir#l1)cET-0;7eH{ZwD~z!mvWg1AH)VCIZQqC4`31u3{*` z68NvTmgD%GC2W>*O{JOJ zm2$qqnyTp(_S{k#6o)NXj-LQ+%NE`q9MoMk+3^Wdn&mf^2ZCbVTM@dwyfq$;IWl^H z*iiqOD=Qg4UPe6D?Q7lL{TY)K|ydFF5n2IT|NIEw_IV%IP1IJ#az#%WiFKT2U@SBPZM47;G$c_^M z;A!bNDOmsU%K?K%WyuMizOx-FGme2teMk*{e zJ$V65NiYou-LX`MmvMa~5?|6U5vPqrqtm_y>1tq?pIONjaJ}V(il~_FdDgp`-kx4_ zwhI<3`^sMAg+s*Pue7a?$JdZW!L^H}|ow)o_1DCLl_i*xT?Fw`hO@3D38t1ZQ479m_BRox@*QV*8Rttmv}1#Ja!)M* zJhk+sXhpqQ6hv^1D%EanmFkD$V*P&=lC%ad03p8gwpZ*S#qNu_)(bC%FQ2hd1vgi2 zR9XL)!iS;x1$R_d-QFwq`vn@wWTX^ zHpIw`2^g_a+ApI_h`2q^xwmC#nsWK+fzxuc@dK(CujNkCR*D%r`yJ) zl@a#H?GRFneUaa0q_xDtTQR^%oMGlxDXj?6FT|JUDC%0g<1xM@Xicz0f&&?#Kp0aR z0hXf~?X8f$hK-((2Qt80aJm{%Ur+)H^7ptqDVx}9^SEF=ELa2mB^n$;G8eF3=PL>> zl@ri}p0$p>ySD#jFLi4bmSowBDF9%rbSSzZ zEEHzWV7&@Y}>w>>c%%y!6PL~`u#3o0ob@RKP$y%ho z$!WFygME`J+~W4PP%lwo1lLtp8ASE{R{Q79-l29M_;v8&%SUaSSu^nFKR66u4X+9=pT3TM6jzqu&H^r=c}R0+UF~H9W;|j{b2)1&A}^k`hhEd&YcK z>OAOGs4bXTFpS-Up@5;a-fg{X2of4KV0sp`Zh8{YPS#U!dHRG6+%({-23@K?)2DT2nk$kcax#E?e;zB2TJ{of{7{{dr@Ur|5d64m~-npPF*x2 zc4q9_F%t7`eHS_ftU=TtpVP`AT*Gje(=6`uD0W)KgOOHVhd-!;JK(%S>Z$pR)dpF4-#9C9#PF9fw^H8d5Jd3_~D1FU`_XD0;8Er0Z-}(Axd>v>EqDrZ1 z%UG!F#_+{_K8YZcStH$XXuTd-IFva#ut8-E0r%yaG9+XYKk-hQ@A6RJ=^0?i* zcT-gJj*I%jch~672%3Qi?GN_2-Wg2gaW-ffIfuIaM*k9~{}IUfZUs5tO_6idZ_CK} zh9Bs|(*24Ihcx`C%4r@!Kdmb~;}=4H7U3fQfzQ0bJPnpbnlg!u>oZrJ;kl5ct->bh{Ywr5pJ|Kq_sZo?C^5CoW za2Hhc%IyMkGfrpxaW_F8U}lm_kGn~xA}zHJx|_ICoZR&N)^BHb93OLf^ zdclI%=Glh;?}EXal-Av`GQI2kY>%7iY!Si`fe>^${aW)nR$RrPUkmvxn4%LS3=Rpa zIVXIouoWVoM*Y@Ra2$?EGdWESOCxOoYfOVoR+1}*4CSV-R)xE&=u5D4ZQLOTNuwf_ z3AG%9tr-&pU%@aeCIU=p{WJt{tZWf;+#@cir$D=i{*&U_~an9iqS1VHY;A zt)%&5#9EKmd*GXa4xoxMdEW)++;RiEuaMQaQFbps_B$Zng(PioH8rgh1je#We^2kj z{mh^m-wMmAATQd$I76U=1w(9be-22-;JjzPk3d76Gh)kYEWgYx=k1nVE;vN zJDc8i--85R;5I}D!~v4Fgt*i75IYHrP&p?132&~S#)P~7GJsdlmx>ZHN2x|z@$%#< z!<%G`Vb?>~jGNp|s6f;w4K28llo`-kuhCW3&+w$xK(q9={J1aiB8sy02q>+a#>CZ= zyb7P9VT|sJi@grK#kb4ETsou0l(ak6JKLY|cck#YV5|swyX5A&9W%&|?Fk$r@*oZ- zK?5FGo1O!60$%|ihAe!9!{vHK=3A3#F-G|mhM|ylBa=Sot}NOU{uLL3T&5g9;jH*88ko!DH?Ymr032L43UI@3hiBsr@0#eEEvirE|W$`F0o>2M& zBFRglPQYgFr@ulkjwsA1KPe30h^k@EpKD7MaxN#7`E4c$`tJDnWYisB^}FBRVgDT# zsCe)X5Xi0kX?G|68P947D<+=|iJ@)0fX{Nn<HBL=v^|9a!nU)AQL-$pcXYb|*1g3q?WJe+r2sa}&3a9wp**U16 zy1SIfXP%=SELdcIVSht^B|y<~1yg+MK1#SSE3gT^~V zZ5W8p&7Zohh#kMKT~y?M1dM}1TXpU-xL8uPmAGgr)sJu&%1LrP5Fj5_j8Iv7RIh+l z@~F0}_PU9@4*QT4$6TDrJgz^twye)k2@f=u&~lCOq*;5C{o2}_FGeQ%52Js?&5XcT zEEU{A#8*Ba%x@7{4>UNi8?UQ_gE4D`_M~ZXv#iQSz-b>XEg`t+%n-eLLsaWZ>8RRx z&#xtY^zYCDP}8UWLp>o?ewFW2$K|qp>Iqp@>DpsdA0PwGeCBdE9!&3~&CfB0He47X zy9nPIi^3k`CWIHhP?(&^@IQT)?4dUu{leL(QW}vQE&w5$vAT^;hYz#+`x+k_nle?+ z9`TbKCND^k|LMaQA{YR>F%3~#TFGS=+7jK`YeU^bQLtZzgO3(J=zs=$3Jby8BvY5D z>REp>?+@pTLwov?WNxwvQ+v?7N^To<6%O+ncP`Afb0M(_ArA3M)MW-uzf7u!SShKV zZMKU6;~1G8xIi3c65ElO%#0IWs&J3Zx5izq7K3NIq$nkZ(z&qjb2Y!=NKMxnT zv@Opb6h@VmjyRod2!<(|6P)N?2wN>oN4S&3uSAk;2g;vuUxavIBr)lZ$jt1nrv#(U zPeLUDRB~TKHF|N&p~GW@R(2z*Daq`}STP>x@%<7$%#PrY#tp3ri9f8G`R8>7D?Z4v z1Hc@TDNCyV4HG9A?Rtj}>jhbtHtq#$>hf>&v0<$63E-rN0kpK266T`hF#xV*ewbPX zhqX)3#=0|c>5QtJaod0GSh?Xf#)Ai74g#zg-gHOQ2vvZIlN8cyQb@NN0X=j4TSPz9 z4eEmCCY_h1$OyYSFm>BWoWz7WY?Y;GMTt{b8j=Zc_$|dZ@B|hNygqQn!}2`>dr~#px3}%eRAP(HVBni&2jw=gXjmoU*4$WMTAYXe90z^o)+j5wp(R3X|&^fsfxwS$DpPM#IcCWUy%D-xEzI{QcHx~kCsD8S#r z@ZWbAKNrumgL=DzMQXR-47YKh8RTZovPJJ=shE~k!gu_v86hZA5psvlOiO6x_01-@ zYMv`*|S7S3F{TYsy-xCBq<-Q9_54hng`NDFir}+ zhtA8%M`4c*6n}yS3Wv`Yr8@X&;pWPWA(n?d=u=e$O~$H_IVh)?gK{_0T2K4pmm>a` zXa0;TO@Buvy;EHLl>9b*CH}_kh9mTr+!^#IB-#yvjmOPpHNw+51&0Q2b2Q8n_}<`+ z52frNj{!9#+8v8>T07{$7++4`bgu@Zx$-8k{8n`Dyu4W0@E?220!SQ|um!cMvm-$9 zoQHvFtbz2vnAiIL9t8IZvTe@bCS|$xY#qZGaEePHLL5Jby_ecPl-l#g@1VZ;CcnxT z-*CBX@h!28_&`Op#+RXtWR@>o;?$K3rNQ+tng4>BMfZvC)2q57^1>)65+} zRCP2Q%xp<9Y5HWxFFOC$lI!b&7 zGu>WSCrhZsxaTqwuhPaEH#{%4ep7iXRzasTL1SL0ILpBhlS%IV#8y77w6&(?)dc^} z$t1atn<|0jEX89k|>OFL|Fd56YSEy2NRUE*{>k8<#Jrlx!jGN^4`~6I(SZ1*B ztIUbPznB&76Kw;3ZHBwn;ArF@RCTrEz^BOA7czvhUidY^?>FRp6 zfFA#Af|0=gGn@@DwebByhC3}olYMDR10~TzXhw%F>p1VHY7`j1ny69mStUbVcOG`A z>&pV@=(_)Mr|$wj*$+C|F_l0s#}`5R!LL-vPXNB)oXDuzvh!H~UhKnAsFmnr-S6Vx z4>L(p8Sc8+MJRc2Pqx*#bMYEb)88ZT_$6Kxz~h~rYW^i>N)B08xue}`v6{>teN1TM z2~a&C*!JzhPh{X+&~zrl@{JtV^2LQ6_ygm(oNTPkgT|!@_#A+Ti-OUp!%)3^0wwA< zKJxK#DD`EkS5Kd4+q%~w$h}Xp4B%wieqa0(gcpO4Mhh_#?RP(q&Y@t8I$R+R(Yg(5 zi-;r4KWC>AJ1h+cdR8eo*7P*8PU(ADq+RAWqX?OvmDFktw~F+td|n|B)FVYTvP43k zSUD99-?}b#5HJT;(99Kh5fDlnOnQDEMd$SrMdnru)OXWi7&jfxB^Ur}^Y#?$^84Hl$IXQ&sL0>V&_LhuN8&58i`vKKo1{wvr|@9%lz4meUka zW4?XPLh7-R7I1$uNqLYcDc{H|g9PMua1_)CtDsux3&g{WITaEa#}2L4J!;1-c)!Kb zK%2ye*PVY%7V{b2e*~K8NFzvZZ#tKS(NIt6i}%RVa8=7{YHyD&w?4dwrVg!4F(_qS z-~^fysiZ;o=lEu4papYSk92Pdb48lqg;nBUDk9s`Pp>Vyr@A2n}oVGu#r0N-Mv;BcgIQ;huP+g;usog?ptoi~xk8y_TdGtqnAPWy#w zEArLof_LwYUh<+k>eC%HJ8`HRh9O(;E?&SWoOL<&Oit%&7sZ%u)fTsD2zX@`LEA;ge`lR7BdVl3~QhVAJ89S{s!miF7d|eKoa0wTz)R zsDr(@)=OrT*piMB!gl+g@n2EG(zQ*Z{@-(PYbK>ISfyF)yv~klV7L*{J3HK`Nq8$8 zSCWpQ4ric?s-tILw2=r_%nvWYhp3O`Km^VJTj>8vOu$t0s{Q7J8>oZ@C1q$wU%?J1 zol=hF3+Gn9Ri4e{rWJ}eeLt8)L*#ykNUxEI5Ke(*0kNRKMjOH&C{Bl*G?wq<<3l;y=^!E4n0}DOc@kSaR5+T~5E#0xB|w(&zQ4`yNyi$jTR(YKcx_ z&fhMLjYk9uACR`o(K6X`W-=~p#QQDwpjaDXesG{&A`Nk#8*(co>eoq&wjYnm%?deKvOereq_wMa>gtP?oAz^EV_ z#R7sjAUTKK`TP!4Z}B&B2JGuPq-N_kboA0hIkIwnjkt$3$f}G-)2=ssxrVe^6RC;q;Bs}QjjS*Fn58L!o53kI zVP#8&=T-|$kNH3&cN7Y}-@2*Oro3_@cq^6bWI>%ypxgDiRa@%x%M@bN4MaeHvrf zLQIvazHk`2cy+#}OT=;R#P-a^roCn<09uCKtKoeMyuYG1g4s3klItlnD~tZL;84fn z_U>v#aqL;IJvw`R51bg$f_AHFgm#2PyLn$-I%(!h`a^tc(^AY2xP)!{ICI0|l^8J_ zoo>txGfe}Dgrm@je~-ci?0E*Z;%CdQ14W{?$9rgx4EEpXo|oqhV#GVPM|Y*C-$1L**^MfC29XZ7r3w0E(h`rV zOaQw`F zmnG)x7C*+$l0*4)6F8|1qb@p)P(P1_q8pz@mxBUCGxj(kaXa;iTM{w1%De!V7Ay`8 zXBHJ20CZFMS>FH2YrOf@_n_80wQ(Yu=!sukk) z*1ir!zj-rm?Hod|uqPTT4q90{m%?`?mkYur<4jCkOUMsaDOP1Sd^6`+z~sjXSW<*Z zYcAoA{(ZN41a=Cv(||Lyh5WjcsIXKkK>R|jXBVlXngzPa}61$+3bv|$(Mkv*W zB=X@(I;*lpu5FKtAszA%9oExkBCcI8kbyjY#d%?UsO?1BKwYydlfsUPjL8-$wp_nhEKUF#$Q zGhHLQS}yV?rogxvW%3JbJPpD8=hR*sZJCtCm_e%+)kakf#Qe6&!WFv15e#t7E*7cv ztg=Wj2O!?=CJV!nD(wT#B!>SMgGGoBsX6AJDCX@Rek6tZHH|uzv_lP*i)_O(HBpmF z=xq@y)ZqAA`%wp^Ug-%GnZ~U}?-r=$eWHE~RF74C5nky0nfs8@r4mh^wbql65n2+J zFZWhYCvYgm=g3X2Jwxt%E=z45TU@@<7MIq(!sP}I6jqvXvwpOHGd{veq_BE~y^RW%#S77oRgcB- zM$;kaL}4bBj>|tgzp8g1NE$gXoA0G}V*|w&W{S-&pPxy{cL>zFM8Ruq3lopAU_ThD zQkz|EnGbP{l>aq44)jo;Lu&R(7^{EZ1u0*1l88bmRae84AB5#=)WfGw={FHXPt@8IxgAH5`; zVcDlGle!ItFy;8&DMvxSiSkP&I|&Thd}$~A9^4OQe=NzCA48C@H3T^rPy55`&&6yy z8u4f&o6a-w8Kl00iR3ZMAcrH;sU1Irwf#?@TCLSd3JeR9xBwuOT-3%!(%FKTIo<~i z30R1wxwV!&V=wU4#YRXOLr$hnVQsZioJBi`tZHPAK0nCe5PdY_Bj9PQU*@)pf(A$t zj_~Yn6{~b38Cf%yk_MFyy`>o|1W9tjF;d43bvb7`615-GE1|Kq$w-n=o1w|R+Hm3k z?k#<}sF`)|-jC6ZhF(3;JwD4+tBUrJ-A%Zz+U6QvmWo-fd7YRwnzpA;w!hyZ$_d}^ z_RWD`pQz7t3F9;3DrtSs1=GRak_dm`B*T&H5uV9yG|~&KNyxeRZillG18vqR=n|2X zb$|*2ai^#|oL@q1^?GEV;Cje=}*1MuxHjcxKTl7W|Cf+GJKjAL~ zh;;qz74Ge<0%{1(DxhA=Ei`)ERZgAT6er7#l*XnUxfzPtfDa(sM})SRW{o)b=NE{B zgT@Naxq3U-k6G=}uWXU(OJrZjQOQvrzVOQ2b2|On6~P?|${I6EN7OOKoEN4|Tpi-z zRVC1OlPHW0=tec-xRfaB;;a;=FUFkXOBG}{E9v9mxXBnz3QbuyK3*mS?&2W}ez6VB zI@V3F+LJ(4Zi1UOEm}kr?dVEJX*a918S*=FXX6Iqqx}$zOU{%Ns%8U9ytw>(ytvAu zZ?`d)>l|f2o*sOuicz3cwHSrYVu9|2ka^!za|N;tK&hprqdIw?ml zs{QtIn5cHXyai8;3`xFHGxGLFQ8Q=gYS7)9VJk9%njVRJ64eQ`h%&RrNOod=+>7qR zGVDbIk!X6%jD?hcV`_Y4`Zfv@w3b7P6jr{<1@6`5;b$-J&z|Ag{EY4vk)enNo5Xs~ zMng@>n@y24pq-dgg&sF7u@r6nkSd{M8p&0EN5if&s%TGl4l1?N%h~6DmzbS2j#g|) zUF^zTlS#rB?ZfNAqIXkFXKiedQgac%Bu~pr!bv*mU4fy?}E` z^9V!l_R$iBqNZXeqDSkhoG$Ou>_L9E3w90u041gEmoI)qtW0^+_PaeqM#atq?KQ88 z4gN(i4uY|~b*ZvZyGGe)qYo9Oded53Q#lGZywPXkeTb$A@K&UdHqg;`Bg>)yCt&0s zOalXl?QzFd9@gWI+h}q_G9)kSc2jTZr)U9WdWB|F#7DmlT+*Y?JP}-EVC8%3E5gvNL zQu5Z|vX(wk4LwvI%CfXXZ`udH4n7x90nDerHc63-Xe4m0w&A{9C*Td9*obq7L~$W~ zvXT`>8U+&LNP?P`QIILY>i3(0lT3Bnf$mz;wta>u|Ht8CZePxT9>iAbsVB)w;TxAL zGpgvKWFBR{gh1bDPPHk*y1l@qls=93Z|a&L@h(mw(b`Nv!%)Ss?xCf!zGZkX&0gxu zfcV%K6HOK@i{wFy5XM!F4_tF@AAs59cjDdE=$*gZDiB+2O>ufD=ch27lWr$2SDdKq z(l;)1`KyGJPOrhW8bs2fka>}l96`lqvC^}PW_#cg?HwRx#Vt5$-S^B=FqtnNsd~Sq zB8_Ev@(}g~l$@&L3Po<8FcRd@0fn=J$Q#&p-(zn1!Z)bDgQC~@6bLlNn2SrWvi>2# zj5|E`wn&9W->^z{v@f_RaH4(ca2zw2+8&`T|Mq{n$X)jDP>;Gc3sZ3wXI|M$>!dp! ziUmq@3BQdMU!HY)|GI&nD_t2(}-Z z6KwHt*Y!^&ZWj8Z9X3)h#6Wn!Nex8cg-?{)8bRg^HIjb)p}i1;0J|6|)Q-wMm|XX1 z*qgqGeB8}YWz6K_!any^JUsr<@ap(Dp0Yw0Ap~Vtu7UZniekf;7sdO@9qYx=TrH-z zbNo-rIz4gqkK<$WNhjr2dj0U@qXGm)2F}u=4l`eML+#c%79`A(*-;l zcW*DJLCHVblV3h_QN;JbpB}I{%Mgw?@X()dzxA6G2{oMDLY<#pX90GLD#a`{Hz~~7 zenwLb!L(Z4VE-6Dk`5tGaeDU+a-F$F5`(cEh0zN9OtVXN2==0oKjb0v$QU!94z*Lis zQN%6ySBW1*k_L-8M<4LyJ@UJ&J8A~C&)`5Ij8rM>(1i61Jldn}=&YOE#00IuyT#N-`m*Ikw1h)bvJl&TZtuf$>u zd}eICVCjLaF4ko&33zG+TncYQ$N&Q`N!4BOMx2$g7_+WQ&I=(9Pme%ic8U>x`tbG5 zHQh~&exC1j&NFq5)RW0*G%3ob9oPpdXw@09z=VtzO`+JC#dUW)9DR1XuUf9fw~8&e zJHD=-Vq}0O8$-f(f(_5+aD=@D6CvL#g+JXg#DQDjq#dLxyhB%-Tg`~Uy0BcVrsWIn z4WHSi0X!QCjZj?H9MdsM zf3Tw>7UdK(E|)E=<)@`ECd!5IXz{hFj*L_X)3|_DCdTmiIO$%tCR=PNT!)t8b!KdB;d~zQhtyZ3ZToQ}}2w7*BvPxw)yOFW8 zvyCzeD=D;YkU1*Z0xwCNT0^0?1ggt_M$r-QsvApwH9-2Rfj9C!(3YZ74mc)vqs0&j zVSn(+4H4RDB}~ZhB(Ti?!JcNXel3LE9gQanB|1?M8xJSCKZg{ekSIUjO^Tky`_c3Y z^40d$L=b_a;Y%5GR@0VSL3}TEMu7+?bfA{rZKpEzPm+%!kv1}k*Nuz1?II$+&+QP@ zYihSrDc*}0Rt$KAF4y6`Igd>U6{fTD^%5pZEnXyNhu@bxEO1<)k`@a83AkJem<)&T z7TyJY>bxahTo+>qf`lccEpOVeUMY#y_fBA$nv#+H?Tdr5D6q<)!3u}*2ZqJ0wtn1> zLg53@O@JjV+Q1K@n6ZB)R}QHCZIf8E)*!em^B!7@u;LKlZv zF&*X(4_TVio&&=0GY^8|=F_6b(T`^@Uk*noRV=S^Xvx;GZtFWzg;Fh#LM4bWLNC+3 zy8G*3aEm61(clHCleVKGym8}{eFM(*9-di0rd=mh*9|A-^h0H;F2`OQk60_0rc{Pc zWtQqYx@HF-cM&~be{`1hJd~Kw7SfQm8J9ung0UHEIo>?{W%_D;?I|xE@_YxL-g4hy z46MG?)C{mp9uAECgMeTw_Qm-EwV=gD85{Bgg?%hog_0>S z6{+kUAb90lEfIF!Js?1rZ&vIyuO>WV{)TD$~ga&K+S!F3-WAmNctbrpbnA z8c9tHx*$HMG-th0)BsmbqWm7lt@dkf#~>SjlMaVE#R0b4Kze0kEm<&HKbX}?YQ^I2 zR=KbwyC@7OKg!hDJ<+3DdUn6E3jY^fVf*Qm9V-Xa*G3mss*Nq&7_$sQ zHlOsxc%{vt(~F(-81<*2B49`i;AC^vnGR?aaOVjizi{y)^A9iNvXN|by1)S zQsCWGU~r>%%yKL|BsxAj|BIkPqKRRQ60m+4uTFj;`S$Zw4 zJ|W(ai^sM4p=>u*nw9CU8q2lGhsBx=N3?=c%stq1aYUwDGlh_}I-q7I2gN>E-1hWI zDX>E@XE~my;_2do9ejsP!ms#s{-y*SAVi8Ae^-}VOd~D|a&uHZB823@+t_9zdX>Tv zTw19Tf>%|T9a4r!87X&@E`(ofkWn&&`{|QdWJX-OubT-pKJXKG9eOt@H>k9Qvj~=d!6cr4w-FM5H}0q1nR{aL@?2YxJzN zTCq?tB{jJ$z?`isgH8XfZJg=L3qXq?BDybjr1f>=XD?dzvr;Xr2D}dCdyyM(=qwRi znVM#(t#JrrD3^@g`0s&Gr)Vti{Xe4R+}fiqk?4J!IuV!AQ@}%o$k)c{VHC7htES|L zdbOP4Kf3)lxF{acUcb2R)7*0WormJS+QbApH)pS*M0Z(S{CB}7p##<%q@KM(fw=>K zomA@Q=m>d_gYAxVT0_Z}WTSf1VO7S4z#J>hYnN&3A9(AJI{@6Kq9D{!akevmLMx+=ZSem^_tXgdwH%(wlBl4nWOrTY_zQ(gm$*Eeobby91 z%22uHZAtf(HhA$`i1tWLGM)&zUF`G|{yM%#^trZ_uk#acaT!Fc!pm>X7Yrc?mP?0^q`M523{V=!cLMRqJ;md*(R~YQ=};eT2)}@;l)8;_HE|~| zCr{`M!7a2SOodL2gjLg7kLD-fd)q-;&R*q8Ycr_yfw~!hvdnP{&N65WxW9WT5%HoA z_6i=74&;`ayI^*lx`&gMvl^m-V{6jQyM*W<)ch!|mx?6HEv~hbwks!{QXMOLNvGi*WCpb6D( zP3bJj!<~l}KzvzXp#8f4vKqKsknrF^>Bq6S!5K)!m=CU%ox|B~ zZI39_E8`1zq5*fmyZA?OBtIQauBYvbUnIhbd1bkh+v*4_m^D`C4An*v+3{1o5?O0E zA=JSDRT55Vq49tlD-oFjUo{GgdwcmF%PKapi>e^zjiBHhk(5`Zub7<%TAY%XLY`;P z#lk}f8ObOoLM*Km$@pTF1|}CeKcq{MuJlsOW^5M=Q9S-JEVCv z7*h%{`7BSedKV1_NnaFM02b^Bk}W%IiHX~_C`U}(qjhs7x3(I~rDU7uHNvm!TUz@t zjtOAj>bjQNzu(c*V7QB2II9CyOY2;`hM4Z(i)RX-Z&PIxMK8dOO8D5>u}#q2x@p$+ z4_p^?nmr6w#o$xmIM5|9&Wti@U_i?8+XQ4*NTX%hsiDl-awncglE6(e$eRF_8{E3f zk}TBFrFBr0)oBDGXq??J4cMSSaG1_?8i-i7S`I}|=(BN_+EDKBnNvBcH#y$G=z2@U zf`Y|jIOzO@@gp?WL1pp9?K$Ka+R++DSW4$AwBd1uQq=B%eqr%xxp|bHQSyFFLIfsy zaU^*Z{h1+F2H$NQrvnXFxwGy^jS`@;!1f`dPo@B-?F2mYERrdEf#*WHcC-(;Ag z5;2wbtvnSgT&zLcF;y^}Gv(6byxFB2PmS2?Y0(hn#$gZLMi?LQ{v^?rD|beEs3%Cl zl{zJpS8USmwsL0PBhwe#@sa5}ogrFzg{275iq{lzhm)Ee?PsoO7)ut>dtKV@=tBr@ zBgGH>ofLuO=cQaf{34s($y@frHI&vBcRR@|O0pyDgu3{r#7s>TMx3%zUZB$PHL05* zCMTp2Dwd|@9^n|QH+P&Bqo}+EI~kXxLzu+Ztv4!(@2Ktl(EblZq=+&uw5dn1XG%lh zjjm{}zmQ2zy)NoeGCB>5O2H$DyRs`Gt zxx}hBHoa!QSE*NeZH;rF1iZ)0^pY#n$(Op?vmN;#@&^1Dqk9k*s#9g}5%GU^8)`cYXJu(dE_2;WC>-P})y{U_i4?YnQ?Ov1l?=j}uP#&|Z+$njQ2u9#^%_HWZOotWm5 zA;|4Df->6cEG8immrMED(j%jcY~GV5KY?58C49Io%8V5^W>`#{Z`zi`$xcK1SwWH! zb}wSIY2c`Zdxr|O_StE6>Bo!cvsl01+a2dhEV@b}7a~5ck;@w87OwG3u`KW;Lr6Vp z@5@uPxBO-JZz9$fjIHCy&uhiU(dPk%V#VbOIZ>ijuM`?l(7u*1)*V>KlFAMk$5A$5 zwRLdb{rHB7&HR@kGMnivHpmh#n8CKglov-5h;&~&!e9uNN?S!Os%6Q-8iBhTcvFNZ z=*4qcJZ6>huMyi3b4Wu#9#A9sx(BAl!f4}o-gFD`!^;_}HmpIYgS0wGC9sSq7$}A! z3#-Un(g0X#MJzg-!9C9^U5HpGKS6$tO3k4S9l}A_ta$a!mp1TA*yr?;b(TzICv&_a z90k@hBTeO2toF2Xb~nEn^iQuoK%mPhA>+y8qDH_kn3}L5m#y?6e6Bnl%PAUE;X`vh zs~@nH{yPXxU5S#wjce zPe|C{WB2o1Qx)|hbYwoTmN?whg3R8FSUo|U%iB-`#+&b#qL-=)@6io;%Dql zWQE;c4@+-_2FLw3jT|O1#>J3Snt~j@Lm+w8oU^Zd_el12UUA1;S8S@3S+d!3fybN1Gu_`LT+U=qKHPL!+0^oRFRPxKKkxnJ-K5Q=toN%R%DNp<5=& zjt>fd*K)c1Y!@|i`~gEJx5MPr_Paf{d+F`*iL|ZnS{lx&CavC~mx)?o&PIdoa<5hZh z1UW31JR04m3!wAjP)m;8PI~N^5X6azhkjJ?{|aQ=L;eCa>cPI zhoXhfl5aL~x3aHRvkamcO4Nd|MMGDqG9zqJHdF?@j^jAC#!umsLsBSiUPVw1~UUpL^hA%{ewCMaC(Syv ztvf8CtnuzC+YW3J)XxonljhCci6l~$frTlC`iOim`pWc9#as&FUT+}0N_4cfIzuMT zSe2wdp=!lthuEHriRz6PfG+L^vpGik-uWrlE~MZFulT9dn<+`k@LpLnM?ny%?7pS| zsv0bwPGmHqe_s4@6m;+8Dnj8b6b`;};<}c%UK0k!EN1H&)BM4)$t33q=lvC`V^{t8 z6sTJN9oWuebZXUPGi%<<2p_rP3TETd0Y$IH#(G_+Wie%%?t;`ufdnbS8 zjxs6x`hP?lVV;4Z^^N^Nz(-gk(48WfrkGn-(#S@;xRPyhS;q7>zmp+itd#dPnMuIT zOGZDbNSY=1_2-?nmE5@5QfXxaaRC@5k?O9I?~oh`>sp z2X-5*X~NIMjByCE!u`K-&J$Bat)!RIZAy`U3oaMe#2sv}w-TW623%^ABF>E#m8E=4 zDO(&Lq;THFP04>#RSp_*NCerlg09QSr!e4`-wfcp|6zuqOLC>1@uGbzTAvc6tM7>< z0-7-5zDcj$#RoJZ+COR?4=vOYB8`HyPL@60bShjvIe(s9TV!a=*#;BFN-}j7UVct>%H_Tofh|$)?N6_(SXJwxUk&>b9~+y)dj7 zsLxtbv$;|akxYm65UYr5nf#UPHWT-Hs>YHZ5HN8xhC4S0QdF{UZeQLfx`pn?V!4)atxN@ABAtq3pNCn{i;fP%>KVTPtb-bKkhAwblGEobA=K!|r-D#W7b_d+HLJ zMgZ7M)y0A-#M<-8?P7F}JJTt$_Vy*JtykFe;1D3h!H4m?max~o{tTG`!G@hGrf^nH zet`&ETsf2frYUd@diZbtD2D5DB3h?~Yo64%$@!}IfYj2d3i*XA(cm2wwrwp?XL>9N zW#7~F&zi^A=-uk~&LL$X?TG!}&Fst1z;D6gsIK4!u%WHiYOxBXlD#A=BOX_PZ;XSX z?Ycv0mQfxkErnMNOr9OD&O|ldqcl*HV;@JX2A=PJQH(=cSDnoK=e@~P2UX0WkiywW&O(+0Ok7TxI%EAQD)}v; z8lKj$f449*TY)_hxwjEq&c>ag1AoCwXf!eAVlnw?dH049dFGoWmX82ZwFZ%x2Pqfm zjTxayMna58?4QwNsN(hT4Vv919>9_Alr-}M&7odW^r^xa_krSkB_aPE8d;6`@zjgq z8$ENy&fg{Id-CO1sA5H}_1kW8jokiWf7?ywg~PV@Yh?RLn}S_4*E?q8g?RrkPONIO zPfn0HUiG^OVCQeqNjVuoUFbVKM|d?^V1N4ldh>ioeZg97-uj zy8ne|ZSynGydfApd@jF+_cbg8Uj*QDR;M@kAg84a|MMeAyd=IoCmy?%)4_&g=ie&Va|AQ^tW;QhpX&S49t1 zO?h72OG?18#3a+SS`KakkP*lck*Zont3-UckHrPDLI5X&3ADRcC}}b@VesL8F`CSs zZYJJ%?2ne!YY^%;4yg-=M~*`NC3@asolBW`N5kDM25DS^y@>m^Xs21VH}L z|8C*RQ-)aX^e1XBSb_}5n{KaY%-Ey0$7nR_x@-6sVIPtoC~->fBs(nm4?BuZF5kd> zN@9Ef<}FeNr$FD&WO2pjxiktT=uB^Iz=U?nP2<+Do-1~(Sj=x^5y-45^J9m9(z*YO z$Rdp!xkk`!=*m4}_MK zj25lY2$Q!$TJh?9**RtR^5@0LiLkhWq;4L;Sn&pz0HWOpJNHHiKe(B|pt-j@3{Hfsf7EL|rqs*GAiSz8Ft3qesPDnc23LF#aNY-4HF*i1tks1UXYs-?3S&di|!PU zuDhIZU>^SD#<0!L2P12f$ZUVh16{D}+wPOrt`RLiJO=aTXy&t~aVr|Md_z<`N5ei# zD$LL#-i}5*I4_PALBT;>+k0BA=g8B5aH>(*#>$hGDMeI8I5O#xs z@GHp)#%j1jW&Z-DMx2ag{~A^a50WZQ%Q^l4Um5X9%Fn9jP` zTlS`xI_6zog5B>Dt>ii432wLQ$%;$$GjnQ^g|0g_V)DElN>BTJEs3v&fT_`+Yj0bKD=o3vtqY>3pap=mUKAQXIo&WoSV=-LZiXOf4ol=7LH0Dg=gAsTI{v=cq>Q7vV$a@58`8=4FXLiIE5ML zLAo^hC-DvrT>Zml<-S(VvsFG! z%$UZ#VgE00E^h{-{$z=hgq_m*EFC@t#rVk%qv;XNe>ViA5U!A|U5$VRR&IomKj8nl z<-;?qIDPyqu>OR;?>%+PCfh4d@!=9AJ>}artXDnq(kCZLKXmpLnUQ{>Px@<|;uo%2 z^QJk%*6%=;4J+|$2y7G3x@oT*cd%D9!xkpztO(FnI5 zMM+>hOQ|$Y=4iA;P~SRUj)_-?YcRxV)rjt@y|o-fn4J;n*v#bm7>a(9$$T<-aFrR^ zu5TreRBY1U2c{!NP3r<3yr_^Y-XmxE+#N3GgNObP#7*Rac)T&H zLsq?iskF0I*DTU5$P-@;=KbrXsNF!|5nXzadt8pYR@L2VgJ3Dy7Jk74RtZ#)(&L9K zI{`wL{1G4Vao2`|@G&d$FiuxY!qm{ZV?}fbdJ|fBVA~=X0GkE2Nk<$~l1;{>)&L?Q zE02vWMRZDIQX5Y@CiUk6vu3va8&4OaZSp>1H&ER1zB!E3!+Nx8#szNwjp565JZrfD z_b6?^J*+n1?)06wQEYD^UnAj6<_o^XOq;(%^947U*z+RoD2ad~>v}M6)$9PLbp9zt z8+LN{?j8cdN(BQPU@?=p4CPDg^3hI&8eqJIox#U=cf4@}#C0(vNduES7a&d>Q<-3nPX87lyF>7a(f#(zo2fLwDHqB!rqBx}`nHS(kkAdPs z>|ws>ha(-qHJsRM*P?Zol~|37Vc5_RhW_GlonuLwbi3)O#^4{<4)LM!VM4}6Bq<%Q z)jz_^MLZ+osxCCQ=c0MwEUmLvceBYz1aGTD!J%~~ z-TM9|h6jZhK|HF#>M8b2OF>>G99}SKu_i-ZERM|Hy^Ilv)Nk+^Q3F~U?5zEE1TfLp zzDk*!6-%D}+LM#>`PV8@qr|Le9hUdg#=4+e5PyY8519uPi^j{5n$#X`qZ+KFELRTt zQ{~J!84otIuBVC>YHLM~C5dynJ4qg_W#SniD<;BEwG*0c`dJIO3^j;gN{d*T=S5Ia z9RZj9)NJjE`L`Azxv@4@4;56#e#cJ_+=Q*v{5D?#C*n7{Vl1Jc&<0@qPT_Lvg$peD ztr3aDDD_I8Bx(w$kN^fkD?22DK{9%`TP}(q4@_bZFo%}?pm%`;V2eKR#=hpr?D+Nx z#P5ch2-~Yh8{;u*U$xauz@V(8zkQ<{!Sv(l;6=UVaolGNFifu$+P0g;952P)r^866KzW;87ZM~Sm+4e^|tC?!IY z8?YhzX84A~X>UA7I|$ep1^zed3>NKCBo%S2v+A3JUWlNQpUHWv{gj72$(Rd?p{5hz z2#LAswAT~G>K_9PPzR~EOu?~7(ha3!gnruux2A_?pLJWy`=ls`5W%> z#c*yDYh)iqXE<{vt0&pw^s_CxKpXNmTcN?*CJea3 z^LD~SjRTe;y|x`2IV>NF8>&%cbj zZ{N(<9rmrx^(IV>6*3jbzoQNRM5BDJFs4QVyVqho5n~73HcF#*>t{SN67gu#D^zxv zXQCbmdy<(WI2+(au=xQYuFxx9nhK6Kl_+n5SF+n_dLEr7_A*cILzUMrD`- zL@kw;Z84;OgBg=hC|E2IZzM9I7MU>)$+H<&LjSVa#c#n+^bn!ra~y+F@d5enE|pPT zr>|Y5MY>Gt0?NEbu!AXGl#Ae;MS^)H6TWV_B-Y@!2l-OO2)oRHN%e}pK8xjM>KUsf z8}_|0g|mF*w~D`%phj5YZ`ERn_7vX1dVH%Ei_i@C2OwjD4{`8Y|BE$-7#|IOBmu-M zPA88X8>-dvgDKS+Y!}bKVd3+u{G6^J4jimQ)~mR4^wi7ehYWM(MO2QtT2X;(Q*o%nzaWOJrnW+Gj%U4(SuUI-75a7~g*k;zr zv6dL}&znjNT#g74$-p^lm|1J#*KhV$PJM;zf>UVQ)RC70;4im! zg>WyZ1MlEWO(MjcbM;K#GrW{v(`r%?Z?tr+l|^X=PN;s znUDt!hp2U1cct`Hf_P>Vb^43tY%Fz!Z1!#qw6_BcIder7r>nB^^=S+$kdD)uOp*xu zcuChg%MT;8$Q4u0U-;q^_v{-&!?YN-^xU4D1mU(4Z=eJr*z1sQ^M9+qQ#PTtAFRCh zWc#kY^{;iMwpds(;shw7j4o>|c8YLCK*7ZQ^k~8>8JT*gk0iGY2N@t6ctZfEu=z1c zMqN=BZj0yDR=TNR2`UY%QbM80qdXtlvddGZ*TTIF($8;mG0Rha09$8a2i(l>#(pRUat!Dd;xya`*=u8H!Kv&L z+G%lT*Nfqz{R?PZGzY)1=*4HsCbq?qpz>|f_V6RI67nBBp1LM>lCkJJSM=?iyDgb~ z&H>pSzU4i)&v-4$q(D$IyXzjmczJY%M*i6Yi|$nk0d)3F#{F0tp$D*JKoXj;6XEls2qwa$c zt0M%&FKT8u;x|6;MQ0f8ld`pnEh%5rTvUloN_di6g)h&y1nv7Jud4V9 zU{kzVjz%sljvYzx-5UVr4&IGXjV#Xt5iS7`?1F;AO`7#d4q^pJAYCB2dv(vUcsd0= zO>iQ6LoQ6PJMrWqAI1*!frdB&F=Z@p0X9MF<4rNxD*;CEfo@hkzrRU;&KV)s%UdW) zVAuxByyz304aOf(tNeJW<)`p#er=Tr^z&rCNcbag_@W{)K<*<_n|}TTgl8z&=tv2s zxJXyPNg9HjguTVLbA{Vyc?5}}Lg+$mgGdRuD*8hH03$CL`gqNEGfu+{ z%O6&uAWMCVU^(_u3`rHnB#Qp%c6kTo9OP-H`|6P&aPe49@3|Fo0*q?3>en z>QsCW3lADeu90OL)FO|=Ea&t|2}Zt0l#1sXi`MdycY(dpV|eYZ(uoXCPlQ@F$al&8G&~agMy;Y;26bCefQZ(y*A0l04$e zpDy2`T?RFkL-a{N2C)I|i21%)1FO{YSjRlkGM(AOusa@2=Y*ShhhmQmcppwaL6(@M z+&UEm(j`i|aBRlp`Ds)%?2gMCcC9OeaS#Y_2+X?yk!Q4ta*pdQmPZ&5#KU!3YR38}hadbDK zm`W_EOe)x@-@rjkr90fX?eSi!Hy8KLuT>Z%rEtqP%!GpX#)KQWTL*esr3l;DUwNIN zM9w1-nQI+D*vV!O8w4hp9EB%1t4AT9N3(G7kZ{?4N-fJON(*|r;T|Q8_r1X!#%kKf z;L(ReeKe2hbCesPWc?7_0x%0f-p1Hcs7@!^7}XxTN`b!mlBh~wHlQn-_A(vdc=tPi zHW;){ke%Tk>T@`skr%Bq$*PmnVN(I@*LXq}-_`4OL;l&6>Do(sDZ7*(I z8sEayIh73X;r4W>Y-`@_;1QpbhN#bY>#uJd%_r&J+n{nX{P|qsh8Uf1-!4x^{u(Um0J{SjnWuu~mgBS}Ql6mte*Hxak

        60T5%Yt^abB=*nm`(T+p(wkvH>4~hwp!m(KNG-8)pUNyyI#HqvZ$krGqWBs?y@)~0yq;=FuqYNPaQ4b41d~uga8mpMhbia;`A4KX zzd}mdc)NNZo0!)!8DN9`Y0&{|Eg@>ae?>+AkAg0=d?6v;lr_5vP*7SHk^PX-p4zc# zT1F#do9d9E83X9Ogg#(M@m74}rxle*zS_5}Ag&vBzVv6WniXXV%VqQZBx3T(gZPrY zH*RPARxNV&72n1}^gs7!ahJ~~Vgq6JMEFxp$B%8mpqsqubGW&Ab3wtGe($F9A$-r* z_@|n+Sx5DMlB0+3rW9d1!{d+sGhB3uq*UK+7A(VbcyjW<&}vl1n@fAi2v_okKJ%>o zSGGv_>iwGMW%jDNry0hD>j?AXPEPDS86uX$w>2s*iTA^UqJ)*m%U+hmU#zN(mtuqw z04C;a1qMhL?A%F}+cc{5VS0OQ!Ox@u&Ky(I01ylFQhy$m`!*BSWtWxXpbCHz5%xAv z60;z;xLi0yB;SLz9d<(WL^hoP?%J@F0Le*i`{T21zkpxyFkyW*>XWuGF&j8$(g75~ zQaNSEZ6@ZX4dVxb3^OtNTFan^T}K*2*BI2cC*bmMj>AOM$8cj|J0_V@^T01ns(S4c zq!OF<>s}w1nb~3(IJv6x{bLIS7++c%j2~b&P);glMd`yfpKpXr=9(&zsJ)00Vr{Bd zjBhy!b$|kEuuaM;cP!H~lqsZgZCs1^zc~W?MlC{0t2cP2ab#=>)9yQ7bfI0&$sowa z30Po6hiL{}oqcrYZace_0OU_}6L>7%%4tyn;(kKHSz)cx7kZx?l_&L%v zfU)p0xCZMYEHe*Y0vb_WjihrRUxBhV0Pw@vuAueSUkCk9NQCuPwe5>0yMptst=J`~ z?l}rg|Gh*-rQdV99G)d|azdI&5_P0v2YM+gM^SPfNN;fzyPrQd8tVa0ECOYsEmj~C z41bFa{>miYR${(R;Mx`Z3CP6#ddC{wuc*$JyU*6lcwqrjAx#!1TkJQg{OvZao0Es_ zi&y-2_?uR37rZ(cMg(mmRrb=)NkqPRg-^B`$LYkIqte8i@@l*;fW(&m#ufxRD+7K- z8^F1^ydJvIhEiy%q3EGl&R}!ahR=dP`7<58(VvM&bOgPiZc-#qtxqCwB0si5r*?_C z;5xCwPigTaoYqojTo#B7t6v+j3LbQ<6GJC~dI^pPTFaoA)Dxmt2@fQrt40?`DY-uP zd6j`vop;Wn!+wQx#x_PBv6J2BR7`G}j!{x^#x{@MnmWo5o7TzKv&xNitaJ)-;DC3d zo+0uF28=0jPFD-BQU$^j$kr8lKg#RCX@Q`mAfsTA z%WuaHIw_`_(+N!!sj*BRp zdzp<=JYU|@Ts^+YOgoiN%m!FO!PCA~2kLXQrBQC6UR0xmVdTyMuL>WOs;2GC`#CaH zT!Y^zpdWRn?WZjUcxqx)=h>tdaG@kogp*?|NTRkaoEEk|di`zm9QQEKNrku>FqQ)C z2I_+*cDy>sw(6ee<|;T(TC5nxO$y70)xvTKxN5YL8SsW$$@VN|@&OcC+lekl6kC{V z$wSoSJCbxV{{-PIl01=-DT~iPKKrgHK8%-)V39vDNOsy--!~;7=0e6`!1ku->uKQ0 z_S{BWHm6h1y-+IET2iyY8M1-&Ega)_uuu*X=u2U7jz9p+L7dNA$HJ&JYBLWrM%fd` zQWB`08qF&>CaumYjYrUd$0b18A-u{}X_K+maQSDxc58Q)XCEblh4}!aK!|=Dm>rmX zepAM0ztk*PdG{Ii9x9*HB}$Cm)~6)6`bbmr%W}|a0E5ei^+gq^v$_AFkFinU;DE3D zFhF$(qeHNP?w#+#G4{{U$rI}{?B7mo_}=+opQ&i=e%|RxBd-!LbhP2i zGgYJ2Wv1}C0&14)V4<2Wm5#7k>dR{sa|EeH;91R=f(cHmKsbXNb(O#v7D!>0I#$jL z5&iL7qR7C(+Hq%#9P=k5PE?!Q$~Gh-z?9fdI~fbeEVgKe!Kj%oW{6z$hQqq9#TP;c zP>s(VwOrw@93EyY`RXW9VNga#n~mcP*n;>?=LgM0Aj}hagHca3?L(rM zGI|?zu9IU3i+rjlzsl!&__*3+kG_?}U5wW*uF>NGwh7~BEE>3Nc%#OY^0T(1r|B=U zb4MVrfRD0MW~GW|(bnF%CksTF{DIW?yT>C~?fjC~tY{Lcglwv|&zv!erP~5_LN7?l zg{fjuslzGav{!OdS4`I(9gzKzKZ3R}pi~n>C_IF<>?OPd}Xk zH){>sAz4=M29A<|;HxDt0+8%IJ^F#5opM zt5e8!n?KT&`6I&)q`my;ksR6K4;7CFEz=52Yfx`m#fn70L!({rt?BvLG-hcuv~gJh zZNpwm_ zos4cLuX{bJVO1Do`eqj;iU&^KEy<4GTt4DMT!txa|52V+A{cg>5)fcxynA2{j`Mh+ zPs&_Gu4ximTSrrNjftdl57c-le3#iBX`=Zndv%>Vtw#EO?qzl|;iC2Ot`EVGqJzp3 znQjSQ>OyIFj|c>ebdM*WAZ!Sg1c(FzL|7U5daiaDM+xt*t|2LVju`0)p0Hj0cks7P z@0?MS{>rFFydRp{(x31Oj-a+NZn^WlP`_3Sd3H&1!OMp$%$BB3~dl{J!XBH;NbXBNovl(alO1 zGZC*MUiyZb?mWDu(w&E6b$!ju7=OthuKyQi>1XS+t;IK0k`<=}Y8qbY7N@)!Kqn2( zy-BH9F2yZ81CMH?LUKe>q7l7>3MeTR-3L^Z5CrvSil7?As(fFZMlWU6I9N=;0=pKO z+Vj(tKjxL@f48ZPo$EI0Eg0Vjsli?QZ`~oWA|;QK6N*u}Xn@C(Uy(&~D5N8% zg6-=!1 z8=Qqe5C9Q;NaOGUw95sy>t(0=8>S~9Tx&c>cs%H0j4^eViwE!++g+YA=0Mh`2?8Kr z`@*u4_S@V0#p2@vvdloZ?$F|n!O`mKf``w7V&y`O@A8zHOr>HXYKg{Q-11{B>;6XbFGah+cSGPfU$XX@oOn8sY#hMkM z>Mo=<&j-vMQ{pI;$+Rou@Yb;=A_!|u3YvpRJ0JRN!EFGOyID>_VHc%}eU}C6DV)&!18wNv@Ekq^G`C-_>II!|(P5 z-ZSbqNaa!7t9I2q`D#7g2kOK!6uIOnx?B}AS zdkv3)BC!0JVJL*Pe46kr3lqerVfmB;;effK#t6vvH#j=v80__QB}RK?DE(`K<(IVl ziybpB=gUKUvAW)5b8HE4IjWfUxL)9S^Rr$;A$j^&YX2V17adens&(*fm1&TsVnQzi z&m5I?M|$B=7gSVNrFWnj(!AMn4j~>$Ik|^XEIYl24ul8Wmk4klu5M5ODxPyb%y4k~ zlCP5SI6|4%T#9Re(5S>n-6oJvPLPdtHQFTFgUM!{!BBE4E zgExg1hoJPg&qw=M;51QI;kT zj>PSg5{8k}ue0MKB6m1Wu~3oTK#0-m2|xV4Mma)n?oS8Z->$)%?JwR=X4h!XC3&8m zo(RUN=jksqMB}noetDD-YE=4SZ9+~AI2G#~O>{BL3S0|G-z?Bdy{vpmKlMnvSUW7nAN}_+l|pR4T!wn7~zPuf8Qnl2EGFC3A`bM3Y(ytau9e0Accg5C81i z5>iVZpuV)484geUb3@($TD-yCDR3dG^3*wj)V!9TRvg70KFtTlg<}J-O&7d{?xHbY zxUcdlSp4}$+?3=m_lxKQE8Q#ZgQJ&Z*iF?JWk@;I7x_guDayOfa1JVr`%t`fNJZ!7^dW8pf*SokYKq8g%n3+TTE^suM! z7>}J|(*U#udjzM7t~60FZAmfN>mY_~Na`@&$42E01dIXctdvMC?%T9U!|J5!EWFEw z`DgSTh9fsN8%GQNBl|sc@bg2gdh))%7=82O;J&9CZI3Vy)n&@N4r4rFZ2^v!V#w$n_=(A z(qubcj&OZZh(oCb5!#M-#BfQ{xw0`j!)pIe@mw>Kea>w|X9^l$G|p@`4IM8T7%Amu z@qt+B5H;GDnaNvtWHklf>%Zc1>MFYz3{LSE_j)|68z=Fj>98aTB{R@pz@pxGC=ovC z0?VY<^GF0~)xP0JCAL#-Eg1|q8N3tZjs02Xue88mT^_}2R*A`0DW_fK7c$6FZd&!z zU8p67z^KPb+KlwJU76V3Xi7By)AH^O+aeLrR65O>hU)^D1~G`*MwBygfzGVYNf=U! zO=Ea@v&{ab-qdW+8KaN~|M1%w?5aH$KZ{of&F9B21^?7&>7XWY?r7Q*!wU(Y zw9{=DsO+Kp_TVxp@F{UbK-nI1Bs{<0O}lU( z{jb6?p+>YMC)G=<2AnXM24-DdtO1p{KJ+ z7Zi96aAb0MYC6r2)2SN5W+V?Q$Kav@Xg4quTr-nH?5>BmY9^PLdL|G6>IIsaUn^|J zOJ%HLm%6r(7_X+V5WFueqJCK^aNvdSSO)^){;O!k3e!YpIpM=glbt-X_}Hg^#)!h* zl>3}3T2s7cZzDptaWkgy;^~heXN5NS720Ck=31CvP?Kv_G{&l`W7VH%8f6k_cqTsO zI*7n>ec#HI>zFAQF0Pz%?Q~W6K7QFxNCFQk==wpbH-_(QL{sXJpH%O1lb_&y*u~tG z5CdY<7)A_n02rJ$IMoQF^VQh^@L&)kXrH(vgDy`0P&!k`|=wp}mc!8lZ7by@5Cr0X@U#d^JXY=3XV!JTOLA zlo!Z(_V53f{YKL0FzofxVwHj6Cw1p)seeT--@$ zdV>eT^C?Mnck|V`1kn8z-YCcB9DvU?(F zKxULI;#8G;?^a_z8LoSpu^?rM8c6^aIqXtkBlJ-Q+=9VE+B#)Tx8FNezxB1p=%;n0SW zxqARF*fQk2IyQWalz&a~KjQpO$*of6DU?sjQ&$(Q>3M6hH@oW|zj%4{uD|H~g&N5} zQ6iaH7Ur9xr$u;l3~!*}eGBNIANan0%(2&ZK8ud-?voM*8e>GCm2r2w_-wMgGu}`d zN8OMLc*9cPkc8;mS*x!n7w6S@-}3i$XEMN#gq}@&upTV)nw!64%<`YhDzanGswa2l z%l{x+a6TW(-qUWB)776@32ruexjwecxXq9e+MwIHSWM1p^5f&bZI0pa79F1zE=x_a z?TXZ^pUl^>IgqH%7td<$Q+p7ThdkXXPX8Y!}HFlH64 z;xbd{$fzzh_JxZqbwj}>S?Qn(&uFiMxB$gIE_{$Ma2ZM-!NC(o=;5kMwp^+7xkmyc zg`=&5WRi^tJ0XoQZZno5Xwz_FsulV9x~&zAw^aHQUNo9 z5iA%q4(9jhu>Y-COu#{L{ZZJSX*2cCd8!SYDA8q%*w3pVz?V^;0bWw4JOhT=9;%e6 zrb~v+f%3fNnnR!O9l#C#?wK4lov1;Jo0oazrH5@v#+_bxyNJ*>Wss{F!=uc`k`>&4YINYcw)G8#LuU++jO2ZP!C8mRc7 zlZ$!1Qu&Y*VIRPk7^)H{)~0O|p&J zS>y0izw=uG;ha&ixF67pXwVfq>&8J6BE#F1OE7sCuI+&V%dL(b4BbDpMwV||X;1!L zmG8-CHQ$Pp#O*>hZHrjHusJYf-6}rG3~c`Z?Hd0;)!kjLt-9#`hLCBw1C@q}jm_r* zA(>EiH;+?97Wqg4CrAEfs(~4ABxnGRo`b67z7=z)RUKPNZKKw7N-261yXUJA3|au3 zL-8!|4B}dHtaBgyu=kJ7649}QQ|_ZHrlQoUMDj5+09=1`p|k`;tXvd$W?BJU;33gV zm9KB?%Jv({5shb14lNDV6?`y6F6%!pZU?sow16a^K}bkR%rI5xp8sIkkb3XYV6dDfRJj25~XAm^w= zrU@LOSvB^dRz=D@B3l9F4EX|>_#977z(&s0d%iLC{tcLV4RoJVCV1Ih=tw@++Sai3 zF6!8N_(cs{55K8OT}Es@Gs0(ajScNROZLlM+LXt&2+mmtQAg|i)6KdCH-drJhV*>C;@-LzSx_!keFf;{8b$GW^S}cQp~?Rey+6R6_Jg#e zs5(l@`qeLT32obaV>);SzI+Az7JPXXV`s-?@Y_1zPFfEoQUiyLR1Pp-nEk6{3LPZc zW5^@jW%zeR#T7KfXew|>E#22tB9C&PSJVRD$RY5!&Js+o(|HupuwF+V(&&?_YDS?C zTsE=U5ZBZqJ#N;o9*Wm0ziH5W<0Z-klTX*3yZ%*&L-J-bG$wM^-u5er(hawMvjJQG zcG&qa$8^sTjty_3Kf8R{8^a&)k9*+ue89J&@A|IOg+SPz0D?~FX^)kLe(xMo7U_I= z2|-hVLmw;&^0vBL$i>7g(k7E9Ed2E}+xSE6m!;TP0_*s77E-Uigs8d{QVaLE^w~4q zCy*NkI_9JMO1GH1y9f_%y9o#GH~#jj@w?rmEKU8dqtAXSeV1^nu5B&SY$?q$k^^qr z)&gHfx@OSL_u{x>6?rfHIdrY2%Y|}PGzd;%>!YTm`e+<*I%!3pj43-c#0?z7pWS1o zn+-cdJpk&D`F+ubm>L<){*xMqPG#HLY9P1PfYV`nod2M+2NIJdZIRrD0FvkUN%Pd2 zZY$k2Qfd*n%Do2>Lesh^P`kMCy0cE{s%n7v&34Ae{YTi2o=nWt1n4MH<|qj5SMfQBbYeghTT z1vI7J4u+8Uqf?5*n?TyPaeTo6r=!nzaSZi5cd z_HM)*HfO#h_M$empB*s95P`u0yxPtbF1+0F>zyM%TxlK%3tmz7y5hUkd9D(!0N|wz zPZ;NE=L;)*R{wmu=3M7{;(s}a(wMfJi)@Od|o@ljJ1fd^KLqVd2p0J%2|< z(bv*^CRBw+`~$v=XS5Olsy)G8p~yHm7SvaDkEr|zlF~$IH;RE**C#4%y_I_UCT*lB z!~O#?kCe}QMRzd02Xm)!;1aQc?e=!zQCltyke(j!pDX>MY;$?o7o!@DNrHRqJF;Isnc zOyG~t{2wG)^_$!|tE8ghUaG#)8>y7fw=M8bU@!+bh;|qDcdT)Tue_)SY^Os+(P}-D z7aje|8cTcZ`X;_;)WR3GM$^R?^IK2W@`w`(Gahi+kR4;6sGM!x{mMndn`%-j@iP2!$OT}e zB{z3+0tb23@1o;kj>hOWlM(bYzVokUnDwXcPflJ9JEPlP=Q|D&eo>&c zoPU7uO65-n&GcsxMf&?c|49O<)!i!=6xMXCr2V35#NtKBxpM8l_0OV&PUMqZoZ6C0 z$I}Q&wT^#G3id7xJnnk;R738}JZm#6wP_W{8Kp|neE5mYdlH!`lDM5*KGWuizier= zU8>8h^TwZ=isc9z&kCM4x#$v-fZtYvCZ2+xQx{&nalCEDr=P@JASuZxq4&~wo(CemYw%#>+V$f|K9<$!^Z zhJ)^fpgH~Y=DL-MTO0eZcGoCuh#X0N@zGh1a%EIF3{knaUz^6`yo*`iiM-yn?G=>-09x449Kjq)`)|2MDyyx&KPcc{G2@gtWhPH&nM8ZO{VPadc+L1}* zeABM|rd^9D69D`U+O?5NTe)1Zi5dxJrA&t)?6*e5J`Rh~Nc)C5%Ma8h0d_YWbR|YF zfBLpVmm7!5hnyGplOalahr|Lc6DM|A&SU&xs$=!%+zs2p&ER>#vJ$^;=!kn_Tf9Nf zMeN|yVL>EF309M!4$-9cV+7;^lvD1dmaBW%OQ1ODb?ZdQIMr=bIvJYmVZe-l%g*9{ z?i;V9%Vow=Z6Q7ETF#{zO=yDc+ZKiuO=kVpEe$mu)@1gjkVamvK%)_rSE0^U7J_W< zpLhQ63$pUz;{KGa@~k1u5k;VY)#*VgWcWoSdOUa&EhtuWwZ4UkEl^5+J_UiP4=i-L z2OblrbP7K+S(#0H(xP$fbnT`M^(0TYT$hq)eu6uYC&6MPu3h(5z@b(q&e=3w@^?)t z9Gjg_&sPMI5w&w6_3A2C7)$9KaOnfLtBLsnM)ZtUv15&ABfIqi8%I~k?13G>JZH;< zIjKa$vH{CIzz7j*i{85=Dx2FyoTG! zYo$T`_>7r`vFXDW7_2kINWpeY00x=xA77UX{UK;%%!ZQL$(Z%kcI=1*AqE+N%%l^1 z6+~mgUh#)WQ&AJwM|8G65@hVH;s9q4IKH7n|W3>Sg9jX>0Xy%Z2C$3(@jfr7Og|g!0Hfk)7mDEt60p zKfC*M0oooLxd6wqh4>H+@FxsQyrnFTPsq%BCSMrOL zi%kX+#CP#=djC@E!i9PxiCA0qPM7(+)N!|i#j8#7ySK#)(2CRWu3$g};uIDDc?e7r z_=J#v47*&}>a016#cS<>OC^Pcz4zCxQ|^t`=+b@bzJ(6_l6sv$Bd!`~@x@M_1BQ&% z&}j4|g6m$d7z$I1vQ`ja!3a&0&~PpLCL333K)ytJ!CNZlT$^NcICi5hmoG~=61Q3EQ{U$rx_(6kUSC6Q>ud=fX3lq zPUWZ`Mte}%BSa|0u#2d9&<4PCjOe+C_R5Y3*?GASstDqKVKk)WeTderM%%5P4JvIM zmm6o=pq~O-owInpqsYsL)H_LyYuucPMjGZ)RV9mV_49S4O5b zs4^K`%K}m&HbK|u^30Da;Mf9B4Ts~W;))@@E9%S07iSuGU@U0npyddL$#vCCHYZ^# zBc0%LQ4(VfiNwmbKR&ZR?Uh%4wLA+H7CwK$KV)vBobi%6OZ5eggcPc$)t5-sRGoWd zDRRC{S$ohiuks#&K5H3Xg>@AYU5Vj&wN1AR>l!-AAi{< zmKT+0xZ#CLCTL-J-D)sTJ-$oM4(FrZ+Z;Z2!|*r<5-aKyUcOp z%ms-*V59_p=b$qq*oke&>Q&6Zy7q`tnL{3F6ffw`l~~h1S{K{}XL96g8cz7VGW+AX z8-3S$PAO7&gw{jr{a+S^`zW|wCh1B0LWY=Q9Sksp%8S*j-MWdxakUU6-U~q0>rXM@ zlQL2TGEZAdSPExndClr|*m=JNC72g17u^$=mcpExhv+D?PzPeo^~Y!1vL&4jOext< z`2}p!wS~zr7tLGk6hF~gCOt8g16olzqRx%;N9%&Wq$Uk6#Wm?YP4Fo3;JFGuk%%R6w87mSNEvEzEMvc~L!rd5A*B)PE**nrx1Are zPjK9ypv!U9r=C24Y`oGE@v7!=uAo;koJA-^>mpt7L-6KdN4 z$ME3ZAP93q7U%Ty-~e}{@+KePF7Sx;{Asz{?IVo=4?m(m1-80;;~GQxpT5fGmdJ52 z0tvGapo{AArM)|pFsMH!3M}7wa8|>+YEw(D(FH`k@my5viP`60kx=y99qCbP*PaZ3 zA=-cku#|6EfeE>}#_NC}0i3oNfqYOqmg_Y!m~H>oQCog2*I^jTbr_H3k`LC`Hazbp zObSN)^PFS3aB*d^kL@o>Z-HNi>B?}BtDrKx2;W&A%eB*Y!W-hC5?zDX2P^Rf=<=d? zT&S>qMw$cO`#s*Eo2Tj|e5XZS+19GiP%UCnMRpWyMI{r(&q@fBw{HuJv=Mb=#53{E z=ar5w!}yMt%Rz5`$bX8xQ&<7<3+%|l9-}(Tkwu-2muJCXcQETNhfwOrLj&IEgMznjprR1KF6TH!*cgu}6N6ZZq)h6>gO@sSS&3+6LxMg~BK`;AAsWKl|GU7= zz`g6BUJLj_$#bVcML_yQu8k=}cX|DEk@BqXQTR9FBHoPK?+W z3E3@@v`eQA=3%pVBQ8&6L1(-gHl>A3oV12w_K9-X&LAhVa>Nq4Mf3Y64A8iBxrCIR zJ*TdRstPrq{{qsT7M)}lxu5*-y-FuI0R?<3z68a0=+8Oj6!^p%M9>@X4T>Ew&VUPA ztxKu5=*`)}IZHwso{c4kcq?*b$^=}URi)FT{Zh6q$OkvrH-Y)5ZCQ#$RX8{3vbP_*1c@k@Sb*-N) zA)CQiNvFpPGjw|CA>~C^qbz>1gm-IdU%TCfo#D9jg^55zXTDNIbuIUUcfcq>qClTJ zQix#I7n*>Pl0}0p>|cl@ilLT~Lpp?~fb}PjdG7kB)QhoFC2~32DdqTQpLv`2zb;aQ zulyR+bTYW01rp&#{Bl{rHz&EHtzlw!{p;y8wl2(ge*(itPK7&!CI91Nf&}`L*IWM+ z-utgw%uI9G?HwM{u3P01)Bz+-+k+<_geluE0bN_^1LCtx|sLuc4pyF7~fGh{{aOflnPaQ8~% zCT1Jo{qUzheg9q2z9`J^+@U9zXbP95=ZyHGt=jMScIa4Iy-b{nsAMJM`BK^qlMjUsl(1ZLa z6H#s;apipFqduYeDf8aDlt+&6P=s z!raXq&`pkTUohiz)R#US*#2vfN4N%5qrgQnmW4*yc zuqf>&{X<7qBGG^7xLSZnpYr`Qk=%vhC;NcyZcgU~D!B0rV8wUP^zjb=&-29u8WJ`fR=1x3i z;Qw=Rz5U-ns=y+a_pKypwMf!J(orU9ZU2qo%QWFAleE^PPq^Tnz7y|r(Ho-t;sEK= z@dJzbqc+l|_t$?Z5b1Kx#eN%~4;nU9#ke2{)U6ci0A%9JzGf&1LxYf{C#3sRnY=lW z)v=EF&|GF9zu2OVirsU4EeV6W(q=rMye+@G{$I&94wC&{d>Bq{fg;$Y3TEC4rEi*< zr;z-jYjJoj>q=3(B`!V1Yw=P>*4mOH*lUTsbv&52FCUII5BXPLAdn>u&UI*OmS9x! z|4h@&_se^=+Wtz25AqKQAEJ_HmH)%f2wWaKB!I68z{SFb{Gg2<{RMI=?D~TOj-+)y z!mtUP=_5e8} zboENS=R;VTd-m7G%In%CIdjrHN!f{f(6CB z0;;mCWVc=B?~hZ|8Hs~#pUpiI@sS!YK`}!!g@|@Rv#SO1?k{3%S$1IQ^i>B=`<8yYLqoqe8>l2DmUe=j83KY!WHHudTX%0;l5=*w4FWg!dhN+KD91i z4woJH8mJesU#l5UHMC(Vh$RDn%uFdf+?7qz3ZV(N&l3}Ciw8eGOLbHgm?JqT0p4!4 z7q()5Q}hmRe%JYO+eZUyM}*-D%q8NVe3wIP@uI$k-P;}HdMgjI(SW88#pYgPKCYb& z8m1`t&dyMafqp%mc%0ZrXyUQ47@Zm9&3c3jf|4BWFq zq&nC>-}1HX^R?<2n18fB_q$7>{K`DV&)vRgM3+rZiu1w?rTTkt*x2-yK`J=QE{16A zlW|mhSkj~8=qEBVJo8u1vz1F9+seJNXaWuiXjZLD$Psk|Kd9(BhLA+JOd{kaNtc1$ zH8g3=;#7LKMnroHwIp2m3tbxv4eYR|?+NrK@Be);f$xh$m3rzlQ*|aUp*@t6D41j= zt`Ef!xz{>z{_l{ffLt)=!^Om^RCxaYa{H(gi>*94u_Dzg*Mk0Myq?qB?Vo%v-(mk9 zez&c}ziIi0(5hUm<4qIw0!2s~8&x(o3T2VLiQ|mgLqE1YvbpFQzxdSoGIvem=%_>$ z06u^QwHfg4x+q#E}Tr6G@EZla9iYY@!2VMDa* zT^85wxKaaoT>1#N1I-X!rKTC=Zn}bo|jTC+o zKJljkTinJU7ShMvJgC%H{#iAZQ>fEj*ND?4X4b0Bn;O_d=~Sk7_#kV*u=1~&eG*4%3u!cK_>re6%lsVJ14Rl~YNQpnzfra$0iLowha2(R zqu{Xw98ewK0F96xM}2t)H1QbVqSy3sVsm3i4%o2L*MrRj9hsH)DHbeuP1q|Q4S3a9 zo2*7ne%PpH#vSn?8nA$?$?_NTcv89Fu7Q5LeVM1~vrIR_x+p%3m!!^cTIzT*8%4zs zM=pFaVvUg!wY>DypYE3011eAb`C4x91XHV_Mhva$1FBI%Z8cvA<()GRKoTw>7{44( zXOn5?1N+=1v}ovVl-~auQ9{<`00*L(vRjJr5M*T0VMD-o3KP&p;IU<9YZ9825knjt z|02eW+_xe@4J?Og3nkBBf7ZJlsv5RnZqVL>c+0|&{2^HHD`R5rf$BNabE;oeriQoT z0T10s6^kXzY^VnUWj@xEQfZwq7R#)GKVk`vt*KMgX*67v7*8_KuT5QUiUQ;2eZU%1 z2m7@C@iB#CbS4`GTNL{gyhbKJaj|ux`?j2ak;s)i)5lMAZJGy51@9XrW0{RZdU1j{r%MX1Zmq;whc^%vh zm}9m+q9$+_pasYVqtg1J|Eo4#U!L7x$#@PK_JwZD2fPOpT&~gyVETmY@>X$FaD_@Q zsrV7aDCV&mgvTAId!KU*Qpl8QumdRg!n}>ozBH~5Z*ui3nXHj(w)2!{;*~Sns!L#? zRgdO2jbfoJ35J)#lPVZkOp*h{qpU5m3}Z879$5hr;fEIU(?2|R!S0F z7oOz{0Qh@oIsqvS$H*%UeXUMJRN3yZ(a^_+-ch&FuvAD+fdau1IoyPJs8n=`2;A5- z1lvv-Ym^@bRXQ8?ehbu-9cbyw!$!TJi0=uu*$Cj^r`8-+{gw@yO~Dc&Cuby+PO$wl z2e=svbW%t|i%BcGWwvc}X(Bz#H@YBM+5T@Oxmi;WT(l?g9mJ|-^1=GrK-EfA%Z^Ei z!^M>eaob;#-UYwxC#aSkR8-3j(taX*XIZsur|(ok97zGkT`2aEdVe90A1E+PZ@?jGFi+6Elm>_dwB0v%(Se#^~S&>*f zIpM#w0Y4>s@1FI82{F4Z(Ab0CSH@$gl*}eyg7T**GVT4n*R{?}rZZ)-0_>#^Dv?rz zqIKK1Dqp@GFaZ}YqP!9UcgN^v84bG7d~;*UDuENqH#&-y+LWIcCnvt82~+k;QPaxT zRsyG$uNG>ZbF+aQqTWD~CGiHNj%=%fz!D+DHO%0sL(v0LN|YV17Yx-9_k5~VpJ~-( zQ!4#$*%WoPA(o*vBWlb6QCbJQb9q)*r2MVcu&daXpQ~8mgR#w0nASckA9aQoGfc#0 zlt@KBCtzb1b8QNJmfSU>g$o-UJnejud2WJ!zBdORD>5NO#hS8w$2`Y-%m^%L;?0Au z>-BGUamNjwHcNQBQ0Uj(@lc*c?L-;AvA9`Ihk#KSBcG3uJzl74elM#!gB;ERNJu z8YBbvEcd5}MxB58r+uGJgJ_g-kmhsh8!Q+7%jGSG2LsK3tn*pnlq7TA_+3ZVyd%SV9`S zDZYb7oSNF?cU4$$fn2Sk!?ro$f#;+$9Y35OT^ zI1zZ*KPua44+SYWz2Bf%-5077HeIbjix~F-YmQ*(ON9Ht&vvLb)Q6lqBpw{l$2Jwo z@Z9l;sPBM(*(a^pP5*Y{h9yFjgnVud%y!9ll-R?tvWqrhdunDr*M#+?14+vVIP*fC zxdbSpVS#;ub3Ufrxz_G}l&TDXECdYVsqBN+Tnb^~?Law)ndyWbMl!lHS80n{n1hLI zr%mX3(bPHGk&j)ZtaNp&sT=x*FHj@oon#=nZ>H{I*2C;i(Z$(zsDXby;kbX%5CP2M z1OIa&A`3_Z6_idZB*N8wx;|3KXL1+;|B?^gpCP(f_N6V9yUcucoa@p>U%S&3bHGNO zX?uhEq*<5MQ#d6%bt0B;z!c!cApD(tBGb9w8A;1e6K0@$x}0I$D+c;no8DY>#mw{s zKp=w6b`!A%fB7`_uA{ zPfd6-@{O3y!jj@MQD*J(C9- zaKBafn_G$dFhWDus`!Ngii7#}VuG>Ey*-_T1Vc7k;J^5RzK-2!^2o93dbI>U%3|MY zOj^gDz+<|$;ExRzs0P2e=?;5~yJ_*<1%-E0T9>Pv;u0Z6%~X;6AugR799a5brsclsyO}Dv=B`>uMd?tgGr*gTH%* zBdlM{b7k@PZr|+-4PR@wx2_7sO#gC&2{?Ezi^*^Ou@ezrgPL~w zGS9?inF`;`8L=EhG2F8dg&FR3@Wa>WZ0OHcjX7~FoE&1X}9wp|;|Ue%#+>t$e9yz9?E_Ryu>quf`04HJuk6!$a8$e4)BSe~cf zrE*OfZ#DfwN-W}m=)Z7Z;sP2C71tHyvLQ+O>pQsK|DlQ_%_S1ZxXe^M4EmpPwWiib z&g4Uov;+lOQYK94UE9F{vJx5~I8n*z--9{TAKhY%^Aywka2>ygnHINiEG9cpbw;4s z!T6MnLH(Mzu1CVjzynV;0eDw*#GMSphMtY{o@p{yo@BwLI7+UuCc<%D1tazqS%2E#_|@=8`k>WkP4?5j!-PgNsL%SYj;Akhuc zu~0T~=HH-;JvyBP?J*JXS7y_$Sj4)1@;;+?sv_cIlKo`}$R$3PT34+8u(3uD38HAp zoFa#W>^4NJn6ke5E^de*rxIrwm837Yb7I`ES)oEnQ2RI+Olt2-M~dIPCv z?F&kY>FU=TVJchm<9NlJoAaB=zZm0h|)tYGtRTS|+T#U_DaEW^2EjrWw(NWm!C4T&j3uk*ItO6T`;!5+fSB zH8!N1)MaT-d13@1L1ZrTs#$Ly3=zWs0Jsr|jzL8Qk+LK^D(zz77&}Zv-39?jagUhC z%@5>qW{&wc!s)*O;q-;YzGPgZ(&-e!vl#b9omL`#QKOZJ-&DK+N=Vo5uygsBp44EA zZD-;jTVG(*T&I1*BrF-TRnZQ%55B4QqtE*Ke^AdnK4M)!=&W}+GIOHLqupP2xq!T<43OFDo*uSsM#eD1O9+mg<-5i zwgQ{a(5(^(C8#ZSLk2`W1&Hc~vmhbXPOXAFj%yZqWPGC#Xw%0Ma(Qu2}#&& z`yZdJ3UBc};k>yJFI8ZP;hyF}jckyHOL0;5g+1A}f2d|4Yz|4?#`NFsw&jz`kKjr< z`v^x|h3xTQ%C=%lsw2Q1r|29<#3swG+xGyCY>kHO$@|F=zFv_!GalPAsv)}_Bkwr` z>};c6dk}70GD{BYv7)SS`P>cey?py131uX+;UnuuucLnsj;JD!AEzLgrJWCKlxxT- zwMqxTMfwwBjOB_SeyEJMtFf~*cQ6sdAf2fXl%7@TePh|RlW z%Yi;S1b|bhE}hOM^SM-tyA!P*yDuuWIG_v(DsRdQh{pz1e2f+HD-qPO$Ed9HLMWdH zi3Fx}9W#noRlRl>-_Azl2dZsd-V_|%pbo#nncXBrv)QbSKdRZX;6`HqD`9u@V7|N^ z4Hn>S4;S~R_x;uRen7DFUqMDx7v9njtCU&BA?s;nmG8cf zM?CL}NUEx6XpPPi}vSDxJlEi}dp#3;J%Xm6?|_G0!)*qx9={xsvC+*&0GeYz_z#PCMXs5=xa*7t!!P*70^|Os?0o=n07rBt6r3bnh^n5uk)0&R z9I{j00g=LbDv3toIMgEj98=1L*2kFgWn9|-jgyUu5;3P|t3Uq>iHeP5A!P@KtfMUc za~X?!Nv%`L8BRR`rhA39vEwo!Ftv1bmncCZXLz%RbYxDhq_3eQ*aemSX zD~}I2&2kDy2q7~-8)ZiPt9@78@>RMjaR4YgJGjc|b3~@Z;(t1liG7ARHOghl zQXs}hjxfOG*Rs3YZ=`%sskXVFyV6I*@^^|B|AsxxSR6#RErz%%bs63DIyJBjNXnj! z;+}%UR!Pw$WCFWXpIrky2-dDpqZy|-%qWUOJg{q_CQ))MqkkK$fE~XLXxexd%r`{z zN^)j!xE8~CqxpBxng@L$a2-y2WBg=}vSES$%{qfcyVsgdP18_$4dqY;7g66TrZ|#} zqaS}7T{^@pSun%jayc0RX!Lc1HciK_QXp|-SmIEDO$gv_Wfph!&jLjbS}3flD=tt-?VY1uD#Jr+w=b{FiFW;dE5 z_B8Cw7scdG4-dj85sGvpxMG@$^Qyb1vlXW-At0n6MbQ#!qYN&@W@x;&`}gR?Dy8!X zgn(@>r8*(@v{#c0urUI!GIKIH1|?zz?p!KDjAx}HiRDVMT@-t}a4^r*dP~d4ZV=P8 z{srvLVGkTLQ(?A>3Mwae=>5VRk>b;=LjuhTDXP{1?1I|p73t|yOzNu->1o)7X4`t% z>w~ICP_A`#i2@BdqB2&B<|oHvA=deBFb0!_RldcgfIpG5$&3r|Hg$zKOOrr^lVyc4 z(qtUB8)7_bV>eYdSR>*>W!2@-1&NX8XXw?x8gZQybzE z>^e-Fb_;jWfMuyEGvK-EMpNpC8o0QLch-60Enwx z__rmt$y>JR9`%p~>%^pn4#a#vKnM&1;9Uq?C1bKQ(eee~DDOI*jBY2ddon5O$7e{# z<%vngCV5%z_YjF`onBvdX3!n`p!%NDwOfhc8jXm8wmKWroY>;fjOI)o$siWQZmJ+Q z?_K)yT+|lbZk*N2Ro{!%c|R7zRSU04`GdET2kXJ(Au^h4O>KfFwNtJSdmw z01**fRzL*VDRG-9NpBCBAu?f%*tdL#OP?6=0msQ}83Zvgg9l5@0*WV=+L`f1WoRDw zi$~yOBrP7RF@==6aTHtENL{FOnCMXstGmTrG7dij7Fkm+*p>JGPqx8Qx) zjwH^}4<8^HI({HxH)>y>VYUCKc&;r{`)zsg`GD?UhF~ln~JDf=Nxh#(dtAdhINS^ zI^MfboSIL;1_bIw9q9M{Pm$gqzrIm!ka+=wR%-RF1qyP&DDMUmCBXDl+T*H$jTMDq zU!4Le3ssdj!UlK~l5=!PUQJN<20(3#6@%hTbH!sf4%1n^2A+o#lr09tLbhHk3GZb| zUM~-~nQgCK@sH zjFwtVJy&`T3%3KSAOiH`j`Qt$`i|X1SwoqtM|>CmUEvpGtwQy?e8PsrrUkyqh3MM< z3T+Uadq1h@3SlA=XmZjqFw0rBRLi8f-woro-azK-W`YFBHuXn6cU#F`3QVi{?^#s9 z%60YFU6i8Lz?FcOAp#ts+7CWMxh9F1?&~sXTme?B+MsqH`4yvu{in@DiOf`@JiuJ- zk0*s!KK7o&zKTR-$9<*yLaGO28k>Wp%J>q~q)>Kdrz|EtqHn^}PwP8cIX|e{b8tMI zj6VR=WoO#uuV=FUjpx_UDDU?u&fx~00SmDl&h;%KO#};E4zDN~$7R=V)NABYKoFqS zT}BXg66prLi0S;lNF&zEVWSHGQ+(*ZY3a%ZjryIJoh;Il236Gl7ZY^ifLkz`xv`0A zMw5c-I#!*AQWuN+{!CRNuw7l5IE)V3iPH0;+rg}e!Ggn!#JoQVS7nE`X4smn*TAlj z!0U|#yIU<>V5NiuUWc9#k(3^djfWTdRLN||#$qQH&M>4@`X6q-3Z!NgIAbYST2Kcg zQx=A#Xpw)>KS=ynw0q#e;0fCcOeBc_a`|T=STwm4FH@QZyt_nOhVkK1w^!ti0}NGd6eo2;JRRG9FA-Xu>|iubzrc5^qzNcM8KCHufB59;Ufwj?nA+MgjR1W~OB32;t+h&BEm-0&I|Tw>j)^ zS-4su_aa8+@J4*_bpav`6t`qhG#G7;MNMoX@cDGhg`9b(HKv8zpbwm#ygCi9b_aiS zK&lZ^!-YLbU5KTl0-{NS(Q*U`DBli8Tn2Ls=Y4XBT&@x}`YMCzwe`Hm%mzm9D}Pxuo6Ye)Mrqp_@-7??N2aQR7wcDsK)zra z!B)FqH?I3d9fcNI(+4KCJ`mNh?<2~-SK1@1@$pd#k~JTQuL7@|uDB(*3d~ZNsZziA zejI2F^dg#9tpVtw$CihBYo%Hn=4L!)t?lRHdi%d|k*Jl*`xv6uR@7QG6}9cZF?^ZU z__nNA;(~Yj&J`uNx2S^sB`U%F%-!uva1E21a{POgJfX2m0d?>k&FZB-G{?YQTh_Pg z)rOjTv0)M?9<_b#=2l&;$D$XWz6fB+Fof4egH%#)q10942#chXt=u;?j1ANh>5e4rZ=Vkjn$M3hJ-qwCc}JFwL0n@tvFY0uUTh8pM|0Z1*9C_H!*w`@Rcpf| zCrjbv3}o*aY)(KUXwt9V^2d(8VH*LVFMmQ%MCVlQC>H_$!YM|S265-p?EZFy|1Pu} zuzjP;OVJlu8SAXoa=H~!a;RzG-$?9j%)Latgr2*y+KpyBYf7&NFMJFIz0pYYLYby? zsjGoydl&$hg4P)n55nWKCzDbMNA0$3SG+eFXB;1TrV=w&?S zG;ah*BSFsb5HrJ?vyEo{TO`pMhlR-nob@DTBs!bK4WH=o$4zpOpqMH5#CJj=Qrj zQ|PLgt8iS$O)BY#wXB;sBwcI6DjHN~U;xyR`gT6+szilro#MTt{dgeg^}8;yuj zEx~^@LCAS|En#rME6@}lLi(5t!8pr0K!2rjJn6#h-8**4mcR$+=A-t6SaQc6s%4^F z#O)E$&@WV34*Ouj9S?h9DjE-Xh3(OJ@d^Fxe*tbeJk>E|x_^{)k8VX!T82Xt=}92r z9mAqP2*d1Vt>;2=jm3QzZK)lLR*$**Vfs=!a?;CG^bY&a&5MNEH1D}TpDbC|T8=vp zn8%{c11K_eKA^vx>rk_g^u(lPTJCN%HQMfGm-=Ec^g7)9G)JJV=%gMmx`oA88nb?E z1#K?i0j};GmjX5zWO`;d}~t)jA!T?0d;(ddA(Tf z=V)P`VQzp0A?0FQ%~-bmAm@jGkKgR_2PO}3a{DT7aQQRCj2S?IS+VS4ib)4O^rBa# zf#EiGnNmkg`TcdLTLcRb*P!ahCtH$<-9~Gyxewl5ansq2L!T`+oNgtK#9m;DOLJP1 zu+c)XfZ@cLS(cO}hTJ{E_^XcaRq+@olz~8<0u}JGv$%)khYR|=Y`Al$k3}9`X$~Pr ziO<^k{1ce`7v-L7M;}pKJt(_)FQomlpkVg;&iDGLaFd7_@OfMyU~z!ReETD;a$Tja zu23hg4>2k>HG3K5np#)*occ~z_W6%M*#)O&*7;OGj$KVq&BRMVFdQz7P5dgHCMWJ; zNu!gh4ZjCZku86Z{D8eFD37d#hj3^UDp8)$p=aQbf^o?q*rh~^&5G)3%g;RF2ZnIp z*vbgN(<&nZa;pY0IQKDn6VFgZ8aPAciY1G>j(&0$ruqQ;Q#W6%Y6WOl!gFhHGS37E zOAjilo@_1)WhT;C$Dmzl7oCs~5}OI4frf*Oxx@3ymJ|0o%f+OagSpZNmJgF}HHh#D zuGR=JxQ%6^)-3*2U#kj}6c8rjB;{o;uz1Y0@vzD`B&4eD`e>LeKEoHIu$Rg+qV_n%+9XKpxF&(Y)2 zm@jGufhJuDa-7nzCL4s9wZq+6IKADwe7u>yZS%rUHs)R(77O$YvIxu(dMhTM#7rZY zgQsh;2z4r>=`P99T1J0SER)#H(1SS_Vh z!S=hi4l$U&urMA@23?>vqi-}HK0+@SlDoN+Vw^jT!O=i@^Vve-^xW^{GLSU%Fp`EH z#N%(4Q_S>Y-ykJav4b2mhV%xVIua^XI-GyP9Xv3@UQz;}8h(M&y{lA$KC~#5R9|vcf@8W?dbmIuU3#Ns2?*(K~)2y%RZo)RUM4&?v_D=#3GA zo$DLN+-hJ2y0zelFp)3Kb{u8$cNp#`Q~oZm|B4>N*{t)Wz#O){B?t+mpmaL`GJEj! z^H&&bivcv$v%^(F;egl%%}1rG(>z*E`4+ZvmfC|Aci1oelo8Lo1+}}Nj61XhEDhoe zL`jPzesKwMB-!Z!(s&sM3O!CgxJ3gn-vMhwtUo?hy)0b z$1z{0%NfLE{h%+b#f!V;xJz)p{q|vS<;s;DJOq>l<`r|5fEke5$JXb z0v$VRhfaGjVcJtwyYEO8D3vnaf{W1awJ~OntPB_U$5}SCz$jZ?VXYYCgaLvuU*`E# z$B0~jis%<ckbs|oJ&AH`c|0i+bNcRskC&xc5C(@x1IvRVvHqTeVMVSySACq}_v z;Oj99LE3s%>A7{tAM0Ym)+CABPA1%L@2hp}5l_o1kTr-#lzd&Ci4?ZJA=FMbA@RKw zRZj+4ZgTFWP0p?G4$tmQ0R&G9>eqO5QayzWCotsz4Ha5+~6= zizWJ;pYk7^d7BlRqAb!HC*8YOkE;>*g@$*t&xRZhDrn;m8Ztxi&V5Pr^=}-ZQeM`R z(7O7fOqX5tML%0eYh^m8Zpslmj!CR-p5@2f|2xXQLieb))|1DBz$1h-8}ss1=BBl- z5-h^hOpQbb9M2wFjQmCi)NQvJW1k#_VLMp@*g7fRb^Dm(=&ZHHb?XBXno6=0BW}oa zLY6mjD#Z^2ncF^<_RASJv}?|Nsb>b!7GspqaZut%;;JeZ zo-wSMX!mV79#tu)g~nbsr^U~I|NcPX@*?D93h%ESPs#Xmnd{%E-pJ2F`jo&nbr^Ev z$c-@N9$0X0!NcAN9G4CZ#2iD_<)n2`<=4-Q7_83;>VY}eI7CI1HF>w0Sn|9S_|v@? zTRm{$v`Ik8!`^Xk!aoo@?NqchZcrnT4WB*bllymVQK(6LK2V@=??Wd;9 zp_4jPHYz0w*|3w&KTE4Ezj7LZb05K1W?th<3FSnR;;)ua`|;koXVqOKQocv1M=qz> z>X_BR5fj}9OIA$LSpIE4+$x@5p!*!r?CO{v{BHRDQqUifzI`fT*YhZa<$wLB`R5jn zD;g6VA^#EL!+;(f(|N*Ssy)=#C2ITs?7eGq8`se_%Acb5ODazJoFc%BD3)GV*%B1P zlth}8{p94!6i9#~BoIJwp~UBdfBRXhd-uM~>;VQ4omdW2iY*i1T=(wF>eZ{`>Ys=U z11N+L$}O1HR$2?46Yzmr1hit7=2FQQDvL9Y@)T-dOcG@yO^ll3@^girfu;0%*+bO~ zBcvC{$Fe25<8w%2V|4MoJAbLnw&EACyxfFJg&g3%*H$xXHe5xt$gmk>QzJ(!J*+A_ zk2x)X+IXi+(3(6)cb7ik&3zc`gG9dD4qqb8OJmQ~b#z;$DZblbVYf;$6=2s1#%a+% zI(UwBcoU-7n>zkU2dmlzdpWCDVw}{)M#3Rwb2N;xt2>Kx^db76ToH{83ySw5(pgHJ zqv&O@NMDY>>5&7sDD%E*m34G1mW$d>p7zIcGI)<{q&hMp=0it>B?n_jYQ!*Jb@+PT zUR1y54RiTYZB9FUD3MuxRtcE#HC3Tq7A81;>qro%aZkt83%Lb%d3y0@xl6S?2@Ac& zIb&V$L?FoW9&B`F^sKZhNpRBKssw{pS83RQl8xA%4ayXpz3t6Deh<+8ZU7u{IsQ1F zd>Y%{@T)T*+l1vJ{uxoktx|51pEQ2PMIe?Ak+uAHFO*9|k7BzKUVRDrXjsadc0Em6k z!hqP|`44BWUdf=*?{-vFAO|P0oRXKr-6=&T;+s=ZUqPcIf0z}nSjX#E<%%`a?PPQ~ zC<=g?=440Mwb6D~v}zm88UOYPnaeU>#69MRSX^Yjxy8kbZM?W#1=m7khy4n~ajLVD zRhJIG6pC4)S^9!GVYPp5-~e@Z#SIGTd(2Umb&M^iSNl_@BNP1bM5s9tNLeu5l4E2@k)sYsk*Glx zAP-CJSCgFW(~ESK*GBhA$>W9w_J^TP>WNI{VR<4@D0($YGY^p^!^mqIQ36wineYyv z#bgP}%lU~Bkfi*AHCgs2XQmlyj>H(>D^S-xwL8TP2EJmN4amiR4B(X!bsdQf;J*|g zHW;__w07LiNr8DXoBq*;*F%ikyu?Gp^>|&gqj>6$99X{_Kld;hbf*+E(XOh`iH@l>IY?J%|6PHF#5?^vkKdn)~fk5RD&Y zVd|E5=ufHZ5BNpY^;dy|R({){26!HZ;pErnj2Fmvhyn%iv+M10ig|GBm}M^BVqeH9 z=Te`FD`5s!q_HE$(8G;0kj{{C;bH5@xL#ACUb26S7PJnH5gr4K(FCKNS#JG5|Ce&G zrFKpS81Ys0OTgUfFNc&?iw!Dh`ZZ;%l8wHAOf70bw3KntM0EqOA=bRLlN=G_mgEFL zK;UAaJ9##_&j$HLR|ugcNbif#w#t6_qNDi+O$&rLH^e%BnqY{v$YXTCKSZHCs+R-M zbu&>GSJVHQ0me3`oiu2)^2krp;F^XejmzhveG^j1zNjK#2k}MHOx4{ zvc*)#&%MjxT?-Pq#nlMNsDxHX&8{c>7*m2|+9P-xAm&SY#*faG}KCtFI2 zPIJUA|8%%ieyC@wHJW?^0p${qJSr0>L+)MdNcr|wfL*3JwtNy|>}cm1&oS)d7NkA& zv$&!X$ z8D((q`Ii6A-T6CG;3-3l7+PEGWd?M8=u=mHPZ8G{O7Nhya^6~>n ztKB)L_eM55LwjjGTB1iwqy*|Iq7HTuKa1yw%yVDnr5L zmIe#D=BKRk0K>|S)Ip4R8-?06gLaYL>O>A?xVqGWZ1pq9m0W;Z5A49=gwl+Z)&b_V ztJ(&LG#J#mx>fiYxZR!&FdIOlgQAO0LF+k$0mn;bFvu<|XPfZCR7BE(3#g_BRCOuK6Mb5Vgfi%-G`dSfk7f_s^$OezX3XF%8aCr+h;~$$z z4|0Wjhin46LwM9;RjJ?3`Ept~c*9KoU@DU$`*7h9WaBG_mXu&QDKs%pMI4Yq3*Et24TnXSLm5}PbglvulgdXtk zO2wx7FIJ+h`mZ{+@oxc!*O&6_5hjq@VdBqu6?T7 zN3k3$_#(SiMNb)u6Z(dE(M+N52A+x`$Ypo2@aVTfC$ugE@&6^dQhN`C-6^C?i@|4P za%|dV)pq>8bB=O$R<_e_-o0!o**W_5A%)u(pW6q>Z1N;dZ-GKVtn6Jve%=pV2{HV! z99 z#-V#3D#qQCau2>zK}3-##WIN^k&3nY91F}(;gap08_cy`8+lZ*^;cUWU5&6wTWgx0VRIxPgH67NH!4w1{7#p1&P zq8!q305_=G-iTrH{EVkpK^Bgailh=Lx-c2$VA@0-)djw%t`1R(Y}q6FVpKrLNa-m3 z&0AXbaSX?hrZ_)&$38LqK_Ct{A&iZFK@}i8e6apt1wZAE{rSrjj3jLHpN0i;GAxnzZ1~Tr^bVAh!(~5Ghz>KGPMuM{R3dCk%s9;X3 zc`iT1yObso6KnTIw;RR(Q~Ig!D&m_u@S*@1OFIqL!iR-gB0(z zORqp-iM?`Dz4r%PKK~(kl_V+qn%LhlITLU8za_UslR+_uK*vb(_JXStdTJvtbj1ge z28&G+pHgfXIlQpKw{Z;;gg^5JLxj1!$#%_~_*dt^NdlN0Q___U!^5s~`07_Lx$Ro5 z*T`G{&a@S>hxK1gzo5xRfw-1+C~)sicpqk1ebaK0(c_g4VRi zZJiRMP`ZfXBB=y!5D68sDc*|Zopnx-Aw&=}#*6i{UIdrfW*hiQllo9AE{DDK<-ter zY{aX(h;St}m1X{e*@4t%j_dG#D-`3h^7?J{d!PZ-`ln{oWLiS2;LN4(A9&o}Tj0xB31aG_l6uR_r{s zdA~l6puKZu?dwt%mpZ+am~75UoZHtmf7Z|I+O#JWg8jR%UjBg5V*Pg@$-mvFKyP~t zNN!8reqMm@3Ec}lp?h&ps2qD`@4_Lg$GEt1Pv}-xMFB&UhyOzp3=XxsI0mT#>And$ zB2vVZG^W*ZewQ#ZEQb!;aAI8^IDXt)YdA3Rz~nPYU?av06&Izg!HF^nfprJ1ZEpvk zUg+d)bYskSeq#gZpdSTB+N;Y>`L0AwOn;DF1&|i0%oQXoyMZ~nGQ{ydEUIWV&}Z?c zF)v>yo<$0=k!QZCgCHf!QdwSzqyZAR4U=5s$umM&s1^~E@vgCbJIs&r_+xb6(`r}& z!qiMGhH>@FNFCvH$hHwEx-4EPw`0)9UzidM>bgfBt^1$Ax@%kP(|e z(ML8Zl)8u_hs@|qnuj#N(@;{!b9SyqopX_-Sfj4X!VK0d19t4`5aVtYSh0xHAb$iY zqL^J4pr#M6?|pqfDO$?CtSc@t)^sO7((~xFco#Hc_5OkN#7h$P6 zQBCvAsbpu!k5OS|La1#`Onv>ndeFAh>a5XxSV;rN92E&FgkIUj&ajgdcG#JEi}%P)fdAFA8G>pVqF_$pp`oaQM=sqQrf|6;bmPzO1CVuvmbU5PTy^B2+=>E^u>o zeBwGfvEaYL_2VH#*a1&~$2ru~3f_Zq$Z|mH1INtkqj1{P4Y~+@3~Qygyy;up?$YV( zJ)Mh+Nx?RB>pa(YL}!KISEg2Jt#5}nH0Yx!i%EA2!P*`*=QLKAbGMmmmnxDFYypTn0qyw+(KO6SE*}c zJ$y;H9>qlMG19$DDP&3)=t`rTqG+Q^V!#PwoUi6?{ z0_cEzVp@=D9ur~p_S#v|#v?avC817ZPw_Hfju}M>mwF!$WjO__%n5l=&Zkn6#y92X zK5+_kuzJO8$WY@@l}gvzS_jq6xRvR#v?_s1vh`tBp%fsxyE(W9#hR42-;7-NGq}Ju zz%ZtZO6C=*&MC-MO|zm?uT)u$W-y`{$Wonf8=Z-O!LYrS(XU)|He!n-N02pwhg-qA z8qlntl3#>Hpj=>y2Rs|28Gjbu4ymopVm5`|;O5Z7?yYd;3ahINjScp2;?#WmCB3Tb zl(oa$2x>^fGE4l&x)eR;e@3_$wyIj_Oe*jQaQz7Yt|QRMM!lmD2~92vYJ)Y}j&+yeOhM8P|Am#EA_ z(eq!Pvi?8A#SQzGI-jowQ`Zp+_mgzf+;$G=wsABVk2W+_C&;xW5;i*+BVk)XdL^-L zddIJ;R@!Q5i<1;0VA^$}C!SZPGm9qpkHzvxq_}@_LG82R`>|%Yq`fH)=KV^_jcHge zqMw0HW?WR5dOqoyui;YLfbXzBCLk|OKI#78YI9!{Do}T2Ey_cc@@v0}yRiq98 zgYK)0NF<*R&Jfob^QKx1>8kP6W|HL^T^SDpPeUp9A)trHo=oQmExI~h@OCOxiZ0Rw zi%Lfe&0{;ijLuJP5TtbqAn`W*&QF&+EbFp#g}n?a54xM*6*BjLDsMsTR@;yoR*n?M0Lu;+g)zb_11$b)j>u<~1{bcA)lgw_|CB-B~5x+9)E7daDk7 z52VAMnFZye?-cNbM8Vk!lD8LxJ$le>w)S?{kQY(fKakRH(O)qxE>ZO3h7cUNgbla9s129>rkxJJI9J*kD;U3SlII@6Ik&QkxJ zYeHPH>3P7+&E`7jl0ogbmP}?b>fCniQZ_0@81mt9v9vg2>mV&*1b)2QS^ecq>}w%X zQr(k!j1|zk~B~ute~g;D9L4GqRO8og2ui0`rQ2Va&CL z%XMAd@l|gXwKgwAzbQt8>&5M4E{;V&dqK}dE%}Pm{hm98YI&MvkJtc$#iJFZzkwiM zb4fV_;RaY*q7!H6fj87-yfNr;9<=bynX4SEuB`Z3fQl?VIdZ1}(IQhLkQzqzJcV)< z>)Nn90r6h1n70!KIKF^4yKwV+GdBIQ({4FnF=z`gn(drlUgCC=1WB+W+;uuWbH3;w zABPa=d5|`7z`kX2$~cHV2U?laSlRYil{&%~U0EnLz>98g5G0o+jQo~-Vjl+i)T82_ zD{%Lb`z2(o5(;U3PKs8lzx8L;z-cUQaGnP%Fc^C# zw1R*SyZQl2Ou+g}+VXg(L3ck&XRu`;IeR`pzbD$LJiuWM5_GVNGVaP=3Z3PgK1 zEpS}mSpfU~z@C(UoV`-xwY9ZOs#128^|=Id1m0a^2_Sr1>JVC-M(a=yqh;%; z?@ryc&+Ici8#;R)Eppe|9oZU?MzblTH|}=aly&3s_{^0Z z1*C!E#)t36s0-^gY1!!EltewfrvwS*>on!e$I>*hWd}a>QvSA7=~d~Rk`?D#p@K7d z1m?t>xYC|;lZ?DNx3@rxzfT1mB-|m7!3DJ$@D8$hvca%F5lFHUWCcexF=l;q`-H`t zZkML9F)l#$UF4GQPz4{OhRNu`Qmp4x$n~6p%E)u=Z(5N8Y7(Y6S$)#CX}$)lTa&L< zSbHTBU-mz>8^dx_)O36jx*sK>`l~BDHz08+E}>ld*y^fqKA!9arg`mGrg`nBd`3Kw z@-(ll&WYRy7G7jd+FG^t4IHsL^0x7yGf@PZ%J2>{d*gy4xU=eicT_EGped_gjD#12 zMg@56!59@9l}^#c`!FqCQA1a&A~4WKs>+&$(5O0#)11)H&Tr6T;YO`dm2j>p-MTV^ z%MSz$fe(#scR9h4lg@Os5zywbOaV;?=z2G6$^iYQN-Q?q7T(&e@yGiEC z%u;Kq26`sP?%Fb8c7X!QBM_iay(903Y07Z-^T~2{HNcpWdu4NKY_@Yd3Az-jBR`Sm z1*rM&dLwLbEQlHeOC8xlqc|xg)ZZ#@Dl*5aToUK8>lL^# zl5ak+(k)g>CKw)ecBT-0Q!Rcp;angzg*3fbA^b)qw~bK@7tIOx$Cm;&q2~qa$q5UT z++k82mVJhu2ZQHJyO3$@Llq3XByWSFoIWx#+XZXnsfc2c`_aU%^ zE{#zN;de}?JnWz?4Sb{4oJgyV@7!Y(jAnDXf3WdTXHrc)!^R}uCare@K{i;oWT!Y{ zv|y~#rob>oDb#N;=?+R6!JO%{7E%9KRUpBf4QC$CB%;K%Lf; z=xW~=P4wN_6*QTC#PUf4liWeKdPn{;SOh_+hw`zA8#u1XX60-V0x+~;|rb-D^}vk`N^PFZ&g!W9tD9ZB?=Py`lW!qSn`W4B{mHAcMPpO(ZvVgLvbHI1Hv z5iy)B=i)*E4%Z_9Y80ye7$F)PiMuKP)kU==8|LAF=U@+CPQF*>rzGWJ0XxWa-}KDh zc+EREvSg<~3pWVLDZ-H9G6T-fXukl;H#BN0%Zg@ z8EqrDI}TLgP=V_g<<+w}=_kL%x-_Kn-%ebvTiuoQ$d%if`dXR2Wo{y_F#ZuVm*70& zX5)S_UUH26>9xv5&%tJ&Q^VnfhLSr4WtDmWS)9?zHKS}H;b@g#X;qQ%snQMLc3)6N zvTeC?I~b0H*AW9r&tQqDuD2w6{cCKr;^SWdwLY?Ku*(HWer!5z(sZhsao(>nJl5S_ zBR*>^h%gs8WOm!-#)!gmatbl%S?TBLhenj_)NOOjjX(?p1#AoDvu6hWs%RlLO9WCqBy!XA73z0ZjksPe((FjlgF-H7lqn{cAK<2Sp_KvWJVR?!^uzVl3-;_L!c&CT&xUxO zSyKkWIaD!$5x;#BFF*UHp?k?!4a^e_g!s4Y1GlH4q?>&DRP)$ zpIy8j-jdVxOtd9W$0I7qiO7_U$V!Ufw-6}#%x8orgoqI4!w(F)-R%S!k)I$cB3llp z6R(f&C!D~4pvmDU7}u9m!~d`A+ zmWMvHrCgpi7qOAs>XFQ+><t5~z_xpfol((V-uznZWGDc#*Sxdoz4+gEkp<1n9(srm@7Qs9+r2nJ#_)6T zRLO3;U3@R)BpYSx{s@pYML#U^pPQa2#Y;z$i#nw{1PIPKB>wS z@id|-C4?!Z*k-~>9fBM!)lN&aw}Sl1hB$=PmE!AJk!R|?29V&3Nj&OIjC|#Yfem`q zTv5hqd7Bl>Z|cY{-cVy99Qc5y=*{3t@FSGVm-E3~yBl`-EE?clp|X+a`>jHF60LJ5 zLRr#H1sOO}m-}MVFVoCn6BC9por+o!&ew%2?Hp-9f;oSZLa37p1(*+*>&tIQ1qSjS zopS;4qKDLAKfBHB=#V10tyN?*Se}t%=&3K5hfiF6TqAV}GsIbVv5{UDcU2eGjNFpJHeagz7QmA$P{F=Vvv~X5FiBf!*rYu~_hZl-?J9$jUf%>9Q~D zkN)V~PDi#BQ6;-8i^md(%eX#+N)J>d@aFYxt9=9MjXPW!KA6*#h{Sx zFTpV)tyDpGSemHR1ON_2m~E9yUBT*5ai2_Tz*C?!XAKJ;0*zAGnmC;8j%>bSv^=sS zlIk~dDNAC5$m$Wm>e=x9&AQemGZWUtPHk2pi|bGfRt`X|rM+I$a#YG6BU$8dH^yyj zoQH=TRWUkJ9?;Yy4$*QjyMvW3)C%cqDeJs6qSl<7?lx z&lEL4mE2%OtibE#SPJLeSLy6!1LCr47YiahC@INq14#o!q@x#^R_T>dFP-?Slmd*` zaJMtKoi6S*gHkxgr=g67M~KmYWRMQ)0-r{&3*t5xMLN(P?*%Y5?h`%*H(ZNn>teOD zaIaX44H~~TX;C~3JAfM#ATCBZ7Ytk{OWXI!vG)>pg)`TMF!C~aAd|k_2@X0m&47u5 zW~3_!SCfq*PcKSLovfE}AzXWD%3!H*ang?+UiK^3REbzWLSj6eYcJyUY~V^=4Hw_K zI54UwLp3?d;8>QDY22>KF|812aKUT+g9%A$H2rs0^1Eg;Z2g(hHZoCYnhX(I^KzvN z^RZ0_=>C#`q8Roe!7*Iimp7jSM4kA!4?e11?hn+e83l?e5sA0m>Mg)4x+<LyorU^0Le4Mtl zed&q}y~r*~>OzMt0h;qYkh(yp_!27oQrmmp(!P0VvqSpx3qbt8ee>N;AN}&PiF01g z*-K=ezBdc5;tGK=2ZnR--B==Zzi#{frVgD{iuJ5+^k9O)TS4L3fsh3A$xY;|9&0+1KDQ(X(@ga8;##}2eGe`#8 z{nT}ZNmCj_Q>nQ)$IRYFER&UyK+Q&Vxc$POU(9hr(sof?LSkE02z(;l914EPi6Ej& zqDEPFIA{ezhcpz}nmV1}nPA50H|d~%(=m@i-;^~LK`^=YNOQhvq!yeFLK*rZnP#Q2 zXtYldsbwx>vkPX_h!Z?eNGc&_QCtonzc?tQ878Aoce`qu!EHst8|!9=@>{>mUr#;_ zW-m}6(~Xc%%hl_&=-<_7D1$O8^9zU z5R%j=>Y5BNnX5!}OLnbcHPm)%=$Nji&sozEsi!2yTxM02=AtvFd+C~;%o^D4wBRX@ z$gO$193$p=Oa2*2?&x16twYuAY?&{#sG+PV4MLVk%**D-RFp9`r0_4DV7`3TFZdxpsn^liRoo2{$1sa3p+Qi9M{7kh zv4X0nbfznV2hZ2uWpnFk9&*(%yAq|u<-Bzy0-+aF1{&1UPPpF4&jPS6;xJM>#Jx0) z4V?Cx?BLDsKN;&19$Wd&gsQ&xn@k#!DgWCneW9Sd$7l|kz- zryHnxS~aI?ob*E0sJ8?2Ot3MxpWO1(^kr~4@x(I>w!<6bqK>JT#!7Gil8z$6#7li} zp_EYBrT=mL8e$<*DR#TB!REW@xch2m9!u31EPP!p`jSdW<{nE#s30tFF;W?VnB6g? zXCY##otkK#QJ@y)$tKg$kQ+w*ctGIQsb&13BMIqunEu7YYWEAL>N#FDINvxsZCS&C-6HrWUGRH zS%1_OAE_RqXvN?aCG<-+Y;7oTAEc9|%BDi%P?<}l2(YXZzIn;K(K+dll>Jl@F&MF`n^;1o6HQnIZpLsqoZA)qVs~>+rny>2>dNFq;25 z#PrR{%+G$rEzJh5fl@*>(RPz~trVD>)5T3^%R^e*)G$4YJTkhC`TOn=+F_pPr=7Br z=^}Es;_Kr6XM9%IZk(m{V7;Amq24yT#>lx4jqE{1v;^N)D(acnn#l&r?R5ueuR~gj zj=ROpi<`mK$2S9XPh7cWT*}sO>QL73J=Tp8qu40v5C~=w3qu-E@(sOSn+$HKw(Iba z6)-Hda)`H+Cc|^A+%sTJ0DC>dqX-!eso@en%KE|t_~(h7sIRuB8u+>n!-Jv0={C>G z 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


        f^fZDW3 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 NBp{;5lj- zD(ymQ5z5o}e~6yOK=u3*`ObLU=w><>=_mp>onuZBi17Ca)k`{xDDd&e0d|Sh9mIh8 zoz&(XY~rvstl@L-%olzZp=?UbmG_m}o{oOc zIfA8g0-K^xjWYe#*1|{!l&|l(h)8VgJIQZZOmwST>ozlnX+kC++cK+D0JE z%@=-@^soQ0Ji6B#UOiATP6T?Vdp?-spZ{eS5ro0>6@;)p$S_p0cQ~XQ9f41fA9=fS zjGdq0L%gW5%X+YwTODMgkjS7#sCIoQegyCHQH>wp4yb69sxSzxAzN*84Ufip( zygA-FoyvLhIxkc)6UjwkIBB#vIW-!H7vkmI!5NEg8$V#iq4rKd!3@VWV#X=bTxaNk z+y{aT?Nt&88et31g5s?ZJQCgVnCv_{UPNRgMTCp{OHgi3S9^Dp@o3C16F;PoQQ>=S zHR;Dn%*lg3`UxVl*BozNmw>y>BJQ4qRyZYVg!SWm6$^Gio?1a=?d8jy&ZRQXI)w7; zuat(JbhhF{ieo`e239%ZFt4lOYA6C*%TGh-q~cFF4xTaBef`$U#R>?5;xGabx9D;A z{TZOc$zp5;Pdsa(l2afCJ~OCFOQt?g!F*g-*m7Uz-2%f~_HPnT|FlzO9rMPsRuIbI z!5t^)TF$ksExuo1l(D6Wum#YcXh-!pMo*Kqy@rZ8^qkC{eS5a*F%B2d;`Zob#DWmr5TsFzwv!Gxd zelIR=q#UeynKto&@720h>{t6=klik_a@Ye3)My2bJPC9i^1sT72$}<* z_fASl;8%;`aMfmQ{j9o$XD||+j&(Y1I~?1hn^~(Lswj9$3}!xM$04dJUQ*e#RP$^x z7I{{ppA8)zoJ);%-uCChFM+xF;{d6>vg+soz6j_sK(C|w1>Hdsm*n$Nmc#3@_~6rD z0Ap=bM`~Z+t(-Q|&9uR6Eh^rJjH?Y2d@X4UHn3Pz!Ott?ThAn1-DbNl+wUJfOXr&2 zA~wGTzAFvgfxV63ke3|AQAuWs)RU(A%M19H@!)ni)0~rbC7*j-E?BKiWEp_}AX+dy z@x^|oMx$J`K&Vvq`^rLsAn0I)(KCG1FXleg61(WV{2V30>R&**JUQ(Ql1?w)D9zWA z?-aZVusFcL+~LBpgn*g)JGJJ3c|%;cqfb`g|ItWPc08L_VBBDPw=mP;l2)4Hv zKa43P40Kgm!Hosd&WNfW8k=}L%MXs5{X)c)Qth#7x8eVas91@l#! zO_jAQGuR0Lk~L`Lpy9!A1(}HuN__MEe0Dj1rCji@ze@jm)v)Ni&1Q zGe{@xb1cive2OWNkZ@vXj5wOL%^V4fqDqXMfey|FKgz)KbJ6lPw;xNUraDBaORaiq zSr?zkXCItm*zjtC(WG!R(!;}}!cW~yIh)YD&W1$4@?wnm3m84Wy|oP~bxOX(XbAXP zrTbLBqqFzXV?(_ue!(hHCMok3E6QP#U)~_r5!z9Y6_*tk=@!bctIC?vMe71)OZ(iN zlKk!CmYRzS!HvaaMgchK<+__sC!^1@ZSC^qsF3oDGa$}5Y^XVIq=)$ew7K!(8YDWk z+2^{CrL{jsGu^$J_QXTv4TjpL;UrYPC%lSIscb$W`CCZ)%R6(*a0KmYOGlK!=TfNT zp$C&fQ1jBf-2Gr3BNzbvB0Z4^0tzEL4s~RQes@U!NcYH`Vhz;9SR-)JpsW)VFV2v_ z3wZxikQ0;j^%8_@zzjg9%xUYi@SUx@bwbzQ0lHL+0i@f+-eHwPY!%h1Ay?Hfs0J4V z4P}SOiQUuhAe4`y47I_)@Q4`(4LytyQsbiXzEUE?<8nMs{5~58=7L4u-$9zxS*46d zs);Wmd4wxXyiz%cIDbeo^VS)qilJ|Y{(N|P1BVVzPAn5%{oDZ^cK?vH8utQFbi-c2 zVpf_BqcIE>gkn#gb%N;G{wtyu`Khh6Yh)Zyk8AzvCtOi1C5?$BFj&%cRYKh=&2hej z!H#&`9Q!XU4-R(9tirKl2)<;jGe%r=$8I^CFqPmG^@T0P7a&$XT#iw$n##1!P*N>8jku&PP>BU_;`y5r{R)}D_Mukr!^G^s28<4-=@8;= zb0CPGs!}<{kNViSmT8Xot){PJ^v*~ubecO3#A68ob$qCd@xa15MY6VJ_!?Eu>AXy= z4>^`wLdLoiP+-29f1+XG0+m5raR5{S394Gu(b5IoGU?TPH`YnruEr1sBN!2su!$VC z78yRFX;Lr)-}fXXhS+Y}U?~Q~gUu=GV3XC&%xb)tv&LypR&qmiN)ys;)=yH^!!+Fe zk@dD}^N#+S-WL5>M|Qe?#CmswzA=kE?0gndLp~ z+IRIf{(D`ALVn8OE33u*Sdt;X%neQ&W(zL-^qhZPF>Otr0F_jAF`~n%0wM9ZM>ddU zm78Vo{l1Yy9`+XV`6}z{tKHP6DmTK3pd@%zYjg#F zA<2S65VhBA9Y4|~PzX1E2Zq^*2l08z<4Y6QrqhJy>=swV)2Y>~qcqq?kz_RT+>T4Z$LZf8Emo70dbkVl+M< zvxU7W9`>U_Ayix}*u+*by|u&p=pIaI&#y@191>}TP*6ork(2ZOq-OG`NLHk3O(h=1 zpS90>a5oo49U##myOecrZ!qb)wwwBM>#unKus^s(%`FX*Hyq);@5zmFpK-9Xq>2nV zn=>0J^^$WL4|5yYL5=%v3Mn46_RI zklir*P`2flWJMTjsgVz8hn2K2V5@3yNDiQ+B7Jx=$n?odWI}yHJ>Le}LqMXStp-qOhcw`DuRCA} zRaU&O6=Zvd*Y~$0s;fACPUWUoS7@GzHcxOh-vGCJ8d!Q8jg%!ed5Id#ZZ=DbHc1~o z?h87a*24XdC-s+GUjS8mIU?U~Kk3J#*eZ&zm`?8LorIFj_j;aCoowi`14H-S1t;D1 z_h6ESh{%1Xg4|?`p}dPJ4Tt1zg$_!)JldQlalH9v3+KJ$y9vrrS4qL=H!E;Obw;=b zFWe^6VsMhR@uVp=veL1`bI}?#y`XC@wHZ6!Mf^AnXUoS3I5W+?Ap}wmIc?#j9yFX5 z9KMG>EX=wr=p4{LtS=1qoyF+($tV?w8amZ^opTro0!M8FlO7P5#$Id`G0Lo(NSzCvZd&q1OV3j`@z2G7a-)lo+GF*dVY$3z~{v+ z-8l3^1xz+e_+^{~%XqMWukz9)n7E~2QO~L&pj7nxoQmK(sa^@ zec-}?FVi@-5do*-d`!eRz#3BR9G};j$YW#;Ja=ih#g*YuhF%@(1h%k`4lHNG2BZXo zwsoXi((2?mxx{Jm6LN$?ERl=j$H*f8c{C)Rzh;b20Ox<;I3e=u_0bfq(1Ly1{E5z5 zDdML;)37IuNU6o}4lzZ~vPzX*ya1a+KnWRE(`&j>TrZr0`R8xK$J0FN02yrb;XM)? zfC9)X(fsL!cV~FwF5uEdN+SPksg#$z-{HbwL-1C`oDoc8WI~oS3IU0`hu_ZKUFmuG zNi1%H>43wGRYv|!&M0(?)QiI)QDXj0BE&X@4C z2Q2PuQ~k~2=XfVJX4Fe9Vx6_Ywn_gTG4j*-65We&rnwn|{o!(eexmVWI6WQxJUhg_ zhl8k%g|(RLDmD9pBz8U_%aRn z4ANQrWt|?RqCs>`=E!X1HO6e^x(_M;S7{)g6|a4YJdt~Z1B6L%tVW zns-)5_gK(DFi2JdtiO`kXk{{+x#aHSVm&#jm>9of-DGKydDvz=fnskQ39uN;!32&E z9K1L(&6^GCX;_oxPUgI>g-m!Y0@lX9M`DFUsxhQld4@Y6319?I91IUq&))}UpuB~K z#bOQokOv}UQ|UJL{xA`N-9*G|p`AV(FnTWvx<81hSb#Pw)v= zObq+@6i>mD^^*u15;|}gnoJUP}U5 zt93==?-zJuO@Nq~*N8q6fF)v94UI&}GbwfIC#6maqvUQbrC*0j5{8JIw~fi1nKaQZ z9U$ALIz=@2&=#>s(jGjJH8)lR3SrX5*HWh7lo+5+`{;5kVTVS}Vf*jJe+Uo|6D`vM zNItGh4`2-kCiH(eI&X-!xn2*hNb+-+TF@j}kg73CfIwlG#KrnJ-F*MT_= zJ);0@P*Jo-!SAS9Az^-H`ceYqSFtw`pnj1aLFj(W5SuO0l50`=ERFhU%D(>UK+M=S z+wSneBez}4xAq0PhswwyaNjDL?gi!qCta>>ii*q$jCJU<7m9UJ%&W#1LqFVu$v6sB zx+~cq$zzqxFI7qR*Be&9$rHl2Ofos$)5CA~M%eftpJj80(isBY*&< zHBS;n(^-q0yYyvIoQ2S(6?AYd+Z(+zKdA>~r_k{qQE{U43Ijl=0#S;1r1;33#))@ z9j7?x4Vcz>b{CG$VT-GYAjaIWLc;f*>84RCF*V~^lW=u z`E!c6VD2=hc!~Z~V?p%R2e{{KlR#5=vlTqKSN*DV{FEwtaPy1ys zzrIE#Z|`cbg6tAmnS|@i@HJj#=St$BGw#6upxY*$dZna?v^h`?G2gu92>KJHn;F9+ ziW1-hNfr!jN!!NQ&~XUOC@du-Y}UWG3vbv8h^K%v#s9yc=I($ukf4IPoo-49sFvKX zU^MMDdFg7KZ^p;x)VbVFAjW+c`gP)82@R@Tdx>?0jg6qW3rBVTitcVLFm!9x5%F=k zP{sBjcn-v!0RVRpE-xLb>=Q$t;oEb31Fez%I9pv$haZ*~JY4uG3Z5c8d^;F&pzRH( zln9er6jr-LMRhaD5iXL$u+IPUd<1&3*vL=;aE|Q%e2;_fTy--lVAi^#ll=_^g7g*M z!RRGT{O&JvR0E~Wg};VdSbw`8#@EC9=}Ld?YQW#iRqprhhExy3cchFM*}kSO4n1D{ ziN?#g6fE`YWJfF=3mq)TY2ti#)BoZ9Xqx|YG`(6~-wlwSEXOpbwfY4KtZV$0M8--w z{7d?fH{vOxmuU9Xt|hDiQIdzc`r*ix;(SC4$od&I#2C4@zXo?^zro5(P$^1LO09p) zhtri>YWx$LGExb#w_~P|f?9skBIwEAzz4j1`F0MXfy6kyXF^y`TeI@GaNV$;y7NUk zf-|E01U=GT?o9`5sBltiI9gnWj#&t>=kr_sZ@S3k^ z!>mEQ;cxS`+PEy0)NLJ<@t7nD(^J{=z-g1@)Nuls;ur5@(|C%7qb5MC zfseQsd-=tiP(=kh*h_8`w6d^&IM^75+8l+r7y=N7HwZca*{duZ?PkeY#A_)o#BXcj z7b-r)sbaYwc@oc3ZS^SV+|_;5PjE^r=}AT(&}6lAogwWa;XnNuiNAjUok?Bl5XD9g zz_6-?ca3}*Obd`~AuXgPDT&Ojwwc_K4E_tPitcg%<<6H&45v(HI9rjQjX`;6vIYL9 z0WLxWHpl53$Mab|4cutqQ~0sg4k1>*8h=#+4Al8#KnlYJwa;#Fsyr!}VX;hVOEaxV z%g}<9PfLna3FrfMOoYXdG`t~w;yJNOH>}x%8GU#^Vjf9WMOSdKESp*laPK+=C7;vo>e>)&?0zY0IvDuvYCnvTCP<241+=7~LQD(WMiM zJGk6GC=0rwaY-t~IP1{V9o*i}WH%f*@o!^`f2_7Lok{S8jL zsY6F@0TA33*l&f&@&1C%#AFHv3$@@57{o7>x z3F{>hn=%x7CT~IWgkVdcmOX8YV}W7om^!3GrPah&!}Msg);o;9Sc{02D7|b^^5jG^ z(dAa=^3?(LQIJTpU_giJ_z?Rc&?<#7$GZrCH-*GXaadzPr>lM!nYAXfqmyB@_~X|d z{;*^WaFQ>*sGfuxr3$3K6Vu2TzCb<%rjy-WeW5l- z{Wr?Ye|IdoiJI1qj}hY(sBgySNvc>Vr^4Mwph0rfM_w(&IaND^d;JH@X-Il7aNWkg z^=Gp^Xu5~s0W2Tjc+^hRoGx-p@i&Xb@N@mgK|n&x&(~kEEeq)(z?FfbF-XztKhsUz zcVwk5L&0{#NofE7Y6%WsrWL?TvCl`-D4<96{ zjsPEU9q#iyF0z!T&Oie+fH!I2lNgB%se}tcHT@egf- z#d%S8e4)6;;JvA6u#K9AOmMGY8XWxk6AOSoV1DrlV5W1PjyaxnmBX8<`>q9|0`8sJ+f zP=mGBoDh3S1wU^4Bt~FWM|1)mnbmxF`uX$d^#tJznVdgD-JXL}&(5&kKiqMG7A@xS z01|4D^-ugqWOcD^`T(zIykFJ6F11as8KQHgLJimup$nf`4}P2hVn;H!NxpwsgkwP( zHj+b-oqM}JpY(PzJp(eV-MY47_$=2L9f8B?n3;Vg1|1CVf3p)Hmh0t9GIhp4=Afle zh3{Wcg5{CviyMqEpr#|TVr}DVx{D#8m4b1F2pKFN7&&hIci@EKnD7rk^K{TH9o@DP z4Yq3>gC&<eMg$~O=I#xg3E$f3N*%C(Z+f*s?M-5AM*V$c2J1WXBC9Ik2J*^eEf^BaQx5@>d zLJ0Qg4%8Hjw7}xOnnKVEsc;K`1}*^Regk<{6m@;39ZWoviB8NFz3Tt`Ig7 z(BW!6NAz|38A<1dC0_R+L8FA;)%c|3-vG%Cpj`s;Ser3INF@e(Pb-;_<{E%&JHDQ- z_I^*`^F2&dqj3crS5tr3phS}}07}r8FjLz63-FI=MLjLmDz@qJVw+rgv8tJZ*II_< zvA}7B+cc+3cCrwVULtfwjDV?p(@(?COBHZdm<9VPg+!+|t5ijy{He7&i;;ssRFs7B zK)?wo;a9xEpY@*l4`aX=guh`B5I}g~TaW2c;|trBi0|x7(c4`q3|J>-oQI$(EvYF3 zU?z%A9A6`e$f_A@2-Keq-tqF*K?DAVxyeq$;+*a!0K~Sz%dx~LJaLLjJb}gDGOj=j z(^>frA($BIU2YbruV$?nCj*6CBV~-Ovy3C!RuA+OVvndwq+N_m+i()fgX|<@lVCDS zYE#21&wVFb$dkj9Q0!uhFjw*9v4q<{2DMQOxctnBgPv4DR)%K`FdJ=3;Nzejg4oYC zaiy;wJH{RR0ezo0=Y-e~%pL)n@KJp9T1UGvRL~saD%u>OGa{WAD8!GvCb`KlFUga`FLgLZ-PP!4Js23ilW)_N>%RgSxfjGMy? z+R))*tX*8RP!li@c=S;ok;U~SCyo9H+(;sv%1%p9Z6fvCBn*x7PO0Cxz!lmCzv&qQz{X?DMvG8lqicVmnS-8Zho3V6&FWlCy!(N6pxq#f zosJ_!i8bZQ)eMz#j46UFfvqm($`=Z8M(`J@Ejbn>li0;K` zO4_y_bf~++W|r&b(S0nTn)urC<;yj>nW6B#qR4mQWoTbI1&e)eteg7D;?@%3S_@FjCRCMqkl~2t?wr z+>RAPH7uei{~~=wCD)AO880ou>tiStXeENNb+P|kx^6)87_dYfa(-R@7%G;6KJd=E zhK^#j00!}Jmnh&EoYDQ<+v4GY(C&y3-rF7Z3GozerL=KW-newsLP8b0u3W3J*1~q| zBIIo4hN?0g`3cv0I%fB}W+tt{!gR%5)!xaDOWQ~Vaw;+Q^;p;=r#C;(ju}XxTN}HF z9YtdTD6AC!)3yCG?OrT&^>M!+M5_;_>dvTR^uWo&HNk0RX11>TF2jP8g*S-GbL9IF zb^K!>QYK#a4h!nFwS7%z)Ks#?N=pmd;R$9n2gADV&smTs^6DTIUQ$cH5023ci1k*JseHKqc0=>jTpnieO<<)RvYM4B&;Q$a1mhT0Oz?a#iRGrKEH2Ex zGoB~=vjlCs-S3m(5_%tkiMVNmzQFz6bgU!1c{X03wJlPgYPL9j;;PlPRljC==dmtu z1L~HmuXx-+#z7SG4+4TbSoPg|FZ7h?Z5Z63hX*qbx41JiVuw9ds2Ot&O19?LpMTZv zEDC`^dGMKiI1VDb_5>dF|8SIosEa7PRsFt?TaB#Kfa}2=e^c6mAjrb7A?3EUU#U=+ zgRNu7(GLRflvLCEZ%+n)zlWAO0vjBRA7K(^!`0{pupMvQZWkr?WC`pTLWdJ6Akqw~ z+{AwPw_f-+^sA=rQiKoF=j|QcLW+}7h_hUp`F~ zcHtV~I9nT#*9RSV08o4&}7ImZ()A&u#yiLPq zc@pRs*J{(w{Xr!atJMZL+z27=Eo%g4Z}bmXOq>vj4{#yP(Fh~Q+>iPiBp2l~nDjW^ zoZr0Wl?39-$?pcNYFn3{+{wcj9|hl-rx*M#0aEg!`};x5)4;Aa9d`}i);{L~$^*`89Hf)-h4sF&XHon$$`bn=E%RsY<4%%amx zqw|5EXtD2zfM{6Zpire~uu{Bfk9>@X8}r@*c=Jor{`G<%xLIRo^`d=G78<{83M#=f zWI#vNZDb;_8<-)~X~L0mhMooZ7{ zQY-%Vc5zghI@}L%^d~9Sa^U)4!{~oi!+gX$B__bVv?^Y zosA_v!L4f`{ORJcPCZ7QL@C%a3P#s(3lC=%)N!--hv$52u9#$jKQ~cVsr z4&gD~hF}SE^SR#-(53|8vWg;>l_}A;1s0`jxW9pR{cc@8Ts>N@K_OSqUq{@DMAF(+ zKUSj2{nAwfF4`MxP)B$T6dW+bJLH08%)2|L->EyJf|CO`&*8UfAAOdCgvvm5J$95* z^$sPaLYJoiyj^ob#ypZkVXJU(0l*MIyBSaKfKwBe4@b9T8t8radW2ng6No-0$kpk; zBM5m7zlt712JEG?@HoqDAXn1?FWdTJFQq?`AzvmWqs)nbu@6mL#@!+7C-+^N*m>v4yDLLcJYbQpK{8{>L7{Ss|z-Ry(h*$Kx){!HGPx^7;T!%3NDtgI$KVtJ&4O~uSr5|_d}vz-O;AF zDU1&JJ&UX4##i6tai^kpB&UKU=Zsz9?`p_9@`?&v)3!oZN+6^IH^BQ~z>OrKMR=Ky zx8tX)K*ER_`sb?v3CB%l!uN;fdu;E0ySkCwoMj%Xzqw&u zECN+j2by%p()C7YQYaG_>ZpHb9rY)GCX5AzfFlRADa6h~pb$l8KdlEsf_LV@;sy+m z8z58i#l?Dq4EP{$8U|PR94}fCJU|Ty@k|zf7ZT!>g@e59mn1T}K>d4sbpg5rM^xuyTpgsAsoDyA zs|dt zh@^2*SAtR(!(5jpO^Uh>u6V3h9)~TyQ3h2vrb-Nr_2)tt=Z(IIwnTVfpi*7k@0b!K zVgym6$$6FSY<>Hs@^z~81pXZLn(!gcgBX-U(%R%6;(3T&hd8kC(2p9av|N?OVMEKr_GH4?WEwD@eNPCN>+E-6Rx;e3|W6FLA;0&*tV0L*(hM+tR65Lgrvn8VB% zb|b~jHK~^|*SClb>b-l72e~DX5JgbT)EQY595(zOCn{aE#U6uZA5CPgo)Je<(2&I{ zlyP*XAT_;&IEijCJ&zdMjmQD(Qu%K-qhRZaLq2*>~) z1WVnbWvS&EQb+Ws7e_lNEnorg^3Do0zP_4HYqPUy0vdPTi!;pW;buvDbiM?N=Y|T5 zF1c5a5b^4qf7mC<5$^7*5$>pVZPH?|tI?;cUT(uwdnTZuH65Vg3S>L2C&H1v;sYbX zZQO^1j310p`RY9JX;7TaGYd+(4Y+VORIHwFL0W55DC1&5I=aR&z{NcyJK^V2Rio87 z?*M@aK)8&~m!LQFDHYo1^^Vl|Yli0SCIFyk9AEepGF!~&;CGe=OLss8zo9XbX2EBy zQzi*1-IX9YsrCrDXmPtMtYv=9(CReWj>Ta4OI&Z&Z;K8?Pr-s&E~Lhx{*AYo2-JwV z74Qtg0ts+>;@$1upw%`IqubbBCEd{d`nXGZ@?wRfV}phD_{|&N0Rl9Wt@QD_T4$8y z;p;2U&c$1cN4ZZh+V(e@9L=E4LlNHJGh!cX|&Y z7GQ>)Y%1<4<4Jjn4j>C&9w<>4`E8TQCvWl+Y>r zAlvPY96d2w9$3%dMLKXxUt*NHq@fzIRpmw{sxIq?r>GKCuVX5Qm!Nu~PeovpNH=;K z5rtra%9y79zD(4)DLzq^7>Z1tN(}mEU=hS5Wp||^R)W(8vL?C)H6nw(ZzkOsp&&K< zBcI%H28W%k$4nq%Le{O9;3YKl_O?nb$>LN49?O`zzR>)rR5U!1H$0R5XV0=Y!ybLH zT6svZq(dzKfknZYE_?jTBi@P%3y_X2cohjR%0|u5o}rq0J%R4SRl+ z($h;=wjz=+jf0OQXvZYBxO-2ueO&4uu3O2h3}D_X;-R2BPG{7fODBPqV?^$`r3Xd? zLgvPZ$SjWn;NyUB(rzF2=PFylByY?pszJDjJ1v9@KSCNX$1NbUgf@l;6y3*WZ`Kw7{YH>bTCv87;BMW1=>nbO4t1F#&P); z3N|rrA--b%upGrJ)U6S#D)OuJKJAKSuI?clH@)H>2lk(QzjU8X91VRx#WpMcUwa&a=eA9`0T5enVi38*XFpAo`B5Q?an5sHkt>|M@R>l1Er3?PvX} z3N7GzPr;8fnK9Euulwg&XW$%s8MM~0SjsY)-Bo}uGLMonRakAmt*mARb!?D}CGsk6 zHB2l3D7HQ7*g(|0T=OdB_LMtJd!HDAN9vX;P3k7A9DU3aR@8ayWAni7Qh7q%>MVSR++kUb?_L4I~%1O~W zmAep;xszzL&V^DI@WbCrjzEVP?2%6||DZakSB{XnL+J+HMH- z@Q+>=5|t}B^z^u+YB#xcn4z3^p!qT4wp^tHL(7%9NahH6zJ9wyBZkFApVL6L3AIvI zO-i`c;Tfelv@v>dYd2vYFSe5IJ@68l%96ddyRkAps5`wlKBU@4eVhDeN=-(i*s2yF zzVZxhTLVnzI^jV^7sKyFih~?q^CktS10qMT1m;pWy=pl;@_G0-?!<0?6v0!v@-dEz z=?jB~jBDp8V~dXq1p|Idi`ADxWp~EJ(i74Ek}j1xSPcn;Z!p89?;Y+O4Ueak+Ee*S z6(!Sm19>A6W!Z77IkIVkLy4uiET#G{{ENquAQWSxx%*ZR;Z^as(>GcH(nAG~(x+@E zuZFWjt|LQWO?6tP)`nB+>NXV^gggGIp*<$>Xe5@^M$IJt713xfG@|L?*?J^HWkB0xLGyQWaQ%6cu`;&v9=UKZJI!~^qZ;@;CeA}$S8ow@Cr)oRx$t#%;X_}=I_p zieMFQ2R8K#txiT8tP@I*3JKGOgg zHIL{FW0TqUmQhUE#`MEDo;d_p@Pw0e;v-s!CA8IuaBjL|a|a+?bh}cG8QEXi&ShxU zpCR}lC7Q+Gqy|cwuF$(pm50&FKrEA5#i8M$R1O;-H~l8 zbs9kIlv&ah#&lXhC4~89ypm_GqXX{e?vme0y5y2fO4@MXjFMZrkgQwW(qI*-u3Hyl z0=R>8d6Zl=Y!_i&%+Daf80|~!Z*S%UX?0%5z)1w==|m#(&IaG46FNK@Mty`kkvtu* zDSWQ{(r3WX6nItVWcv%Fp0k4x5G2^dyV%|um8Q)8YuK#UMrRH63O8mlC$292m=}eu zpOG}TMvybhLdA;Qz1_~BxJbOQR@=TK?6G1?BQMMl;Wzf9TjDp}Uh_=OU40fO=A)p< zxybE^|2B+c0abE8zTF14sE5hMaq=D6JG9+b(02OuzYGddJ^QU#*>Lh+7|%`JVE#&Z z9a%hd&AB;cIwbLXSfrL(rM&UIPSFt{3GBTe&G1XwjcAJ#e#)mL^{fSDhfmqM1LZ@F zHns)nJ=@)qmIshfjEvy~nsTNJOO>A)Mkb;#lP;rWYS2QMkgL3{MGiXGX3oli^rfxP z7l~>UY3u9xR>FxkFATlgTm{BAfd?x4=H$>BC;Ov_Ltyf%ak{~@9c3oF#@+jmeadC= z8Ci|&Be1U_wA=kiI8_Tn$IWwU<;Lsiqw4AuGzWvqA89wuz~w%UXAh)Hr25nFCa>Yu8{+6`7OTOR056Gt(;$VF(_#Xg4~JOGtF(;vgpn37-6%wj6Ex z#;gSMHkCd?;V6JQAomkATpImxo2*rym9<4Z-t4)mzRM(e<@vX@+ZvtIhvuVbwu3&PJP8gF1Pc|IFaqJUz7h4aZ6=1P zN|%Se>)^6ZD(**e&N~xntMV%3+MH!u>nNwe@R8Edv|q9)BsGVMG%lD|<66Sc7Db0j zhfcNkkrOX$@8gJ)euq2zsH=}KNr*#G>E3=EdPTV8oed1Le@^Q+)#1fSW!(&)H&HqZ zI2iogv->!5^1E-|K&q6^0$v@>i)n0@7icI_7@-gaiy-LdQPf8_Nu!5>(Z(taafxP` zNKvl3rJQ{ewX7!0p~jQ~73@;I1tF8=n=BCeSpfImk;R^ql%2qpH*c!>reW;F_K+LZ zKT1;<2|7V{(>f+ld39uLdtKVl-9uonZRsPDHp}KPawaOe&P;on(BzDI#XAHr{Iu1la)oh3q6M8TDaDMgfwUa8qZeWm_+jbMkC){*fK$rNexbvzLQiy;Lq{Hbc*R+#J^O8w8uRVV%^o;!5eNt zZU%LNGJT}>sTNSfi@5+#<1=U)x<09sj4GsH@da|kaf;jwm{V9y1H!+Vq}kOH$M1_g zvI$R7$X~~I^W_guystT8UKNS#{on3rZ3a=KZfx+%Qm&KSUp1LQQsUg3L=eKcnXi}{ zu_3bb^ld6X;6gr|Am(yyM^#`WF!THxO2i(dA_4cvvcutkt?HO7q6twKi|d$LWiv0G z>hLeS-5B{K?IvEW7xNWetQvai4yCvmAJ6`*S`0=U#F}v!@xtEM-%X88;tk5|GuT%_l~?i(>YYqr}D3%J|D>ZJh}5b2DAaQz$~cZsD|r zEg(|Lv6L35-3P)ln+sy388D_Em(av=LjJUY-?W!r60ja$gdsW}p6Vfs&Z*K(he!r{ z`o-S9Nc$R#O&5q?(gHNQ4XPD8h*Z%eNQ$C)oiX z0LdY()&omw9fj14lN{9GuVlJhNU{!D(~~d0l@upey48inH~0HOwnF!ol~@tn0B$Wq zAsasWh^IX005gx{^)Q)W zpplB$WpFieEU4l@nrVLX2l82VZRpK2UA@a;vR-*GI%VDv?mJT~X|z_E*T^P{rNUnF z+A13+G}dj7ZivPmWc^UJ3T&MD4?owlMK?YE5-Cul0kV*=L74{VR{ zeaMZ`Z1qRg9MoqhJOzV0C{Uj9Qsc?APEgf>rlcAp^u7hPc%-L1Ml$V%JRAycl^SD5 zk2n4l++%Zb&9gRl8y{}SlLbnFhI8s;Dhj(Vd;;o4S%NE z@IiXQIpC$?GUmHan8{*zM_O`pu*ft!Qs0a_|2v1!T7)`Hy<0G-_IifDgcubZg- zl8CsflgDt?{AYc;Z<08lt5&%H^SO4FjCV?&kGavfh;0bK(ZrMIa0C` zE+XE%`II?V@t+UF2`v2P9ve^>jqOx`M*UY4+{^+xlQruA*w8Z+3YJmNMuOu>QT%q8 zSDN!DI5~O4I@X`4dn%7BE+5~kJdEoEeFSW9lE5n6cqG*`zBw|<-geJ>Qrj}2)~ooA zBzpkixL8pLDr%;zB=O0{&`h&MGk3+AFV368uc1eA8J-CB5EYR}@&SiL%5?Wyq=O72w!xk}x^{U@qR>))*o z2-In|;u~f!zgLB?6m4oT(RIG+K9!4(Ui`iqgH7Z3gb-#$=!@yF9}$TnXzt?|Q$;8d zpx+1gnv6roYz{Uyd*smIKBI4rdN>jI zQJ;VkxQx)yy1bptzxh1UcHg%@Ti@#ST_)=;|<`k#D1)DR@216lrl^)YZOy3|8x5nD=SO_3?w|L%t5b?5@GONCLdY5T zV?Z^ryHQw3>w0S$_&m)+;;yX(Fc6cG^r@qKv8HjMT-D^JB5n}_UIS%ig(SL zSmQ}*7*?Qv6gt6nLq4yc+}(4nY!fO~D$tuI66iJixbQPqf$>+>lzjqY$)w|}*=KeD z^eUwj9LUYOe31KG-s4!BS## z`zaU}OVc-9p0-6;wz~sI%bWNvnMnkL@69KlA#5X^j#6*u+4X3Gq{8X?yj?`Mi3@e0PdtY1wr= zSh71@wUBQ7+BWm8ve%+9HVoX6^Xzt8{lJLOK208&O2nw2@gue{7+0`F52^`*)a5Iu zKGFv5>!!{{TtwPVp=>Z8l}2RnxuRXkCXA(@)4XP71RADN^e?@w5fy@#Qa3hBKFa)= z&yU3qXxwHgFH&Oi-l-Qm+|DAjj`I3?yK@# zBmUX2yZpx^3tMFWJcCAa0<{lnt(-64a{ggT4QY#S>Yca*Rrs1h^}$y>4rimd`2(9B zvAb_ZH?r|HEYI%o;BnL&E{9XXWQ(RbW({NkpG2D=vQ;T;w=E2HUt!{jd0>W{uwl%s z?RqA}I_3F8*-OJg|FNbU;rlf%3h2%A?P*Lk{{w`qin&f#fO4odi|g+q7=hXLS5Bn_ z?)4?5hz$(HW`Za1;2=j*fP8i>c^!m13+(MQ~h_7>mqx+tN&6WbJdr-&Zrt~Z=iBbB9nJ9UR=*m#Ku5D*yFHVZTfm0naWoMK+Klh@_zH3Jm_*5#ESOeAk|0=? z^N`BL5zn=N+zpRkuGYhk*uB*e!7xD*vs_vSXxenwe9ck*;(4X&ce;q40Z+;Wl6+%9 z`kKvW=}d`^Gww*<7E6)SLCcH;wLA5>xDG=Zk*>oqRm*U3q?)csv-k4}ZrTpy0dhho zhGWT%V8VNT^9C?oT#Vo$#UNHTNX&N7L~;F2)>YdD4^S|KXgZ3>KJcn^#}Prts^e$} zr01H&LL4ZI8hKeKzH6e?erx?EI9DkGA+3G0rn2>#9fRh2Pll^?G=sHqQ8}2* zP$<3?tPX)IYO4yX!wP3?Y#D&s&!u>lkYCVt=FsM1$AeKk8zY71vx%B9^0yUq*3u*D z?Et-K{bLdD$};2IaZ>zXW-6IXBLmg#k{IJE8kwjKv|(K3bR1~8i5w22?R!1a_pu%g zyrJYx4!U|R0k|j5z0VeUynVf!$VRaextWUijEXV2*^Y49&>r;D3&9yASSb$Z5&hG8 zS!+C8-bHXZWHujG5bWW9dC4||Qa8&(LA??yCV`LaJd_>L%*=M7w_a-UPBC}K8Q+jQ zFaGLSI{VsImPN836ehWsndgX-$k}4J9^F?!t(aqn0PqYXtbrG z$6^6a_zE4=SGTv|;_fiuIh0UG;uly3bw%?fNdq$gYe8!@rk=fdvt8;}6jW>%gdUAF zz~xDC_t2F-|8_OIG6Z{54$?_(`KwcGjyBQ}oF&K}Cr?;~KvO0NS%KH4p0p~DB4jwX z+c(xLcQml`jv2?(?3M?R#dd6?=*j`P5p<;#B^{O*cjYkPs(kmR(4`dXNRNx!VBpGr zmN%QgCw!l6G0u2NWG?s^)dC81u<-p!E34aM$?NDZ3Gf1mhnn32V?5O z4+&{{?nhc{)+MQ=oqL*}lKMBHrr>H|)lHXx7NElrZ{+;}36WR1A15!20+q{^A^9K> zk-mR#wcfl*b&C*s@^i-CvVkr5@sOFSR(m7K9VkA~$UN$1AKuZbBW+ikRE9W#s*)ao zlr{A9EQjrEsuH96lm@V*#_>2$#*u1@t*ZBiX6@Go9mDWyaOdz^%IOiYxrM6T4FDYT z1)o3yFpQ6r2{*UQmtW!~#U@f%?>1SYc%jfSI+;5tmUu)t1oZ<%gwd79%*JiR z?dvtq`GDux6TYE+-)n&u#Y@s)hShHH-U} z*>BH{u5E_y-3rsaS@3Iz zrN!ECGsIWX;_3JWSW61|(Mns!qzS9QOZOw;n2o)vYo}M$ld<_D7!FZ= zqnPL&Rm!w2-GE^=&l8z9uR$$&?Ci?{RnP8cVk3o~67?&`^{a+hF$xXcjJp}Q-Xc`? z_UQPh7igf)0!_LzpGZ-1dB7gI1xcKm9rFPEwk4lDAmoP0S<|rHf;$}aCIUV^Hz0G7 zWb9$#vMQwQNtTmuDSKT5VOO$9hA8qziKLOPwnJ8!lgN*>t4uq?*j zV)$b+ACAw_A*PZ1|NFLsnD7eYZs)TvN&M{#jR?!@XTVEEW4l38l8R$#`484!&2j}<ljc zTzzE+FWK$k1I#z^4>0uzz5KfT_DVm80lo@fUgMMa-0HuH!U^OkFjZB>B$oNae5k?= z*R|Ec6_=6{B}4>qSR!Q9>h}Df-XeM=pBll>m>Sz>f@CzjC8=-h7I<@5V`m$}8%C9$ zKDUyk2YW@ow}?S<8GncHyuKZz_td9ANRC81*!^E{LWmW>1u5Gl#OIG`fArYc^;x`n z7~RX4gwAWaZEP;Lmu{{NA*ocG#{ax)>JFX8%0eQQ*B1l9Sz<;ZgVt>M>{4L2jBUW0 z(Y~>Ija`8J17hRsqSE~+Jlv@#Kj0@{BPmScQT#1gsR)U3K%(Dj1|9Jj*@AYV%t?`N z>NTC8BdZ|5NoHG82Q^?k?V-t;R8{(b0*2>@lvT}IF`am0eM)Ys+`niQqvkiJqm=td zR$ky#gPY&F*m$vnG(ZX7f&BrUsNQ^)&>z%+%x8euTK~!Fyiy%2a%CU;I00DhoFJ}e zAt*G`rm^fzuo68UhB=+TYNuP8<=v`<7s9h-b!1dN!a`?h4;@hjk;63-ndyLb}r*gZuhGp}+L3m~Qe*AO2 z6@}4Kh!ZqnSE3P)SR-JIWc@Q@;KjKXo;wh?kRMR9M{sL-ef)<%a6_F2OEUh-^s9?X z@s<>ZN``rCbtn=ObsrO}kSXU#=0E>U(N%o^#HSFOU?QMqV=XFke2sr-_ginPb=kbY z#RFFQNCM-XkLOdM%^&gqlV+RoKu~;!2kJwUu=`P|KeIJ(Ze;i4Z>t4|`W+}b$e+k< z=_oL87_j^jo#69cd;H*DRa%ug9G1h>ljR@TQIrJEuWQ%*Iy$64XI=4 z4tsMuGJRKG<4CU&N;b%iw`pe@d;ue`=2R~@2Yk!CEfFg4-0EnpjjDL_uq#ovSAL8_ zO-l&#gkV1j+V{fqPf{pvaPQ10@68A7V9R6dgzvsc1jvWyg*6^hCU|ddS#Y~`ii{iH zq+6u0!E8PsGK&9874`BolJqz^GKncSQvb!~b!U6c?F*cSnQMiuM}sBF!UVi1>^%o+j!nq>KmYM5aH)RsjR*;Ter?k_sk?LboE)ZOBgbUeE59wkXKQa|!76_e>YyeYkb4R12;Hv; za!V?%3=Rj{bv`0&E(ip$@iseLYZG;kV8$n^x8G&z5j9P5?az#NejlujdR zTdQ#lFG-(7m8InvkRk4$0rX{pYc%x5Ti$R>1*&DDEt`LKI=az}usO;YUjC~C}zX)8B99!TAbW?t6$@PZg8U#?MI#2oH=M6Ab z;Y-tl=E%m9!FiTdQI4ClzU*W+C4!q0KhJ}fM~ilXdf`-KjdB*nUwFXv(V07ycY26D z`&=VrKT@)SlBr$bbLu$=r`{DX4#^!PDl_Ef|{LGUxFg-CaiQgEbAF?UGrQ8f~8<-F>$48ZGY9 zI7u4{Dg0dzY9}Dv7yaju(S}i`145ZFcpO94xR_rLV%mf-={P!Ypa`(Sz7uejN2OEG zx5G`moUc36#rlVA!;VfjPrsOt*716k%=XBK4<2r2@fxOW^=m>bo-E0wO(d7}55C9b zvcYW+cQBGU-durmdP|mTtUBqR_aMI`XL|p%089ux~Ad8ww55%mX&W*&k6+5 zyh{|{%%l5wvWS=6^Wa+e>?~QWd!P%(>(k-rK9-RtrBrUbnipFc3hg?r+eYH!+Qz4B7K6+&%a!}fB45g;^lR` zT3@0EX$k|9vL%aOt{*{%Z;8VV2JsM~Y17|~G+JpQ5c_#$2giO8tbRSMmtD0q>Gs%nq@dO1wiEACM&zAQk8=(kXZ zP~-sI{_I2Q*QPV=zu=+AvXjL5G-{S=@U$bnuuYBNJMkn-x&X+-f##xZeBFKtF66i2 za%?c1Xg$1>ZQS_zfLrsoDgTY>whnWAQr^3F*=k+J>nZH$^)imTH?P#6I>+?qOROhO zOe;IkjLD~+{T89~YtmK1!4tb^5|0FyNS8bG8|e?%85Mvhd^oz@^dc>z2}~AKywuGH zO$p{;IsXw2AHH*t(LwU2xnMp0iL$cj;_mi({j2M%=(-2gh>6Nf7I~{)3)e^gMCbaK zPXDrVonCbPf%*}x%~S}G{(&1}^j)#f!6GQ0CDCW}SJCTtb6&R%#Ym5T@ zIxhMJCh=Vizs8@D))f9AUZX_=dDX$!H9`Wpu-4&dy1Ki0 zxP|%xcbn|pCX>m<;KMKD<=)_3B0NEH$nkK@TY#vug(A&F-zGR(wa4jBL9g0UiDN2G z$&y(=QK-6tMDW$@@|~=T-TMzX9^?pRQ;VQg{7~h zblh`5$hKXT44+Kb71dt{HHg&Jr4DDU7st{>>hCSS%zsM?L@b>*(Hn#HB4~oT<9Up4 zx5Sag8+t7-TOLWoT5VXiZ}a8X&T=_lGW-+mE#uMSp0aqx4E^*%{f&B}Mr;BCJL{Ph z89iUB(PxYr6x9y}?*Yag&xrO&_vUsoyyI|cqm$AfOptYxD{b`*$l%?>x@q_E`K))| zy=Gq8r_kdakQ#-&ajOk^$D8@dcuW$Hh%D=+L>v$YzfU)Jf})*07HBvSix-BmYF$?> zJnWpm)OBcDP0HL;Rpkz?B`=xyjKMlg;;Z!%WTzR37i?YKlhpmSd3K#|06}xGwjpyD zf2Kg3yLtG(K@P)TVFHvPvl3~si}E-}>1@4Wlxb{7_Fg;Tg{Br&i!W{wsNlBYWb$3x zL_^b;*`|Hi74jZrb~~19P+**KXy|uL0FZK8yL86IK3ESFa3TZ8gTmC|iEns6v=vLc zTmLnvb6yZYXp6R?oU>s!OotF9xK1R7(NQJ*j}FzeVb5RVGM^IiVvdg{aq9j9keO-B zeoO_1t|h06@D@JPc&XEF+vg*Y(eMrIaR(Q}?CCnVS!l)Mv|$v}i$J1nVM?V z6*EjhBHR`|cyMub>MijD(K)aV7*{`w<1wI8+q$g$s`jA@g3~cGNw;PCY;rd(^A{Xv zZ#X$-4ZIXcUAe;=)HmN$5vCy!7-gNGZl_S?B4oi4tHyKSaHJbS@pm?8*&^*@pan5@ zl+4N9;A4GFZIh3D&ikLJ4o`+O<&vm!^${0QwZhtLiPi^!Q14$J7Ru8SajKFykJD$eCs5x@&ZztoA8GqRzO@8JW~IlAb;^t8BzLXty7d#f1B zROhSQ3sC3x={9K~pBB`y*?P}&h^89@@wxN%?dNZ9o#%rAYrRa3MLdprNDo;Z3ty3f z3Y_d5kSNZb;xPNnNWF(qAvt~-xVU5CaL=dH`K+Fy^F5weIg8SV&iE1FLjo0{|46rt zBADRa#zWV1AtdOKERv%rxkW7}{tn}oX~WTn#UCyg93j>~ruB5wjOLR2gUlxjjHZ%% zjbk*FedElX%}`=muTXPCgRQ}aJC~;?Twn^B0IGSiI1mPc4KeZOZYEZ<|LF!wZR>mU zNf*8AQ+!e?!(Y*`gbEN}YU1D%;g~tPmYi>oy`_JU7NAYVQ}IP%^Pg77f-dB6iBW64 zlNovlme6jlV*vzj$C+xox4+)CFN|+8iUKxV_7>@ERXS)V)Ui@_f^!-j!)yiGfqY=F zG!2954<=-Yf+Ma^rKN5L1A9%1(shG{Frb#kpd@k^LV70G&f#9vA3*n{^iQK-05XZZ zPT4StWaKx;Kw+K)M=wA)DWd|sslLSPM0MKK=~NgZC*fVt*0c$GoINa1wv1!ozSts5 z?x2SW{igY;Lr!zVL?!ea2*R9dMxBc#YFRRzlCPH&h;;QTn3{CH%?KAn)JnMNNC|Io zaFRj<6w_6XC7e0l9slFsW+Yt_4U6O$+wRo1W?a`#2I#!2*4XWe86(1^9k;lE^XcQxO zlg$cS51%~Jh7u7=BM50-Pmof1jAW;^U!j$Gg~GF*!U15VgbO7MG4n3yM8>5SMY2^D^wtHvH8FQrk}6Sdyy7|;s+sdqfg%IR^ZDY_m=Vcai}|H zQb}>`L#0ZXFp1j~8?Y|MtLKUZ+Oc;w2e7ilDxuHd{Or}Y3dx+yjKGXjUGmV}cg*xM z*)YxY;!x63yfh$U$QU|sOfQ^6cLd=98L#<-C^*Qyz-J+2Rwh3ht|N*idj@C=nQKw0 zjueO1B<=FNLlbB@4G6i-M@+;#0L!Q&n1$$BykZ-iil%dUt*eQ+RM%qhXK~2K^hng2 zXPqfgnsoW@-~XcwtnUWGLd+EE^G4gxR}O_Krd1l7S#;?I$+3Am(u)EN7$}M@(>Gpx zVg-P2%VbT_*0$D%RqN&pO=+b7${uS)*!SZ2b?g$*zzTT~aC;Y#dC>$Qmv1~4y* zL#`;~o}}1G_hI#oseTHe)Un?trl^B;%Eey6pxmkmFtn)n$y7{|2^6=g*pb=;S2tP* zu&JjPtGmH+M4463l&G_W`(9>Pl?sh>*1L?C6q*-@G&BdVC~tD`@U*Y1Kqzw@i5n?2 z#*W4_@^Z$@Wf`V8HdYJ5ZUjPFFJa*@KpcwDlMwi&V_n>be`@lHav7O3vn{S<7xEJk z=qMvQ)~?=3#;E7WTuv8t-8Nh~!=QHfd-Fl8=6La@L z@TIsLsUv~RThIuJVf9+tEKwWj{lh-K?=2wIML5|VTf5`h+N88Aud%`JN3F56iMUZp|VHC8w)9P!> zN7gD0Y?m>HOf1csJy3o@_JNWg!ddPEjflJh{{mYmdpAjdf0IBpGMX0tb~=A_CMi&Z zXct=Ulo=oEe-&7kttkDInL_?(>?j7@ec~WxD-1;qM1?ia#t)dyP=3F{q0!XnWqbpgjQ(r|1~wcR@vf9~fXdzOFQughbt38w zg-#M9W*oq=A98lsBeZL)iiUBA-63p;YWy8hY`R?Ev;6K(I@35Dn8c6q#1|Oq9(q4-_fD>8iumDRF`lhj zZQUu3(o)iew!}54o^?RB-Za^}N!C#^2G6T7`L`8;r^#XNPjY^5)6B-7O@a_2K1EPmhrb5Cc^KL=NfNjDRr_6AcCnJ70o@Ru)Ek+ zV}R#9l-IsSm=1ZH&<&;38YL`(M7yh#*$={(VJYZi$b02!F#48tQf)r&D>X;kE$qq7 zogT5fa(bK?W@D6!F3o5@vqP?M{OR?BCs@O`o2%8ZQD)x562+m;rV_uQQgQ7?@?|xy z=PgMWTkc|U*|7SZH8|6TcqPwEk^(G_pW@u{h;kgMSa&g1{zRN4Yl`2Ar7 z1wTgnZQI-4g1W>9(+*HJy15TzyZmZ!!feE(pSk#|_OEu?TR1cRx^p}oe&;TCg+Z#E zS#i&ClAdO-kYt@qCi4+`hsN;;YBorjSgSdcdeh%yG#tHK$Q~Lhy6un(0k_W8HC4}0 zNd>n87mI(a_0me%nX>yKd$(Rr?rz!}O+9VnbVsx4=jK=9x#C)Pq{^+Na3*ytDT>#* zSb>w^S5`iP!5gIhB8w|2fU28ftgwnb6guiWTXncd6(n^bV(P1;Hd9hK2$vM_Po9zj zNb(&%eQaV4XDcOG=sQ*6G+fS=;jgB^hQ{-6)(XOQT72Ls(w!D5i3=)B+9f!4BnK&- z&=PoLJWyV*1?nfJ;Y() z8yUwS8qZA|2$Mmn?*PV?aFLCGLdZbCt`4G%15u%5YDa4^el$5a82BDZfRc-RHNPo* z=Pca=%up4RWCN*G^BS#^xuP39YG$ld#yj_czGg@4!0!zw-Sw^V*c(zK^UuV|;aE*S zS!kR1hsbk1VWGUO3gxY1YGngW?bl>|FEz(ig5m-eJ{`8;F#e%)H7X6KrDIIMf+Gj) zM8_;@?>zp!rU}sk2Vk42@M`ZHgr(olm;GPQkSG=g9=bX;i%qETREScppsQ_|B#%!P z#*y#i#C-WMT5~XmqCdrQ{*j&d7iXs5lVESTmC|9Nr!L!3f zy%L8?H?X|}4Bh)hE_~?P>Mb;(X+CL1%El*_jFbN8UiYG|A)!Vx<0X{%7v`s_(9Y1( zbF8Oy?1!t@Q2q<>PS~zeA4YAWc*Tt3fm(ou9z)u|0BAgdo&Z9pX%tsq6Sh`me1VlK zE|b)>Tb5Qj(~1D`7>`DvE%EILwM~@dlWs~;8-%ua6R_)l;#}AKt=?-2<58uG#;Y}z ziR48k#tEPJ;3esh2{08fju1kJp3zZe|ERW0BHR{6DEi#@Pkxoh)SkQypV{LkxCn^W zKeFLWl?_90HUd%IHKB-7*M39)ZgSRE+uhzx2^tJ$6&bvj9o8Uj^nPNIq)@tD#@96? zop6~1;@+SpiQ($OHd=3lhS$!333W~~Jehl`t?D=thf`M>-)BNKuQCIUm}>Fd{DUgc zX}BDVC*ThT7}4-2kGbQ8le>)9+Lpdtx9nel0V*N5JW~wySgzLBOCB}mxPpy!Rw@^)@TABVRIR|~PK1#b)S4a1{3pwAT$q|d z1brnOzCx<(;ItsrW4jb80kQqoeXVc*D}z*_r7#U$mH3MknuXkjS(HF*Gxhy?8AmDY5rMZLWs(c5mMdH z<#O-Y*b=UgKh@DG))@B34sIY^AU-3*c+YF*Hl^;PvA*m#Zr{BxR!+t7VTkl-q=)Kw z2IwM$g_EMa4Fe}u6qBAMOH8tBdWg@22 zwZ!nv;8z9&b+a7KM)wTqsU0Y&l;R$5uE6N9w)Z&|nb)}jgfA$+yHCX?5uEA|XLmle zse0UJ_0|Oe3AP!8R-U20njUf@_03Mod@RfneF7S8I3+YV~b zrnp6gDWRK(Ihs&>%a9t4eKW3l>-$4C3Ye*;jv?rHOixl&Z^Ex*K37F+dKPz(>t!z2)2z@ELXM8C`N7(>YIP*9Q%&$D;X?~%;iVO^(d*`TNz+8kr zaVt#eK;w`J5TtctRS1?;MbV)Sv{c?+vVwA|2xfdtudJZkUP?o8Nb!;V*D!F$1KJ+_gD_ItnKJ1BL1A0}ZSxd|JfYwc_0BPg} z+vN!o=tpi8wZ|PjUdFuP6SGtr0dd*TR+?G$$j!purA$R*IYzfo1K9=#*#hgfARgU%nzBu{Lt=BhVPn-A`c#uSg-rv( zABBx*7p7He_JMDenpRt2cwQ;eW|sryM?k~=qlBf@Uu#!IcxIEh|LGMCx_TUvDycb_ z-O~#gXVk>Fl`vDl;Xm$NfuM2pO!r5MmwvwBUf0WaELCMs2hA*fRK){6Aug1p@OfO0 zr&tjV^-V)cW7pATgIff`DPF3J@f5G9Lv*ZY#-ulA(#WE5lawdyldfD9<%Rj8k}lHD9X71 z-O)o|hv}jCCl5Uo_1KTv&ZiT#l!6KT6OlShn6wF>)C%R=te5`zAmV90v74gvhRZ9! zx0KDN;e8t)!2Gmj7KmdCKM~2=ym{l$z&9j$I!JQ66MP5Xv`JBmg1qUPy>v}I{>mQ!NMTXAiZ zWQh!U>M6E~LwjU77XUiB*?500=!hV?GJcwJrx*x8hukjE1QPZJoiVuCe??x5sJfMabhGEp<(z05UM! z|C%LtsQR4R3@?5_YovXNkTmOnu5f@Z`~clNL#7t{im&lx`nA3)tzi>QB}$;pZYWGG zG$~shNe($ji@BzfWGvP;t%q_)wI|AEv22ZC|IESIThIRyFCoU~RQ*UvggtZhfHQ<% zv|b7^zl-}VXYn4R5u?Rd2&QW(Kv;p@mc})!7bhgY;BXN^UXA`5i=Fbu+6c^{>0&wv@j4;P#*7VX9=AH`?8A}$ESB-3ObV88D+OL{i@IxC zv>baXQa5A*JklK+vvk;E`s*dI*edkOL@1dPxQ$_8n-fKI-D8DS3VE3Wv}6-~n1Po@ zRaw}iYAm(e>lPOjbggr27)y;g58RD{TC&~3Y2xU`m<6LKO$%8e)r|01@R`dgr1Lb* z8p?$fr?n2p$?a{71s%oQEJ@Z6DdA~EE$>urpviAo=ncdsGdKm;hy{f8_q>JWo;^?s zg+wX)5O2A7qNU?Cj!@bpII5yy$kbZZ&~d`**visyv7o~>-CM>}RW1)Y4VBJC?wGqe zp#sgtmO$QJ2(N6%4AdCwim7!=)Cp6Q7DYUI>*@eDMows;v~ zVqki)Yw4NC40q$$>*}zM1RLfTQzL7)j|cDsn85x!eI*~Q>AZX*GTCj5ULc$Nl&RrJ zpD9%jw3ytU%7bLd8h%$T57nTnBaQ^weAB?}ExPMD6SgJD^a8=W=$;Z4KYGIqW$Qef zROf1UmT&ez`vqIx=bNcC&dXq7>Y(TYfv|NO zrdY_d=z!lSj`!nHoIJ*A${Q#f-_H`N$Y9x{`*^a5mmaxM&0uOM_tJr7LExhbP|n#@ zCg>?lc*+c^U_!_(+schPeHtsw3mHRzcc$hggmy3m3{q6^6e}=#ym0~^>gK-&GhzOq zrcpc%%E25rWh1Dpd)JC8})BT8n*;Kf&P~F+0Po<&(D^tEwc6%F-(I`yEfTToXEG&0?H3VhW}xt!mQFJhko}(51L{as3(E zm7MG-t6?=R@dl~AYK#x4#$io|tFLUKywPUE(KKsP@dXc-8J+1Qc=gcQOEp9;X6U{d zXbo?cIYz9FzTQq7ovOX7MLZ(i1Rt4M?Ig4n@Pllb$H@xkmjvnKu_gF@0Kt#`*|Z=B z-$&*;!yv(XS*-QTk@>?3sf@4?X}!90c)bz1tl}k9jHgN}k_tZRmT$;(Ed7m48t88r zxRfICUO2_b?_V z`3!Xv=`kV{4nr+vx}fFWj*T}>z{dNh3WgxXNmIMRZAJR%^7mqsH}EfVVtiuc)3+`a z9Ab&mZ7M~WOWkrZ9=vR5&@PbvNWaFG5HH&V%^3^19agO2dV*4{5n*M%bly~?R{ViY zwh}+;v$0;3gHi?>ZCh1!(ojUXBbh{Brtwwnw@>(188%D`Xy>MP&0?hQ(Va3n=X@fp#ZtuBxS*143t!Rit^JfRVseut zy&D$HYaI}W^J;eaP7R^%eNwZDaje|HYAdcuO{O1(aJxg#Ws7x^m;n+TpW5yyT);6_ z9$JB&USpCT{GMSW@Vzof#7H+gPe)m7W(#h4I{8a) zUL99TNTBQ!?yXIkLvdUqU+QQ#mz0*1M0d*xrlc>w2<)0wX}$pb{(BO54v0D9CR$xNUlzu4@n&+ zesO&b8%If)T&GP-aCr$@Rpb^;%+SOY6N&|-AEkJ%6?AqJ`$_!g5DKD}_Sj`91vciT zNJam)ul!p*75VAKdifB`|Nhxlbzd~6tQ6ch*mbiks8k>%Gy>gpqZ~)EDXN7ju&R(e zW{OR02JT|i^xmMR+OA#bU@7#V5_Eww>+~tIy&!(u?HJG6ZW|0DRa#8`z(2}_*>3OA zwBOf5tb45%eIbKniLyDHw|uh3`#`|Pc#YPmAe1w$QK2ij zDHmPW7IGaIn{o=p@4<3(0t|C6Is-1Uod3{Q)n4?}6{GyHYBC98VHJj?f?v1cMizrB zxCjbBY#piTvIZ71lR|V$w}~bCgD)IQG)`2(APtqo=EF4{eS2QW*w@mh>vSxX%bm;y z#tqpIwoVT#V(^ge{aWb0bVt-NaX7dDhaaygH}1pQ5W`kt3+-YXiv*mp7%o}m?Pl$f zaLK~1z4hxFS#2{GnQT4KSw_OKd_5vxfnw#p>sHrMMXBL{-33FnA2>TbRcCU8 zRki<2Q72dZI1ci|y_(ySZXJShiL?%3sj^(Q+7KS;*wIqrGgIlc@Ys$FkBtTmjP8@k zxJ~ZqwWf4B42PVgjg@7PO$wfMq8hu9QlXeNg}6YQfx*CPuJ+b+DdqFiFR;BRo}@n; zMe!KfgzVQ{j0K8EUkPpT^~!9EqbU6!hEYIu%&PIIc^-v}tgr3x;d}Yot5#(TmkD5D z2J-G8i(~FF*l-+8mn`bXe_E;lWiAaRibBOvw=74%HdhS03`&7Q?%ZF%GA5~8sR{BWAvs1A2}nNofGY8B*}Qz!tUo57yBFRLa}2 zw(~{j3bRHqfO)L@VcL8B>x<|^=lZhK{h%gBSewhW%czjjoKiBUrv%~ z(hR#xYi=W3ri7W#;($eeTdQ>!#2ft80qF{`QWPx`{;H!pt!UsDtp;x2YQ;S_yd-Cx z^V45Wx|e$>x-HkM=o=_$8+8eOdO>04i@(4ApP%=Z4>U+-Npo#a=QD(;7+LaG_UUKn z8RM>Fn!+Bn@ASIesC#+c>0frP_ZHuxy99X-{{DUUyc3;YoqptXwdy|d18d5_OWBhh*IY=I-l;tscYqwXiOT}s2EYvf;z?cCB7U*-Sggl zJGy%R{$2OO-ajJ{rS%b!McL`bQK`Of#!zb~n=vVeLNjqu2p?Q+SWQ?gWleKYCoX>` z??^hL-KmZ|ALD+fch$e<`bM{M1_#u>{)$r+GZ1z!_JnOpdwz6;wK}xc(>Co!`)TY3!Tb z##;9~W70}GDd#Xtl??XyrUiRQFd$S1$`b3h&f6J-x!1ddm0>T-vya6^heXD(GyfYB5VfXv@(MP(ZNCC zg54v1Lv%Btw-W>D;N*H!Wd{+f@6_fVf?uJVu6O-i$B<`1GtX2_d$mggQQc6U9U}kFex9|wEMP{QCw$4f!5&oAr8-N z*QTYGU81-n4VSzVlEsb>DO?9$#na$>g7#XH?Zp4m17V)W^k&hOKB8SbazV4?B_NgP zemEOX5DzqKZk2hK_?JW9-F!iF4kD=0rd_@*0sf`lifW8BAsyEhq7#f6I~HpfUJzI1 z3^gcx;b0IUbUjx#qILWYA!|HqyI>-aPA~*b5dfIuD)<(CMSq4g5YZ{Nef0vjPAivv8{k|r`o z4Dxm11G;dEj9u#8t6XJgln`*4I6R(Wf8aXtUM&pAl;^rJ>>v7uT=^8`@a z=n~-GF)mR2=fe=fQJovQAv_~Tm1*ovQ7Jz}6#9i_&*#@&gNmrE8pze@)#ZEG zi0j9f(X4%d-bwUTNZgg&3NGP;KRP_6L}8HU-OEoZXe)7~L7JLdZOOpdJYLKf+#0S+ zl{Wg4)jA+L3ogb;eQ`NN!IULo8CZNmwI{32@fqEDT_4V{l)6l&><|7iXM6jl~cC69soP2w1pnC02Vov%%r51)o0+i~@IxkWf?`PXU9l_xJFk zvP29^lsKucR&o4wetX-Q;8L{NvJUV!0POJRjHMOG!|~|qTxPSFI-sLF!9SS?Tb z!88DT`^njt?%=BbH{@jRujq?CmevVYcIoyQWs@g(mP`mHlH(0RUCsV7AZ|jq3>K}* zxORRXK&tQx(FIcq4TJS?X6^_gkTuXkW_@4Z&oFieN75kc$KqTBSr0oH!PoUHEPVFU zm>lexN?^^3MFW7&Cud!R@tr=9Q3g&?gz5D=@4JvWu|H_9&dJ#soCz(bjndskC|h2j zn4Efn89Y>TQ0POoOlz&^#aL#l;FK@CVQH?AN*6$v*rkFjTc;uIWUj&b{ShMaXz{=S z&e#`caPompP}o~JH*dD}YcPoiOrD#D7i%&G$*17LvX;q1Y2Z6tD0zt^~2Zj(KT{%UevP~rr zHwvkaXLg`y27b|F9I>*9n5sy{o_#5s(RSM0NmWg1oj5wawnWiw!>XXNrP5be8(WXz zQZE{&=v=aB$4kALtn)<|@BjO(J2>52J>V6G>w83>dIPSnyB7>mU=Ir8HfC|EAXX|lqXlSm zf&eIwJ~(;biQa#{W0Alhx&X_6}^juPAZKi`jrfg6zZFCG?(j2yV`QtutWm zVP&g>`+-dubj~}c*LvkHJHK83a@BkHnRf+M+GzyroC{HEaPS6IOk5*P_zYub0E}2( zVYPnq##9>LypdAln>Q9ck<@_TC9?V1Wz>`f^u5f+Q!D&Vo}+(q+KE2HvqY%ZD;OEq z{u=y%6Vx^-M$_-i8Qkf~;CjzD1N$!p#vymz1sF=D#|QM5GkfFrOP@)Vcq|YgOJGO> zJS22U3fbom!vS*uWM`k{3WSP@5_>88q=_g9-I4rV(Bq~eU&^6YXzhZF*CbY}HG$Z~1kM%X*2k~DX8m5y-O*9t2Cmpb7L zHgnlCTDZKR!QTeg9c)ju!Zbe(>6CzQl#OS)*Y&&eJxo}bFi<<;5BcdutIgIYx9P4U zyHuo@tNs806XQNGS3C8i8f5IB5GWfRXgX2r(EJt@ks$pA*bh_^^OyRg6!fA_ zz{S}+f~lB>2m1JG{;(unY4MSNyFC4+e{~76*BQVCS?yq`wPxZHZZsUc3Or5*d%AxY z#d?_$fQkZ_88(&1eg?IG8BXdz9_sV>JVvv{xUAGL0J^Ir_{%HHs}gh=7iOntC3OF; zF3&I7vxBkN|9q~Zy`4UahFXe}dH`)m^C;?cs-hH?;~%^=7WxI5MYAbZ^|x5y(r?#8K2BQ{c4t{-O3j^X$bTt!NVFqr z(KNc?V>4)Yrr5Q*wBebE90*K~VE&SSAjbk^!#(A#{ZvvzID6|AAx(?3`E;1f1`oHl z$@iYSDP@rud<84&K{IRR11fM_0vH7_1p23F5U()-W0b65P4Qs(J3!eK1#oqz+Z#D$ z1%O?sUyD(n4PzdH~ITU;qaisw{8AUMQoL(bbTJbH1O&gp=DR zRbicfqVdFF1_Zv;N<$3{q4lZ?u!uV6q;rhjo-YB_kkORd^+6$^aT~{D_;^nYs3YT%+6odSyc-**WZ$A1h!l<#wa$YLzi-8@5qLqdmV*>*mvpx`Id zhiMU=&)&Bp+Whext)RC+U{H0V2nycz`t#*w=bV?Id-X*sWLS<=-2x@ej?_QMgu@%A zxoA{ElQ`iumIQe!ol}%&kv6?ca5y20sE98@R52TSdX9RN zELbsY<_|?^KcQYUTT#?Fo=>@&Mz5Z$J!lgN6OLBC;rB?7->}z;nK$h=!fRq8nhw{LRZVM{M$WzIIYDnX2{SgLk8Ei| zo#FWMalBaHBZYq6W+sk*>(x}iCa0~Z_0N|>_4#yIs^XLi`W?a`je&0KI7BI-a9PbO z(n6$ndJ!ATsNm-y`U0D3y1R5V@=SR`mc*r7S)Rp3BF2c8$=&^$S~&|Wv#)-$mSPMQ zWT+vbuo$!M6q#=mjJXAzO(;Q~egzoS-`*jbG96Kpxzowds@HTmM^&wuwU2AZ_P!(T z=h3Z%D^pjX(1KJXq5ANU*&Op-v}YJAUy(*XmUx1qjlf$uI4~6;fiP|Job^yRXv>`frZ)IbNV4H{FwoS!iF^ttXUv6r|% zEu!x4Ldb(GQ1&3nIW~W*j&+IyEzM3`^hsU9ag0WeX*^pOU(RQ-914ydEA5qvK!Q$1 z3M*z(1@neYSf)&uUjt`28-uCyCtbjBEcz<~ok3KXr>SA|&zXlykkq#<_kyniePE*J zk`%cWf8tj{JJL>;!CZg^0j%p7uVcipfe(g>D7UB}i<|aJME~7t|Fl0wFoUKXuNJ^?5B2FU~PYVk>h2g&( z!kORtS0i^^caWLMc>n~B^n^rgNR~t(3Ts#^f*zCT{md=|DKgfdock5?o?*rI;tL+7_%MQMf&4O3o*hNk5!LPpL)9(`Zon$J4DkseK8 z7KxEXl|NB1NdioEfz1+9(E@LDGEgPAtIq>daeJa=m1bgTw#)W7Xog*;9bSG#2_;;f zQ-W+7rArs*hP zFtz9R*1^Mgal{ijK!jhfwz?mwl{6~X=`X;lv7D+BQWZgU{{9uFLrF|f(J)Z4ja6Z< zsLcmzMk@??oa`;vL$%EW!mvQd;1_0>y1rKArQp zWwCp~THUd-F5rt$+X%r#sAHw|^D!y z9Ga>??W2?<1(C>_>xW4XPPQ3~*1n{kV_-;#)(sJN`0YbC3E@($PXP1^-SJS}J)xOTa+jkkRjjJN#^9Uow?{-Yw9XN?>D@LtbD1ExJ6p zP?~)B3y>7gdq-fqynlam0PVcxDjs|}efNceE}EvmnWt**Fz}wK#!v$5Df6X8>@5)s z^dfwuQ8RBP;PmcwJpQOL5Xn9fin$`L~P z!B+1y1lR0j#m1uJU7wBhOvjSc2bFFV9VTul0n40uEvf!G-o$V=O_T$T!UFicpHJfM zY#e`2o0|+Wf*=~9mL4~fie1gxKHG&Qg5B~aLd8G1{ec4o>CPKqXUXkbndiVEO<8(# zc;WbCZ0O3IEec%48_$x*(dwHlqQ#LmqfC~crY(JD={1|zshoSOjz)fQDpO@~NQm7e zyeA==&6f%sAx;KDzW5H)-8ELulT+L}=dK`uPH{~AG&n5eAJdBHE3p{651obA)A^YiFeQboRY)Gq?t zftM5Vu*w(l`>d?MW)vWh(!^kwx+zmtSG;8Lo~4P>lk)J*K<20FbG#vv77q!YFEfWF z5M#;g2O1y@W#loWky%Y9OSwj#5U+J>s0I{D2xbUr9g7H-<;mZu>?r(F4EF|9gvLA+ z#nG%Icgb2zlkDTwxy6jwa$48q#z1yID>UDF8R=40@BI2; zj7QRQb-Cc_Ze)L+B?7gCOk8a91nG8k{7YdigKO9EWVl#iv@{^BUywYBEDAXW5{=f{ z9g6?jYGLyD6r#!hh_Ao&9fh(ctc%8)nOjdE7`Q&$FkPsJzhkpM65ygshVlh+#XwJj z!7HbjACFyUsFK8iSfNr#K%8#|3=5Y(bXa6|supA26yT~gP7941aX!KrItN1(G@sNQS zrM97MiBR&&Sztw#+uASj%(+hV?xqM0QexE?jquA>1Xi^x;fI5c* zB8bzwj|w4)QOV#GP*+}(K5uW-f!Z3q>jC4nd?%mfzVS7op#)gC%MYOL_hcdOmJyp* z6+-Fe0}B7PF>27qP#MBxZFM8LvXAzl3yJPI6)&UaCNhJhcT5YNk`Sc*-($%(ZVSQN zNrZHAdV2Nw@|tHHz?L3yfn;XwCKY%LTl!NDjZdxrS-WUl+&E9<)LsH1DLHnc_ zwQN}9bU|>0ZT}rLT9sVuLnVz5x62se%NSz2qH<8+v-)CgFem)2|Q9*+c`Yq zs}niBO-WEnM9Uqe_P9qXB+&=m24;`PW`xDEf8|#0%dKQLi!k(h{-JvY?%EQHStO2J zk;caG>fc*!8gRpRI9R9xNsH?oI2`4%D;yJLeCO0~C6%ZybZPs8xd=Bu#pYz%j3F6t z%G?Tf0#D`62&Rv6mer+d+^O>hs9@rMx}>fe0*;bzd(j`v1K6sgc;c^JKuOWp7F)-Fc zr}JWML7jZdSg&enIGX<>%-Sew)M_2zAx}vZ`D)hr4ut?+n^vQFen8B6}5wLQkieB-@WR0QHMoOeCO;l>LZxk##XxIiqqY9dZ`kH z&ZCbC*^=p_B6yP!M#49{x7YXaGNv51&T-r$&{SQ8^u2cThSrgi^SOAKtdlc@2o%Ea z_+* zEL#vH8P{1h=}5;F#`ogH`g+oXrlopJ1Yk>T(QXgDvgBeI$p_mhid%sUgq)6`vW{?d z4>b@>C`{%8$Q9O-QF?=n#FA!6{Gb1_>MmR-P0{{Lw@<*B+pEeZ-&eXbX1UI3VBm4g zjhCGaL-b&XE$2mmOXX!UhK%pp_23%$k z5j7J)%~!B2s^|fgS#%5E(&!E7oU6er@)pW$y1v1178a8XsK(BqbQowG1h>TaPFvmn z2~eC*Bm5s^KCeCPh|d$)q|)`k{cQ`Q=XMD1gF}$46D}js#Aw_%HE*!@p`HHYe)^9G zvRlo%0gptKdoDYFe^}SJ7z55bN8%vnfmfmHb&FI zRk|AF3_s=4B@vONbcsZBh=6b!1I7^g=_>wnkAaO-AX&=3!tNL@2vHzPvG~Z|BaKrK z2Ia|Hnn2QD$8ACgLiD`Pmn$e%6Ur@H{Zs{GR+`5(d4CpNe7LyY>-76j-yE)x9SI&p z(W~fa+f3VaEml%OlUM^rQ|IOEY15&-Wp_MFJYo8nGeN*pUNRRZAv24K1Z)R8|NXi9 zCE_}WgkAZQ>m|iXTSMxHy+0?6LHge+X!Y;1+tY=jE-u0Zd9zP25D*fW^p0vESh!T` zh6pUmnKW3sfU`~2&cg^rHKV-gsR$Tqtx|e9K=CFdyI-vIl5tBOad=xImoh&2NZgi_ zFTGztMeUt@pt0xtG0$>xbzEomIW1Xp4;982SrQaZ^|L&yiWO!J(`nBNAad4?GBo4neU?cC^*H^ZFhQ zwvW`Hglj@WP8P#)OaBM*dv{yWf2;5sHSb)W@$5p@sMt)~e( zi#6@mnWeBRC~MGMMvNf2#vrHe71RN9^7cS$tt1DmDMr~~YAsqLLF%|XIUnqCDT*70{5x1j)Gr$a=u zgadI$LGESINY2?hKz+lq$;0s@^#zw{NXn%&`Qx~ZWx5)Ix?2A81e1`7&BRqao_;K3 zPtyIlz^p17s>@4NvXHu6NGqb27HWaXNQx%rFgCt|Zot?3=^# zWHpG_)WLSmX9KOcCzvk)nES^7bW`M%=&+EN-x^5EZydVAmutw8ChPlp8;4H*;t|%f zRg6micm>6m#gKhD&-LX0($X(BnL$8SQSnrT)U8A8joa~~hS)w&m};wIS!(7L#BU0Q zU&@i%zkw3`@(0rC;c|3OiQI^?I5=Lu8zi2C8X7FyXUzUZsS$)GIU<4FMN8=bjL;J> zL9~uBp3EBsy1Hg+nwDy=vhgTtod5l~^O;%4*<+<}jJOQ;1@6hq#iq1 z$A987?^LFcOocY{*r%bo%h3!?5@f=jCuK`;K+ucwFuQvILKI^jBy8A{ zQsH_N8HgGOiM+GZcTyF*yt;fR>R`CRj#5~VG9pjwG*405r1$D6m(7X<;AA^ov(&_{ z{g=A3UbSz)=u|!5MZv}!qJa!?$}qF7WjDMB$I4(_1E%wg6B@b}0ahB0&0vDklRrOY z22LL8gqT-F%3zey>jPjfs~Ur7l@+(Fnd!V3$1UJkIFG+tgMuc;&6DcexsT+1yibku zU0@>c?KUlE%IR1J&_CZPky;`W3%02qVJmGvNgeR#f0LemHC?BnTIQo3v1d4WvIB+r z0VW{ecOQ`kV_}pax8=#1hz-9Y9GTCTG-#fl zD{z~Et`6)R8ay4qZh%lE4n%UxKUNr|f)60)qrT2G>JhT91R0UIQt45?sX(d6l=z$+ zq(m+*9T12AQw-A3LO~?B4^H|(qCZL{dslrxs;TX-o^LRZfFQ7l=Ty2wwtjk{oL_K> zUt_NJJ&=LXR|?292go|}%_rJApmcu;R~DiXI*CSK=^g1zd91Aom~aeC4Wq1-7c(7A zBgI8$FhEHbb=kpysLmo;X!L(x{QJNC$KPADQI>=wf45KFE7+iJ@5>RE5l8HPF7g3j z^C!a|%64xF5%!yH#tCN)uqwm7OGDPUSs zUr=m)w>zP_!HauCW^>?e^KT+aD%O*F&&`zUvk!eWbF}*=VYsj$%QJO1Zws~u!NHCx#;(Xn(SY-J-ODrCl_HN$q{Q%)I=BQG z)LH3T(}niLmy~;muN0#@pRLv}HsjcveuC7-{uAM<{G0{@=*tMqj?I9`XE_zs8na1b znxrY#oSDF+8E03iV80K8P9=LBgwIeGiIgM*;AlP?y?2mj5H~32BOk`WMOc?DIitQ6 zwXPI{)0i(P1PbJt$em6|iUtoPao&07!^!F2c-#`*c7#CJmjg7N(oYEWR~RWe{3dHt zs+7kuy+_=EObcc;Im7(iqAte^9DSi?a|K~7wRWF-93zsqDb0wtxv(0K8f4i?gfZxy z{Ceq(3_v=@y8gC2s@jqJ#rvoFgoC=aDC?* zF}MpwA)=8^OAvIzE;wp3x??dKDq%?OGEuB^6&?AuN6{D9=|78M#q~o-u|y4v%o9T~ zS&OBnE7}8w-K4-$waUoZt9ndEk2kc0bo2|{s!0=VCi)q0YL2gbG#dYy4dV6Q z6p}_fTX}DoXrzJAxemnQ#7O>vit!oMm``EbqX7oTc9j1wQ$8t>!Qq#EA|D|KlnqNZ zf#D1KG71!=16}D%Mu2wNO7a{2;2da?_jXu*UrVcPXH{kpUh4GflIRrp3|#XqL3ec| zvj=%A*GuILl0^U@3yBPzT~>*}@o2XX)Ojpy`mq@Z)UUuY7eEW-ZP#5|7q{VJH%#Vn0b#{$V#q`aLlCe*G}f<_n@vqn!n?C>8&iH zaR^&m}3j)!KV5WLW8sd#|GfkaR4*eNAPcuAzbyO<-S z+Lg?&90Y%#IX{At5ZFmB1lMizs`7bORf%VvZUqTQRX^~>&nPv}$Q9kK_gq;#OeOXE zD_LD-=M4ZsGMGx#8UX-2i7mKNx65#;$>F_`gV!6j`xketGlFXA{ui^KsTb+7>M*DY z=sM6O5^curlv-yJGDbFgI_>|hcg@Mu=?P>Ux|i>-fJdTL4Co%a@8^lpNVqxGgq`=a zM4$@P(ezA73v;P;#Q%XeLliq*Fro)J$d?fU6x&Ncr7R?Bq219f)t)H@sU4yK_%+dw z7w6dAf~F+OFGGXt$s_L6ut~6~Wk0qopVB;7({D0`;El3aK5c0-1_$wW1QgInExZ^*^q`1}9t=vI?aq z$fv;1gs23eqQG-WqEt5q1>g*>M^G5OjHzuJupOZXqKR!!loV}sk9tbwL|qPUn<7mV zJ!^$9TX9TH>@GA3gCY@RuD~}u?+(DbR*X7Wo))@|v?ha$fzcFZQZN7s;3d#WBFztH zKce}qWO%O>{}=?bBDm!b1D3)4!3#S*W1C9FRgDi|Z@SOM5Wao;f_+=)b7a*6)W?jV zvbYr^=;lclQaTvVVntGOi7pB9zaP%f^Fpz~bUq_HnLC1M>qzJk6JG3*3|)rTAR6f6 zoVgG}#vC1c-dl(s- z*Z>tN;1??##qdT`PNkD4L>;(AreBnNe<>{!rj@||#j`tf9goTJ)2T>pw?)#A&yw3) z;#>7U9TU>JTErt2T;$+)T{@t*fe$vkfSD#`{Pe;mdGroN2vDvsvF5QfHg=qn-@si1gd zPfZ{a;Yx^N){{#L#~)6_Zzv}QbWjb6cNT+*0z0ky7#k!!jlIU_AJpiS= zBOEUmO{g|`E$^vxR509E>8Riov;Nyb#E2)lWPk5aiy1l@M#&0oFLKSoH%OSm5NM$x zFKnl9$^t*`rq%=SaZk>=(3tM@fzRwc%>I0suQ6rO;~`MOC zuF>P(ayYxAv5uXi@{{#v_8b9Dc+q;Askzg{fJc;xejUMLiMl0xyatY!pn#NO=zU4mX zzyaui-@}VZZCRt758OU_`!Hj5ZOPr?+Tg`;*@Y#he^lZf?^QA%d)E2VJ?-$y(C@#4 zO+W9w!-NFP7RLWErQH2vRR@2bLr+dnfxCvuVxGkMI#2^WlK2$qi=A+^#?lmjvAjRM zXk#6tTVxavf-v(du`tj|QIiVshtI6xqWezaGcbqhj|W^i)hIskRJC$-7gg56deeL= zt-E2~sk<>1=Q3$`_Ab6llo|JdPl_LI`VqqUP(qj73s>NB5VcfQ>Fl|YueoIAC}Nb5F;qp5UrSKo{Xvcot^xaTBbUhjZp(ikMV#C<}p|;ZqnG zQmT6oI~68p@F%wRAI6Ig6@&+%y{~GU0N76JU!KsAw#j=tD4he)X#lSH=9rAL)t8c9Cg9yoC8U>SF7lZhbB&CoWSp&`E=-*ApI&&#HYtP&Q0CP=Ax0kDr%f-}Emr!Zz zbuQ1Sr5F`R41EB{ws`dWU(xVt)<(6Wqc91O2rBf?uqkC*UQ7KA^L2blRY!GPP*5)| z4*jclpV1#r5f-&Okfa{Y*7gNQmIlPve0h}y3V@nTBI1ZcKXJ{LEkv(yyT&o9Wd$8H z1G_Wx8RAuZDC8~#&tsinK+QxpvTpLl8_X`b3B;>hM=q3z#{HB)=XzmNC`1;B$1hfQ zXVlY`qua~pK8w@D$`TX6!By0(y(`Z29i~W^GG}xpc=IcuD_UhfV7HJ-lX4A%$@pl0 zDTb_-UgLDJ`H-heD;$jRY;^7tgEx|KCWL%BEu3Dpg7!;~TEQzbYqLauUb^H>Pn?0i&xYU216A*PFNvuap%4SuqEACEOa--4M>f zhVV2Gsx%5@?A9BTJw2vd+4?%H8<)V=XZffIDJ*?p7KA?LrZu#9_+lo8pfP|G2&cqW zb5s@WfEAIc1#E%OhPvbsLLhjzK@XH+>b8S069oiMV#^C@Oedf*$uJHM-vg(C^HxQ1nAnH&146={?CCN6dVGpib*Px3u61vmXl zIDlmvXbbq1y5sZJ&!d4apf_Ff1F5Lk^s}0$wQup)H0*ok1&Y}fl9W+?Yq>M&LOCd^ zW9II2pr5ORX!zD%4Y8hqzAUoRs2lV>^~eM@o|dH=Um0nqXSr*p?DR^Z*Ju>bpb!RA za|79M$#owd2V5)dQZw4{6`Dr-@Bg85FBVfker4#FYW7l~kib^%nO4fMKVbOpF#!UA zIudg36;b}IFhArx$P@{3Cu}>IoBXjon*gthmFGoD6dp}RK)$|C{C_71;}ikwo3vPOwlDN;fggYa=S#YTqVHkP9Fj zPrdh~r{CdTPTiTm@BaIHQ2L_wOCJ#kmCMJ@0SUA7uOAa{`OgQcVo?BrNz{0Jnwyx+ zZs#29pt12+$k==VMkg>c^iND1Q;vOXfoA1q1&G=se4Vd4LnzyXywk1@dCSfQ+wMkj ztvWSZ>|HdaIgh5}iQntR-w%N!5NZc0XhQAEm;!r0i3|xr4+cl%H=o700jw14ii-TW zACB_CGd>mc4WWXktAz008(`3b+hH=1+l?PigD@`ZKpoN3U%KaK{SGFL{N6f}+e`d> z(L=3&g`ca=N+OqOJWookK;N=TT%`a#=d$iXok@Tx_UCq|glOs5;z%Zi{6;7$%lJHB z0ALudkkb8%E;`Hw(LqdM-Od4!QG`}49Wv^AY&$!mR+rn)K;q7IeHb-f=o+9SRpda$ z7F%jXln9)n1@t55wU=NZH$RDU*+HUH3ypWnQ3MzsAbqjvs( z_TB|Zvg|Am%&N++uI_ngBq3yhfUy`r5*kfs^?PD8L3MZbOlkU2Q`J3s@VI1UW_70~ zD>Idkeh5(TvH^jGERYSxOAn7&99kfjM>q@-2JDS64jUqX1+y|2gO0yf-WBX5M>qA`td;-JADu?m7SYAK(8X(`yc$cD$}j4rvdgz{$0jP<8bZ znxj(Fn;VdBVy9QHZfre&eOmz8j5QjgLQk?SP{_~VAt!>16rbB4)rXo*`)(Aua7iMp zeM~FiC^YC0@gxEUIo9Y`iuIAHDDTuHCgYphxc0t_=-nfNAujBYgg#q2&>dXy4-TWJ zZVQLqH9#+{bwJ5ksqz+FsURw+1O_ODgDC9(M5_~sOMfWMB*P*9hZ!!#HSe{%=&#th zl~tPjPC(7322_oSmH^9{sm>g2tyqkHLe8rFE~48S)FXh}LngYC;BgTqu=(81jTd&_ z&j&A^2{x~6okWA<%a;*}t(1J}()N{&3suxziWNkzRw1kR&jTaupzO5ioN3I6L>J|- z%0+1mk_Ekl-ipGIu4t#$qw~D9z)N>f=^Op1C`WKu+wYN=yg#Dw&*1KD=;joOixr0m z>h@?m)!Lh>%C5i;7@lu-YKX@J58r%mg=_)_MTk4K==2@hYNs2`dhI?%K8pE3!G_p2 zF6DaX0#3+p*ExI@o?sM1_XQ-|3lJ{T2f7g48uIo*x2|#qOYr`gBPD@xNUp@~m(L)m z0>R$Zdz0xYLLTJS3vY}Bu4+?8Gy;-@J0++-!!s=vd8hXhsc=q48G%Gb3;iC19_mBq zJPcJfc2IbxKCB=v;E))jj%(t_S}1cGoYcXzPP@rwP-FTM%k`+DE6Go!;$C|`KqX(V z-QE<7M$p;gU%9TXZTto8iGyw6$o2YaWGWsIxPqNCUMj?>Jm4RcHXtq*%0oo@_<6{# zyJ$pwzYd;A-0=#RxkYuTc6ZPmF!z&M`o%=7dNJ?OTt(RFs6WkXndz*;I7*yVj6o_! z_&j)6)$Al^wgF=7_6E?NLNSCu8SL7G@@P$AT0{>>>^<~BzzKp zT4cpc-H1}9gH!$|qnE~eA1SpXXZvz+-&Ij225+%#jbE5Cp@Cr6Ue9!X z$nN=?{{XzgtIsn{{wtS=n6lmw==yA@dzTastKk@x<)ted1e1`m8K>}@6jazXH@Y{e zB6)%{mZHN_J7Y=l5d&KLw^@rK=(X;2hf@~dXA4?Wb4^%Rm_eOWvZ=N}G-Fx8#M9Vrg~Q8Y*#suz%b zvSUC7pJn|>awci)o|v(P3qLpg~NkY0oL?ws{m8Itjm`M5;(lIaq)%f z4V$TXy0Q*NP25egQIV%2lrhOlp{RB?u1q!r2dnq?D4-+kC*dw_VF|75U>YZXVkofODA8~USJ7yMmbIZIZdUtEsCy3y*l`G;ZntSk1A*Qd6#$I zca3wh)CCaF`>C&<7brswA<4cnfh5iebKb@oq=FvkV<}t8%P$W`FhYfXV)&_crw6}v z(mXc5KxLkd4b|PDLSM?+Aq=XVgsrtIiT}uS>@;{{FjR_$FqPIxPK*WY=)+L* zv;n3wAiYhvv?sI=7{ozYsciEAKXFXbb)#W_A%DFWNAZg1cbq)WwSP*lz<%p|xa_ka|@N%Ta}0n!_9ZMMln zDbs*iJ0Ga45jr2Kwv6lG2Zw|qBbB=in=q4F#YLHDMI_#Hj^urm};BQqB#GBtE%=Vwk3@VL+VW{{R3ho4( z=~OYe8{?u3)uN~bn|=n3iK4!C9gV}pP1*b)NySMr9m>1^ZIdtNKq=R~x{#HGwL7&3 ziIS1Jqy7f=b*W)|%hsD`lEP*0FbkJ<5^tv%_Heq7ENr$ZnxVOx^UtL62{63vOuge!oU|Ks&L+gDpOR} zjM##NvsnwAop`XpFNh5eXifHf97Nix(r%9nDhyW_qd+($#!-b2)2o<1!a@JY?2H5d zs%M}k;kW7*s>$xV=Drt3d)(jmE(*^#JL~U3`FWyg0-!n1WOI|YTS%6eig>2VJI1n) zaK`o!eibTa3ZFc03c7oH<2?Z-Lst(198LjnXmpb>2Yg_BJ|jD!XIF6!<*2kdl+HEF zvI%0igG6u$EGgm_&E1|uw)~l(en7`nvY`v%3haY7JOM?kvD2?1dH_Ju1{Y=IfXAe= z)x;J^F57{7#m26N3s>7q(kasEid0GHkpb(;V-yEc;2X?FN#=ho>pqHA&1ms5H4>(b zp~AwMPw`3I_8ZKAu+L9L*qP2vv}-aK2&3I(HPAE)G38{083S=ev`0iU-1lsgJogjb z3ZZTa%|H%{)V7TZLr2xllo0kGipwAg6mnOhN_*1L~|kZQgY6L8{2AaLb?e~5cU|sW^1CIt#7gWWq~%YJzs^K zr{_cy=PM^e^?c%twgb}VDNhOyhH+Mi<`B~EQH+_@{%TShIUIs!unE)Y3b=$2Wnr$b zZeD9d%&STdAe;@`W#@f6H>wDz1}b%71D3%y*WuwvC5ouLa%BV2-Lg&M!gaV=4|#;y zD=h2?Prdr0RLznC&)@;ZpOHq#CjF550!?fdIir)m*G5{ThO=KJ2u?mZfs`502HtXk zAQ}K7bn*1=3e4jUitJN7Zvb7Eyb^?D*}Rf*CrKuf)OlPGWh$RLqcP#1cpfeW|ozVV~CHoXW-l@U;4#o7c&~s)Pb-mi9Lgo5X0&Si#;YZ|> z=W3adcelHea^V$Zk5}1LqRL8QBcp-K&c%%@RTnUs@LD(ut#iK*PtReCdeV539({6f z8yVFvqrEr`K@OjIf8~5kiif(z5}tF~rV$h(*`U`^-Fe<0a~>aLK^_^B}|t zohm(Wn2}-F*%CVLu`m<#jDJEwa721&A~Lef(M(*cL{qh+cLQ4GKz6dd z$CGNO)gm}$fdXI71(&1$Gr>2ft&|NSk zQ_X~TAh<*Vm2ludovNlGqPkN>2@pg+hx^A+T=_d5KdldPnh#h1^i-dygF=hAoUk=T zE+aomR2ak_x`sl+B$E9%vzaO3ES8MlV${P-c`}PYueUDfvEqq;a<0dC$|xKh>1?XY z%S|Xw6x?k!hPOBOt1STv3X+I4b(-Re^ZDNqEbXk6X6NO3BNKihsG+{bdOzF*qu z*LTp!1-Zi%blAI#?B!DLE)=1`;I6hvn^-H#C5dpQ8VYp!aLA)yLdO_Z#-au0L&00n zv9FtCWv-W%%1LTd_|;l-zJDWauI#TP;E+?qN#Aq92&N<61XbO5AU#bIBr>6(e}Q5f z(KhvK9P`SVC|8?^RX&BkRgA&-@ygbu8WewPZKqYXs2hitXBM{U+_*|fPkB(C5e;Cwa2 zW>SM0la2?;_Cl$SbUUHK!}b8j?AhHYiV3k6pg0Z0xu8TEI*L7a<@$w*5KUUGl^Te>u8UO9hl5zsijg}KE`AuN}ro9Cek*7LEI;WA@^#xppp`d z#pOzjSV~d?QicK9kevA}(J2M0BPxcPAn>;K$p0{SIpjg3JaJZeOrsGwc$V?foo%R6 z*EUPT{oWQxQwU1eFIg3cq)w4`=;GU$Ka>={z%)?TAVJwRb@Oelm@ zv+CYH$2OD32lC&>3$O*CrE>-(ViP$D(yuTxvzHx+CW`YoJ@JsW0S@c0&BVVfE10}; zv+W{M6lUh9*TQ@-0LaH8#rsSLN=0A~g6_5c=2>l=!j(Vsw)o#7qqykd_ zj@BzU%juvji?tNhCO8ejN>roDOI4@hRs0iNOmN+xjkgxLCDugNGWP&LsWk0@EqV~f z%=M{^GxIP3d4QQVxLz0jgJNDcHq^m%s@LcYDrXrgYBs2UXNy$+?&b%OM^powoE*54 zz-p^o`{W$L1e3Rw*zQ)H+JUlFK-pTzRNHIUZVi}`T)lqn`i<+?(0UzBzAljMaleX=NoDQqgT5DLIG*l@#D)||B>8}XY7_BE^_yd|bi5YpF}Mbh0)|2O8)DN4b0 zFc=<^RJ&%vtJSZV`2L9l2ce?pUmxlNl3@aDJ4Ue;1wjFDZW|%94_HHs&KdD?t@_>@ z&tKoVaFeSv@C0eaiPNAEuB71gK^8e47jPqjSEvCg_NV~?$Og|LxuQc)~i>E){)Y2?K$Jx3Y$k#WsB#2 zW>r$4Cu=vC`sgiw7nv-^1DP1l3&n^S_~Tzmkc^?F?dvyh zm=DBk+cB{2idj^;QYG#{TC#W=WA_xSl8oL1G(;{L&-cYEF9bJ;w**MqF$uC*!+a1K zZ~zG3(f*ELA4YABB)Xmf)lHM=3X*`d&lHKSoM5rU*`wrxCUQTZ#R4Kr;Kq_`8~nY{ z@zFt!C;#To^N=JQoJ4ABt6?JzjlOvG(gn+#lr@FiT9&gqpb0}nkla=s8vU+woMKI* zROZ}0tYT_SiUTZ;kPDD1wKzB6bP<*#s(p{Ls&_FffD#h{UL^gLeL$cx~+&@rld@4)U>CsoI~lYL38J& zix(iDN6jlpl1-=Gpoxa6C#0~!Eet&`%*B0+OISHYJ|UG2q;Rp;-|cpuhY*$$b+o-^ z4MIUKwhh=ryxaLmuNJe>*=9r%mkor?jXt$IcryU zRMX6wXH`bM9tue9cCqnv$+PE_6^2D5uUg+qb_GyL@FvE=DNvf0xR8BK*~P2}CTTQ~ zh*TTP?~`GjU|2>D@4m8i22Azxa3=Qk>)PJ4fFi=5ErR>K$k z{o$1?8Vl+^;Y^`81rt>a45$M@r)!*bF~uEi59%1zHdFqiHRdJ;tDy41bqxx2TM1GW z+Ng>vWjJQyi0M$lNMw0ll?6nq@K6f$S2Y$9>xT+3mjXhL;CWs5k-3(Ic1&9%SG0(T zHJ3@j=V>S`EVFB{3xeA)x?vroKulb)4aKi&?K3gmK#axgD}?n0CS{wU4W|5jzzxq` z2S@;meC_?!?d!s1lE{SmV2_7&5^~}DB5ZBSLsq4P{DXDRV?oXGD_ckdA$~#GAdq*r z`sBeE&N2Nu(}*dN(&(Q~pWu3ardt02y8|jI?FHe$AQkrzQo79YDa2{^!Lt-=z;;@v zu^;T!_FHXo|6otJyJ-l1zmMCs_MTh=(81a`#?DF^Hb61{QfJfl$O?S{jX^XEznPN2 zv{F@>#ym-U!zDtK+o)~fACQq2G`wm)C5rKj8Hq;JBrX`whe6+Tmb=3vrW=Yfobj$3M6@1m-mMZTrpoZbN1dFDC$7aSxrV89`br{`8uqh z?VFQx9AKN^CGk)buTCU$MD6QqRaA@P3&I6hO;dG_aZZZhiu(T7t5AqBlT@j)4V*$f zEaOoF;n*(-;dslHQraNIC;}-!Op;ltLKrsY7vCnS_|dKGrAl!o+y_v8!+KG$D(8LK zL{{;Bx3ifnq1gOonk?i?!P2EI77JAC<-&&In(dda2A8jFJV$!@&UAghDEir8cOY_# z%c54SBzLX^8{5y>q@x2Y>T_l&P3Xz+;g$9S3Bh{*Ihg!6y3cK1N@tD9_Ag|r!R<}u zP=fp!*>n)%or5vN_!5p5Nb#yA46CORF4yF249vXj^(qzMubjJ9qQZRFM*F+XepIV7 z!4uFEqGIVFFz>K&0Se?M@L^SiJ-8gRHz8Jy>-nnPdg&&%@AWOHvG{moyG0woqtdsd z!-Nr>=LR1vTl{BhmGINs&0EcTnEP3%5b90XFK)Ao0DNgT6rcd+yC~UDTDcq!Wj)wG zCYxfKRAA#m1QZKZjR+~u&JrNsYdj6?#A`gggTPb>%>*!)Fp|?02?kdgf`LMjn5?fP zk($YwG!m5CI!=)ErT}rLi73O}ZXaeRCgH5<(>cqc+Rr*CL&v8hZoy1IVz>bpF_%mC zFtg(7+Ib&f|La?)9BZ6Ujf zs^YQihxnQ*MZJQGCG;(k^mC^JP=o;G8x1sa@T69m3%KC~$5ybT>%3kH^nGs+dLg=; zd7XGrA>|C9p%cOSS-77Y-Tk0euOk$gQV%HP9lo<+?H0pnFHpN$HS0IQ0~wcAlOVA= zcrqy_t`_nlp%t=l+XS()PvKzay3G*W>{L4%ntaBJ+{`PZML=rQMT0@jrj{a#SkdI5 zaj&|eo#a$=r!$4Ojd@hU@!eIwpu`Cjlt}YFf&u*Qb0GU0n^&P$P$f6)`+l8`MyRp} z^xo`9cB9r#SGpanpRlxDYqY`9`~6n4e@;&ddWXr3@PFAPna%(#qQsAf+6nE#wDzi;qUiaX*QnJGRTob= z9VqN+9)PZcMjcLe>HAKSm_V#eo0kI35!WUJVo^{6l|Ld`Os@CP-v5VUyn=1e+l^T5N4S2Q6q4W{*zs z0F&Wtq1D-KA-oA?ZMdJRjVadE0S(3QEaN|{8f%$W0HC_G>FW1u_l-eLNIXcN%Br#p2JbFm)Q5@yQ)1%;&8S*sgeBgnX*=EKJu%qCXvcv zr0etotXGPP<8AKs_(D`8E(vwLpg_k;By8d=1uHN;N>o6_<~5PH@xeQYXs-`1q;Vgw z#7V?D58yti^*2GKRbVH^X0IZmnv$QW)xvoa8m9%YFlhuV^@6LL@RE>o=~f5P$jBH* zwBD;y%_Ztda=V;x4&zOKM&sa6RH#mZ)h1vWkaHDknGs6ugwc$tM-S?%IBO9Yau1M8 zeJEb55u2#Z#^Y2^28$5W16?{69wP3X91fSzbe$A~3-^c3!R3B;ANh50CK~g0diUF- zt$>|o{dNJF!PyGgEa%{l_JSg#=u`uN{EWe&N8E*-;NtVui!W?l-@GQM^>#J5bW@N& zG?_+hpa7I4>Ww<#$Hdrhxq7Sm!4dl5acrLUQPCyfbP2xc&EKb)EiAcex zEK;%D&S>BW7C+=S5y>7_v8~C)*t;K?LUSN8ihALi+@W^$p~NcmP=5MpuZJ?J?!+i~ ziu^31DI ziJx%=opOMhC5S6DsG{O)4|q06|cSqC3Odm zCQ3r?bXj;|=Y)$k3N0Kq?t{|{5SDnW-yQYj5t*`h;jR{d!5)Mq_uRH09wq!Q(^2>d zro;!hoYi_D1=n2F>Ip2)VmPEON^A-e&`P^#LeRgDWJgfxZPs`~^&m(`)h1wD+t(rB z_2srxn7kdQ**nBeR~EeSfhtz#NTsl_`yt|wI}d-{Ir7KZfo@(Dzh=h5KWf!c_YF(~ z00)OD)g zkAL6s_?>R6A#v6qLrwbp3>Y&zk@FW2Ux|TRU-I)_k)1_pztvppJi`<9I#jl~99>YT>TY*s0TTKKz zz+r(<2OxPdF5?LSlJt{(#(2O46h2WQi_&D10}74R$1$ikE?kl2u*z1RI2Oc<~s%O&-WOCkWNSp5^u!>5S43LjYwi{ECgSY!N1gnxIrf47AK+T3aa+dhffpkGms-1Yu6f`_0|^Zf9)V>tKHm! z8AV7V)#Fb#dF@gao0Ozq zvbSiqRV0NL))9y{)~qA0%6|AzjoJ_f5v_H@S*FHd)FLm3ta#%Th&aVyvPL0O$hst^ ztq>`7nt;~6_?8^*E42tib`--_VZg}LZSrEtG(~~69Vm`~o7%yLn*DC5>Z?Kk2%pr{ zImw!e4!~tWynh{aTRNo83@N>PhvQuthDN>CG~Ax}9yIt@#Nd8MxByl>M0eiN%OG>sIH{l(kyPE|1eCPi#U`|N(fsAs(?MHWSc02O+#;d zMWWlu$}p%7uI98?EM+Kgv1iE*iMD|ShI^LKXK zl9R(PlP2P7_p#!HT5E*KwmO$D31yHLfAPx3&Q5S`UD z_-$0Tc-(gb!056y2|djU0gPq?4^ycPV?iu{@9{_uVnJ9a>=bH7IhD63k;A}aI6t6h z2;9n$FEocZZ-||dG@1n-kEbVabY`NS>6UWJO)~)z#@H#$CDJ`Byi}GHpbTP~PStHW zAiO1x_b0AQy3ydB5fvM@6DlhW!(P#4hPH(@67x|JDfl`Ka`o$XvzdMUMbjTAP zTsU37cdt@0wny$`CAikqrySh_Q=fohfXB;(X2pu4z3QbV4d`UTpp=`XWaAAE74tPh z#Ce4Jv~GGEKGl8&Rg!o_+DD{wfFDd^bhONP6pUA}ig9-stY2PK56_wO{b@Nqy#`V^ zuKlMvj~wNvn&s47k?LAe$RmsMs18Ed8d)tTp|@^c*{{GnPFbq1dYu%JlTxu5{CXeZ zBAc+gNROgCIl>?~Gh195+^dImrK~m^XaUd<;-XB}NC5%?qHAM>=9V=5q->iJ0ny(~ z(5-ehX+cy~VBo@r+k4^3gE7TeA{J0u%k_gty9;8xPe1J^lc$8d74#0*qJ1Idb`hjW z#n(&%ksAn8bJi9&Dkj|GIzb~dnKK1UZ=6+=8=shzRju1M)nLSq0PnXNoJYi&kSbDG z$Myz!>ZHG!i1+NIE$}zEfn#$uqpDh}`P9WYoNA18C$C;5Bjm)Z4-?Fga-+i%G8++< zd`v8Zub1aG2?cuXrFlG6s}_QP>zBUmD^H>K357Iet8RK|a3RVEC;ZxqrAl{M$@@eN z5cn_6GxlW>vp`YR{sv_J5Tk}A@r`Zl^|9gSW6uImMIyJ~)0$^7JN5~~(p0%Z5&OZ= z`ZC(cl|KW% z%sVO(+Dwm#GLEBHDj}AhH^r*Mo%}Rm=quIK>be|C&!C(rv2c*m*Fs=aka6$w%wW}1 zsFJKs;y5*FHeZABi0h8an^Y3fJ9hM4LPIyg_PwjfdKCvql(zEW#$Xn(;V)AruU6H} ziWlQm*LNs^jP}q0p$e&0;z;cN24eTmb1kjRoX3RF2@I8hNsq1ejHsgrQv(?*hHSiV z3Zv8}MxqdP&=f-mBe1dg4^mrd%$Cg@=P@;)ih6yNR&oSvXU&WV+F6{gaIk*O)Fm@!;);tSIK(pJXe&(>(@yM;RX5ZHcr6~m4hRB9py7H z;*u6vUC)KcHXA0Oki}Gf&9r3h+AIsZP4BoubRy-0X(uE3o3;ujKPz_N6I#~O#I9El zSfGZZp}IFN3nT4fPzw!IG84c?jmK1?+Zgrd6Xf4)mKX2>_}-A@CcdI=97xp!EBTG# zn!ZErn8NmKw8)JA>|__6<{SyuFpX1>?ihc&mh?>RfQf%B<>GR#6om~<`9<~~>zg~Q zGbm{+k3WkN6dNe(R%Z>(!0K_9`xrBwRoY4vo@mR%28N-&Tg~x1>^GWuojM0CcGYRB z(YCm4X2L44n?=d71Tluwc5F_$E>wz1y+p_S({VBIzzG3$k@8Nyw9aXPBE{IoJICcT z4shcD4X&hq3Mo4= z@=PEwfy^*tF7|~rnT+0rb&HR@^4{;3FCWrkC~un<4n@jq zEJRiW6BFayM4@GrB#tQ!CTKP+q)cMLv{6)6pX&C;1UL^{#PO1>MiMQ42k@UkO2b$&}vD zYHO&+jXkU zCV{oZu<59Er$x6jf5_J)jGtC(1$DNAN@krjAC#Uq1My4d)Q!oe)VvrJRc0_PtK|fLNiu0aK z@UrN=DH)>Jh4H-B3W%(@l)U^B1#6(}a%A)7CM?&fK#8}1J>?($QK@6{gz3i|Ig)k! zFTcUhyXEvWPE?-{<@TkXg%IuF1p2Xo^Wmatx;xVC(rUHdCfGzXA`4hw=}m?b`)Jcm zh#0yIO1Fh1DEv~73fS^q%8X?zgThd(zqNq5$xq2~g%qKd&fk?5i;8EqdZ&SMxGKn5 z@phnq*N1UUNMpi-3&3^_fNs&|#TbW|1&>SYD1ejLqIJ_H zgQW1>QFg`j*)SV9!r~!VoUIk7$#_~e ztDDwZPHA6yVM3WHG;#1qZf40u^hf&P>=Jqupw zs_nO?@d+FXPOirSW~qDYN`HN`q1 z=6NO&R;{M!<&~LQCE-5`%x9&Sp4vknY%gF;CU8>3b8<_qv?3`s;(1CcPWw)ej5*~x z7Zq_V-Y^RvJ2SZvH*O%Va`2#OTM7 zSlg+fs-%(>Z;zJ!aODl&9?DBgrTGw&H6i`mHll%clcg*md!?8d5=ueo?*@08{nnms zWf;y&NjI^kIH&YMpV92+5X<#g_j^IJ7E{nU!@$3(;;&497T-WmwQ{;vGu3x+R#-k* z@pPJSTH$I?r%1IYPYM-a_ZP@AC_w4J;%bOwNG`6XKvssvGW8LTGnO@aEgdbWxQGq3 ziH4V}>6DqS%a-pp)!B`!Yj8SL*TC(_+_-{g??yu`u6q#{F%EF=&M<78Zq*P3<=VX= z)6?vo%uF4>%z@Y6F{OnXhezkbRXHGXzk8<{G-|^dtg6caIaeoFDV@n=jYPwxBGm(Q zIz&?ABM@`a8n#fr58c;;c8fY9LV$8G4F02zUbkuTneeEfpAadgk?5H~KaS*PT1^H< zMFR}!Y57cMjB2aQKMT52>l`#hrNQeEj8njyGaCPBs`&V`2cw*x4luz9HUrU^Vj-C=97XU# zrLpmCaY2nUPUYdFwKPm>HZ`|`?pbGJ;YqSIY$#Z$nvr>9+6D9aK@!fPwTmXQ`&l_l z&$tgD%;VfkGtFTY+WJ+hU>gizl8vip`REL6@J`?4eCK(S8Zp66(@9UM#R;(KYUTQx zcyiJ6!)^pzKOVFx;=*Z7`7FV@7IV2qwHWQ*A&S`E#SUu5l|MA!E3T-qFUh#Fi+Oo$ zYu@o`&3G_20F~WUE z&206x%DP{k1c_h}Bb0jxO*ug`h5kQLzTkJ4F6QB$X=NOEAC{-UY&od38rYX0^E?AD z3{;Z0 z0T612OsAHoq=slvkL3|LwVw!=wevnTqu5RcA#3fswflpBL%l^01YNi<&kd*ZGRuk? zKq$J((*VbXy66;{R)5|ZcA8+ulXBN}pQa@C!kjKp-lr}KK7=@m2gkS+lt}FP8%JSD zI5EmDEtiCG*NSTVx$QNva*B$9N;Ww-a;-nA59g;P1MG>jwsP3Q*q4rt=A+`yR0{(; z$`!oHisr{kA^Vtsm(8!Vm4Ox3CGcQkNtO|Ky35qT+IP813^zZg} zZi;R+L{tM|v%o#vMxRNti(hvLY63FZX%0s9+sS55qU=j)6jslgehr(H`&qrSCB>+) zn^iD(uzma0FLS8w^^vI?C;fp!QH#%1I!1 z5rd;Jb`EYe^F)=53HeSAZ=C{!$uvt$L*CNEmW*gmxtC|#0iK>w#Nv`F=tnLew6wNx zcRD3qb+XvJ05IZseg%gKxP+#}x@pQuKZpv*OVXzY!@X`i+u*ZV1*omphBi%?*m+DA zz>EaA5D^8KOe}FxE=I350nM?cu#k^&XW0B8#u#6;RYBc!+XAjcrS8l$&T!ndZvo_{ z)k*g^?uH`qZ@O<%jevIlq@2{c*2qrIN1H0+)^WF7HTS>Q0S99W(r!bEv_Awelcf<|4CwlaT(G30P3gW%AVmh!X4I*|&a75z88 zu?L?F&`1C$(tcC^mPhB!xIA1)z&K}XfQ%7FdjJ`SseAeqv^nWGwn&Scw^XWK8UY?c zrNRt1Eo9HzD9(?wu6`T_Z8MB&p3p8CnnsjHbDL{)D`1$MD;GHPSVH^kz`~1=et!zG zD(*zpLer_UYB9vZ54KGZ-V_(mFqI^T4O+lS@8+C$CFPM$8y)G5GUK56#}VHlV^VY`J=vi2_%F`NQ|Gv2l=*1J zh!3HN?hcweBV32^jgT|$PFz=OxD>=e7cBcJcNVc1MLs_+2?1Q_lEsi9h`eoY$eH_&Is{3{ej^w329|> zrxS3kM$<%`H-Xq*2)tU*nK7J5eAFaoUpk42n3@7x;rgz5w&|tc&;bT?${pw;J0}Lw zrGGl3bQvlz=QR37U77jWWrrxBT2#%Ln3hg124$kuVaGs0LcL+vJ>n>b=e>7PfGdEKK_97HX_AiECQvQ7olsS zR%Ka8(;Dh=@KB;`Oe;b{*;;1*dmvZZ$AY{xLN7Nd@3*%;kM`D-cZV1@K%NlzH#m;% zgxPS1n%b07B{q5>A4?)ygDX~OVsZ-OKE7^Lh|0+hJ|ZcqB$q2PcQ}*)1&PF9VKp)r9+>Vn$X!)3KOJi$QjIn|Cw}iKfw9jmIRbY|NF$zXYx35|q9)e_Z3Y^p zt-6%~GXyV!@AsUj08;`dX%#EjAyRfXw&F#cl|7r52$JFtFl4uMp<=Z95I)YFQEo6p1 z6d4L3(3WmBw2W{73!v`d?O_>*V`0gt5pSs+a;K0@bafMV|FRd5bptZ zLQd8*C$QED-9x4=uKld`q|XqznS>hcwmP-`{a|m@sSjJ-PF5gnMp;q2-EN!H=L$fz zPoo{i&{RnD&C68MK*|3w-e1TmYhfZi5X65C5M&6JOzzDA3WhOqM*xM<1O@=e(K|*M5aRmT&L8v$<)3azY|geR ziyd*iCMj>3spsl@&5%3kjw?VT^4&sNLK>ogM~uzf)UGpriMG%z=Qf0pj#qDs@>h+8 zU!mtgn~Os9`HgfEG8T&;DJmA4*?gF2Y@AbQ9J$S#ru``Tlks*c3c2t_@k1`4IAk;6} zcj22Txk9%JRX$aZ(wM?JB7oX1mb}b@! z)&`lYUOBUCZOTx@lnOaE$wVr7#T_d!_P0)1lhSWf&&~IgBYCsTF+N*<`>`;7jI*BdX`n<%qt>M zRnzNihh;`_pJ^kf;$a<6br#cE*D|fBGLcT>$Z&33LfD05`T&KWs0gP0N-b7Y$estv zo#>)g;6HI)Q>wlTpn;G*)^H#uoIP8RMQ2Q?iQsfv zrbsA%$UaUV87{&67xB0rOPkUE;5Q)?wXt+>N9EETngswIQUeYbGtW^J{qxc zC_vmjPjk8rJuzldv_(=^gHH3V&{}QS?F)alKwKmOEKd+lQLp@Xg!7zY`fY9IY}X-L z9t}QDG6%;QPews@W=pd7{9h&8+xU6a-R+I4)Sa?YQx%; zbKwS=8#|8}oiV`27%NabIIY1c`nB-e0{ET!M@-q@=?crG{8qnYXPkDHWK0yKKu+pB zJZmJ_A^KTKFk=Cv;bXF4QJmX;j2b-$qW5Xlk8$`uJ75d_!3WLBadfCiZ1kVZhEb_V zq$o#DSpwt(-v3Ne6OjbEwdw#-*5uW#6Sey@4JduLo_HaR?P9 z{MNs)-Ju zdMj}n5`Ss|>QF((cqr*+J;V97QYkZWd!`<8=4Q5CM7h|8;3@T+chIJ|8EC+A1hEgF zE{d{%)QVBK5WXna*jU zp`Sy73!>{(RtfjB{?*x?%BU{zLcMim7avNs18g_5jABiqh-y0XL8Gg+%X7GZO)9z? zR$chWZ1xqI%xTpW*0wqi68m;_@gzBo?Uu<&}Ke-kUH;)`WPo#EF*NoO11mbs0d1&+MOV~G8Qf;&wXY-vkyAh7!AA3FI=){ zre9i|+nf}eez$AN%7I@Vw!eBxE(gi$H(1|5gY}*DVB7XsN8#{DkM;Zp779EB4-ms7 z94Bx#6eo~3iL$1CnX;>0^1!@n&Dv74aWHhE^DQ+wM2ec3qVYcTo07FlsIN^dn%O;X zVW-&?2sG&3SWi$OGR7nhiaIG-_)W37MT;oofRxN;30az*hDJez)oikvEMB0vjY}&_ zOZ~f^BA(L=#oNsq&e>u2CS`bRr&1#fBALm&G;AT#yg97zjkjrv&zvwAd)}iFv!-^h zwLjWFpqN0#WL56MwTZHM!*q*k&~ID5Xa1hZ2*0Nu^TpU5qT)}X-lg5#veV)jhtcJy zG;Y$4Al~^|@AmEozVp*J*Hf{AG!{incvf|a@T@SGOf}k}sZk|>N*+r<;6%v(%%)~> z%0I`<`oUn+%zTDB#g{Z547R8>4|7{Xlq6|yp>LZ%X4X+-V8{yj2pCWl4m&9;0nj=OA+7grQZ4Oo9x24UsI zomzX;4C>weo_$$d)jLK0Qz8|vx;Qy5V)2}`8Xz?f0=9NgBtoJGJPDf5D8)^;4F&!d zNpVO)1uj_uF3Fx=${Z-xtIOIlmtzQayCa|!aSj5EHL4Q7Tc4=c>LN6H~8m8a!Og*n)qTc-dD4TCuu`ltzF zK9>M7&j?;qNd_B;5CaY+`Ug^q#*nkP-LBcUvh3Wcyh--Vdlyt01+ zn=viSdmS@WIXN8l+RXr+Dk&#@^Sw8ywzMz^)Xuw6!A3hZL>@aw2O5+%6wMi9-Ofl9 zY&Ichb71QQ1CwT@xSlmR+@$btK;Z|aR4FV7&b?UI7N!7R zyPj=5l-0PzeNBc?W^bUd-%Ea}_KcP^e;nTO_y4Je_K z#nqi6bC#4Y0iQgSd;U3!erC93I$5mgG-3uhn(}-x75(c4Bu+qU3**MLgH-oDExIpGRb%@A`UF+<09gz_mz0V`pFnC^va7;2 zVUmtIf$#K@aL#ULFft$HvR_FJ7>&zN*no!zIO*1s^%&yFQGORDpv z2f4_4FJX3KBDB6R{Ay!21hZr|$3NM+38k_eTX@M|WUr2(1ap{OGIb)E&GOW62<|C_ z;KqN67$$Dt7fsFURMaAhNgK+fe$5jDGC}Oy7HeCaZ;Em`K?A|%;*_!(Y{5iU=hcUW zX{ZU{F^2k7`|YsicoOMp`sNf-GHIwXc{UI`V=QEu?EEyPG5WP`0dd%0G^WKluLe#xyo%Z|Zv@v+I}zb`8@BKS z0VVMu39BCywgP?!fU*sganZj1(2X4NDe?_j@H#GqTsZ?@4jj>ACdoo6Zfq@A2~7e( zXmx{0i3FB+NBjyo^KH^PWCbS>>?{!;$s7TUE2)U(qU{S8qhbKbc}lUUsiLzDiw7DI z*vvGb!A0GOaf--X{gTNG8gf@&V0R_(Vk#Bj+?A@a6if9SZQyk!^ETb|n*6+!CyqM+ zL7lnNtfR2`W@Y_icYn9L(P;FWg8?ZHXys%&Gz$n~?O;afuI)fDsYyWgFv3>#S!w8$ z-YBrIwI}D&-cpAcw(M+&%k|(T{{Db-IMNOr=DwLKjrmz1;~|Q^S4FCc-*wYy0}QjL z`TV4fc_4q8sxC7a45Zt|g;QA$Qvo}ot;}@|edwi-dLe``d62bU_aV6Db@*hqOe$K%@m$-9RgXOLC)qbMuT7L$@`MjWC2%(Om?J=Vjvn*mnUBSR7fac)z2-t7`dlTP z)=n~oy}ZPhG_RSb$k%Xq5^$5sTcjChGF7AdVyzPtb6;hLwR5Ap!@l>o3Kv!h0wCv0-}dy=&$Mg% zyN#Op(YezPcD?I^!lLL)-(~?{tNCrFS^jzM#2K=*$(MrtyY43zY!Y&cLUyrgJZ`WN zjf*n_;~8$ml^k9~aOoz#DG@Pu&hj|6l7)9B?9lU^dHL^U*ii9C3Zdd%)cB!>k$>}D z&-l3N+l@XWplj$SyF>E-65)-)7PE61i{yiag~m|LMzG)9-yIqDSBzz2j6KtvBG%eV zR!p&6Y8@4|V6Glr*0H(CibWOPX#^^2_h2L5!xdxFF#5zd3au`lUKa|4EJU|BTkrdD z(gNwc(cYL7oW2k?JM5ECD}KVY*?>V@WQ4-8^9@uvXK*HoQgJyrc^V15YO6S}Jn+bP ziwGovz91wb*h%MymnO64dEo{$ABF7Z({* z!%{sugh<#hsoZyurfztj3l~0UxIfPS*7WNYJpH*+7qZv3l!gu|aZ+ zGOpqb4Gq$WM>{SipdB!P$J?5ukx_GndrpQE1Edior35I7K?+E0C8#t*Pc&evR3D1O zYhkKITvx7ne&T^xY}6iz)o}?$iQyG#Lii@YqHm9;7deOY+a*NKlgRUKhLKDo(E6%q z{WhV5si;QtTsE%@UpPxV%}eIFb0t{eITHky$%k)JrXS*7CEgp`GuXTlAXJ{?%!{Ld zLp4#&mpTFX?qIJBZ}+=*IZ;(zI}4jX*=8B zv-=ZzaAaW;g)4w)JBR|@W3W7_D<1Zr0i$C=*Dh8dKGU$IQm{FM<=pEx8_zg5RaU;R zd1<8!={ge-Rx?kySVI`{O|?LY;!p&Dn(SHZ08aWj|0>A&IorH9?APkU1M^rtYB!4J zm}4&+{50BB{(!WB!n9!5d8n|Mgw{Q_~j$vh{0J&<_~#6p$Rln*)VOYOt$E|dio)#s= z>|8qCb$G558hVq-S(v61;s-fu8I)=bNY$>LgVqY0iiI!66!NE#s}i|iX144+79Kfi z64R$=2#Ek}VT9nqb>u6;<&G+6CKfR%L^q9Arc*6-ameD3NwE^=14TCuXY<&sM4@J5 z2vuXDx0rCcEIqlfN)KaGwRtZBF@9F z-jSowb-^?FzO*n9MP1b3BQXi130}nFOP6`|#TUwWbb@iwSiw42f!{#!x#ZTBHuHUP zgd@8)Cg$-k8t?&_vZj zlZKF&9v99F+J^sd3uR+a=x>@N4~;|P*phhYr{HXlMB!##r3)oQY#0fr%1*7xv z;_(M7OND?M$|x+# z=>!snQG(fw&%4eDHA<{G$%==oJ4q{)lLizGyI3d`hjK*2ja3$Dc;_%WFLUw*FWz&` zO<$brI$S%mTJ;L%!0s-D7dyaep>)Y;`*{?Fx>`-5hrOvb{dZ7h!L(DEa>wG&My zcvCMGah}n%#$wU$A~wH9kw93)$kLnyNZ5il)-wsP2}Vga;uX`8Sfcw@v(xOi>OROb z-&j+Q1U;P)30eqWK8uj4S<~nvM-QcFt}Um*;tbz ztV+ee9LBXcv%|o@rk@qb>ev9*%2IEAn_mfIdTb=wp-KQJI~XdqvOwdb+8_HsM)ybi$za%` zMd(cmuZTrWG%cnGi&L?1(Q#}}VPbQ$lY=HI?qOZD$2Y2jkkgUcq)DNgTyxQil4*c2 z;?+SIXpC)m3M_V+-(BtC7ITZ_74%^DP_U4Cp`n>B5WgS~EA>V3*;)RK-zu`?H^{;g z*S-z}p=s0}Z@Y*uaC$goexV|U34}9=&QDAvDuVAR{n9SBwuK41$vKL`CEt+7vT$9Q z*D2!M=*NC9%1y40TCIY{&o?`@-8M|Nz0LOy`a8q3twAuT?Q_+9{9HM$N~%sUa_=iA z(2H%ZEf%ODurm1^6?FD)4FLnI#gmWxzpaF>C+5^Uz zTc8~|mYPR6q1&di_LQ4P=k2&%61Ypwvp=TVmsZn2DV@YUiXntbdtzKxkw^DlQsl`P zAxs2~I|j{(SbD52lZn2A$}OkHE4Scd7EE++y%KbsT=m^oSx{< zfw0ft@Hq|BUo4;063+-KZ)u;QzsCg_pC!Q-4^nDCOcwm;Vr6rCBdJ9D0c$-Jt7x3y zmCq1FSzzkb*;=E~Zw}Ck$TJobAigZ-wpu+zc&Y?U6t~+cGzLMmCS?IVsNk*Iuk{Yn zFy}<$<}uS~fQNnK>BpuHYJP~bhLe4-ozTBSe zuU(|BS)^GXDK46YD$8a9eEl!fK|9jU4-qTZ(aTR(J&Si1DW$QTuw7!(v&Q0a7Yd1v z)ZEF2YcegIN+gBc8Gwk(Yn*CR>onTU`P(c7DaS^JMv(4>(c2Z5cok?=tlUf!&lm$& zWWn301ciZt7iadcbECOyCT%TMTAGVipQ{FgrdzL)wz8atTpJ8pw>oCANuke%oS49E z_v_qwFiaU^HU#yWOa02?Te*}_toZS2IE4M^v*j{Oz-1TE8LbIe3ux|g_Fe6sWZyx( zvYgLFud;K=13`1E6i9Ixy6j5*Oabe+LuhnTFiQVAQ z^Qo*b0gZUa<3Vt%GoqwfgfR!*-T?n>4<F;*N!P)mlKf_)r~PoRXElY>I|hOSITR zQ9o-wT3ZQ1!*0w7x+7vH)R`5iXjH~zgp+!3i{y_TTn;g#k!U^2>>y$5VaPC?U=iII zp$>}?)rFGG7-L+dt>bdQ7A%`DS`RX|_pO=HVz)Ku5MeEgml{J2XvhsjqtjZ~`AZL( zo%4Y=MJ~4kxd_d4SRz;#6&7%ha%m!D0t5t-2K4y(JLKa7rQ86W6y}N$S{+VeHPHI=-$O+=h|{>?gTRS+ zS3TnSiD1UGET9=m!&YBQ#|+d{G>39A&{v{m_lj^W^oG_cmOr^^IkS3qzh{C6bcWNg zF2@!lEz&rcE2%LL2DHPS?Am z&d`o+k(6B0g!!qhggZ@*kPQ5*9G@q(}`IkRcIr+}@cUGR-Z4C$EAIHzQ%fnZ?^H1G7cP2P< z>d9XH$#$zVy7wg9Mlp}}ZfG=jN4F9m*St3j{U!(P*6vfc>h;){na?p_7`mAU@)Xr= zj(n*%oZevAj@;Dk4u(&GUiVtJo@zAF2`cu2TKiVF-x}WDe@d!v#62W>&4kCHF3MB2 z(Y+wu1OP;JswR==t^uzb8-Q z-l)Tkwc_5b{Cm=G6JA>H_M36HVrlEm-Z1&jxSN{y=pJ+ci~Er$2`<{^y|`Z~rX%Tm z@*tk-^6P4`ORv98xE)_9P0Zq6jYdNK(V%swIpG2Jnz#qpr|SduTZ8&LZ{IHY1!>-S zn;4N+qrp+gSBGO*!C+YUqt@@&?w7C?8S0h$n1SJm*sQV{ahjP2{d|`mT(XNo5!X09 zz{zHV4j3(_3yC3iz!32tVFWls#d74AF8|YL?(x51Go?C8cGcQVjD@ZW?zEbBOJW+x zPQx>!4YBznF~mFgP3{irZDeaS2Q(yp&fZ=6N{pJuP~!jE5e{4X^g0)P%)fB?d3u0u z5D-GEJHUhJpCPKr?&Bs<9Fb*-zSxeB?~osGKY8q%h#$bbz>iO(0Qryls7X_A;>dq7 zAJTL^iT~emN2Ac8oX0cq$1}U5R+}z=wsaR41w)(*5Ue*C)`qB{&qtRxuT=RSYM~dH zBVNCCcY3&wziB4;CVU@VOUHv=6LiJP@-qKc8+P|m@(99@rnGslSs&51gmJS+UuRja zOgRR{%Z^`yU=MJMd48kS#VI0=u8g9A#g{Yq3(wnON!Ttk7=S?b^7kTTD{i5Z<#B1yWMuc--aLYbP- z|E5}_*3*xvHSX98MuR3%P;JzfiP^2yU%p%GH{f%_$_!h(tu{LT@yiTL3BOqSPmsjn z^Nr?yt#hkwXn>mrl5_}B2A#bN1p=k9kk>`!z4+FBXdD4Zx-H+$qQ#p<_cMlO-lo!k z@7Du)EOz|>-&?z7Y0GrBR1yJQh$OI-V%G^m8%tGWh+GaE!eh)K6Cg!noUB`?t z_q{IBUOzy&NBfb&Cb6IPK|THZ=yNydj{3}yh=Ancs z9u9pd{prc7chc>`-iP)x`NMb+^spBADVBwg`L8y1O3(#6$5|A*3i{mg1Z(2&Xc;Ok zU|^*#-$BztQkrKU$qKE|1vG246Q8Wt>bIK-^GBNM9VWF&DzJY^Sf`~G?(XqKHR7iE zPOaYp$5T}$WD&^Rj1BkVPmB;;5>qJhsN3{>MhEKv=hN3Zi3Ws<5H7aVP26gx; zo#qgF){wLYZ|^}$-|4MAX5_uo5soq@AlMZ!l8&U6x~*vj*l7vYh!M+GFweWAM!y z(HBidZI_+|$%hZ+ITn4iMA6kC6snCuS6Xw6Z^IyXX(2dho9H>>ZSsTpZ2SO?vehk- z;)ny*e?Y&&OK^g0u$Q665;=RO0K^hqZS;S1VaCwlq$I_-B%^;)M)V{J1o{ATvo5VU z?B6w0*ps{TYMM9PbPH!8|BWul`bA*2JujZWqS%;i1ZG2k@lQf#C-`rsonF6X^e5u5 zd>&8?sa5zzPXcnDr zhmAYpZ)CQR8b($zj-g}kgB+o}L)#2=Zpgao=q}*v(7dhF#p+;_QFX~4Z4dsTx!)V! z2RWl{8y~C6>FLcp6~XOh8{FH>gHSKi5Z^WI2L0Myuu9ff<&CD*w;ihX{^nmBT^bMX zRMl=_Um8P4S{x?XzBbGvcB2A$C~j8@OxQ1yxo|Y z?v$lPl?wbGzK@JvJ8nHh<)q50UQMDDh4IrM%Oy~ zAjCc}E4wY2iToATu;aUGBdi6h@b2BjAY_O}4~j5at=S-p3&I26@%I9$GW;}yA>s9c zO3DrU-3AF*LmO;Gn>}i5Y`%BD7k~&!VU~dnKrtO-TY>HINs*)Ub@c6f*dT^E>n+rP zkpH&L3Hitv(sjT{xS1DAHwb|MY-JPK>(2pLN)5J?emI}E8`I}l&|ARQu8e9IL0AxJ zeB}T{K1}Tz@H3@q6U3d@7pzjYL2+-IJ;#R;$fEx^BV!-uYk2jE|<g+fh-ccs zT~C_3+*-N?Hr6U>T(}#b1$(*)dH|K-CuJdcGVM42*M3`VMku#+{tW!iCM|9>5GQzx zSvNp;DyRDp9?;L|ac1G8tLGba;U$q@tjQMlqmYUsxe!WCg5pYpo>4czhiGHNkrK#? z^0!%|SUz>Hi3LR2b~*CywfwmT_B6l}0LXO;gd9T=B9PYz2T+8)Qg$vB-v<1KU?L$E zOjr)EQQV84$TMh1MH@woT*0R8gLYLlW~too)C}%4xKn=;2p*&eo`v_w$Y6W`2I>ef zW1dG}#K;aCpZs6}xLX~#1Zj{^w*aYIP@EKc3zqWrKxSZ*0cR973hyH99fWL@Z2BDe zV!9XZEP^dVz!oRSnE^r6^HcqE1cC|E9n|)ks7c#3ucCQWl#ta3zSX=!9>drGZ&l2& z_fY=TObp{LhG_Y3yOMkaiZScL_zYPsVTlI{A@U|5E0E{*g3hSjX2H)VAP{Iq@Z1`h zyrC-w%>tTVUk8Jl;S?5F0niis(5?6}5MNH%<3J5S%JmB>;2-!#l_=gc@rv*=SjH8< z=}1gHMchD*bYlAWb|o`B-r%mJIMC+CKQc6~a>Zg!xCt)ZZ}x9tp<(^pc%f=y7WSi3?Z*+SHiExP7w11xu8Yp1v_7W3WM$A zx)CV__1@@7!536bAyVYYC#0WN5I`?&yi$*SUAOvV0AgvMY`4#x!k?XH>(=dE5G?-g z4>56=1t0(=)+|VN?A1F%x*uW?{}tF4Q|dD!95x;>$%9@@o;kuQQJuENn(A)pgJZ(h=;|{mOzv5A4doevKbhuMm z3I7^8EYGh+UgfCJt#l?_NANUr@t2e`N-0DFX5l> zUi$cw`4NO?pY$V3c(Odod(77?ZI{31BTFlT#~$E*Tth1@|6BdkubX8kJp+P&=Hp9C zUsL}0(tljyJ+yY^A^G*E%Y3YNh5ija;>Gea-?fBI_+3k%phsYHeF6_#dTCXkR4yII z&&NM)e*N^)AJOH1wDkMSa{2Es{~@+*`45-*l`qP6qxXegvt54XV@pe4UH+Jibo)Vg zq}vZlOXcz#d6;fuORI0U8|gJGU-doZ@@w99Ui%??@k?~Ef5>Aft^UHpN?SCDA6xoy z45Iu~OTWZpSzbG4em){Ef7BeBm-~l!xgMIAf3CflU+y2$%UA!keKo$c{F6&RW8V2+ z%z5*{|II#zKiEISJN3}KbNLZNOZa|#aOCiBnB^@k-K4#(q*j7t@DEpC`K#~b=~-G+ zf+#HobcsD&edRUZMVBm<*Usxh^)~R}v2*1$cW&vcOa7rgYSp_$&#f)l+ddD}aQqQ_ zSi<2$;loF~i&qBa2c_3UPdxIvwH-HF`GUt{&b{u9{&g}LZ-_aE8TnU+!XDKjuf&{N zT3Y)Zcbz=19CHrr_p({-W6M2E@A6tdObj0i6N7&UV$efF4Bu=oW@7LU@#HTzq+%{U z8KxZn5Ep-q`PJ-$y1kfb(m%xNf9%(k2tj5s|64s_8TwlwC*E=ySb9MF@xjuMniD^Yzm|4Zzwo&3+Bf3oH~u6s=9^%s-pf|6+Ls)Gq$|Ja zZO}`uy$Anke>0Sm^0zI08~$0-Cmnu35VF4{vno557%ffF0cKxy%%a-U!pV#f5)%-FZui+RTUL#)Nmn_taZ{Gz>> z*TO%o~wFx#`4fyuq75hgI zjgI_d=H7>w2anOB>G31D8aM0V!>fbGNW~1D!w&Q=p*za%4m!l^#vb6GBN@1|_OoUP zw1r`o_=o26PfYy$7s8+KA7XfVXg*&L&F8--^7(pfK3@<0&$s8~^YzetzJG{M)kFIL z|D1e&BmDXPq51qz{l2dLqgee%-?cItJ}AHIvRQw=Xw_ZwCMf7{de_SRhs`xNR5|vp zdDqg5<##=c2SD?F_A-p8u{XU7#sFWj%~x!zx$uA6v6R>D4>IeV_dG z)QQi5Rek)kpZ&aN-i#k162ACh{0mAjZ*ccNL?Yp#H(<1H_`;?4mcQ^RViWwo)&JMN ze*WH(pE#$i@4(!T4HM}LXl zg=wvrTmNur`Q!s^<`w+ks-7&D9$8s?@Il7MD|D*K&V-Kwz$N%ZDC%ympL&uIEo9bz z@&2+upD@oTmmYe}*OyK|vGTQVc$7!;mIviGd@-~Ytc+gsgph+C63GFivWL<8OXXt| zeq5dO+=lt2Fr1_yXoe?H^ii22p?p$B4WW6#3|{#E^E9c_8pp8IgzIsbjD-nGl8AAqUZ zdqeN{&#%7ntzS#Cal$=}N0QBJ5yrxpMoMo!`oblY@C=Zjju!+#w;!$0=t7(7z1dx);{kNxX#|0VOhqsLc9 zN-#v%FPQTsoqJHEo_q7^E8nS9YR?^C`9^#HBQe+d=lpA5<6XOa=0WMPH`@2$-SQs) z-0_u<+4lhN(D#?Y9w9=!9b zuUxJZy}uEfxLJoc)A#wu{=IK<*S&$R^N;=Ou-;$m*8A_-dBl3(a_cScKK6)xw_S%L z$J{ypo5JTE9e}s!__4R$dGMCl^I&eV=RtelV#fE->MMUwY0sWJzVb`;_yk6^{ z^RET%*=tF+c!0)QeZ6>k2<=LcYrSRUOPuve|yd!d-%K? zJLtl@-kk?s#GVIT#GVIT==i{s{-M%^J$HQNQ+B;T1NOXL>!0(l1zp%{4NuZze6zd< zJjtFrzVavbJ>WO?yx~dqSnu_(@$Ut{vDebQ{;}TcpY!hpzX{#zAM3sTIsabJlD#)H z58nCJSKjpj!;|z{lHN{%89h(3L%JXwM$&z5X@+y`U?5t)V@8toQoY`1gXY?6q{Sf2{ZV z=lpv?d-mSYJb33|Y1k`+7%v|JcqWXwUK+eK%-N zpJCSlG-l8F-xNOY=m50mUGL6=_F~V2_F~V2_H=K2@#-r-t+Z#)9bYMZu9$8xeV5mM z%6uc}RIc^U`PV`>x7X4-9(~jv))_eVP z{=E-H?)8uLUjLkbFKi6`UdUEAXa4!sSAOV&M0<~x?6pjL{;_}WW9~YpJ^$Fh4z%|# z9PNFsok!5#uR6Xb?}p7~$En{0drsFIy1QG4@Ok%5pgp}l^sS)1*z=&h*z=eQ{BQNw z447Ch#ewU8Xnr-|x_<~;L=O$RtcM0&{;%d<1=sc1pv!t_!C^emo)dIg4-LBP9|B3% zL;C>#oS@6)Pt%Iye*&)ihjQNk@9LlYrd(Yvoddpk?!LgC_u=rnQT|alihvM()AF}U zlt=kn%YO$ED)`UG%Q*k>@(&*6%hx_^JdDT zAgh2#!>3>SMX-Ut=<&GUO7t-AnO_8G{EHsPR|4A8H<6PaSdKl6zLv0@xB+ zO#TssnEWHGW&M$2oI-~;3Cq!6Y4pHy{6m4!SD&ymS&n{Ex%_C{Y*~=!w7JzpYWar% zdEC1=^2i<@w`*lQyaaKVR$F!)kF5>`;C}4e32goLrSD%pDhv9c{GBV`zk+k$zw+m0 zJx9Q{fBW|{to@z1Vhql{Z{Kkb54rc3?zw-t{2lb%?^yZvRef&x@2q~p9ymhOpMeIH zmR7&pKJiZprY!%#@;@yDcobaK{U~VnA1wa`d{PW@19kO&l{^1pIqpt41?WB?Wk;8f zhF^$iBzhmb#^XQHUHIv%K*AtmeHUDaYoGaT-Nj#3I{wh{WeV!Ur=F9s3K& zY-x#z<&*ZA&tcJ@`_&~~)bg(`{r1vvA-1)~=RYX_U&}x12#r_V-OIoo$7i8D}viyHaAS*u1|7AyhVTZS#CzcEWu7@TL_knrdL--YnmOJD)Tz7~^ zmF=&FyX&tc{2>S3AztJka_Gz_&5I}w7n<8om_vRP6f|?lU$eaSkHf#}p^3wFhy3K9 zGZ(Kdk7$b4>@kLgH~q8lv-I#G6NhV$NrNe`{fb^q(OLen4BP&UL--~2kOOi3WBk18 ze&#@2|Ckz>EYx-sdCR`mynh?OA%aaX?toaCL`_|ND=_|J#F zK_hfOx`cpKj#buM5NAta6#75!QC|Wt+n2nP!*Soag}=8({P##Ab63`W$Bgcc%qBvI zAS3Y^TWy2SN;WCpZ+-v1V)Hng6IpjLCqZx>m6i+>N#9Orl%e* zzl;3Q_IOQiVONh{1xGtr#R_i^_;mF28r|$4>&@)r(X0HM;mpy~e6xS7H?wm`ukvq( zBC4nPX8%}keu$=0ukvrEU2VR(OvCn%F(p_&{kcRx`^WehYp*|-S4LmJo-}<6X~AT~ zny15f|N3ud$-BJvPsh%|xOC@aIWdy&Gw0qUyV@OMU}gKOF&6Y!I%E^$7tGz|(rZ=8 zeeK&-`QS^K!2YGZ%vd*H@jB~r_N^Q5^q6(ye#3Lu^oho((L=+`?V(rz-mNfdl7ECz zll&u$n&cm0)Fl51V$mOsQR5DG$f(gn8a<2}|IipU|JqKVF>2f=g^U{Sw0f?8*W7Bv zo_`1(&b^C`8hdzrMIU7%XqJf$uRd-pW~?_%%GZA1GFb2TE&ti_N*_^If42O4WgP#b zBY(DP(<8h)zUc^<%QqeQM@PhP=F4nUlY8(JkO@!x+f`hI_^W@rif6q@I@!ad>Kak7 zvQowwJzgS>$9vBct3O!&x%+2-u>8amOYblL>C#7+!9YH`j4&URoh!Zh0sj8G%g6Zd zdvy4N%m0k7_?_jyTE_K%yZqy2{PW}Zzts=P^*>(znes9Io3H=H@~7#FPt!jy;y?e{ z|M5SUzvT$de#?=M9C=i4xmSATOTG+Q97kTEpXig!2#u~uTLk|*_{SQ|XQJ6W_axP4H*5 z0yl+H5tO{Lc1cmCaNX{}_po-*U%D9V@SW+8rOI<3DxBt91O?|DUz@fYYO@{>Gn~xzFru-&8_E zi2ZL_h_BfHXm*Djz{T}kj z_i!|k;KkD=4&DTQs6U-%|4--Li3U@Tc#i8N34hrihI{#!T#hwN7c zk#cGAexOe(_6Usu?5Gg)-W^XvU<;OMFLLOLa5pdhpGkWw-)!7 z?=@oHd;Qt0SptV5P#ME#1L^P`UsN8(fbFX0i1sdv%0^olZkK6_la{(7hvBu`Xbb$= zWg22c#jY(<+a)sx8*L$vU3S6jv(9N%!bY#7y$cmN6ycoKG~{e@VQ#jxuNsb!R~`FmoERwuy@DW%9hH-(^G%j^b^hAeXK zWEyaCx+2995jifh$erALEeGq^}xG+$C>C8kQ1)fge$x=fvpwHc-RRT>=Zcq=$(O*zl; znENLtp=7B`#{wls<`&#Lcah81L>2Rxd%}6}2}qz!@-RnXybU20;~w)F&V#=5!6+FU zrUu=DC!w+!iW=uJj4?gpqkx3>MWkH#8M-As$kANAm7 zdG8A{%^Bm|f)#TyPgw*mc#s(B-I*k=WN-`S&s&7^SWsCs0&}-#ZtDmb6>sl@!S0XG zsv)TGydju9HQYM=;ka<~H-|X@(!mu?vEU7&k#py2)7WZi4bdO0PIKHVpZ|CZ-M$nsl)(JQ&=TT^-i`X?X$%jAHfHWUosG#OUqiR0_xYDqbs1Uti@mQ0&Tzo0K|8s*?ytYM_3okYkvMl@^cJ zN*D5hp)h!o^3~FTY_$0VDP$FL2PQE#pQEL%Mj7umABRFWZjKbXEGzC+Gl!r6VMR3t zvFvUjuQow1#6Vv0gKk|6!kG`MDqE{IxQk_zIoS~P6=p==NV-;SAVtw3jX^eR18PF$ zX}r2t{d7nqsUTu7&k6&%Qjd;P45DjcAXn%OQWUX|L5aN~>Y5OHBWdja71@aDF$R6F6TWQG0Ri$=eZ>;HKke24 zZ2z=HInEII?VtS;*(RIL(I_bx0T{@kHRhoLSPzfeJ_jaZd0}88R!9dXVuf^IB6@d5 z)D_Yaloe6~X+2g*W6<}p^0wf@{#Ho)^-|dPIm*UktQTAngP3tB1Cu4v09KYr)6l=t zYq2g1doJV(q8P;J!a&`iadlvp4H_|c#T8uNtX|p3%#B>L#TS{WIRVcZ^{t=e=F%sV zXY~r3XOm;NE_F62*EWCQZ0ui>CzEteAxfLPuA*?y zCWoh>9G*h?L{aW1KScjT(eI}@R-%5K+h%9DJZPHi4OxlH@_E7Ir*OXc6wFp<@JnQ3erRAB4hIe27&ZOIpTyfI zzlpbR{!s7n$d3tZvJ13pFWlYXQ`3}17D|fj@(`CS}tDM7*Y6h@(dI087i45N_++qJrhMw znSt{CLh$TJIoYpe4w7d*h!1~|Ah^{tQt;utch24@X|VCsRNwvNOc{^W;$aVxI@s;t z`d0aiLKBaCAaf%%n|{f=8BG%+T;Mt^*VXME**yfnkfGj*sLjlF%qd9hSo`ESv%sk#cIPt5NZ`s9;z--Rw`V4ix;`5frrP@M^G#M?@Gupg8^TC?8 zQkhhym|~oODaOA@^G2oGygl<@HgBNRh%8Z^R~4`ofcnk{anc`G%E z^Pp+6H)Lha+h@OE9$(1jZDDd+pXP1Hz*1}8_D1uz_e^Wvz8u(m^Y-<=&0A@qqzIe0 z)sAY^#x&~rgw5N^G6!UXc-|B2{BN4KQd%nW58k|O9fBXId8-BSf!Ygc-bw{%x(>Ox zY~JMEH*X)1XC=*BsYyKYfy_mPpuha3;Fnc4Zx$k&C?6veF~CN3bfiMvEY3{BjXAx@Ph?pKP|CeA=@;!H@JxDwPRZdp)T zwlavHp|w>oP@6adwTUxOo45exz4!l8o47tWY2pkUH%VyI46RL^foRUWJ~VNCaMHvX zHr9tG&d?f}TQthZR9+wA+hHxeZ{h;jPZMYP9bKiK9jxkI2fgWaZex9YTk<8n;toT@d?j0ll8SLFf&hshi~9N$=sgzk9OfSvF_vBDXwyo%ixh>eIT$ z0Zw%5j6wA~<~0U~-88QyS8ltS2wXM<(y|D&XF6-RIE7V1B8U!zq_3TR+>uHGfKLw;Mn3>XFnr|B% zcp6*HMG4H9;Eql&r{VXckK$p>^33-N0;AE^jouRN*Op`PHueX2JD`^h;Nj`fJb+jJ z@&kfU8|ZDLz&dIi-p1{Qx4n*m5a+O#8CUxZS<|0WtjdinG1-AM9fR8>j zc<>89@atUXsKjvDQ(atU3eveK5J_R=Mvbg$OMa$w^2JJTq)*;Lb1$dz>&8eJV5lM_HhU-!>t77~yJ0-?lQE9a{8WJ%IhE4<6obf5 z2DVAKlAjC}vPhdm6E(e2JhS8{L)DnY-m*3sUadHydIrs}uTr=(Gi~%wL1x@XlcCG_Ys}4X}wI(*~T+qXE=B8sIpO2BhghHVrtRO#|2z>zGpmN^)vpl_W2E zz&1f_kqebWD=OnJd^xI$^Nx_vJT@?WCjQLaKi#iz2ONaI^ljN&FL_6zsT;XD{5gGp zyzMWi-w(puL38P!SY~k0KNR$#8$sq;F#<9TU9ucJ5Aa()>obGTl<@K**N`y zIM}p)Yky8kF+20ODl3%hz$m`s@YM~vqrF?)krvx3F+>~Lb%EkOBdHNUZeBtuK2@n} zsNZu#a5ig_D{yB%0xr%{Hms$^Ahw_rJXfi$RS;iBVGuDj0!c+h5K|+tO=}e+lN%-l zkmLyVA=5?q{b~$8H-lW&F-W>z!#@;vyz)l_5BuC*gYjqZ@N^FMa6`kN0u{?fZZPt< z;42h-2?56;MEBsey>84rnO^Odm!Njb{}wb`w_LW38(Mp^268VWI*X{34MPUxZUY<2 z5MlD(_wUpE9=HrA`Pi_m%>De+6efeA8A1f2bMEz_b8ajFCl#?_V|}Qy4XsgnRU?j! z>Gi2c(b@i-b+$hQXMgAncDB#J-f@W#=E#wSwTW>|LJ7Zh5U+xn*F% z^0&)Aj{tsj7-z^2!v`I@W`z;rY)*k5i5Zse5-0sccV_Z9_$~Rr67+3~F6N#G;m^Ss z9msmWnKR59>wpmXVzkN*@-wReH1>c1J2G|&P6WtbZYT~tOFJ?2Y(uNuHYmpNTPw!i z@GX0UKnR$N4)k=EoCON7x7U2fZ>dP|hTv&hIMbJk!muMHm4tDt;3Z)k4C@B3Ax=Uh zN*7K+qU{Oq#c39iH$^h-`5pZE&iCsn_5FkTq!W|DCsU+i3bGPIko>ckT7_K#u(Ft< zpzmYE2(Y8X1v-)|2Bk|9BfyS!+1MLGj}f4wRSxv@An8vA7-Wt`aK2V56i9qRE+@|tqtf;>PLCuQ&l{!+k??AeWKtpB-7zF1bd_y?D z%`Po|Tv`YY{_?{uP~4(0qk(~~FLZ|Xx_q-0^WsdiTsYy1YzFSuC^~$MOpKWrCK?zl zsv?l|H52+%iBYXpQ;E57=l-{RY0kNj5-`t)JO()vZEElH8M&Px&{^Q z7zVff@)=*UmVQ@M>%0DplR-aAf0Y&s79X4!qj946SLt(pZ(Tn!BhgzK`3v?Aev$O* zagbhzTc{@E&vPDOVvQ)QJ<(Y0c`0YBE=5@ARbU!S!qM&NrB!>fO&3l0-X4DyEmM>> zr61aEO506oCx@6GmZS?B?!D}6ocS~B@?!$|^Ee>>`D5AF*=-R{yI;U)s1gJp^G#8{ zDS=N7squ|hK70*D_3`6@_2~EnV7EzJ7$wpJ!M34jw}<-}sU&OT)Lc1DMp~w;mDbECXuGL)2K*WwJO$K!vL-)1W z4HkUf`eiWz#aYLEn8eHqQ;6nZmshn9+y|${%kZkp)ScS9{D0l;tQDa_X&K2kQ9*R4kYyM0oVYI#70LupnSk~J^Nz91c%h_o z*p$>rK}b@gOs-*)TsTs$=@e5q_yG>iUp^ zI@BqLsC)ACK*pl5JhhEqL@Ggbnju_6^4vDaa}_Bzi=|T3*GLnS*#^Btw6ncFO7~c>jV-K3 z`a3pL#&vcc@gTdCY~#n(qV%U%dKvvni&=E`W5Kc!NQn_kxd{4D@@GDtpb6Xy54KVX zyXs<{@3Id}LvAwV=;R@TR6tN)(V)AnSQ`S}CBM|y?dLhFtdi3PV%7RQe=kJq6SQ~R zljWe?RmrvT{B?3CpN+I1c0?T9_)BIy$jhau{#d69>r~G=)w7}~C@Xy&8<0sdXP-J|rkw3-SKaT;C06Bx1^R_oYeDKWQ$%zg#Cypct$x ziUU=d6x0fWEmlNlwHd>{9f=rN<2GyhVg#$Eh|X&=V;E$#dBGe87sIVHbb~4eRcW!6 zS&g`(EsH_K;eVCN1HTne+TcKy7*)B^Lg>3=HXvd(K8dG6;2}+w#g1l&>q_TX)Fw-F-14O$X zgvlMl%zLi*yIsD7x)xLeGk}TTp%sEs+wgh?U zVFbz?XG~=YuwVYUR$ua6V>?VeY`3dlT-bFkfVpx%4X%bdhaZ)npIM3zR%&J_lcJrC|0}eFa~DOXC%JQI{7!^xC$9~|;plK(llwv!57=UQ+mipo2N=eg+^hJ7)ZE!YXoAi~W5 zV-kMFu4(oqZQ7jWy*IC+_SJA=UmskVAn{v1e>*EAJE0uxw2VXFWyy6(cF+Mhxt`pj zOLDg)*ocMO?9+3($L-woRt{Tl&F;inu)8z+J16A+?%u{%&++G2e8w{lBfM7vo9K2z z_MeXIDPdsKn}jjlhcVHIG2MqT(T6eJhcVHIf%Xo)_~H?b05&WZw{EY_p#c?Q-h1Mj zxR|!&Pz1cs<6FqdrpGn9mF8Yb{*E!d2)e&#Ct;JSe?QMHv3Dkx{Ey`kD~jSlDLg2E z_SqZ9zZLE&;C`6bGd`UDJu>{%vz7QfEKdNg8Mjj&Uxdn1{?VWVqym&GwV0N2G; z5r{xq=cpp+$2vz90S@$4s-fTpohl-)=zvJk6LB1zRuOPoTb&*wKyR`~HDQ$)9?y zz8gwPy(+(*m7z2jtjci-tySeK*M$6X{7t?q^FHLhyBpB>F<`ZL@`eB6zzpunRQc^pO* z1g-&eo$FHjhWPUjewS#EQtK<2#r0Y-r%SC9L@VkmUkArZkt~trs8C@#EBf^|;opBG zr>DfxU_PJ9o}M|8po{U4k-Tei-YcVsb0^-1hm{VHmisD)q!oDNNiIn< z38boNvS?zT0-9vM=PJUIN~5Bq|FGcKy*3z-D;0N{3hxi~t=juF~P+ zDgrJJ2ne8E3t+}9Sw$cT(2!L*st9nPDXVf+5#T`UR^>qJRz;w7ix3b&(U=l?0`ydj zpeO3|7(q|e=`jLyv}{%VC?!<{N=ZOK0L@qc#Zy%T{ZQwqBIt)YM->4Mv~JZ<(7II- zXx$0p z=f^LAJJed!s2@r~-t)X~K3zk;2)7-|>vr4wiHYsU0T?#{L#PRdaa|++MRFTq$h?ui z$8@{24(NVIAH5@J}88W>!{pjlpeQ;(&OAGC=CG8<5W7D&B(_D$x)z> zTE{c*z;DNlpD92vGvZwXmaIWum<8U6o;O$(adNM1=Q@b^4l^~%`KBRA4lc8yf-k*%hx)kvN}I*-U1am?$q;qHK&1H`W8r60wNZf_StDt&B)1 z*#?iaJ7z?3#gbZvUQ-&fjD5_37Gr~`Q$Bh*&=m=5w*eV zgN$h{FM$`8D7T`-!B3RnC;H&Sq*KHJWyn2V8D3NwT<_B=3Y_1oU|hy|W&Udc)!6pq z5?!2*Lae)_FNgO;KQ8gCl`vP~lD^83br_4_lD-@Rx}+~_-6iU@?LtoXQ-2?wD^q`m zCrc`Ge^s_A?xTm2JjE%W&F!?z9Hzt4xx49-ADJv z``!}vc<4Pp0eHSQmAkJc!$tw5vm3O54;q1|{wh}B%U7^-oVSy^g87R%+|0&$qsio7 zs7l^EXN5JL=|jXrLYxVnwD@u;oluW!Jt7cum&X|>GkUm|G$1&48N={m49eUkK89=j z8(=0q21Oq}SZ(x1HWR&q7y*Gnb$W~d9UrZ(%Et)MhYYLHht?6pA`K8&W8Fw#!H$b+ z2t;|!I!6@&j*)eaDgqp%)~tW@>R9XJ9 zMGMn~Bk|V8w=D>bz?ETL0U8P%Za!IKkYUCybPIcke>T~&jc|7GR-o z91sv_A5wze$h03^qtV$9Utb(P5#0}8UtFVsu3#|3!tLn?H>i(3E$o@rtUdo@Go-tq zireK1P8eK~{1)S*v5VYqlQ-BhVm0ZF1e?XMy)ye{zem2IG{FaGN@dbDdYwbE*S!uj zbZ;a_@M5ncQrx~g9hZ>*lF%>H%LrYTE+Moey^hdzsRR?6M70@@D2Pot2e9cb__m?j zWjr?6yM1w6)Kr9WvdkS*Ke5!z=atZDyKOcMk$#XX@3>D%_F^W*uav-9R;IyYrbaBfYyl#9KFZ@`=ih@Np){8qL0c&#M}tr68Lix5;+ zf>>>5U=bqk9ltXRCW@8mL}B$f%zGG)!B#+A0v}OL0-K_PgyAqJ9&pf70mb+~nRiVB znhl3*i!VQzU7+Go<-)?yvV&o8K#aD2^k0+%^%ET1(j$#>VOYJ~={aTMQ94wCF^FIX z0Ogn-=K76XhxJ6@=Xdgj23HKzX#VmqD-O~qNH}OHAWCDl zg|nYaj^u3z=yZ|c^Fi4NFpSs|4F5>pjfZ#<%UTHNAIYl>?^R4pGQ4+iaf1)9_=c+D z*#u-;(~K;-<5x7>_QClotYXJX0wH%~&f2P3EVfXjS+sCmW3_nvjODutp2+k57lpGD zirOe=iNH}L3{CYBh$Ea{AF3r|2{<``X4qICDkwv1WRBD*!`WUR!Z4h}N$eQ32}Ie1 zl|Q+yHKQL#N%%Ov^DzP6`B=^a8fZP2r>BL9OB9@ldoE&kC{AzUabvmLuW zOcM+D@XuJ3Hbq#Q{s;}_+#A_k-kiu~n&+lZ$_*yu-7N6Fk;pplPtv<&!8ca8bzo}G z7F=_%>)c%))9^hefM3TwPP><7rsqHErhFR^w>;E+65J=9s46v6@mNmE6j88gHX;Xr;gM4KQ`VSH61+3*N>FrO6S zT{-_{=uYAEi5>IycTfu^n3$gbGSF*5>sLi+H`9=w(oM|H_a&z=JEK-J zDtFLUV31KmR>(2TOpi;$)R@lfVCM7);j8#S*X@S^7Jg*ffB--DPX^~uUyJ~q8z_yQ z9_%+%8VoWbW8_ZRPzieweZwI)wI3WECw6jlyfelz0t;26ztpKH6zs}oO9Y|NQ1}oS zs_*tLTF!tXyj)DtrJE=X?^V=UO$9!PX^agCD@LFN!;(#)v$>C9kfk$X46v-Uphn>W zuIp-_U3!AC9*}D9JB>UX8<7NKsc${x)jrZ+~BAykS>FWanz~_oXjgA>c-LH+dF^NccqpxZi_# zbYZwj>O;2RhGVbA>r2R)#H$=JVhvCgG)( z7tdpO;d@-K%FU)FJKiFRP0=;l)E1Y{Vz2A0DoIr@xY-My_ilU4#hhK%#E{Du@DQT93Ae?NWUrqp6=0_H>BTaMa1bBaF%{so0O(s1%}q0mA*L}h?W3; z1R(B7Fe<^U3c3i)<{@XxTxUyeBK&R@(5^*BP#+N%OlgeM@J4zBi`7&`=>Zi?9Nf(0 zDkdpjrz;H{UP|s2B>k+QNg7_K@eFJgN%RQ}p|g?(VnC00V45-@^4^;c(0R!|IGL9; ztj!~e1*l34uM?97ViM9T*~aG;Bp7$MDLnQTm>On3?nnkvah<(ZH^@DgwLO zst74eWjnf#Xcw1TcT{^TXF$l-UAed*XpN6o3*1iCh7=EZ! zTM;Nh9H>%VH7UdEIm{B2F>nkblNnf165&V5qi zGI*5wwPcX9(^GxTI`tb?ul7rqQGVV(N%C@yG|9J%Xb6qK)6~d{F~}6k*9!Lbtyc%2 zpnl>eVU&^=cJ?dbNr`y;?<}UacaK6+WfbhkEskiiqpgfU|mas!3_R zT7l^m_@yUwMF*p!JNP_KmY0O_%D<;gd>DcYo0DA2o;t{b>M=p} z$53oPwhj7`+wgif3AZF}2BODv^18(PYu~o<*S^W*^?)=?UJppaPU-CHJVtyCIY{F>k#wGrJm zZD6>(tcuXdYeNp877;NHoxI+$5)DjVR}q-J-rYF-4R@Hlu3<2FUBh7V+AwhO7BYEV zMPTx}iooQxA>dJnAk%$aLoPf5_e_{6fYMxlx=??7u){eU>S(Y zcmWx!KgK=D$X3RP{LrGbo970#O%%=MXbG|~Y}lG`eqifBQS6YeOrtO?a7=>Blu1|W z4b=OE4b)8m2I~F729k=5XP|5Xh+)`=q^yu5*oO=!tO)jYi;ue3^*-`GtT1$92BWhZ zw+g%NAx#WI@x{KO>tZ%k+*9fq0`~x~ZY%Ls{W#)iB(6Wlpdg1Asi(5IqA>E8SOy0&W!g^P!N9p(7z zdqY2_X!ph*6q%%y809hNI5+egXm!6qPVD_Br%seU81%s=*FDA;V8f1Kvo7Hp2B)Rb z83UjHP-GtCA&+GXuothWR(=r<;Ij(yvog{0E)))|P_hc9;#{?Xt00CXj ztS~fZjF7JkuI`FKEXu{8e8JgdxsL+@y{7?jvkodt z12x=axuzV=NQ*WFB_MoPSiub4TgaB6Xzo;M;rBQf0cOByv1V15f%XOG0DJDWtK0^1 z2?rsUpm=MvGIwZN1=z>Yz(V_f0rtM$P^G02Op2|dki9eDwnlDf+~uCnDCBb04j#<- z^q%;0OmZT3nV*PV3`%4t%0w=}1hTbUhI5T+7<5fL2Aeg}6FVjWPuM+v^M9=P9LuTa zW0T)CrSKGY_ISd00cn>0@=|07a{iDvIa&FpdygYJ6s7mv?{ND;DIQ8-BzJ7W-Ix;A zf;;EsC9@;g7$PC%AA8qKlMi`4?1zjIb7k3uGWm~!$To6;@s97v*Gb%OvcKT;CH7^! zmmP&0aPe{y{_!QK^IrnN{#1=-T^l?n+VJ$+@Zz=M#cS)SXzO7`Ap@w=s!zaGJL2P` zlSPNPrq03M6?x?8Ly{^-W&u{Jsm?KwCdBOT!B6`k2_HaHl0HGgznugJoFrc6ssC-=HS>-{;U!49TzK133 zI9J!m2c)8A4m4p$H(~7in(2LT$c|Bx^oaKVovJhp-OA*u($c~xJ|d{ds|cK-+QpJo z)FF+l2y8+q6CDe%sATq034e(+>c%Pp2{uDHhNYj8QAB`!^%p?5;Ej1Q_&Zw#HpSXK z{Bf0nLja-^6N9kWK)E`jS=^z_h$0Fbn!PFlOTqzx>>Y#If};**{(3+)j6!gTUkrk3 zRbat=1zGW3%WY^i5LgUi4kCc8_*-hQT()?5$R)UWa@z0Eb#ynSx8i;kc}MJ#S60D; z3|8U6*nujfwMDU>5<(b*Zo(n%MC|xr_x>x2@8ql&8f}gBpuBfunjy`69Ve4)jof(o zS&^x(1AC}l&mcD!>n+suf;JM(NK+piHRXmy44}d_VF^ysSQXFh5jaN^gTopDY=XK* z1j-(nWKf{9@0nJ?tO^zpC>JT>RBZ@M5ZF@_5KxDjAO?}XG3e6b6^(gUh9;|#*AW<~ z8wajv0td$FRRn61cU6byz($iQ0&b({#&+63^=P)xM%7* z@~t%Yi;myPOKxFtm4MCkHp|cuV)s?lDp$3j@%38p;w0PXRqgUt?4YU8CSVx?-ttmx z9k*b`JbYDf2NWVN3otiXd?v!vn;3ArR;U6M1-BOVnyU!g3-lFY$g3MDw~SRRUsa%9 zps&ye2^6i9xvJsah{6zI=nb?_!!;E`eP2bO`7p!~Ha``3R!;?X3m$+@l)+n7CvNHR zZHOU!Akbk5&w)m%ihz#0&8~D7&cjErZ}cpyt${iZjZ763$9<>U3dUKj(!@W|`i#63 zQ#E%@_H8t|<(HQtONtD|(k&^jFOZY3FQ9_3sK8640+1EnQhenhdb=3pe;uNq3aKb~ z3Y~HEa_?_0^(GqW@mHnb{A;y@A7+*q^Ax&7M8Oi!DKQK5LpY@#T z?n>_CN!t6k^?NF|elO!j_rEpYW>s*0aYX^-6~!$@4qf?rJ?@3#pY|@A^Rt4w#Z-5B z@=w`JrNLH0!;GZtxaISF=;V|7@C=n&zNp92|I#Fzid|CYWVdGW@<{epCRfqCmAx+* zHs_XjJ&ZNGNmT^Rh)i5Fn~UqcF2_}ie5ps^r+%PudGflv^h2g+h0MTsLD#^#Yt*{# z6u+D*_0c1ljm%N$cnj+P>isSQo6rJ7jWoqAI+YGSch zFbXqbB!)=i){YQm_J_Dn#-f8fBL(h)c|nXW!8K%l>rLUT$sIUg4 ziqi(9!cwDoOMwU>drQ;e*H{8i=F;=f*0{699x=MxnFTi@2= zzm4Kh{5=lE-*8s^KdU^x_+w~YeBHdmMzc73i1uvIMN2b`<^$O``XfpXMKDEXSOSE4 zfobp+4GY6KXg)6v$Jfz;A@3dY9wJflC<5(=cJ_@G=N*)W19-f5RRrBD?hFjI{rk_G zSK2#U0#-Zt&Y;=?c_}9pmKRFO3&kXFn~VrnB^NB4hhU%P$-H^)X@1pxBEISlO@v>; zWG~=1sgSTJ#7nJ-Gj}?@hDB=w!Eq#Tse0y zz;<>#nb{&EE3^SZo*|Jx6>B!~!rIkG;#aaGIa_(8gL=ZEo-d*vFSWGCtc5A`9STfrR1vOY zB?xre^Ey37fR2gfs=}geB?t)M{-huP5L7##YGnnbg-Kx`-pQ3OyFNN{Vb2nIti z=C8cISSZb`0W0-xpqW#e>1{NyTr2;WF8l=0@ba z09rp>8*-S>E;6w>AXN+1$bHVZ{#lyjJohLA& zO%uL`yO~56EN|okQpNHCsqmuFeB%#92-#bj7B2_0be_Nv{mv8oOS$`*C)iTsgn5F8 zd)lOY7N1fa<_SCw9R$PKJi&J6DnCsqHNcftYc+CIuQ~cjt__QQT!g|r!oPIclUv-- z!p0z$N(0CNE;?%!7`4`5o$18kp2wfydTq*(X}?>&fH{VssSl2ta>ItDec4iM z%fno}$2Qgg%Hln&G6bji(3OlqGzKSXv_6GSD%=)>h;$4V5$M06*eI@1=^k6!Hv#Sx z;3glX6GWoLAeQ!rYRs{;k18BX`&9&%_6;F3K3v+bB2ZI|Q5~KGjcpYn8MKjap?0X} zISp9K^9zZ%Fu%(qij%s%{5AfPEHk21E4MTV_ryh2ZrsY?^ST$xmjqKr zHWwEBfbGb2@G=Q6>pawKSy(K1XD;3!!r)Qqk2H_W4Ik+?6!RwI$p7~RPxs&-v3q9{Xcm_84Z{{x;XmZ(f9HHoV-}{FA)o z<`37{TnLlj!gW|+_;+#*ChYz;H=c^BYyLPq`|-!PkrJ+--#nft?~g|a9>E~wEe^wz z5Qu+aDDoDpx0igMe_2BR!Ef)lFFh3lN$lcSif?c5CDJRfqwQq)ce2onoROaGUwTu- zhC4sv9hnTO7EBKY;}Q&Bd@$JmQMw4hfFQx(>4U+G4+bwjm>!!C$#3|##bH|};`99m z-5hR7Xr{%_)sNrJdp~kZJE9!p+?*%DC7I6nT;mIF4!2u;VG>4_s1J=W$unaLz%UJu z!A8p(22E8BgNpD!YRE7%B*uA7s2u|r`|X%t7!dXn_*#K+G$;|ns$o@TabG%#D4otH&$@tjts9TC#E zBNY|doTKK6EMH0?LhJ+mUo~m4n1nj8ia-l(h^BDho85-MF&e}IhmflXTAP1Q)uK7X zMNH1Iivuqjx>G}|^Y(X99BeW%J;G<8*MfpqMflmG*o6MnB4#G0NB9n~)Nym>BL&eT ztYNYev!2h**sx(dib4O#Fhe{~ONnXm803V5%dl7pz%|Dz28X6raNA2j^mrke!80aY z4b}oSIZn{719qcvzz&}osN(Qa4MR8OhU=pc?lGFo0A$74Rg>YK8YV9>Bi$Sp0#sne zqZpiMG)$-G!L{IqaUKKrEGomI9{%#himPQQL#sONNEsH){Utv9V;q{N3{*96R}G`N z%CG|{hTDuobJfynRN%HcCM{mGq8#$ady3Io9#usR11E(Fz~@(BOb?`(gCSMJp!qR9 z7#@ggaazaru6hilY8Yrfv$Rm9epXsY45Vrpt<4Mzhly3r;eG>Gv<9OuD;25HbqrH~ zuo~$aIJk@E{J=x~xK?uUKtyS*2O?tdU?e}PMVT9^p~!**f-R0!gddQnX|cW{Hnt`O z(M)s0Vyx>U*}XBl1kJ#%DIyayC3Cx*!yTyYYoT_mkxUQn66QUZCZl>VPN`wgY<*5m zYnW+h;|j0Zb%mWd$ z%zap599YmHF_tcBjbYe|&qo+pw&cYy$jHRIln(MyK>|-uoYp-UuhuZg1xVuJT0LBa zO)C@ZCa|b;IxIrFyOZZ}L0DjehN=p-y|Jt`(G>EHa#~!jMwMmsdNVzg(Hcfen_&km zZMT<-w6xVQ=o9R$eI1<_i9rmp1E}*N6&MYoRc|;M@yRjFFlZ9{;Ls=roXv}Ds=>O( zFpQdhJLqe;dyT+A)p)I2Zxp>;7ssJtHmP0J~#*loEOC9 z@H(L5Me}Go0w}{8&t7KMqH`8|%Rpg!7j04cw#Thac z?o77^44VgJ7L!-;Cm;Qa4ZpvIEk@t^BUdE<*u1eFGY&Yi-PaEGh-(Mm#xp6m4SsPj@GlNtL1@L`_X)i}`0ycs4j-~`2%v>S zE*;`!E*)|;5myg6d#E6a$(r1s7BHSwq3_29OW)_WSdVXiy91BsyH3YMtowQQHGCX3 z_;MWZcGnI54IlRmewfF-*<|})q~qu${q!RDlkU^I`J_0X6y%eVct)aq6zqrqcHAGE zXZN3v!@X{PfDj=P@XagXn^(d&uLN(wRr#YK<=14HJiP7vHa?%|e7BR&_j}GAgeUlm-QMxJ zc^!5<>c2=2&imXvcadvbGno!`M=N+V6a(=@=Za2GUx5&Sc)#cHK^}4VpmPUdV_TZ> z6OE|I%rcyzfxhC2H+=94E_C1y z0r5oVi!hIf7dzkNhkxJiIRWMoal)W824RQyN;F%uXUo!&Ft#Z{22Lg;0m)kMd9Nl)B z6&=u#|Z&|4+!ZxVCsQt}Q+~Ma^(@dacx6ZGYgI z?D>O^7$oPeDHlmRzzX1a@ZcmPW~9Nz7gZkd-Nb#O$G1JtN?LUJ6$9+<7_`Fb^$U4t z>ox7yv=>luirW(B0AB1_(GwtOEt;=-?rwH{8pZNAJ=h7`WUt7!N_UM9qsCs`dV4GO zKd@d+=-HAwgq|IOD|p=K591FReaTeQ@yK@xx}*)A=&ww>vg?K}|8_^$efsuT*R%Te zUe{6GzO9vs|597+Ei&aQ?hd*txuC^2Hr{4;d+W=(yz+9}yWGq1%k~@E@wmJFaXubz zKTnr?e%p0#7Z8tjJ;TS#UGMPmPS*l$02g$h%?9x7?)kh~1*;&nwhKp0V!v>2(&E-j z>9rR8i_DBDj7z?K@J>XLG>9nKT+HB8A79u`q7xA0@;*HVB}F}k0hlqZzPpmpb(-`Q z_D%c$<$DGd(hweitbM>CYzPlYj$uQ1SKGt5a^4-)eg>{ucZ=JX@$u8HOS+IPmUi95 z$6Z~^`FN@8Ej;=UMzL{d(n|8SUfg~q z;VWT>z_f PXSg-;rTr-Ylo5aKB9&MjScu}^3=l~f!h?PYbnCQ_M9NM*DQMn@G1 zs#MC6MpVR?L#A!0Z5%dssr^MAZ$v~@YXsGUdb5T>HJH8T3oK95p!;c{R%|5_=3!2cWkb-qXD3O%8A$UMeL|e|lKC z3k`)p=D|w03=0wC_{;Fjj{cX=4~hCEl-ggkypMaC+-0qgV1Io-EN;P*C>-SSZ)B7= z7A#Z6aXPM;2%u*`_BRY~9~L_e;ZJ?DsQPh1$?0V=Of*(1k3r9X3B8yh20a5Z`Nmv<&XJab3CqYc@|fYxEERvWB2chwx{@bt?e~DLQ%uJ>8t8CZ2XMF+g;Mi?fxy4 zfN!0EtpsPxbtfbjB_90;_ki>{mCaCif5@FKv3&n@`pk)?S|C8(cQ({jPG*4 zcliMg`BcU4-6O6zpn<+EuE}?|)t30)p9re3 zaI{=t7OaLr#bX$>#7G6!JvEHl{7SI73)$x4{MXD<7qnc_g20*MG0jx6wDw_i z*9?XgE%0f8rCbzSsuAD!MZW}P6Q6-nhc^PVUYEDE%JO1q*js|qizq>;a)BxpYz)eE zdB!XORjJVYISokb>iuRHFUH#Px6%~ykFpDphmD|!++lC)6^LrJ>&53ThEGW6-mvA1K%`d;UBdD5_5wMrG&oP%DD?-k8V4YW%tasv!uxS zge$eMx_W-|gPN3YW2NYgL9|Khmd4DOd{1Xza2K;*_i%dz{H-<&c} z7)d>0AVuMZ7!)5EqOJ)(Fp~PR>@kSg8#n?@8DbxUh`oWVsu6nw(S2k-T@*C4 zdsti;VtWf>$y=0qE9uppxV_EG zd93^L=2DO78!YZ658-|Vqmr*+E@Xnc--nAeF$s5q4|ie|F7}PPK@u*QmL$KS)Nc|A zCi;e5Kj8rt1vwFI)w*>VM*&`+TkxbkHbT1Cy2kyo64K7{sz8P2Vqp#BRDX4a*Jjgro9`vS(3fL3d)iAK=dn zS-LwU`5osbfA257x<9!;0ap~sC4>>NJITegAozP&i6>_`Onn1AZLHiqp`kU>k72eq zg4q#|K$2sa(g{xLy{z)sk*SEij9RVi3#*YBP6UV3uYs2ElA#!MLTxMS&S- zZ>u1fjjCns?9hk*UF$iV@)lC}) zW^q#t!Y|)bs=8@LU=}yUpv+XJxuN=Z(~nI)xT%JLeTGr{4l@xHKe#mp!QA_@_xos6 zOS)CbQ2lRJx=aOVUuCP3iERQ+=-e8pTa{uE-Pa3Diyw*vu-vK?g;QU6G*V~Ss$>`# zRbiH_=S%g9HgPZ_DPIphQ;$xa=`Q5OAQ!r;J)(GLsCP*CvPG!_^+>E`qTAu73|aZ6 zY&knU=!GrM&g2#PqI06?#Qpg}A#0J!ucB?7Xq#@@&{q;|)4jHFUfc9Y8;1e*t7sbU zb~qD9&VGKd7acF6giB#U(sD(2zD7}Fw_%4xyrc7AcU5+if1x>oVf4sBpAiwOz5HM^ zNuK$Z?dJ8Dc|qsP>1*gbyVuh9Qn`8Bot!<)YZ#u+-o&F+gf6>H#?+jS4?nMN(lxVE z2d#;W8PUYuoH!pi;$>W(u&|i>DSptH#_e1U<|)I@Ko|P7UwE8{qsL2&+r=+=v}VY;f-qeB_?-Ckl2_BZs4 z$L@v_&mDToUlA@jv5`abqVB{d^dshz1$z46;Jkq2u%S^Lrq<I15#Lx<)5>JZ;V7Y=Yi~TPB!CgfHi3HZBJL6p~;1v>0&y^a(!?J z36aVT&s!R%hFcos0}QfTW2GE^`|Zkf;ADh#HHyfZJ~)gg0}g4|tb)kVF%@OR`UM=g zVtOzJ(UEJapY+>x0hEp$sdYR6aU6$Oy4VsUnE zx=-Rf-bu*<$}fOCks{?sl$6WQ2|@0I$%lPrATBfZceD5j^99M-@&zx|AFBsf_X70* zH3Oz%bRlt9gbSUPNc*rRYD@GMhV4_}WtQ|$_L))kRc7qp&Okwuo(jYE5(u3)m5ULd zL;Hx-HSm+!MAX1`sX}gOUN;JY>lu@c!(+@w^4RE;e4rJtM0yw^ZSh=fN(S>qiZ7T} zs%p%8A3K3H0M+WduO&)XN1;mn5mEY+mRcg>DQ(VcVV4y8D_WBNAK-HG=3G4v;>c%9c7H`2$V;2zURPqw*vwTH>jaw5I1QXxH(cZ2J_xg zC$h1_$+(zBrh{;cFfToh(wQR_Tplvk4do|h#(X53fo%Jcjj|b7C)sFo#5Go9s_7YM zxyK^i$duv+<8A>7-VIyJxY@PAb?d9i&8`l5g%LMqxCakI_i`AIL84||p~0f%_c4X< z0uC(jTmbXlT$};-1suGI5?~;{Pr&qO@D6{*tAVebRX{h3y#Ss#YxNAMEJZt$0p_XUyMC9;WDTg19txN~JU=?q*$fs*=j|FR( zA3L#eYO1>=xfYL5Lq|O8u_|5<75ii`{Yon4Uy->SUgwj7!tbIM|L(qs)4p@uJXXxd zC8wcgM>=cR+XhyApWBT*Up;X?HckP)D7n0E#awFdX-<=hx#znDUhr*sRGHu1x2%}= zozu=hL6VA@VS5P%&f>UV2%Y;hHrygR7^QEE?J=XJ4SvbcCG~RGrt;WgdyW>N1ikzD zK}VL&?!mP~AL0X)0w)n9mhDp4M+jUi>9c;717*Pwo&&vYL!iuUc{*zs^tJ;I1qxct z0MrFbP9qES^ueJg5pWO#_%pRGck@`zP*YlDaZ91EDXR!%_9_C|Js^Bd8H25zX`bdK z2bC7sDJCwFAc|kbP@}Cg%Q0pNI#wyr-sy6DZYl^MW0nCB2>JmuIy##<#)qrPEp6>2 zwGXW_^08%Iwp*)3VFX0V`?DsO_s(N#34^}-wzgm0($+?l{-mX?jd)6%rLFCk!qmw3 z4DlR|3PASWOIvFa?I^KmYrko15+Ag+RRn74tCRzGu1nbqlV1WrmMIbj)^CTd{!55)(kFse!OsvDNK&v*YfhI)+BB z>X-LwRp%P$z)W%{B!A?b}xon==a-|NBIjAU{3 z(kUm6Vl5Vt(WtB^y3>;5GxX+<&(6|`*0ZvUiMZIu0_~8*0?WRP#YFtMAP4z^{2c!& zGj~qs%{SR_tZOO!0>Py|Cjdp~5*4}kGHgc%&t>Rec(MDEH$3W%1!tXL=^?B5-%L|D)aavNXK>h``;1=H_p>OMITYI$eSjfq1zF2eSDRWk-Stj2_Cn zo93v!3ZU~@{QAe+*cUT=*8C)&b58RV*YQ4nBiEYsP9q2HP`B6xPG1p)m@^9eMK+x( zow-vJe2Z(kTZ%0$?CD*d-YfeU?#-681AR^VW9>vg*8VV$l0MmqBjnQ~e}5Fn%Mw&J zSUE}0gX4TCA=v!n-~zd6V2kvi!fkO49C6Y-cX9eNI07%fXurFiguC09!yzYC9dZ&J zVh;Uv(1z-Dnwy{g2Ok@BKWqO5?m~{d$hF#Xg}f|lJrTEypriRj+wu;1d933J|MGOl)AACz0|k$~_azVcms8Tyz2Y;|bNtJB z=}-O31uTDH)&@iDsr{+g$t8zVX(wOAPQD!80`vItMBAS*$Bq{A_xU;sL>4vaSjCc>iIv@CEpF|PbDXK)1` z-f85^Ls{88?>*-{_C5cWT#L`<%6lIk#$6c13G9-sN&^dJ%u~~l7iNJUU}Vzy$e#*k zbxB$28sug*P-X^=mePPJ{U?k=EWwDUiU5b{&`JLoY!+#=q*Fujy6W?0aYrfX@V4~z(|BIC>=MO-JHs_QVkQP zGMGt^P;MT5*~2~A`ebX;r#C8HXY^IsRYE@pZ|ot-8@J<`iU!&#Bxmtd*yo{V4|;Sb zgKJ>V)4pNn)Dy|m*z*)%SOa?^UNoF!VZ)gg+o=xS7_+m2x~DbB^IJSs!i=cYOQP3XOj9}89*ayEU{Q?$x*>XarB4iFE-D7I z8K@A%l!JpQqx`Vo$n;zt7Dz&_gf0oP5<03Rqc%i0Vpp7`;rTHOF+Z^k=6O(Y{akrk zJO+l>Fqn9#VVLXk%R*c>!_CO<-Tdb*ydk+x6PJ@%Cdk!6^20)XGhgJXk{}V4dP($p zi^o*1QHM1_V3e_7zb%IBtr*hc1~Ej*@VE#ay^hpHLm6C)?;EGLlcTMn!UTV|N**}D zxtNO+D2}`Rsmb^HI6qj9n(7SbZMkA)44mO@i^pAc4T##SnxZ|JCdy=*sD_c8cWcfJ zhVU9Aq~N`noF*N2LBeqn9Xr-vOioSlI5h>6jL1bee>5n;8BTX8_MhW%Kc+Zr*v@=W zGRc>YMoAK1Dok4Yf$8y}Nn$iYm@ZE4m0_6KR5Fb~I2Yp^VR-yenC4>$mKJZSmIijz z$DrniKrgs_)QCWT=sP!g?7G1n*cz^MtQj}hlff@!W_Zw|2u-xvu zG3a;n!C`0-aL5x_ZjZs1Du@jRF%_kAeNA0oXVWwJriyZnk0Qf8oBaeXG?zs*8J2+j zkIcXQBRdvTPW00tjoX@DF3k;rQH|#<)&wWwY=kvg;$j$*QXv^bRT90Euc?vvYyyYN zwEGhw&2jFN7oUzAFZ=w8y_JA%5uD|XLG)`3^p`#qM=3M+W1v1eUBPu^t*8QmI?qyw z)U2?H9)EjN0QpfPxO#8x1>+8@D(G(!i6#yVrGWw!ZLOZ z1GD@5^7(7~;@}#eMxOihLn&;2DE+IS%XNQEmkk19*`OQz7cblmgKj3`=0UeB;`Tvz z5^?9C2R)*gGMv>?qwyv5XTv8lh=_vvET(cli@C4K?qMGky1;);AH>a8rFgXJN9n%5 zNZ<9mKA%ni#FytU;zdrtU(|MbI}oQMoju~7_P=!i z@wbi}II9ef8#<5Z0pf_BW4Kuuh+}$QCgSBDiRHLOrI|vn85dc$gmcA9U>Ux{Iv2LR zPRC-l`1SMz+?U}_$d;mk1Z8Q9XvTbT?7wKbIMO)|mE|~Uyq+3GZc0^dN_8%!YF?xX ze%sCaZJPNFldgZIZM(s?cli0zcbvEh_cZtno%_KrL0CLr#l zo2HqYFiRUp29vbaUu4J?X}X|+fS0!Lc@fql_++~9d3WbKoqYbJdr>!^3PD!#5vp!PtPAfob)!|?XjL~_)s0qlqgCB#RX4h>?o;bnHEtzLO}mA?*1~P_SR?oW`u9Fk`&-B6oUvej0(t zbzjk4f^{1XSl4Vo6X3ENFsi~gQ!dLNL8l%se`@&!+Dg3Kjg21i@?h(H^aFu8q5bEW z-NkoRs=xfGps|3);+N34VlGA)cR?dwe%o>u6yfED;z|EpeFyK2{| zbMAep>HgQh*1vLDyiib+G^Eq4mhnULOdqzJ@Q6= zxS?8(v+bSs9hE(@mmQDpHUo{zTDqmrB&W|_to)UE{A=ZG=JA^38cxwYS38l}IX^oe z5C5VgY)#fo(j-WNh)Gt&Br9T)6)`Cg;fB}m;PkeEx}E5;zArsY`}rH0SDf>j+f32 zwh+WS9fIsS<7d*%oLVLtiEFB`gvcD1o|3xYMd?K@m^-G8;%DQ&&Y*DKAKfa0zD;mg z?dIvIl^j=<4)&>H-@a+*ySuu2E@sR{t8_gd&7xXa#kF4OYMWe%AVsaTycV#H$3Y-I zcR~>QgdoO|Uv(Wz8BsLZaMwOWY46XZI)Wh^a7d#82RdzAxbvd`juS@<+Me%sYTIL{ zE3rrhO->ovz=aO%NjxQ)TMXdRU-fO-_J}#Ab0K5+3uDScL3e3mO8iuD(gv0}ATW=# z9|iLqZ8e)3O^HU0o+8z~$J%XinTK;KGy&S!;S@$rTg9y&GtgqHt=T!QDTz4N9m19Z zTLuagA#5qKKn9!#r%h_ISlY{ExqK#UcX7@!uD!}|@;_H-DzVe3p6lq?TN*GJq4zr3 zBwD*e%)Lmoy#dqFuT0a~faz+$^lOmQJt&m(GSV8@fZ@xRxH=k{f7CbY>!7JyXH>F3 zzKBPi#*uz>k?*d)%QFWMdMo`~3WC3-cksknAXa5PT(g0GvIuJ?aa$bQ40CS#HN3xH zI}Kwhm;t1f%X{Wc58yXn zoK1ESk;A|d(+~Vx63GklQu>-T3TD7C-Pm_D#!57jw^FN92ORq+IN;1Il*GZ4`9=GCCMa{FFryGW^r_0h?aqb{QWXg}F1y*7x(z$3h7&;BcV5+?~W26%` zOb{59Qv?R(EX9_NLVR7srg{1-p3BnPQ2R8*i0K$7hGKMqFVGt?U-dcSSjP1jYQ|ve zbPTpyu|c#LlLS`b2qhfEmY8L}IfyPY%WQHGTVgIp7nw00yrz`P(M4v-Rg`|s=UOiO zxFLOl)%bDQm0HqbwVY}Lk@Ac=(bm$W7YsQVpu=N>rIRWpm>r{Uj1a&{zB|S`*~U_4 zIjHgT97Cs#_n^e1H+GGRkLPr8Z;)$T(zkqOq{p}eXY_i^z1639_|a2UTmdVHIoYM~ zL_|exU77N5u(bg05_N>JyF{Hu5Mv^Lce)raj@NbER+A8e_300?tBl$pCQ+)iIO-t5 zK5)}97zeZP_)mlfuhk-9oErvct&u)PK9L*Pk!`TUv*q;A!E0p_;-O<}jdWO~m~}br z>K<2>l`R`MJPxSEJKTaBi*aw`irTw1OkMDo<^(vMjn-$R%_6ti1o0H$ILk3*&bW$g z)m!+aBg`tJKiOmFLzod53Y|BlK<^7Fmq3tY+o;Xe!pP|Z&exz0GwwmFGcZp%0v<{n zf|dX`o8}&b*@iR+>6}UFm2XSfAE&9BI%tc^bmbFQQb{HPOD-BDbXXSzDS{ zYWG?fHVN|LTva_o z4z;C7!W76S#qs&u`l)ibZEs62pW$#3qqo@+e=)P^i=xZ+g7JN_>tD3EERFcG z;^d^FQ<0A+)0c4=FhX4IqOsNk*r6|BY!1`!d0!g96$1ml1Yf+AlZ*I}KpFqoMUUn* zY?LYW0ILTK9cTOJx*_dsmaEZR!b~PrDI6&qYi6hTbagLD5F;Wb(q$5}zPWH&6I?lM5B?_ z(U>pCD&74q;6%o?l^giDp>h*C_`p7bGtdA(QF%&WCnAurJy!PYhvn##K|0?rjBTXb z3}v?8DcJ3ZB(RQlCoI|r*UsQtN$9=GNf`B24e?BW=an1^1%_hA7wYVD7Pa{k=ZME* zj`)FsQaQ&KP-maTRO(NZJK4((q_U^A&oNBSXnueD!9?PPpN|C3dA?4pmGD6 zzEnVg|JQo9e&8w01rRohv)7$%od04}RxzD$+7PsE3ZGU2+-!j=BnK@4WWJlrq*p?S zVzAhH@pM$;(znV^cCLue5WdEs^BBI5A#5qoX;uokUnPW{d*ZOF!V5|%im~gPup07A zM>51GT*5%GV(=+N<&aUu*vVAM)AB# zD6XL6h7KhRKO6d#hfF9ry4Lj!2G1@**qkwk;Kfw zfPzrj5D6vZc5kmyoZa9ZlJqT(T_faoP1-e*^eql8xQc@Jb5I0*u|KGZINF$GcLg9O z=slPm#wm<40v1<_wS*!>*d%aThLX5MaU4c~c@1h{ysCtOCq3iFQwPZ~XbxJj*zl_a zoCiTu;z6rO83A8Xia|mVBAhj%?4RA6j3EQs2QFE{U|35r$PSf9V_d?B)4$^kX`;_! zF!G(+IXwMKhAH3oF=G(33X@rO5OIVKAOnPQ|K&iQfs2lmg3gGzvZ91R=c&LmdW(uH|(eX`rxT*0waToni*t^>;ZawEs|Ufur1%tPqP7~y#~)Wf{q=QC}E`1Qe1;TM234 zUI_#BN*I*hkNp&m93i~F1Ko1x5JW-t@k@6aU^@gR+7VyJJMM?!tX+D{ephgE^oq)R zyanjJ)|1)*ozynF4bbei(+Qp4_DDZKkMvv7573H!$MBNNWBQ-Kt1uzpg#HVF$Zi{G zyC*o91Ui1gU!c=SEUFo~qYU7PYFJaV-*afWpE=w-m)ypYWngZrUxk59pss3p&t2L1 zUhCc14G7fTZO^z}mCv*vgYQ(Jj_G*C-Cy=f=lj_D2h{tWD>$+TSu6Uzja%k`db{6T zcdO@IWJOR55D=;Y!>fVc|#S|J*UB`x=G((#^-)!fwx#OjWlxRU3lF3ANDQXE+8V~Ya_DULnD;&4;i zUe7?I9npOjYhz6h9bsp21SAFcz1H3~AbQ)x6j<7$rjUFGYkRz47bwV|VC7>Q<$maR zPcUay;69j@vibsjLjRMAIJv(R0uXcipH9T-{m)_%0C86TbBH*{mI>Ah6%+{;3#Cg3 ztB2neCo`}&>%rPlnFMaHuc}L6UdyT$2G9m&N21*YGwzlBjDUXd8{L{vPTIR*CAu;q zOv99@;Zq>bg>#7x(U(lA8AYNEQJxJ^nuKy$0{XFb7HC1gPn}P@9bG-7Aj`~Ig6<>D zWTmjS=|sbZXIdKEFx78h z08T1^A}Z<*2rOnm17^suK*+eL-ckTtItyT15o|Al9YqjRf?ivj`tT7s2KtXE7T*|r zbxh+Z+KQGXtu7pK#N{_H*kIt}S zFr5IB5aHY-#(81|hXIXZxE!7?%pPr~RO&JKiaS_cjRQdeXhlPDB|t9%sfP$vkS@<( zs`5=V6DN+2#I$twK_-Fcx?aS2mB75%^-5QY>V5Rcpk{Ii=|5Xh_HQ6?BQxg_RBIc3 z8DmCYhIB63o1Og@^C<}YHv2QW?Tr636C~<6q{Bd7{Skui>o1V~_bHo;`oEA8W5HT^FE%(VlYUr7+gM$!Vt5h1D(&w zZWTDdA{=NYnW4k>9gBrQ%4zeCS7jY13fs(J4EXc<>dzJtWnUg@UxQAi*vTQB3{+<6 zrd}aInoF|Fok9sFDf^7Y$Ck$NAb3`b`7dC@cn%%0IvkEVe0TB1<+anSQ(m4uWCPcC z-P+7M1A*IkEx(CM>eqWWJeF z(_9`ay*?zADCHE3fszF>GqplKc2tgf9Z zXX{hXJP-9^9?~EA+;Q&txD4w)wPqt@5G@*$z^a65C5$aG%iMFH%rdzg#Fm)L(Z!Ty za=CBja&(bd42202pKCcPV^Qq}I>M~%Otl!Yp3{sF8H>0Rla(OJ7_bx0N+t!9?eE_V zS4;;x1P%s5+L;GM01$&*e7BAFpvJ2^V)k27^#17`VRP4^7f<5*yMum|3k$|36k#dQ ziYcPgj-TY9j01h!@w;)L9F*8u&UD+!;eg12N7xhhA>L#3{6LSeBxn#%b5c-QV0S#E z%y$U1XC;Iai$m24JQ(;35ZHZ%alax0Gkc1FR8WKnr%9CUIkra8%bu4(U`{0QPO ztMA_`4(RYBjNmG#pNW3yc9fk~yT}fFnfK}o-M7x8tyf~Y0b@kwwzhLnr8Bg&<5@dy zWR~F?Y>WF_$KPzoe`S8reiMC6%J?W}vUo5}JeVLJObrhvg$L8YgNb0(xqiofkt4VN z&ocHgDMQ`=QO1gG3#{mVLAgD|1^Evp3%G&`BN(UE9;6*Fv36Y8`l#FI^k}P?@|^ai zZlBZg_N8uEb9X&jr2XZf&Dz(7shj zre*kouVQaI158o^Oiuz#O#)0y0!)d4JRL%|*a|77U4Fnv_T22j^+LGy>M9;0byf9J zyHe@o+8K5^>Gk#bc3I@ow)-(=2-4@;o|8b3l3jtu#L|&o`XG$l4f-lR62JN#*{G9u zmjgFC26Y*$mG|l&V!XGns%C{&HDUKXufvYvlp7`BQLH=2h>D_*q|@G4;#PbPlU2jy z*D&7@4O5Z}2X93oCm*9kUfKn&PnUlw&|H!$-_&^b9fDFEau$yTJi2xb`-*4QFJKpI zdHomo#>OdP3wYncHEk#JM89i0?(4wgp^m5cSkbWpkGxpX%=7&ZwC%#W6p+2$foDS; zvhU0-3&Qi_DR4QBaY~6-c{y&iX30NUf5!R1rEN#J=H~K_TW!;#d{iiBZA+%${b*ZW zk#~RsBtU)%kUe}4Lf+-v%S9GE$bbjQZM!1L1qppJ9c>*#-hlNJ>!{oTZ{Ip<6Hy@k zBz9EBzfVW83-j0Qi*FfEdw5%yrOs_O@x>R?RB*@=KqUg41E+Z-m-Lt_i+b&n= zK`I8HeUi^O8}4Y_*d4lLUW}zd=T0%W#+_Ut2In7yprni`Tjg+4LyVAM4y;5HVyymg zwq8lM$YTtKe~=v|Fk*M)_%n{99&>OifGt6sZP_4FF@t566halTp73Cd^83nzwW}d$ ztzlYn0xoU|VM~F-u)PRUgs`Qk1v0om7S|MOnw9{V&DV0ToWDkU#KWFCr#p;`5ru`8IY~!WM zF+x+o2o1hn&&qw?$vN9$@QK%ev68Eq(x8M$gL*K)tO5q#uO$o?k(Myn`lT48MXmzI zYKT#4rw`8=L>592Z>V<5Ij_iuD?QzfL2xi}GJ4}f*5-pNA7;52o~8joA&6Mz;{tY6 z$RQ|a`sIi{vdf$#CMxIo`AAeXc`WN4InS@}Xyl+*g(WlC9S;%GKMxQ{4$Jn73{6Ekc0`}kiS8_O-+;s5rN_y%25cGouDbM*@D1?$s_!g?vFI5wP7I5ow15wz zVG@I5IPtF#<9VQw{K_957~%;(JeJ5_i83W8?iW{=__Xtn7c8i;G2@XkGmRYOvGQrt zJO$A-rwme%!MrfWr$FBm|I1_7kOFFxeVlFUV(d)6ioPnFGZ3F6^ee5&mlG1r31NMJ zdpWsnmEEC`kKF;WAt=RIK=2byY@{ihNIuYZfPw*Gf5^4J^t0YQMxbdMv1w&@v*{M@ zV7zooA8DiuzR_mMA@ELI*PCP-hfWi|NB3})kr3c;$Tbs0)$A)OTR18K0%L$7Xp@Xf z40y-BrfG7ORW$(ND*;$PFmii_k!6E#o%Fvn>1b2^@VlaV1x^*SABsn3S7CFsgsnRS z^l(&0%S%#}gikAp!JGknC`ePJXsMN2m&>uB8J=X zQdC(QwACm|LmPRLzBN{rG6D=rfw2Qt8aar=0dlZEVgs<9g9Ra6ipCp*Lt4EoJG79) zpcb>hSa7XBy2j2#<2V*^jCo2n+{~?=B^zxntzF7zK88VQ&Drr*k{b^)<3Zli@JDk_ zX}8EL0dh-#{0!uY6ADr!WNMnAFy&^WWB6%AV1heqj@piI0fqtu# z+wsjx#0Tk7*k{GiyxKe)%CjyJ{It^oi;}}QWs6_B(kHh*t48x16hcFc*o1L1cG$p& z%9eb{OqR6{ccx%_Q$QfT62$Xx-4GV~5CM9$4@G$)0`ce!`}lZDR)7(WCF^-Kk_+M1 zDVd(BFO}6=e&L1OBOZdt#gnco!g@=)ztc#)k;RSIhBf0f7nsZk~4h zuDQuU#^M*JFDL~DAvi|HBP~s4n-{cqujdNDIQTXwB2dhVV3l0}IVxU=4MA3$AjoZ zv8%?hC08(UwnQs-i{b23syGvM+6=CUk3`E#4(ap-@%XS^5q}s~(+;YUCh0bNrWH>*Lk<{gb_!H5J*eH1bgB{L2<;^&y&N8{}q$qS;*qPzn^*`IXOOI|itc!&y~6 zd(+EOJ77)1fXWWsgO2V6v7n^GSWDPWm6S&=x1LVVHy(oV=&B-)uFk5WuzJ%=Qbk>Y zbfw_LsJRdxwLsnQplZ^6FOjT4GiS?O+!|=v>DT{3zW<(FxZ=)}ZOn!BwCsjr$!%9C zs_f|kC~J{03h=3T{5IY}Lu_ZyL?7^Sq~mM9;nkcU*o_3Y*XOoi4R=#w*~vh136Mbo zWRblMXdG3xJqtJoB_7{9VSETmyf~!jmagY@#0BtJ@hCU5w*QBOS7&G9u2LYE)Q`g5 zIyZz>`$$T6L%#MpFYJu*$+^!`KqDRIGvQA~S2XH87W>i_Frd1)@tSm!pf!QeIJd zfX}t8=)5hvlO@|zzglfcx`1jekwP*FypkOyo+2E?*u|YHRZ1`GuSYQo0g8X9L*QCR zNY6oy|E+sBcyBV|J!li4Mo~K3E4~$%KAJh{4XFf<%CNrKUcg)?G&3+=C6qQqQVF4R zP^RreXd_|YLhaDTC(yK!uy3K5UDm8eR(A{|oa2n)mW3wSFAE5ag9iw#=)?j86s>l7(GxDmoPQ}1em)p6NnA)B@Bx1VmEjI!FGwNM_9qw06jt33;j9v6bF|L27&NLS48~6sgDf!vsM<>y-r3~33@tV68%^Dzm>W7D#*z3l z?d=#P408Uy`y#e0iBM03820iYJfL|57#v5W7&qgIdw@$A?8GQx#Cv0`yt2Iw6S@9m zwT?bs-FA%8pUgURiL>ow;v2n$5kdHa+jdk`4ZX_R7__WoHpKEy?7Q9YZA>>g!hlZh zMOhcb>td9S>p)djC~RHSQR`9;_NQ)$kB6Pjhw$)I9N0*@;UoZ) z9&*=uJ`}&oyF^}v00<1Wky27Y!bB?pCmwG2Z#Y^0-$Vi+kuXsuxC7$T7kt(q;fC5* zD;Gge(XJ4cOhLzqkqk(;r4XHSvg1*RDssY4ws_qd`$TN81#$MT4&JXaQEH}un+BX4 zi$<~@E>|{)ku`65%)p!n%WxDQ*_L^g%Wc(yZ@Z+sY?doo)gij6b#{+~Fr9`>qtmix z0@RjkCV(qz0#+n)-_NB{lQbZpn5Y~*wyC2*8zx{7lA zzBER_1Ypp@AqefZQ*r?-QL2T7k7-fmYu^_^{Cw*(F7`!ibB!8L#W*umvNK&m7J(|f z0da^@#0TRuE6sBFAi8VTx*y1%!|w|4Py!2voF11cu&<2u$9L zbO}dH7n&Dfv^@nF!_s34^d%T$-i3Hn+8&kz+Hjx?s_h0Gju-YgQN311;4tAL1iAq3BdmCfe00VD{QyRVh;>Q*hVRUiAx21sG?0WCAsM<>IiX<< zn6&~i!ZeZQ7oIMKW^cG$LozXS@_^p|mGzz`+`$o6t4jKsTldT>}nu z>uu1O?)pt|8yO7r%y>${b`(mnpQoVP+NZ|P|8>8JKl|at6Q22&Ep~CkaB>(rB&ZD)g9YHk zBz2EL=ZqL+>w3opnqQME^BB+&!@fcKtWTE&_pl<;xh)EMm!LF=p#O1XQjPa!%|Kb?|B|%49p#B`(|8ux9{6}VXj*Nw7kHEEcL7i0|f!jldF6iRDtz231;;1BdjO zmJ!JTcrYmj)Zj08ja#5`3l|~2lKxe%?SOZM1QS7EH71SK*a|9;O%O6_Y{{e|1YJPX zMU5Ftjcpqc#I{t&&&#l=76$~(xn>47yCFi*s2OMLa<*XS($pELJRr@IIeQal0 zlWH1q=(VaXBc7jG1QEN+8A(nRa%sy0*Iy%B8f~Imus+n>QoWO(;K=@+)yH^7)N|=` zcm%HkFGm@?rKQ<&I{@2#)dGjj<{lO)V4rBGEz}&wRZJC3d)GWBYQ)6o;$xY!Y9=y5 z*mB^IvjRm3TMAUo$p*G68%8}s*xrnT&ljbD9=t0j#83}>HYkP22w{J_PJse1mxnC{ z(p}r>!Ldr};bCYROR9>YJxUm-hf;_P=;2|@fpk5Fsf4hlK)M^2^zbk=wW%tG_9$VT z9!jBlc-V3vU5{~kc-T@vkF832co>>uPzt4>7}}$Rae63)>fvF_0X;m%>EU5Z0X@E0 z(!;~h)TXK!+M|SVdMJhJ;bF@GJv_$g;bBVwJ-%7e!^6-Ny$;wzF|EU5$YExAV?NP!wJ(NQA@UZ289v=MORIvqt z80b;F%TltDEo(HaRznnr$4NHOKot>~y(l7RWPHQ(k4Ya2+;mSfatsP>%x32BS!hN# zdo)2`@mcex!BLeDxc+hm2XQKx^e)f59AAxQdGcoB``NFW)dv0SoDbhvCQ}X`6^9R! z5Hz&{2(^7|asbv6)?2W!&!f`bt;eE-vJadJFo+-;$Ua*p69h9azjWA!HajNT2%Ga( z@dDXNxIp%3?(aCqT*R$<^0Tv0%?-AmHQ0`Q8O-$!H}pvjM;goGl}u`7{I)%UU5G;Y zLs_0?=SLHHzKU{SAh)P3ZkvlWi z;Az~W{$l)YaPoX8-)8%k%91ta+bUOZ;LVb0-{`@e;$UPz42D2pFhKn7K2yuV9R3If z*TP@=OO4|wH+Ow@L)q?suN{7`T?BMzE0YpA!Ov{E%i`k_E5bR}O8>Ir1JTrY zT4ZaRIIdj~ZqhYS*fS~DL=hvI;AO(m)Ase*)9!l7U$ZsDh-dMo6W5k~Elv4kUrW=N zTAx~ov7>YyU%u<17+1!txR3V?a~_7Kc=)git+JXkx$6K#JCj#tI9D61eS| z!r?*?MWLV<5aMjX@95ItyMR|C1TjGLgmWm@lZRmygC%7{iZwbkZu(1i+FTp{GdNaw z2Cs7-XD*IU=XK7fqw)fDj=9`m0ieNaG{v zGlZT=kL9YwV{5Z928F8`=M$P=TU(<@yNlS`NsU&JjYE>&zTk6ZX~(b6}dQ#*S}52 z<4oKTYtFRS!QmpB^azZCBI1Y|vb2+ANnpv;uE^9ST&!?O?P_KUD;2Irri9?J+B1xK zhPjiefC}Dt{%`mNx%m!M`VR6k8F{&vIlH&As*=oT$Bm5@l*=TWm&wS>Rn-0}^Oync zN~nRj`LzYOVaqJAx?mQ9x&Z$e21h})0-8`%L;B4Sfli|^C_4%k-BT=zf)w9i>n6T| zQPs=MGIWvgM|=YavFe_%>iKkv^WhsX4)Bkpj}!4Y+`}ToL&jMT*%KK!r-sDNu^s|? z@sM%WLs08C{iQ$feta6wK{_oyD~1)$ijU_0wCUIx zb9=hl23DsR&>1hV*N9FxchG2Z#G0g0ZO_BSowH|{53u+h;E~B$*!2zgtm*Oy`ZjSCyae} zt-}XMM2h$Va)!h$@im{&{Ps2X}%{DBn z1=R;q==ebTI^B=oD)PM&I2n9-40;K>!0Wkaa3;$ z;e>a<2K*-K>JH&*ge%p9_%s?cG=y=&emy%OPrrrw1TZ#Pry*Qt`aygv>y_Ib|6P@| z_mHDl7nYDeYK9yyNPOtu{(|dn#QWFz;s0O`qm?n)^Eq52{6-F^gg?sRD&h7Qy*xvB zNDe22*Uw=rpETLlIgHyNO!k!=MoyCKI}V=eb63E*%oT7xZ+k8Cy12veY_%9|X4_I$ zwY!+=16+Cg0KOfhT3i^vkO02a+!FMMa*ms^$OCW4rTiE|wJ2m-Ey|0PlXl_7>Kcv| zh6^?N<(HZ(SqWW9*}Jeh;b%c2)gyWBPb(IUQP@_Tx%lB)aSk7jN@V!7&+K10t&)8- z?DM$KTLRx0Giv`>LOUQ7Nodr;ywhXaL1UT_9}<=64mxN9PiJFu$xa@sD-n6nVHm1Eb+eeb~&(dQ+lM)4nKYR*tG{R3vT8R3Q1N$_bUvHqm5_Oea+4R+_1wGx-z_ zq5bAodOm$3msghZBXubrXxgN0T3Wfgf~E~&$nPKU?dow$ijMpu+Z@RE70z!Bbxl)_nM-RsVY9@=??JD-LqpT3N=&>dNV?{V$A{ z@+<5GsD;P7c%%o~rtRHirorh*P*a+=ndV3{;6OHQMHPF1KZA?<&cOHO?gygdVareq z3@?ZFMN|Poo<0eUG;O~$m$9raGrwn*;hVOgP*5KY$B+R|P+n^N1}l%Cp7x2>tVJ2<`R* zo1RksAbo$)!%UCAbcN?%8w~4wf!*m!_LRfA0qIwiNc-eD7p?>#7gseFq@{|Njz~_A zbFHzHW1TPXA^pifgF>8)kM_YQ^B#S~$##rB;;6u_55`^(mVtrihyLma|V zV9kmm`U?fVq!rtG2}-1IViEKoGIO@93JGs8W8PaSQMXc9%OU~b70NB z>^o?3K%k{vXvbz2Cf9N`FI-CFho|qGLu|2U%a+?byMf?6oCsV4=m&AqAA7lVyyo?% zF?@6J4D)ong5S`{*B^>94shhS%g8O2Ob_!CF5`6PW%0F+^=!vF%t|^&>2$(1N{?4m z^e~46AFjN>E#EIxPO*1OXXA3l^-$C3FsbPnK?r&WGS=waSHE&1s3 zqGY9Qk8(*Y1wqvLij4jPBW1^-@x!C1vWNngR^9>xs%)F0q>CLBPcXE<^fE7JGB|In zJW2tNR$j%OMoaAIS$c#M!Wn_F#^4}biOH^1Ry(8`rPnAT>JP&2?236R=1V9M$)?%2{0L{c7fNqHE|5bZ&il!vWs zoQsYmu*#$8RJjPQZ{Jp{ueT7+)62Bx}ni5``J|OS|NP#eu zKs=n5zw}D4?5s+>9S*9i&QJNg5_4F1Ix?$7K)eHTw!<{!Y}yR;sb|b$*O9DvkP~h# zt7a^p`x~%-1(q~lITS(;oq?8-{NurY1Wtc3N2JH5$rRILj!owfo|DeEu&9Ju!AcIK z&B7=CzE*V!kdT39l&0n7#FE+&X(iO0xC;YA%omnvBV>sY^7%@)+gOJI`g7*w&G^`a z&&M!9$meXFFU8Slyw!i))KYfSi^5+h18v!x@iF|MI3_uk_fSv}9$=m}{%L4$YVRf(TlJsU%FkQU4TKpM|vc$3^1B_k7a09x!wsF{@iKeg&BaqhhAa7>Xpi0_&WWi(u3|5MtkRTru=>Lk!^^`7jRt3kA2d_(=s8# z(}@nKF5rOEOR=n?6-joq2^)T=`m|5w!2WUgSDS{D7Pr7q!mH*l9)Qej7iYE>PK4kB zRcAR|LM%>&k6j^h!2ud+dotx9d>i1S%rUpe+W=k@G1gbU>WCvO z7d_k!{=q|5x_&{#1qqmDIv-!8V)8;1&LCja_$ENDYiuGMvTKI# zjcJFy&$IV_oAWA*D}WcnGeorMiSObB#$EAhyS)$xjLzaj#Vm8YZE38~!rvf;fheAV zlaPx^k^%-7B?T{9aCh-8x+LO9;ltE$U4r>#+O(KVzx}d2(g$A3_)kk8D1sM zUj3!=AxCgdjL+dQa4bhSZBD|e;UY<#AQdHG&3eK%zLrIbNVBgFmu{8ewP&mcV5hyu0|B~beHfc8` ze<+_AlGCq^l3tti=+-SsZb<;%V(C#ANXjAYSWCl?GW!ctW`Awy+6j`DlnLGdi9|G` zUt`KLhLoo~s3o~(FJ592p?+Kf{Q?-}5BmhPl0I@`r^Uh;*7D@08nAN&Rmz=$anHa%v@Of z>&ah<|7-G&L%fq5!7kJhW{z8ZILDku#A#T#EG$8qHW;KVA1Noh_V(m>342mY;=eh> z-{SKUAkM>_3MAo;zYZ@05PwKSv}^q#G+4VA2;UZO*0vZ$+tVBwOB$$SPL40+2>gXe z1Ngti$HQOD@kjuWNFS@xrSZ*PbVkD1HA^c5QICfp4joaD9|Lf*m1BsW(bf*B9;_z}%QQrl7Fc3(obnxu{L({Wy_Z@@bqzyKj0 zvtuk%WzP9aBTv$TxE2iMn1?D)!pS6G=o$1)AoX}-Gz;J%CsmfEN*AL~o9|5OR#3*$v`2>&X+BZQIlSeBC(CBg(0B!x~1 zQtXQmC@5(t%$X2Utk2|n4MI5%8Xg~ziLChRJ@Dg2F`vJRuVd%$I2SMA`@romd|pVkFMQftPD@UKT%*2aid>s= zs(iJfCn}CA{)JWu%X!j10VEbqTU?15e5dVXYIw!DI#01|llcqkAk5^TGI^QrKRW$d ztGVgB?>g&qXbb)^)CsqnNU@4hs~f!a*#_z>l!Osk$I1!;g2PydlGP+QQ*$?8ysfDC zS_k1w9TSu{XR~|zB2zKeJ<-B#wLGuVub2nCiXVaoB);o~Uy&$h2 z5TzCbThnB*rD>4NVcTRmgFVV6D`84SvaCM~3aciuwkhDOtsB^2{~YJoLLAu8O6DXsqeYx! z3+ccHC8s+jd8V~Hcs0j?1Yd6rBq7e~+&}{TJkILpK}`s{c%0ScB&Q1}RH0f9N<;s1 z^)4HmgSIhD@6>oS4dcv0jx$hwQ~XcIJJn|uXR zi(mO(a@d3(^S$42p7A%8TiN_ST=_W``Ab6fPl0i~*#yLsEb(}(_ITJ0y9k?G6Dw~{ zfo&|=IQ?K5$Aa-`3qOtI&?}VB_&$^c^S5BuZ+$O0z$rUU#XQUj2@7$R>bx(R1dG;%)3S%+KY3*as|8wPr*Ww1^bDGpi} zqwP2&MzQOHt3<}WJ;-)Jy@By=B@Eb0_(8A)==UtsdpXc*gj2FBo&lYxmSXS`EFRj{ zMdxMnuQ3^EL)bcSoULE*2T&*?bB#IJvdxr89Ree#`zelnnE({QXlFFO&Xhw~2yp+% zcU6GAjJOmzN6480?KuMWs|TP+Xe}e!%80K1xdcfAJ+M3t)&STeTSQ=NyokWI%pwBY zGK+`-gGvaL&sgg|U5oZ^WTCVODxQtQy{FzI_EJap|A38NbfXzfux#wJ!4Aj!2Nxz?fSG~0h4 zx;DDut|PtnD2D}icBoUbBekg&ah98JZ3A5a=jc#tG|&}ro(^S{Tbc_TdueECy9+Tb z$=tnle3&EwZ1Y~AhBNh67ShQUf>xYPsM7EGqUfkjiMAMnNx^}cxDdk3^45-ESlZip zFq%GAky@-=m4cqG2l;If!tw=_-Q*&)bLJ-8yIj8SLE!XUq zcHN=Ac_`fH(C4`p@A>#GE(3lm?x_Om!5&QeRxYSwGxH?uR-MK9!CAF4>VVFuU(b`x zudm-+7b=%ZAh;d2Yd?dlLKakS=9Fr)UqC+$qk_X^aPoQE$%I0)IP^Fxxd`hQm&`C1 zC9-oCLyDpcVxS9B2jYzSO*}c^CaaE&BQ{IU;(|mE!l3Oz$o(Ej?5~_J{%d?+0_eU( z7P4T|?a|!Iy$4eK2phu8N9i5B#p90bSQT*aPWbhI=;5W%X+aT|;elR&91> z`Q^X#AaDDQO@0>jA3allm9DFn-E}7aCxZqA=uJ1QM1#8FXx*F9<30t)k?Fj2lPRAj zjd^Kr`o(Fi=eAnE-`%3jRm;9JVszzGq`Ek}Df@IeyD9rq)+E(WlUHZpz`EV2S&u|^ z@K_A_=m6PYfn?VL3A=i-#yBsdZtU;MHe9Pm=rH5}%Lqu3E-EkEC_T{^F2-FZn?>=3 z+>(AF4>4gyeUZUNXm_?2x-`rKSju>Li&b!(_LoK)on4;eAEY33S0%;4lApVO>@9 zzwyF0zG`qod10|$gD1tOeGk>d1+opAaCXeU}) zJ3b1(4#i=DhTZV0K2o%_1n_b`YeWgY@U@4o58K#fC64 z4{D9Bv-cRnhz9ljj+++`;)~)8trUfsxzS&$QT)U|5To&JU%=+HFML|E(aOXW6rKXwF`11}wna=*z{Uka!C+?iW%&~&UW2PnYa%-Hz)2x zXCdy_&*~B?(+{1rew(1e-emJ+3I>ihhZpPw^S{Q2cmYl!qWO11^`O5XGyTy0=?9*% zw#dd>p0SpPeTb;ja;3|?qv049v(`G2+$JY5orMNVQg^~v1Pi$AI`3PeA1WkVcgN zOTgBg_PoO=P;8y#XCNgDpTfd`upq#3LoEZ>_Cy}hiV6yY4I1A{5l}5#<$MB5m4*~x zOAu$#QunrrRt%?#!t^c{IN>zFc*?)CHdcJ5yjjl6@l%rph$&?RD6o{=Q?P~);be*x zv4NM#9Ar_Zh`KdfoNeqW*#6?ibEOaqN6-riBYh2W##tKNflE1d z4EW>Ha&=a&Pm{D7XrOaBEms%ha+>7JT6@j;B8_bv0=j-kuHP8c%bWb1mGpC1FoTEW z()Z|}^%gyaeUbYrS8+7>UG^UA#sIN$A`1v+ z8TD(CqJSU;D%>IkD%>#zJzcI?ocN_0iAF6s2wwzdQ`E7WZZF~4Sh)u1YHa2a_-b<< zE8^?S-9npJr-2Z}o9(66on5)#egRxf`a<=a({GQZ<+Cf;0koUBlF3X(^-Fr#2jx4( zX})&LbeVJEFkFb|Vf6vohITOhSjSZ>aVZ}2#N^6B8KDnBH0lZ#gamji1ajn;?(|1% zR}*cImSp>LSYw`3xroyUnB}^tg0%&^n9D0yS%k9T8E}3ZbF$6@Sh+ywjfOxPE|zW*iwD>x-p3F!*YE9Y2kVMj$2i(^obM5dtaDS42w&^e4n zK`6-B0x0G3rb`ct26;4B2x64XgR;N?bA3ewdbf(`FBDh}rU)EfEDampz^XHod~9Hm z7&j9k7m98dN^7!^78BOeamJMxJiI=`jcm+-vbCW|0?BLz`NzjHutmp-Cg_cZ7GG}@3klv~mUk&FFHhAC##IoKB3 zV6IBSJE^gJC-K4C7Z@Lil}bT0wu8CRoi)j~c7_gDc^%qX4rFPk!?(md9X`XRMpGgQ zcXqc~S8(uv5p_^nz{v^4a6eib``iPt!lOw%vf5@%PYORhvBWD<3l*ug?l14W#%*e^a5z`^je>8|D^s=kJ)%TKDbP<73^KP4B(m7O;s1 zpie*G2k7blU|-OnpTF;MII-W7(IO$`STkTBv;g~%66;<_>DH7z=;fgZP3I`v(NXLu ze#r8dDh9WuV+0#?yfLJN2R|000-LRLQe{LO*>_-n8|y(UJ&1Nnz2lYI2G#06KZ6k* zDiNh&1kR*GgzP0zbObtdDHL?OVn1-wuqutZ<)G|}%|VDVK9-^ipzMlOVo4|@md@|r zTtaTswt_C*%AZ}yQ4Q?CaiAm=c`(7+1^9=?Vh1O6Zg<3)n_2WQqvLF7QI>+bE7rr7 zdhH^$f><=glygw5HPR95CRq>DJ~;Z_D`saEJ#1~gp^KIS>?+yTLCV$`QmTp$cg}8v z_kFv)@aKdI2IqD$r{Gvox2+bA=OvwwFI#a$I7cpK5|&X-!dO4HvV$KqEa~zuH~``w zM@+!S^wfxd95L~aBPOEkA4g35Mfy4P&&aZ5iFb9j52d6oHY zw0VBzL0;JTuWQ?8dIK5m))qA2-4dO~Ezv;Z$S=!_eyH&78t?|4(md5I(T&{l`{?I> z|3RKUf!pqVVgfQT*;ijkZD+IP6bx5S5uTlkJa)yj>sO@neE!fKGj0Ez95$uL?DGQl z^W%9T4$F|h132%S0lN)QGZ>`{J@7 z7lD(%%ug=kG~{KKYbrdI@c85$_6n(M`qNXiAZF5z?^aG`H@-1yPaB1+ z`N~`dcWdExcrZ#RidwSYIH8eT9u&n5n4|$?8ZgxcOxA$G{8A|`%qNvF=v-Xl^yx5j zX5z53w8dkv6=~*-0>Y9YDP=+?$b_3)OBhVKl`!p{WlU#~IKMYS*vjpfQ^?}D5VjP^ zz?CioI4%?F0@3Rb!V1W5##2m-Gp2_PHe2*yB0i_EnEnlz z?gq?&2F$?0UJmk2$%7g&gB!R|Fj1PEsxMTxeKQXJWyQW2#IGS5W#(%QzJhp_gSQwb zCYm4r1bA8M{~cHS24^4dVP3Du7j;9-t~O>@7MgNE4*h3O^&k7Cl!G#t;K6kNh~r_* z*r)iVGp|=0@Yt7c;JVpym@l8hEixD|niJoP4@+||ZWOSHRmq=t640M;N~J|SWM)RmppxJcR85%U zF({%CL=lA`iYNqYT{)Qco+?S!o8VfS;95HxdE1)c+MD2TUy@ft(?z{HaFl>`io-w7RQq=QYGUc z(bR~u(Wb2ngFje)piy0TodQq=f*br-JFN{af^z%`?iNKQc?5dCC5DeOtF@-t`sZECugf14b-`-7KEOCY)rybItI&7}doE z!wRhnK)NM{OW2=b=2eVfe!iYxuqtp@|!idJC`;%T6 zwlY~uMCo(B3xQQW=C0~p=nw?W{Z;HzEQ?>YTko@FO3h{oGbFBCz}ghW{-Og%v?M># z?bHQ4S6#(ff7isyF2^_<=0L7pf%Ar7oP(L=9p#CUhd2vC5GyDfnc{3CPmF1dA_%pj zwA*(8*rr}?p5Ro1w0uotV8XGEW4M`iqwW5eFmO7>v{@Qdxr(V-3`{UVTYHB=N6}$A zlWF%(r_mJAWl2OW#hIwJ1~OT{(dsUh(Kt@ZK??;PJ3cu|80kAGu0bHQ);O8vOS1in zDx>l*W5lJhn(Jk(3qR7%l!?TT&WkU1el)-l$)pL6?(zjiKSIfz;SeSYeF>*QEXUUT z(6@@T_*N&0b(LG44CiKd`!vMOLJ*##pmVbaJ+Zi12!dEa=VniOVsWz&q_^jl4!+;% z|HB*xl@2lV`6321`#MY&RTaL9fccM{h8S>_Fi=b}sNnc14X&T%T*QE@gaOU^js{$G zYG5|Yxx~#IFj7kHPrB0&>6~1iu_3-fHvCV#OaHl_?fmce-vIvmU<(|~YjqrxeFUsy z&|x3*U-r!gI!v(2BVVw+<|g#U7VfmL79BZLG-DMu>}xH zAqVM&J|Dcub@b-!Hk9$>%;+t&k_hP?UiuIr-pk1rdfg~C0A<~u#-{Ps+8(+c4 zV%`p?^Nyiv>36(Z|IX7tPrxEvJ}<_>Ykb~Td0w6`;Cw~G%PX(Tb4BH^@_ZB9A&H+8 zpDxFP+C176(&=9IMqL~g7&W@T+(Rix8*a2|{{u2?YAIqj{hVOoC)*6qX(#-!k^hH3 z1+GMQB}OY7uuvwu*lE(niPbne)D^mHM2WMR4&-Sxc$-2HHIagHvO=8A^28X}EP^1` zSXZB(>WQU34MFxfe5`9LmN|rp)(P4Mv;QFhB(_ZhN(_VVe+Y-Wct?;+89U%Hb_q1D+VD|4*o5wc z2fYdIDyyUmBy_d1%h`>Rp`d0|Zh7aLl7j(vaoX@sgAk;`74hwK--5!ISMKCe^@l2t z$-I682~{BtpCqCnr%E8G8I^sL)|ebL+^?vx2bm6Qd{nFldxhB+9C`-z{axio>f1;` zO+dm2X(+}i5{PL+Wc_Zy^!*=I6%Y&#An;4!X)OB%m6f8^^yS zp%ABPE~MH><1`Iu8WPHW>9pVq6Vx6aWEyMwrM)Lv6-=}(nw)KMAl5kC7kid#G|sBL z$TsN3c$I5|R>?`|=^n$i4Z4U77gg?Z40l!TA>y9Ovkvhrk7DIzfXf_W8Mh9PGp|+N zvE4%w?Dv z+IS-VOgyYM=Mi+?>pkYEitJnaIgXvz z#Ff+|szE&>8`T50FZB?mW{c9vz92X0*guk+s;BaSBHLQ7bWjO z65WL)vdzbAzA4jbie_TXBJvcQ#c~gXzF-^`$DobAA9%AQ-|4^jJaehyyWE3m>#;%% zXHe&J29S9g(r};M2f8ZM4&T69 zXZSj`(3Lv1GOx*JcTS7W6iIA%>Sl*`-KnKM4e2I^AbLm&y6)8do>;n5AqZjxU3cm+ zPb}T35JVflv0KyNByZ(FUQLP)Xb3{Gf==@Go>(M@AS8do#kzj*cRjIWFa%k&>7%|} zaeTVjezJZ&Ho=Gf@X5mIjeZtXP7FR2?tkdfu9-W!ayHjgo?UsEcP>BN{dBke412nJ zB@pQ}r#LQtL-bHN922vKN5|+*?rKhrFL3Sc1@ZMnTpvH@=IfqIUgRBjFPazJA%HJb zmvcMS^6F|_2WM7S@3Gf}nR~MPc{Ses*#i#oK=v>Z4`+`$#G~00L_CpQYtI)m*Vb>q zD_qKaA(!LLM9CmV1&*%tvR~F)S;?G@?+LObs)6K%>g(*lyj|OqU%*#pHQ%8w0|m!e=YEQ&p}D1f*i{uL3wiY0qMyik1uw*{LwZ1()o zhJo@EF?%X@+Bw^8r0p@`_`!zkejK78ae^xXoW&xdC!h!(uH%%IhwEYx;Kd-5VUSz7 zK?R6gJ74S%iWmFOX8wVg-94`xh$OWV6y*XhMU9Kq3~JtQG>| zf_Ns+)SGF269{pD32=a?=yE_j1z!UN9Ze7)m-98m7mPB|8D*j~%0w9DRi1|Vsx=Dm zVw6d06d=SXlhi0ch*2h~QGgJmOj4r&Ax4>`Mw!@P6p)BfCaFn|&}i|T%#mgxseUgMNxK|rS4i5`RO%2%IwU0J=`H*frH*u@BSX@Wq?2Dj zJU5HyY-r|YXJUE&hUUy{WjEkVYtb9(fJz-p6@oOQIr;Cd81X5wr|JYJ}t#zh)$)!yak+rs+gJV2GNc18ZC{d`&( zYObyR6@TW%OA|bn)i1$KgXW!<`502jwZj#go@H~Kin93$JX7^>b92k$RtD0uM(DTJ zk0fGsdQy!66=6?*R7jrb{az%`+N;e>aewgPW@dU^noLFDxb);qFb~$}BN1R;Y&*MM z0#~)a(A+JpymkFXh@Nb7{-fxB=8$-EujU1OBRZs`BXJK|#HMq!Dv& z?R+GSz(=(kL`LZ=NVN$plk4!9>VSaN0f9H_zZV^T-*O9exJ7gT-se9T2cO zJO(?&+4A|;_he~FlBp}ovJ_jcP|c&UPBhh)!fim4{=v1bS8+q-7q(--GbVCb7(=gQ z|2fjhbKk=0*$!c%je^lQTpF>ou|pZq!mUZdk+3+s&&l9)D!|8m8q(hiLG}N9uB*Au6LVW*lOk zVg-U3KgIK!cX&iH*ZNIeN;3dug_4iewQKrSleIa%A?Rf0HHSFS@0}A}o6fJHU9r0h zyBxjyDp}~>asO5Fgn#J^PIO&*BaW6WO$G+EFgi)B6ZKoimY#E>wH)Y5F9czC1)UR( z_Qc{uAqZjxT_J7kiKUQ25Ki<&(TSe*B`Urgg3gH))!d0*Q-1G6B@FaajMHzGvREf7 zfUVgdT~Tn(SMI$~1Zn~-lEv6awG-ZeRSg;Q-8U>5}NEC-{#=EZE;89CfV_~INM zLU>6IkJKt0&vcc;n`m=s6VGY85p5D$%{iU(J0dU~R`3XSDUjw3ve}B2YgnVxUl9NrfU@X~fwkP6n2{+v52rhv>pF z3HW6SqYnWB>X|BvOWqE%XL87rH)xuvL4A#)H01YN1zoY8 zqlmC`vZ*3Xv~j#;k2$mbckO)M*l}wIp8gzc7sjL?QKnF6>8ce6Y+ra@nloZ=}tg-> zHu;*46l{`h<%~AMwZxh8s(aN z1$~oWM9}F|MU|yNeT{NW{@8-9X!47Q+)vX=;|};=TpO1T31rTU$y ziUqD73Mwg2SJ!Cg>a(5EysH-x@D)XPS6760_4!VQclBR5gu1%IfvYR3?3{3QjdHH8 zpm+5mLR?)@Wob}fqnxWRD(K3sDg}h=-73;Vo3T}XtmVBHJ{PoJ)XJVkzAiD%De--P zn_Ji46rI~mHZE?q>Qora?cF zT;eIYMAg|y)u1eTwyG%o$@%GH&ZKI+Y;{I0PHvqm*0WUd%I1`~ZxDz2uB+BV_%W~v zl6(v_5l@9ch6jnDfott^xkc-NHn5g31#lB?v0h34#x%rwq=NM%mwAsO(4;|G^e8ks zuwHh$HITF3lKSIyYVktLa{8b%f>mf`wL6VOFwO-Cd-y<0wB+9LqlN78+ z+Q3@E6u@e|fSY=k^>@|_sbDps!c%gYTQ8t$P!`tH=)iiPD_ZZb>FG6UaZ$^nvh{LG zSZ_#RJ%q_7Nb)hD*2|e_J(A%;qTG5pNx^!g4XhQDIy2|1zvRcg+%Dua2zH@4GHAL3iT8EyCQTkTg% zoX9pV@9Q{^llC3`ym`ZjFj9coc{#!KiS+H%!*8cIW$jo;E)h3ni}G^LipfgNXj|46 zqLv}aD(cm8c1MVs-7%-5ikgFC;zCqk$D)c@1UmyCzk+tt_?iNr*v2G|yS5?UIX!iTYF;nDPdu5NfQU%`U{UoPizB?AxV z<9UI)J@#Eepe&~(_)vgHxt4=EC9DU#4(bgt{Yc5{94s&_2bKEy0S|xbH54^cdJ1Ks z`sJNqV3}dXy(3xAlW_#Tzs%jG$*wVlONLC-19$HjT0Yb5r0F17yr zd5sLs4&uw@vykObBfx8Ia|$xdDNcr;1;@$7Spu9>oF~`wkOU*3yxeKN+VaunGd>QQ%qX~;qM~*FiE_(8@o0k%TmVEQA9i;{= zSB34Tm<8Oro(b16Rl=Uy!dJtL4_R;Ft6|2+Qe;akE(`fjvwh)&(yrik@~$DVLmDzX z#6YlB9M8#V7aAt>0MSxH%=D1qhC-^m!qV%A{8ELfG%K*e%zxD|VbWRgv3-yc08i_606SCE0o*C;07erIY#L62j=*ii^OTQ!9RwZ}l!Mq( zowe^|9(W>0#?%3E z^J(E=|0@G_bRA)3KobHh9Wg7v<|4W>AST%>i;vqfB3&>1r|cLk0!DvYR}9`TPB4jo z=2$tYk?370H1$N@d@$XbB{?Ej1GF9F|SyghfCGgI}z0mOR0T6HM}Td&_j1xr1Wx{%8$k);@E#3b_J@9#rXo8iUmwOa?;({fki zu%+vJx&UlNQ;SLH_Zifn|J%L*#r4+#i1_=3AaX#nNFBh!uKCWv%3%TBYCxWB+L?_D z$3Gu|qtPO|g%>MG$)YQ{vW;y`jyL>n19W~7d94FzvJP029pM7nWMdM{PTH3U8wF-r zY!j1UcG5lp_~*b3ADNah31%nF8EhGt#TmpTihHWB`SEPd@Fh52Lv;Wmb6f=Z0y)6kGEeElBLEclH6%0d^PNJJ zi7#Vp^ko#=zHT`_3YeGAEdb0d#BKnz8-Q62VAj~VV<9+KjRins8~a8!egXVq93o*H zC^Ic=pQa^T^#0sy^Xd%KCl6*1a+dbAu0Qj2;hHf=k8SKzQ@f9-^C{&1s;M|JsJtTO zOzXqxF*4(NOnGUE{m1f4%lVu~pWpeEya9ZwYbM-yK6CKxTxF2oKKP|!AYU3bZ#c<$ z!*3V`@`h0lj}l#@?${LMYnvWB24phW45+1vXX=O3`Gaw}d6Tm?#f98_!VbTpFPMnE z74o(PcwReua(+kp5FW=6IJ)!qn8`-q&zruvDFZfoYl1a98+50LGfjE>^JNOmjK-&T}8*JTkPBe=ESYDjnc!3n=Jl?ea`hvmA@NmBmZy1s0o zg-u1QB)HNONmpdmJPHT%G#)A>kYLYLZ-Lm8a?Rw03HD5FLNF!WgkXo%CIs(Hnh>m$Y(jeQ+RX}KXo_(S z_BHe7K|8Tj7_*40j6)XD#I$m7!K4=?+jLAT2fwE%oQHdMU_Jie4C<4v?vNhx%Jgth zTCIud-kR+rP(|I9aU+y@NN=-vPYc2&nr@y-v4)Ck4a44WFemRyC&NlMJ^U~JH$+a! z=Pbsm(;NA9w}jR<-oXC1#D3Lr1eQ}H)URAN=fcS%CIL!GfI=1+F7!Y*hOcxK44=zk1dJ?#7uCOYEb^)FiB$EmzuDp%;WmMG_yXRUD7T^UA;o6m0}g8Sh$4#9JZ-+J2$_Q65i|vNV!6DDnr| z`7bvHe#k+FKx<(G!msEtt~}XKHet$FH6BbgG`Hi4P6;V%6Yn&Xit;j~ya;j1({;j= z6Tv8c3rhvaG9p+KYR-SSTN5M3v;I`g@oqsXLL{xEj1WrUfh$7DgU6-_Ax|A44_>x7 zkJ%g}Mc<$UIYkEt=v@D)7S$1ILe9QtR=2xcjD?(>KSlHQ{r(Ws^n2skKJY{cc~bl< zei~{JWw{J>@g}D?q@3a628?e*o(7UH+A;m(`nB%L?^(rFRe7WtFxbq*Q$)SG@to@j z_GN^LtR_d+)5qkBln>b#d8Tx_v?3A9f|J54uA8idm?yuGjTQ41*k40KOS4OJ4ZWH_ z!oAE;FsF=KGfG11)PX`Z9So@shExYbsskYy5j^t$-HvtWU`m=7hThK(^_Wpsr(*mJx7gt z!ds7uHOVncD#wt@F{E-d5U$Zv@=P?!rz~wCeVU0|&4E;|F+z;zKW1sm-y=vx2-CvQ zI6^2@N63R-*u+yu$b%VT=P{dOr06^FP`XC+aOc`ZEvh5bgz7oltcGh;xflyM*h!@xB@mhD~Ggfg` zRW{5_w0JQyEr%FlJSZkdY|C0yfg|P`D^gtJrlvv8yh_T76xWEND;{u;^9 zNOwDd_GIZliq)Z(%;}t&o@ll7Kz4@L5?PygnF-}(NO_qZxEI&y#x}~oSt?bV{Kj<6 zP~~1Cq)$83#z!g-MqaImq=lo|>O5$-5kek}vm%6g>Iiu-&T<~JIYx@Uho;!b%egS} zq9%;IB7~YyG5=#0!M&(ljD?(BZTYXaWCJndJgX8Tx?jP>4)*xsocxFIuG27Bb9q`#N10oihH@(G?;s-$lzYivtrJZ zpGju(Bhu5Y;Xa<7=M7igON|!=XS@t4uNJttml|(h;AJS%tL~-7OKoZcL$O{shl=x6 zb1z4vG!m?6Gc62EO&JhsWuSXubZ{?~dK?(Q4({dr8O`qHDnlyw za-AXOUT!qf-AkZ7Q!qOz7Kd6g_j1O%-Aj#^nNVJaYVO7PtgGU|?ruw^YLlanYIZLX zqGejHF`ml3Lsr8w8?9r@<3F2{OMIffn=IfhgY zA&!$gC36aJWT#r%RqKDrtggmM5z;56US4;s7RFwo`$veRg(urO4;)#9kOyunLa4cp zkOywddCcY*Df$*2XO7Id#;ZjbCq)P~!D$Vy9>Y{F#zIb3*_)Lg_J^3JHp^S($RdP1 z;>ex~^=gk{7pJ$y!N#gPpVFOJOPweHHn)k~s2&G1JIsT|p->pXB|j#Q4!5p!e} zDUR%GrokLpMPhSFblu_yRy5cN0nHp+eBYA3%zlQw@Y!afcucb5#59ZN*=aHws^nYZ z#WM^LkEa%oMUhY=D)?fnbd-T0X}Q!8<3SlXf-)cvnyMpK1{En~@LSVhWl)ib&C3I= z1UUCkZCOCrgqhE_fsky{F;iD#k#_5t9Ne*{eiDes z*-0Qynm8I*6Cw@Wu@;5!f*xllfm~cS87-;_5rvLn2^H!Iu7BcLI`YR;BRbx?qq(|k zfM~qlbXnGzx|R*B3;10EFO#coMIPkZ5qhJ9L821ig0zo&&-X!db{KYcz6?ja=#rMpxmV@*{L1vEH2cM*h51dI>N=LT z)Y9BV)7%AVegexJKCv%yvhP9JAzhv@Viu$qa8K?FG(7;9r%MSe)nvj}n3}aneSr-z zi}kP;U_BPpu1MoCZU+8XV>Oo%fnMFX8Oz%1MFJ{Paa@WGwT{D~5fH$RlE z1ZJkEqG6zmoQiV`ELMHnj9}UZJrfh0RxzeiPPI6U%fC1HkYb0VWq-p@e>L`hr^z2m(W>r!ln#9xfBm!yt;s~R* zJq)d{wGpCPrT(ivFbpk5`1X{>>ZuFYK9(fi>z?@UM#MPL_1ZB4hv~@Adx3=K!F(cdPB5y@`i!5A}+B3jCRD1s2M0;{XxvJ zu5?Q8h6%e-T9I+KCF`@ti}AR}a<%5z?a{}!|FRnP<+(iUdT!(NmL-}+C54Z1@?l@X zlC&>T3OAK601Z~^`RUxQb3%TXsz9ZP3g3Dr(u21s!RoQ}x^Z3O?t6OUB3AxI zjf?Ged~xH~1b*F+4M@Rp9nt_G3E7VfU5NA2U7=H_ImO;v+?|iM?XjSVM9zR1D1U{ z0~T3Q1UqClA=uZl3BhCeBumJoFpK1fyeN%n)r)6N=a5;xm{txvdr$G&(XTL$^F(9- zQl1o(D7fNkXHPantsS_KpHQ)S`;EZoF!u!o7(-{}>qZX6{1tMJrqhIA7~u%#l);1N zZAb7>L7q=`eK z36aNI$66F(faGyhh^!YkYB#V<;5oSo!ClpxI_8^cGmvBaOjSiNFl$2M)~w-T@zvhp z_Ckl-3+{hhet+XpyB|E-Sd1Ng^TpkF;ftmGuI~G~_2ztE_Yp&YbJI)#%88aV&oGd! zd0Uej7>NuSjSe{)$9(OZ|5gpbZROF%75q}+ifp-_-kvYdR`5%O6~zkf1`LiB?N4*t z`KQaL^|*%o>5ji}+xfqA%X6zfcv^1 zH{kK^CkQ;z{h9%#q6!sHMHVmT-T4l*cyiienp5 zS$lhB0bh=_d;l&*B_SOEsH}DXPq$0m0GQd?*9oAnQ%nc2xck~}sJgcMU6w0=cUi7` zR|dnO+Aq3&JLK2M-Vfp4{Gs1so%CB%++sXlKiaqkE2aTmqb&>2^6W@_PYLMAHZd2_ ziuOKy@dl_*+YX@PyB@~}J%AoZi-3iI=A$VHWQ_q3%UhsjgC!q;m=8i#PDr`I(KWJt ze~gdz$DMkg{8;S~cy@oZfdeNe;OIV-^*$(TDLCMZyYKA=es8x_@q~p{IwZ}SuXf)$m`IdVam%mV+i*boUgLHiS9VAGBro^3y}~bI&KPvjAb!+Av)&43VNPr@ z=fryOF^zcV{-eat_8)~0qdfv%70S4!NE3p^vQ0?)y3N4-=&PO`v8p`a8qM9#svq}> zfZ)ytFCR$0%!_Fih!F@3uLL$$h8O_@Zd}J&lDG*lOECh5k?VydlcMk5%lV3Fy-F)i zi>i^%l9!bjSn$P)8!lU~)JaUL#<68@MHYQ0Ns^uYU|s!S_*y)ua@p>FFnmVd!iVok zS}>Hx94jAu(qQEi5KjR&SI1CD-&n#zLQOa}q(3ZZ>ofhEMA{sKHqAeF4QatJ)^jY# z%Eva2=E<<);N$=fu!nJ$8Lt35YCUYs8IeIAhGXvpvj_`gTpkAq@QJMSC>-PwlU;77 z^f_m0mPd2fGz(*dsRK4a#>O?D2)E{ZFLpd-`%8C^AfyBASdOluK{*xK>1$qC71Ok8|Lrij4 z|Cq)|twu`vUoma#v(MPGeDVK6AH(;Dd6H!lv7<;PAIEiVctGc=>1T!yAIk^g^+xjV z$PbO_`R7fr>j;bQizbW1u$i3eFVh1$;dW3XmGVk21y|V35T}8#Up;4faClgqlsioo zE2&f@Morjc!ekQ;qGFO+_Fu8ZwSKe4=0Z4`X;Itkg4ZX@XK>0|webB^Yaxxn4(ofAXi_*Sj@1&k$OnGV^fot>k z@>Uql%YTtROj7KZQvjEFZBNi){Hk2a=Y~76$_RasjZlA))S^ZgEGUrXRNj#&-*E`- z67u4<2ij`!)K~+kI|hPn#nO<|&YlC3!@04Myt0uwqt3w{6M1T>5W_x&&h}#a8uT+M zreabM?Zu-)?@$?SqNg}MR2&vcb8cYlM#Fo%{cm{qP!(~^IE`WdsmZYNM23~u6ce<; zH!bv3q*X^GdX-g0afS0F9eAKVsyvx5c~36q^YrEUI3FxK9A1LlHBM}pg*b5->x%JV zeNAqF6iP359=ie`P?6)fRwq(z9A`M z&T-&;QrkLW9tb*mP_Fm2uV#$@YO%W^_7SG=Nc-bV;c@U<`IJwY7PG!0<+kvy#SS&M zlorG6Ho_ff#^<9p!bVTBKN)iFQ5#8XDMuRT24+^_K%R_*=*SHs(XEYF_HRnc9wRd* z3*X*MJA00M38E{Kb4vUbp9*GvhIg<0hV14HP5b8TzRd1sbtaVH4TyuO7_qu=uUKC0 zWx9sS%x*+V5rtR`5+`!>1cUPH)Qpkn=eB!Wg=y)u8w=_V_LhNk31I6POV%Gov9#R4 zScb#h)JVxk6)WDdB87P?lTB2%B8AyWE@(oIDiWulg3RD4(4^`G14K-|Jep#dC6go*~I!kE!6+Hc=SdCxFGv2 z9=#EGq3sW&71%l#6M+uTH~zPrZ#!OJ}73X2BK(#2ie?A(sj;9SvPo z+-x^rF?L@ymP0iEMd`>RD2&he3RKpOh6T%z?zXUtT(;86K<#d-raP zD^IJ!@QqngcqCS-u>sG-D>61j7>hc$_~H6Bl3h>dcN7XANQgBq3j55Ioy{o=H>bP4P268D$yi_ zttF>$F!^TVkEw?#?%}@tk`SgM!xK#Pc+$M_V&9OM>>XB-*lg#woX#0Gvce!SqE3z+ zRmFN58}@6lY{p4*B|uvxKtm-!D;Y>e^(+29r4(e6;s;hGd9o$^(<==e!HR=avbT7d zmtT}6;=NFK(G}%aeExbCB){4i@qxC%%}0#h;(%o6m}&lN z^bELdZa#XGZKUB(PB#6=rNlIp_+=sU`(s?V|4(Jg{f~_&@Y~2tk3-pcV22X_#ijQUt?$xST@zkt4WERGgxtD*2C~e55Q*dmOW?mvWN~k9hwh-rdNfAuNhz z_Ei}SZSvA_-u^K_jY$khD-w$Z>ZFV?Jw8t&8(U(6jUDDaYW5749d`$h4*Tlnqc@Is z+}-#iRSZjk>`DKc(EJ9E_D#V@Z(MB(zVSyK4NbSa-s)m-vFCv8F(I>92b0m3k8y($kjm!8D0)flYB}`*U zdaVK1;wx|fH>TJxOgP?1-y-l<`kn#rrPDdsnV!wC4Jc=1GYQPhj#U6nGyWBqh0L{M z-Q1^Uruh5!wx@u9Fzp+jq`(;;lVA)kQM}c6M7Py zeTqm^(pxcXEVsmRQ!{BjkT5wWQDaW>g+W#)vB1k?dDFzeGA7ZEwg{P(>WxXn{#%G; z4=TqSiJb*$#2$y{-CF{LIrx#$`~Ok9!?UQ07m` zr{!1W5?IuB3^w!xa(VH44Xi4jl0f7hIz+Z(sxZ!I9E+7L^QTm)M4>1_*)VY&4~CFL zXM3UuXrc&cq6lcBv!}#~Qj}>TTGO081?3d~iW5Ti9^>Q63)uobuAJERDz@j&=NC8d zozC*&UR)x@Qvp&TJdn)3S7jt74??;atdwV)?j#I%J?SFZ(;Z}raYy+C4V!$ z7=??#nRsI%f%Dq##PS{>_qIJEfpUNA|5%oD%oO>=j7npLT&%m>w{Wlj)_*hjD73>b zqnln}_I#K-aN?=mjo_&~H4;O`to*%OpHA+?!xN?ooFCuZq?7Y}w+Z;`IZBE&WC;rZ z=<~u+Kc4Y{C8j;j+}jxi_B-G^SLT_e!4K_;n&FJFN`V9rDK-M>BjOQ&E-5J=`x_; zXO>H>L}fR2azy{RJl}+euwK!lZ!~%k_ZmgTdImqtw9;~oMGr+hG;i#sf3u;%x$>0b_JZDjVk1Wxg#94!9xa;9hs%G zjY(|I{NPvYY5-nt`@Xz5QHw@@6 z=g$03n)B_AwU_mpmpd5gIS+JGbkX;bS1sqxGDyyNPs;~f1rmU9j~dw>Za+;3`fC${ zJpLt8qAL~(hp?y!{pz&FulTLq9~)S~F0Y=nge#_YJo~l}qpv3`ujHiFa&wiOQL32sz)Y#Aas7|w8AVqDUh1O>xNoYn^KjfX;fOyD}`2Qal8lbzi)a!{Sb z2F}i$R~k`!7lmw~#nwr5iQ_z0?iLYU^d0dg`#{W-&Dj%ouPh{FkC>irBJ-DhNufl-azC24C5vAnxd%fuQZh2MrJ`L<}nO8gTz2fa(aNX-T? zJv%!Ca5hGEFblxB*|h|&&BW|o>S@)!R@C&0e+>on8OVL+YpUi+&X4bszteb#1qQtj zrLQyP*Ey##9&;KeFqIRsTlA}f;Ne@8ehp>#WaD%e_UWl8L)ku*-pInfF`I3LJv+aQ zg?(8r`rw*a)RAdl(_P`8Y#@FPcP)Si_=XuSi#d{VcOyHCzWLdRxG+Pw_-4o}zXZIo z@i@ObxH-jo^6~lYJWFqv{ND8Ud=hv&oy8>-v$6$v5SWG+>DgM+YqRNi9>6rP|6-MD z9JF!!5Wly#%{MPn&vb z0}=A5R!gQF)RnwPAv}p}rh;{Z@@YGf0?kNriM%+8(+-2C12Cs=T%$pCn<@h*XP8?%@U zfLZBD{AT4OO}8JzMBycYQR z@u3SF8SbC?!p8Yjaem`6rC;Q`H*9y|HsyJnA9i1SF=)uMg9qVz9h{+-cW;zU>{*y^ zv^A7%yc{ej=sH_qF z1z&4+c4H+fyoC_mV}`2%o@3s5&_|rKCDyxJvI*@cdjP-= z@>>>f*2n>qAJp=?I=rTX@6q-oo2g9MpfUQ2rAIPAv34ucjh>CdG*-FVk zS`uE1>%11L!-F@ruh=c0mfqDP^JjPU{DF&_{?PNTe)O5Y+jCy8POsJA3F-(o2WlsPv6PSCL*d^v^;UZ`%Rs-^d-71kpDgx(K6~huq^}fvK;JlY zCFzx7Pv4ZfJ&50FSH$j0d-~R8Ph`t?x&}4O8b#Ny{%v`Mc=D-({XLul!!`(L+HVE$M(hd+2$j&y#dO z-#GME(zi-F^XutElgz~z_Hl=?ANufq3mfSnN&fth*M~HAE_d8OJp{iC2|mU?pzseV zXm2q)DA}2lt2@tX!$j*WoT5!?S=-%QsCakrV38e;q0WQFEPf|CtMg`_ijv>l`Aiqc zXS!bMlIWMZ&cH{a`Lv$9dT_b4_exC7#5D%+M2;r7>Z82f5`L5GXwdte#t?sB#@}o4 zf8!b1)wC>3_Lw|jF%A6_zVWf@w3rk-<^>YpHam2VuOH z1)7gvC@@48_kG)ocOoV{mN)L>Tf=$TBRZI9X3^mzximyZ2_Y{sr#_&%7M6k3RfQ4R zcnywO;$V4s!_v){w;fj~_GDc>$}z57h$^N^grKcbSyPA)FvU>0!c1PN6W2)TPK2oqSJ4&ez}ZEb+sA|XrI&C! z+9vobS~JK+Pgd&~PV(UguW-+-BXHo3pjE9wr^cj;vxwS=_HtvX6%U5i@;g$HRU>RE&pm3jdTktL`Jsd%I|2?-K~kVB$65f z?u&t68PGoh0u3>#40s9Z3}$4E6n&cx<%1(;LY(VApe81R;TwHdEiGLL^%gL-{(F|0 z?=+D?#~fqWP8kBJ468+&o7!)TY?$gXsE+cVEOD!v z?TqAfJlf7qQ7n9%lN%ux#qOkSV_1(4&}d$yANXfe#;{o z?oIMqApknXbA?ODy&D4CnTN$kFqHpKBS(YON`VnSGH^4V-RC!zJoysO?)%031}_U5 z=keN)jF=Wn2|zgwP*TlDQF%&9RM`%BNjmz1)*QVD+_kxH;Y!ogHkx}iodqKq8s!s0( z5z9d8(1I(@)6^Ft1`<)yloX}_mMt4vUxsAk1fpG23k4bZKv&P z&B$aL<#BZcjn0waZBKU=^R|KZgvFIU6Y2wA0aHB}vOd)5>Rw(nvU0uw(LTRyzsUKfWgsoZ2%#5+GT zsq?+HaeQ#T{l%P(_+cxVW*RatR*mE+NpGQ@Dh8yv14G8)e(KYEA+! z!I9t+hB=G5gg|=%ic8o%)CUJ(w=}S+?C$xr?AFL7L@Zi>-|VhZ=j4k>&$_9mT>2IB7n>N%H{}DL&wClQkbukuqF*$Z`~hTLIuBWKw?D zhFkxvrGSRrgrM4+5G*-&#G77H{>1cjT5+f4Bp=8rf^0c5+)F$lSa87hUU!YyE50-A+4R{3+(h!pS#6yaLn8G;%y;v@wWHV zZ~*sj`~0@xcwTcdeqnP?z_Ji$!$ammEZGPnD7}K+KpxmNh{0w!LOsfv(Za z0b=F^vh3~Bl07gjL{5as@&br?5y)}_h`Ay359FtRmME78VcO>))FAewU=8l-S;YkV zbNO^06F+^^JH}$R>5j3lZU*Yr%`W^fs0%-Q+UB56+x(KvL0z)>eIEmL-^c#6B`N@- zf7$m+a8Gfs!2jG6R2`sa$n)Y6Z-b>myV$r^t11li_Qs4gJP5))kj7DYhHeX!4jdq>Q zS$epZ%N|}X*!N7E0Aj2O0MaG^$eIA4dE5SKTd4V!WDYUb5)h*;0g$zXJz81wGh762eCfC()H046Db30441i+z296#!@}0B~vn0I~uA zqy_NaVa=7CM47xj=hw5$3$M%ouk5+J(neg12ZA%bSGJCMBt43oBH%6jS+Y4oczJ}R zitaPrX+O{Pp~vNGxsl_Ft{L2VaqTw8Z`;^6Quu9vm-35^_*3u}i~9r8Vo^wGWs0F3 z)Y};901G2C3Umy$jeM))~WD!`| zaXdG;Iy`@O>r){M7wWUBMI}k0t6c~I6+%FTu09-#nDo~qw9WP{OAx|?(cc22N#-w3yo;(Q<=aO`u!!Yw!|i|9B`vJA;;1m zDOaW~5X(dY?+jvbfJuu3fhW1)r*Lb*06K2Squ7R!6{AH2=rNe6kQNpoEv%)r!ooet zU$Lusx_|?%sj9$j&QZ zp23ll62~kV#!Oj|l}!7C zR=x(2e9}Xc7sfIqBN>pWvT}(j?J4>$-jWZQn2Uba6LJjC&@EUdrB*neCx5}ILadJK z^Z&J)eXQ+u>?AFHti4j82uyWR%K-LDXhN{2wh6(q+JJN&m_TCwezNsKy`2OUgH`UN^w18EKi7 zp+&Ft*gV-@^lkq+(f991!a}H-li!g`;Oe%!+8C%rle#Q&vHj;Xdm;>4g%MC;WUu)StGhjlmyA}hTx6Ec+txicgs8jDRrX@3aQ414_u13yHRTNpfC$2*5R zS2}f~7+yF7MrBe;JCEl@b#Cq4_)cTz{J(JULkli4|Am$UnMQ`5?)ucwX{JFa%miZZ z8)v}#%XI3Y`S`u?w(iXFV1l0ht* ze9#c*_n0AUS27lLB(L*ww%4@CSr9R;#hsR4H3rWhQg%pM#l$>sPp5vB1@|Lk?NCFq z06UELF#~S*P8tKs!VzkKxq-|Mzy}|kcJ&klz`H01It0MI z-GM{^d=F6vq;Qks7SqE#9-Q!uzVUfEC_Ml@F)2NAkf_kc7)#&_&4TN8^D;Xa7e7oQ zh@oL2D}fX(u)PlG(C_`!q6~tVv{%&6pv$~}bf%xgaXEvpAB?MHtQZ;Mdb0x#Uzqo9 zTudyBPvWZ~{-Wp+*}*vPXT-+*SSu-AY!f?QG7AWXNPJCBYa?k4iPvC>(BRSNG%(S{ zM=LYNkB*o)>ZJ+6*HE_qRFW2-4p!qJawL~O+VNK$n8?tY&bfL}Vt#!0c{rDY*b{?a zfB^_qPXR*0#C0iMjNzdwWk{7Wq)Hi5r3l4JK@OmFWl+kHDrHEOGNeioij{(-QkLk~ zL&pC_v-YRX>6YEM2F=mz_RG5%%9WQP&h!aJ#SZTe`Tfe!q@D$`S6^5R;Z_`D2sl zN~h9>idKfSoZO<)5j=`KH-$Y3m&%yub1U-GaGog01vn>*G_p{W#tQ&(!>92a zErx`l#_}D^A$|wi4ql(yu-Ir9_Wz;(8orGg1gIjKH~@)r(?)9+HUz7UBm6Dj^X=f!}v00lTvpe(uVSO z^fMguV?PfwV`Dxb)JYUoh|Q+LX`pcH05m%=OgJzob)ZuKDW<0_4GuW*fmqJ7aZmyd zcMGTbiNZnf`X^!-YSJP2P}4c=+%hLs3oNPwHq>-*9cqy?=djbuUNxIBzUNITE9(GC z4jzTMOE%OBMA163LD!_!lMC!BFH;e5M26a@Gj>jsMPYQAw%(d-93iq1fFtGDl%UOJ z4MAIQq^>QFP;FVckw3DTwiX0UKeN{|{QO4qT>jXg?YN?~dQ&DVS}(=7tMO9S!kP1A zvwYHQ42w3~4ttqJQi@VeLi`ZPWiVAce{vJhHM=}CN^C$45Z@qH)uvS zh!W>5H>Oo)bj86peo0I#2O3R}y&c1xHq4b;L`@bS4KK~6WRqqej*pPB)iwjKG@iod z-3VOL@hpzZnvIuOtoat1=UfH>l|evdo;zHgoY+M^NIKeKn`H)0M_=Xn3q4-_KU4Q# zWCe367Ei~X^axDP{ugK4po!!&J1)Wfk0H-R{%q%Q7{n6#UH6@M`@zsdL#7SW(7nS} zjL^`k5pS)pp$A4iiJncqS2vuEHqX!#AH8e~4gGzKUt*w4?DUT>`M8Gu`tb!@Yv|6c ze`le;Z2hK&!u?6rOXirV513)8))z1(jlc_Szt$mY{_A#Ty${xC)*13jx2zM=tTUup zXGpWokY=4B%{oJxb%r$S3~AOG(yTM2S!YPI&X8sup*ZUxLzbEST77bE^OeSet$AI( z^}}-g%hvDl8m%4q38T4w09Vl!>G+Ve1nmK6yLdtAy#sw50D94+A0E%b1=CPs|s)92_NKqo6G6(N#V4WSh7P)$7W-Vs8cIzl~o zJLf!RbBq*y8}80`Iv8*`*MDk0>IgN##-q&Yc9)B>kpDmQY2Nnf4>3(|8qfBDCql?0 z3pFncHHflYjkeY?g zr6ZVugo&&sM{Ff$MapdPqn;_9H>*g_7NeA<@QNoFY9Z#y&(*Emi_f<;bb0nmJg@hm zIG)dc&(m%Zx@gSIu@YLRj%nah9So@shExYbsskYy5pEy5RmqshEdh*uUCy&rEM5wqRlLI&Auya>BFtcYp# z5Acvz_Gx8X4+YOnhT!gkoKfmFL(E66Fw%Wwpj`km_!VnHJNk*XlykDV)_VSgQ>_#` zYs@=ito5i^lN<|IqhE$FQ!ZmtIo{2^|sLEEKX5uMxAeC#35aT)iN-c~DZc!N_ zl2#HUltQ0t;(;TK5c1R!>VYG49BdXSZc4A+B+NcyWyb#EWb6c$5sZ zmxURnB#qj{5V%G$Gc7+}=YeZ<1g?=hs3u3uHCCj!#vM(AEd{Sgag8Xt;;+u(ZgFP% zOU-uve0GI4XS%=^-f1WzX~gH4E#fBb^X5JM`rGtv-qJEM$rw-abr zL3Ks>OI4gF=5)?Z=UOfODLdC|iL6b$EKTKQNO@UUa4)XYjct@;EtRTG9&XlE?j=G{ zx=63w`8>4^Bd=CO(rV#ByN#sC17{K;)Kf>u183qqW^;@beNTSd+>3Kz`D;Te_i{&_2kym@%Dp&Z?xiBdz5LNMn0u+n;9lOc!pW1vCA0al>DktB zpUN)whO6$S#*2b8UWSxc3tZewjkhoGG8E}m_fq4fHnoAFSTCGI#rcl8mt#{J30Ab3 z76zuK3<$L{(7iA^xR**jW|5ivu_^Y+_wk6w%7GbZje%AUxEFlbj#QYC%M3Q8axWtc zG54~*k?vjs?JB6QD9>+lFAK1CQS0l0>RV|CM`*5YyCVnkx4aA>>i_5^B)g%egpbA$Bk8j#u}x?s#=C zwYn?kn&Fjuxzdozz1&>qfqQYJaxadUd#OlqFTXbp=3Xk&-3yxIyH-4TGD#ck+38|y zx_|7v1Fw7g&@dnEx&d$S5wej?vmA;McS*`Iq;d?Y973p4eSrJG>Gdo3kEG|5XzXTj-)0aK zeQ}^wDbkT&QC`&KjhCk9Ta#Ydd80My`@5ESlkQiJSyDNMRE{B)Lr8qIr4;$-3h9$7 zDUUa+D<2&p#`B21tl85#SyD!bq*X&G1s~nS1CJaboRCwo}le$XFcnvOD_%11{CdDKUTdNm(?UHXTbk6w4Y z`sj7XtBNI?3laUQ?`Q`DUdf$Sx5XB|3(^ zDQt1v7+oCa5o44Yi{l(IaV(B&LL@s$F)!GBfXL?8v|oz%6i70^t$a*F%39+s`hN3K zG)>|5F!?RqkA%GUH0^kwYTETBJ=u%vf+ZM;F#S{7k2OoqEw8UzQsc!U4&!A=dAYD7 zFH7gMQiu_J_a2k-K?z2K%_4P#YVj(wNo^e=4_ z;}MEK#lk`*GdfQ;FS(}RloFp+ZT`8o-6Zh2FIV7`IEJjE&gnR(BT%J(p}k>%Y)pp5 zP*nSsaP8vJBl*jh&wb;8wu6MkZMCH z)&|nG#hM_zI0!SO!U)B}Aay+^hR{)_w&(DS>GDcJ4%0$aahQhX4PFKu%hhNtK^&J= z>fs@~LY8YD!w7Dka*Bqr`Do$kq$<$IE9q=qxuKtKZ_t3?}?U(2oQu z8VSZ$w?tJ5!jXjHDf*88Ifq|x!YvrqC56fjh4y7z%+|rMiT;iv*LizPx;0As2{1JxHWkM z57pzZm>xL!4SxBhkR^}!626;75ja`m?gXoxWNbt-7CDP!t@a(tlaW~cH*z~9w%wOx zApp#s6^s~+$iW|macC3$;!sz^GaPvbiEN52xkH8`U2z=USZmxck%RMesZPqUVDKvz z1haH0-Y^)4BSrX?B1*(#hl>u)W?iUxO&)f}fxLd5D7U4cgPY`_-0CVZ@T~*-wEuz9 zz|)HBkd1h<@=D88qGmS(XkvF52Oh4ZiD3%XkYQbumQBXTM`5jAh~P)t%z*j zLqJFHs7s`)LNH(=0{`KY&@CSo7J#1+5sDSOYu0?vXU9a<8f9zPMSE1rwNhbajZolipS%uc!rsQKB&*i zCZquuQ*3KodGaAlpx_(S`*8S*gtUUIc-%ZL4Dkr*!{Gq&;=u-p$NZ1S!bWODBb#mu zx-l*jBrRuEOT3AoU>w09j0noo5qr9>NIpN83rvGOT~{Px^YY)U1USt{ZCOBI6%lML z;5_{x*`#Bp)>twg-QCur7j}HXQtBBrY4+3tY{lqp^nM*;L^xvYRTF@G*@U}VghPxA zJHTm8EuSU??#GcPb#aWU%gbFYWy?GUCQV4zg5bPB=fUK_GW06+vnB-n%n>ZMBoCfn z9YN0{0>?C=N?j1_2xka--b!vM9{_Y6vPjQ!Cg~_Er_>yi$63#F(!|lgnh@!EjKs-MR8z>%A11`-&dHuSSbtRs%XQH<%;qu>+O-SQHT zU)JHzF)=jXWi%ZJEmvbmA{Z7nA=m-dN0pG`tx2zH-!1X8QjpdVCHL?G3Kpyb>{NKFGzitHEvGDaUA^5nqIY{he3sFx&Jm|uuD zm=VnuT<0DOqsJa7YkSEnOSYNANTJSsv7~?}vX#@spcph_-i~RA(9FsYd`g$;I zpU&)S&%0r#;F!~h#upyVyj3QYH_&|6t#hMyx%UFpIAH& z6GV>7KuSEyd8)-8(3=-X-T2sR|VFtxJanbt8WGVtvlkEa$s1qIT}a*@gBINk~; z)JW%ZEF^rPF(o14y!7^y#F@Z*hPa`jHDGP5r;rTq%yte9ZDwOuBcj=IYP>WsCzI#? z4%1^Nq~GT@;ouDP#+XD0b`o2XY1uvE>;gcb4xqTVv4{Ms&wtJkcvS22O$elZXgqjk z=A9SF|5Q>$kW>?bj5hs>)!$?G`66!~ck`Tw%_FgWBK8Pu>+&u=s z-DCb@z+Vu;=|ay|TazNX4fBSSZ%U_5MyZ~`%{R~B=9~L!lH-x&Jlk?}UOtz*Y|Skm z?1EBk%K2c|x!iB-+-@-nz>+byje&yO#ym`;06a{i_RYn%@sVvE;OY?Da6FYdMzyI} z@B3Z?H}Qn-)!FJ2mxWy~4#MT!F-yl_&&Vo|UjR6zk0*1hR6S!t(fi7;m={!EBRlM^ zPEX>jPJU8(mCT}DRW9sgTAeS-4tpEk$m9f1=%AMTRC>`l+#lz||L z9`)NGE8EOXhwQnNv034bkVW9dj%y){z$=@~fb6-G>BQ|9$!>+Y>a8fd$Yl{wSp-ye zk*8an^+T`APT1Qy2D_k*`I>H_vc#geF&^AeVb;m+CTaOeBNN8PWL3|F^W@3?JZIs| zF=vk9H)~PbAdJQlf3k*xsN}ZE=U}{$Z?iv6ilVrXu>y^U3JD}xXX#A{8xXI-m;vYX zH6i#mtqH*kohAfhv?c_n-!>tbdUa$d&-umx*=vw?VpM_q%W5kow$B=^97xAG5^}_} za&X70!g(-ILM^pp$7YPJyShVq$Sc$1R(MfMup?$<(18PZ-MA6Tj4$9EF>!3|)r8>T z%9A!8wzpzgXsFy2DDUE_=F+>-mWp>mSM%5=P*R zY$b{x4KQEXKHa`*o8NJRg*+$uFt>~Lkl{d z$HWXm%G$&`E$}j=ya;iU!*%)tVx#<&r2<6tl{=Y#u2!u?i1BRx-&zD%xZH|JT6il_ z=fNO6Ldb(>=m?>nIzk?dCY{G@j*+78>z8v742S4kc%e^Cb%dHw5tGa!tXfgI7z;VM z<|mrB@Arq8rYDRC@9~%#^h5}GWYx-{p$1Ww;KMbWij?R3%RE!MnxrBT%Yu`_EAINS z7Gj?KLKgqzD;h81J$4@oVQF?L<^ULaHGc$SW`?d`e?EK;LhIBq4P2^&A=SZ<>R?E9 zAOs_VNB+Otu?`(f=^wX4J!VuIOHc^SDp&~38R%EAFQm=T(yX7-GbdO}k*<#>^GYFJ zSy=Rba=WPtNvDab46tcQYUp&^)`K+dS;d_&AfUSy>E$UwUQ zWbi8<3hn48+EOmg&bHR`RDO@Op3Bys<*i4>n&eoxD#wt@F{E-d5U$Zv@=P?!*DY-z zeVT~}%z;#{F+z-|?NDv`djzQnVOkjTMhK#kgD6<1YdubGJ!FJ`9YhYT?u6q6%xjpRWUIAX4`BE>as zV;bz0Lq&>fM9~#bIY)A+=){2=XW07G)!F&loaq8vcu{c1%aHOSgsPKi<$p|XKfLSK zi~Cchm0vn5D~;5ITNwJp#*ho%;bIMRJJZwit8Y50NS!TZtj&d^^?B?d8zco<(}&x6 z=BL^kt@T6ZHA5=5^Nu0rcK&XpyPZILrszM4HKCTw>723dZ#rtcEF$G)sP;{V^SQD3 zBDFFfCC5&<_e9N50U6-axRR#Xi*)ZCgg02Sq=B1axoTia;xRPaxW2LnqD@Z%DqGgdBnZ!ZDkwWOVc+U z1H_Aa86aNVi^r?4D5scFN;1Qz8&bKK3+g;@FOF31#SwEa6)EoJI@4h8r6PlS`HdBG z_)vd(dZxLTKW7)z-Aj!Z1&7{8UWSxc3tZewjkhoGG8E}m_fq4fw*K|PIaHjLd!dn< za0`Q`8*)MS5^GTRazW)@sz`ejuDKVF^)FHb9o)-p2R6Hx-y2f7mxm28_wpwr-Ms|b zGliy+6e~k5nR_{X-R`Bv%hFU{hHCD``6~DFlBH6$$|P=SrOS5Pb8xeJi4dep z_YxtLsw3oqGilRrzy6D)%z8&I9-2NabD} zG51oD;$F@$4dz}dGPsxbteErU2z!>hA-%%<%NyDKb^lUlM$zTU%#bp(IQ2oTs5AEk zW`-)w{W4Quf0}hdt(XyP{;oQ=!;aAIn?ELN{%J&itV~&08BkV)`eCKt0V6MD!xf$h zy}Zhj&9J?Z&Bl`p)5F-sW3BC@y$(7=d!GA_K)dfKU!SBLSUOEDka^D#b3f_N>M8>5 z0+7KWFqTmGApU|d2K{SxlUE{Hn|P6EuDlE>FAc%Nlk4>CG|H_lm8#7iZ^l-mn+WOC z3>|7Ys75ytB55UMgis3ZCql>rXA>dhsUzfpvvD4?IYx@UNA589<6M>di4bZ+HQa7i z!~LjSj0N{I#JIlIA7Yw5WjvMpi4gLL`UVxywi}%{j93$+yHymmVMHGR=W%S=(DC+_Vl2YD0_*JHSUoEuSU?ZNZTyb#aU@ zYs;&4D(Z49IaH_V#nFObS)22W(NzF=C)b2vS(_txv$7f;5pV4r!Tp8^)&+D`X$g{) z>lqRjlsXVED0Qr5{U=(B$Jw$rC#waeO^7sf$66G^QF@#$Yx{8BWVEOzL=-v}mbG1y zti`6?_gz4pj&v62wC{iMOr>>I^?*Lw0zmfgxe3-Nvz88SbWDp**5|+KBlOXVD?z7 z10nO@12aD7sFPs!SX&&_cANEUT^tmXV0N`r+c6C9=QNc%xBZ&C?j1n)*iL zuZI4$F)ej;TDlAaC8|V0dUA;*hBJ%Gjm-ctG~QF=H)TMKTr+A&#w)I8i$*x3q*tQ&pXWzm8*(g_wkwbaDt} zF?Hu;0g}Jsv!PCE8+|+6E%r5YHh)rt<2slN7qV@>oum#}5|j3%=Mda$e=3n1=ddll zck&9PS=b>pB2iAe8#x>m0&|=k);YPSIH>wuDB$U2_=bv)VyM==Ov~U{EXFAo(Kz#w zT3n1ID%i=ImKYZ;IFu-40b1&$l={ysK2QEVpR@v zlVV!X|F2vt)p(?Vq7}&~h7Z4t3J<^Qh?B9vI^x=!QbX@jr3_#=Rkx)c%MXlS z-eWmm)nK3{7Lts^Vz)-4ywIdNjI{!|7_L!XV(|r*yP=VM-aKumu*ZP1Z)ou!LM5Py zU1!pG+*yVS(_RBx9nX{hkeK{Gb{7x0!@_)bxK!}wdw=MrRwuCv&SMkAVmudff%J7Y(t`XV@XFuaIW^)7l^YWzl05Z7KIX9MvuP^Q8 zZW8S*|nJcQ6D3G8za(h%c(9iGx(R8*#cW}ydZxO_dfiYQRsT&8O3wB zDdo=J*JWV>%x3(+uVZJCB^N$hF&KYRLnadXFE*7qS;AP;Sr`D(?F1-xKNV) zq$LYcT07FG?syoK95xk;At^r|@<$Z798nxy$d)cg7jsC@DR7!Lw|EhgFafEWBW=fE zSnwS+T>@lepg+#M^SMk}HAG$s_0Qb%VP|GYnGp(kEB^IkUfJA*BY!PDI^*?^`71fE zC$^o_X0LcxY^j{Xcpr&>u?~zLU&FEO7+W5d9i4%qB3w>v>uUqp2Xz=vrWwz+gg5cj zlg94lWm~9zd=FEeYH1PoboreOI}y438YK;Pf?EncT-q5HyqRW)fO<1M0+X+>;R%g> z0()4ahEHrexlQ6vZaWJLwxKPR|B*I~zo7=wyFnU4%mH|JOWNA=g8x6T=|y{6!T%pv zu&v;~@*7rBERtoRsCF+Osfr5zLjE~xp2!mT*VAcIrzf?YB6Zoyh3t_D7xJKjI^X_#=Ozv4-7gO=DpS>e+N|j>|jwd$^cTB(bD{3L;NBsT3w$Te%jc z=t$3|SK#SiHSr)pHihEgkoIhzUNsZ{+9#E#=ARh7Fn=*$69{mZyIHYe(L2c_t>k!D z9OzdpUgmvdJklS(md{9Q)3tnx$EOr)v-dKo| zw?HT$ohX(d4XSyXdI5_+I)cT9a;P`2!{S13d#e$wQ^!3YsDvhl*3CB}j?FGC?H>I3y`KAk>%dfSn0n7dFPE+@0O z0($QAZ_$JpKFtzkcu5p?V}J)wPLG}m71^U+y6yk7_a5MSRn@xiD)U==?VYw$Nhc%_ zigXE0x>ONDDiBD5h@Jy_JRu>GqbW2cv;zSIq?kacDiT17KmetPfFX1gP^yShr5+IY z-*?P0=9=rB!X9Y;-&kGJ%3|?E_JS0PSKXT|7M*Y*kI94wd62p4|06{m zSj-8a038;J;U7}e&p)Kk@r>MaDLnFIB=m`FKK~5WI+IkBxP|_oJlWh*nDA89kzPzo zO$66c`hU?B{Qv9__V?)jKY=rDnXCT)X|($Wn9k9fbohF4x7o>@q&#H!&`s9F7qa98 z)x;PFk@7p5x-G$WDk^UOvQ@mEh-uH!Xy8WgfLQMECA@uk9Lf+n*~T=k_~5L?EgZRF zD58REvdu}$6$*0b1?uk=?CwEh9*n>-o-nWnK-{AdKtHf*M!-kaIpC`z#5y>3)QsrX zjDSfmt4XbmBa$8b%?JU7Xht0PY88|M@tTUbN+h7Xh=KSt5=1aUt0RzhhAP zg=ZuR&&ZuoZg$=ceFmH+-ECh0`+fuHZ=8;*6p2Mro1+qJzAGx^u9QL#WVf#Y^EC)? z>Jp{13ZMbc**Kj?O~)Z?vT_{_I>D45y5BK~5}TFV2l}M){O}GtYQ$p6O)UeE(Sbt| zPd09TIewNNM4x6FtOUTPonbikvSScS7)hYEGLRV75&|=$UvaxCbICR+3ETW6 zO{cq`q|5x_X}2uBgDuS+>0LSScjb5cg*A6~e!K(Xc(;hH`XYC6Q9G|&1rX^Uh=Mq9 z8?5nc^ObDk8}2KYaq(_h`b!>m{v|XMDSD@Ry%^YI?t<9!sh^Y2UH_tR_C$Hv^SCtK z&mG6J^NTKD;7;@r8n+nXEyP!I-NI}s4nHni;Fe|*B~b3pujJ76N_TPtq9-?&a+Cr5 z(#Fk1+}v2mu>%kbi=~{!SXx}{5nUJ+Sp;Lo!x%}_@oK|(wc*BK11NXrmpiatjzAF> z5EA%!3mgaue7prdzCKUTY)SEK$lN*bW^+zWOK3$TFmyXLeGKl*J(j+d7BiE>QLEic z=`mT`q8k?!NSFffG1(<~C2&dp>l^~V&i|B~z#I8x=*zgv++Q7P=J+G2`lHbm$Xg6+)Eek7O7yWUJ_&K$97S>St%^Cx5j5nX z{I@KdFSx(+@tekjoLsP9B()zJgopBT*o6|_$(~p0?|-Ro_M_p=1DMY)rByXVQ7k#V z8yq%%W&7T~@#!r!A_Ac?rXq@Ypo)X2gScYUR3*3t1QQf7i002g22=wlp%%IvNNmGa5_+ejLwf%QbXa-hK_8Vlc05< z$I2r~B3I9RYad^nWe-A91~8w4?MNulU(%%PAr7mCNu`l%VnDMOFknC@umWX`Ie=ba zjbT47Zv+N32{GvTV+{187a8-%py!V<;73KO_`p9t76gp}&WY3cXUPcS9T z_->~u)Uz3s<~OFoiB+H^P6f&$X$8uHaRo|3RiGqP1x{o#R-mL(1xhMa;6x@`1xgZC zpbR)BhdlS4ngGfIuq6gAm16V*SSF$+|UuFywP=ySl6%;I@7#U z`N@=@6XfMh-Qq1-FHe~fu-k5KzucKII#2`(J z-h~gQj`Pwr9BfBMbP%iIR4m3p3>ncutcFvu7$-S|@bN3=g=PzT&!*uUQ1@nde4O9s z@OT(Abb4QK6Z0=QXC%y%!Hh23WY6sDRB?W&hoje@mGl{ftpom-wtu3(1q1p;=nd9M zlL37(qw~2jbCUVVP;?$=CL=$)ppVS+Au_lJ{y=w5{vx`ULK5>U@`j)u4xS0%xs+Yd z$H~fFL;e>fOM#wVu{FHO2^p3~ru%4mr&3G4t=saS9&DTa$Q#2<$O!Hj%GR(!0yxkI zAeH6{jSi-(AW@#KU~92t%piJ26a`D@&qFv$EBaf(d$X`%iy zrZ6R$N*!gUdWs)M)wE6X6ztH;OVhq$49eVrAzZQ{l3y%gO>eS3 z*l3l$M(>?ZLsjoRyqs^xf&iKra=OA*jv(N?BM6|0AslT6Z2H6%sFF$gLK4MUB3Hv53T{s|ZBDnbM!p}z20B&*LV_7Cb>O+{-D z-=#8APw+~Q+Yp$4ukj-3jYQu1uXy7m>&3}b$6l~+FI@XJ8P~pDpz|FUq?ZtJN%~`t zD7P5u-OO6(XGE9DMY`IdrhPAT3-=P4iHmD8y3v@HL^51&>AqLGzsiiO%Wx)9ev!mp z=H9rjwTEo!XB!*2bXvwxTn{`WG#$`rE_i~ zxA00yMxaLO;XB3#sx(r#2_xe^!!_$er{74_heX@g5>2h?fWel$=^<^FrYH|tgh{!a z7Z}QHMw>5&|Dqxet0IS^|CG1zTGA{O^paVIxoxd0%mmDq#Nf`W%UO9*2hJyN*2X(u zG!{j&83B$7w~IA9aQcLYpOEdH?#c8S4?mMWPx|xepFRBN^sj{fitQKFUkpb_h(FvTF5zu3P2vOd z=fvjMK~Ud{sgN%Wfv-(Lf6sxYCe;9N_ZHKMtcG&QFbQ*;FB$WQj?9KK=B;)!<{gz; z_ss8MvZ!syju?c!Q|ruMt24(SQv*h>e9jW45897DUxZ8j;?C+p^YX7sMFWF4)j(7c zqjHH3rO`n4_)y>8Q`zp>to9i88?h^LF{_;wj~%HX;_IA&y6rj!5uAbDO+k$Fl?>&9 zkwlkHHd)7@$NRs<8xNY39f3p`F#$O{VSh;kxBsOqN0+8oa&rC3^qMrEH^ZEM2kEuZ zz^pwPU75+0#%dI$4}|p9+!J>-qy-(qjsjjA?abPjl8$+65g2CzXk?J~W+OVzkT2g= zlQGLt2W8-2Q8B7_ftjg(=pxV`5nPNG=! z4N_dJc0GJwS2Pu!X=DemYmJbLq=qA5*Tq~p+*uQT0`VwlcNNk>OtAA<5f=wyy}6qo2fNz*`nPMUInwBS0EPecCW!K6<| z2F76r$cMc!sHugmF^nEX@__jgYz}ebaPA7rh}l9tX0?#>0h8R~>=EK0$(|wfOm-31 z9xuw5aTn^c{MQaQEPsD=)pSjDects7qLAX(TBsA*#EM}Lt8J>t6FV^~{$P^kICHh|X&&<0zz zF#Qe*$2WtEe;P7V5|77+C;3~W~ka4m8kF&*j%)dCl3UI}LRelTL+k<_#t%vNY~5|82n{NByQLmJk%30uF)E*f+h~K zeUs3*w8tg)qx6JYNnVOip2zg(vo~Y7Q+<{#)Mf9~WAD^q*(Fy%ik8?S$rM^^KznP7;+sm=P`(x^8iL#IECIRUS`*f zf{nBo#`PVHVOBGq`Pz2~y2s6g*5F(zSPi+5!#l<~d{po)|Ao7mW8ZX5c54lO78A`e z{g?TJF&uKd9)jg9wc9&2+dH+|J2mRNWTjS)n#IU-szRPq3m(sAud^V$&S~(;*hcms z9+C9_s@Up|_bM$>IO4QCs+M-wWWR`E&eUC0FDx;L!VZhP@6>7U)Ti&rVE*JXsK{0nfc5vpA8NpZ!gx?l%0y=(vBCdb^t41&=AcA` z$itTFniA)~Vwfdjo+i4ktH&TpL;xeLED@dJ#Tyuf?qh=M9^6NT@5>^g?jtA~+#1Zr z^a1}vjh-3`#E7`RvHjQ>dN(^39^v*-0Ithd#&DnK# zSPE@?r+7B%$P1%kH30c~Nqz+n4quVqkfZK*WMLLxf&ng{%kmq!5Gb94NK0$57@Rlc z6)55PKgCZ&3D_{|Ji4D}k0Hj-ggiewKMQ$Y!RO`Y#cmR^`aBnJTeY79MFgQ3Dwfh_MKcvM7` z_ZY;aXWTKyq;M1XqSckS$BW4cx}c;uGfd31BIjCh1*c4gzmQ(YDH_bST$=sFzjc&2 znk`kh-H9SGOu-0dX!sT9gaGHEhCP#Bz(w$jvdb*lnpp6~F0x=gi7ec7Ct51Ak504Q zIa<0f62oh0Z`Gdkm93 z3uLy2l8(O$xv>G0@A~v{CT9m)oL1zC;10YfMr1(8R*j&Fg1)!vwY4RP(h;f!RHH9OsZn0LBy@dF&&UVldCTOB)>xEoe&$W2b4 zJrqrdBC-<|ghAtRHx9&9^*CmkT4UiFo%GitmewN@-qtl@$YNoQKx(bPT22&4gyh1O zr)ln&>6!e}<(c`}d5&y%XXn4+CertCJpmpsHJ0Lgmt84X9UQ+-(Se%o&Vqac@}o*< zc%PX6Y+Ta7LpAs+YKn^WgAp4c%#F4|`Fk$?8&|UzHLhWyyrywIi|Eqg$1IdTF0S&0 z(i9|-hHcvN?}u7XEit?ZdSZAfG(~Wy`Z#AvJ$zE0Ps-s5{&Kq7-r8Vk6V#rH>Rv2a z{*%?flsB*!$+9XbmOS-iV9V$J=4+)P*gwfDHXJt(9H@A5;6LbSB6chd|9h7Gj&>qf zrR*Q*%RX0h%WrG?t%jise}y4jG8AR#g~k#)R#>AP=qYkhph-}Lw6KOS6{u&^J5s0u z6r^_D3T9L-tY8J2AXCi^53aQa7IhFGpN^T)6N^C{l&(NI$YfxTd_ntSo@@#T7~i8; z0C}fq&pL<#cbq1p920A)fiNVdB6i$0qrc(|6?DlE_@p79%MYKi*lqb;d0fOx;U>7> zA6b=8670;dLtfDdB0A|8K>w=uG%i z!jnPLe=|Lc&V*MTURqkdB~lo$Il&MOUi}w?NdBa}RlS{Xq5NWG-92^5GY18_yLQ62*e24 z5K+;=4g-wcCr^w39nPdqj}bn&$27QBOAtdyWnhy1v1YIp876LFBus_nv$0{*t&8o$ zr{ve>c%1A`;~C@A-0Aq>`H`|a^(J=-GujtJ>}qa1xEj&|i~K|{KQSqKRyiUuESnLn%?PZdg-jHYZp|D$ni1Z> zV&^x#xh^@8$J>9M;+p8`a1@WC!(x$0BCg|kGF?8rJ{t~E*r$4Se-;!;v`Ur1*Hm1q zQt6FbwMt9xh-+0UEmp;p5cT$a1|qY@q4KyIr|snB^87Yr54?GB0hP@IkVpfNV&i-g zjPpr=rds`PqtorsNVJ9NSC<<-^yQ z5d5ye5*YlNA;=HyCn~)mbj(E+OKV{zd;#eGN>pG-(QA! z5h%UhhgGUqla%4xA%#LX$Kl#SdKh)!_KjGk`{!VPBS3{|B! z*T-PyuqV|JnAzm~O=C3-5t|9<<^#_K>2kKJYX@5mX9l|%fZ)FJ!;gf=T^zGBXCuHRST zF2737af=-}**<{l(V(vv^z|Ak8cM^CpB=#^egt+%y(xveK*k!Jvg1>4!%&AdN0HcT7Z|~+GAh27H9WoK-`~w z#1#%K0e^%$dVyHzPVm>LN1E+53ZXv+D*dM+9@8WQ)IkXWM*(~YKu8FaECe7v%8%o9 zQpfoa!fFJy7c+wG8=;15v=iHN>RQs{3EP$Ag_itl15 z*ycOurm{7i!W51{^wbSZK*c;@4EpF63xY|!dG?L;@65K7GOSbcPCO3JA{HDXZDNtR zXw!j9u*wt1XdfB!GTGe~Q4-|M5PC1^l$lEP=VsD3{-DrpubVOY^bbyjS3WRRe|EI3{-Dbf#R(y zP^N(@P<%?M0jak#P{Zw}RP|Q<6!hK-aW@2()2+^yxZjZ;#7GB-L#gq89u@QR2e4i; z)8tqDAmrR2WXGW4zKOb#qxwniw){@kx2W(({KJsb!^n^7cw>G?4)6}okMk@nJT=~N zo~N2mil~EloA#h#Se_!+Z8^c)ppgjCL{lUFRff#bdBi&)TFHj;JF&Z_TH$ZzmGBW0 zj9#0xp!kY3i?NRXtCSmnsCP&KvH9ANx~st2EJS$L&X9Y^}tUxKAH)%lazM(Nt!(DFCVr;OCt)MTS0c1L&KpIug z_5N0wap=4q2~h^vH;=!o>oU+9(*S$!r|aAXs+rFy)mqO0`$!pRt!IFJtj=$)bcTo< zO09H8nr@ZO5H68QH$AF!#WPP@%eO7+*tU6#<78En9sraziHSVd1s!_$9||g@u6bCr{UUB zfzOBKfW>?Wz1#8_KHldZE1xTc{9Ji;E8y!9nRHr6vxIXamQHvUZ-yjq9gbL@>Bz`yS&r8jUElh0?axQEC6#NxnlzTYj1&h)DirboW!+(NIhZbS^mL z+?DQsQLx-fBFgy<0)DbVZ7VMLgDD>jmcjeL`#zoFvV7A4<8KHoJQX^8bNso3UBP|O zQF}P+CfAv6GWu}zy(HM;ioib>_B@z9i;K)PcZ&A|Z4Css#@-0-fP+F{#h^c$HSl?E z#P;~}Ccpfs{<>QrPlD!8IQebe+Tt6}n5d-Ekw~N~(qGy3tzu>%OCt3}n9{tQ9q^lC zbU5!U?2hO_z}2<$g@k##q`XumaCkiiadi*Uv__3UQsIVU*$5;RV=1F@8V)PoF^CoK z7{o$z3}VGQ2C?E@fs?SnjZ8FztWmXNCbu^d6-(cSM~9V5-v*-h$))cY#HjKHjXIa| z(d68sAnnCKF$S^YqTjPVL*QoM9?^deh!!A8oM(18#F=-c=TW|CB7e%q%8 zdxM^g4N6J_eM=;TQ~ngEhZ=*`YS&mJTadUlw$2w_Hs7ttU(N}>oWGq5LOwpRz=R`F z@ZU~;^5KPidjRoo^1S@1%VE89s%AD92!=lGwowTc)? zE97Ct4MwDgXT*zVjIumpU8Q2p;ZIkrIb1RBfUITscrbJndt{1{t5_D@LkxWm^OUG0 z6oZbaK8FJp%1koka2{oi z4jWF*W$bneao+S4ZA9r#1H7fi%slLP=pmL)mJa~FTjD#~pp*7IcBLwLvk#%~6 zARX@A=-yN~_&NeEzK(#CuOr~*>j*gdfIt}H=nWAZJqNdN^oHlx{ov>gR7W3!aKrzi zNzw30k(J+6gtr~ezK(#qzh2vBaCmng5V5;IR`v83#Rw@N)ZqtM7~t{^VJ<(wX4((x zrX{5z==P)wmW% zKzRW5lek7Dh++_fh_QkE1}@@fAivSaU$K6$w)U+^Lr34hH59VCi!VhQhkhy2K)sA9 z2G!FTstc7c-#GLukz1*?dOcGOOv*i#x|$59AYDhefu)UUaMocZK0e;sqrxCTV$d_- zctn#3jz=_M`b273tYX+}=^t?*n11~$6%>eJFMzt(6i9oYW(=ICjQ~*zFnolIcujjG zqrDn5Nh1`a5ymoc69y%wNeby^7+kT(WJ0+y49<=a1I=&MHKUlO+6BYWlXK?tm}0=- z3Oq`&hgKLDj<}WNli6pxLeGeLg`R;b4?CJL;$schQ6r*aM7czd;s3i1x?M6dI!fT~ zOn*~5S^(A>FPcEI_@3YSszZ+!T&$q(>5oAy#2cu$vHdhK%OZXZB2}MLYFkL>SB&3d zkb_MaNcCCIxAA($U^NBRo*0BZ2C6-)2WGJ+2AKx@6&pWcqn&jzUR-w?Mmy6k<&J$E zDY&%dXD#YXJh%Ogq+}n*a-Pjwo?XX{OjJ!Fn4VZvidyi&E<>(wY;!JQq!k7I3y_+xNmi%Rn2YDXi z!Qve_KKD-X5y#8?75^GEao755#k(8|r+xZVfrYn-*UyM-#9ibY?SN6`5$AI!)eR|@ z`Np~9@d?j-(U}XdYyNfr@_LTzo5#5;8uu1LxVLzc#~v6OH=yHCqBz7TfQ{f7+&$Sn z8K2MQf5{v3xiQ^~gb7KR``{OxYw@7SM&IM@M`tscry`jj%JX@c{dkC%D^GPVLZ85Y z$zQ{_SAtR0mVXZ)S++M8p%(2(uph z{@wx_0osW12<^%2m1;HtvHW&mky(#TVav_got*W!6O$kKuG-9G=q96a6E}P>e#N1I zpND~dll`8HK0cJ<=Ycj1!3~>)l6Go#QEigt!N4LjA6p`vzsbyp`yl;Z)>9{0T0b6K z&9mGQMD~XLM`dT!?C&0^gVO_GGd>S^fO|PR9_1gO=sAnGRv+LK4C8^o%X_5n1QQ;@ z;y3e41S_UhDD;J7l?r`N11T0Ooail_s1`0!3-#`^_F!KR7WL+ zo|~)CE;oS|GO1`3N1OU$$#y*lN}@!#!;>R)gu0&cwNq(Q8mN20HdQK>YHw<8D5IOf zx*z0^FkR1fm%_24371q|6^n4-PjOVx!}7C;2g@g7v129ja>)XBhP#N1%h+oelu5iG zczh6K!kz5SW60v2Dhd-$DM%^9ODq~S5JSHUR3EA6-5BVKB^R_a;cB=l;Vx9MUJygV z87R}_S$TP+6jW>4Mj}q=E(DMrvls>$-47$LPI3%`jCOde`YNvXLbrh&8X&Uc162li z(-h<)37BhOURn#so^JIkX8g%q$?nLM-A}-5{QL88DaP5HjXyg*y*uG@!RLIA5RIES52(1Uv?q|%I?pT5j1HeOEODP<+ly;FX~FFJozp59#$k$!=r z03rkT=9=E#3$j^>TW~_kuk4-x`v6AbfDrfiSM+`<#8Be4`y=cMJks(MCtBZZd$TQ_ zUReBGG7GeOir?ZWk^5E4Lt!OEqG@W2)q_fz55F6!^2R)OcgukBU+eb~X}nz8c8!1W=>d#SkCpSH^mx^4{e6B4 z5(X?66_+4k@WQ;1m#2%r_?NTMi4)9ntp*Qx)d*u5GTf?6EVm)ZJvTpyc< zm4c_GJM=Vegc8J?=xCLooSAMtd@(+meth2JaP*QEBxj~0%Z+hO{qZ@Y3sH$KR9#!1 zggGc6PHjC^zV3Qz>wO;a{kBUHZBVXhV|l=fkM=!rv_}cyReYM2FW#w2_Y1yApBks; ztY9?oCD#MpsSckkI}m@4Yp|boT;pyW$c^l~yOkiUB9%q~q)B+tp!C2f7kHuVaNZ#N zDz8mC5PLt)#HMIDQ(Bo}Zyi$gRrvF#=DAmMocW#P{+6#qRsvqxcm!P+_XrFV*pkjC z$5U}~uoOVzBFS^STq-&I)Vx}iF0Kf*4~t_f=Y_?w_dE6_WpV5kd=c-{7;kQzhaNoo zbXQ<;Y}GoiC~mREvB;F~Ad0UzP^=$^s`FtmRMvFP<&B!hw;qohDT2r1w@mpfvOk-b zk_DbMbWy1m!XzI;=$G~Xi^<^DE;pF2_o{R`1`d`*NwHC2!B^JZfc5a_2XxB&xbv~A zs^j9<8iD_d=#(wxtySXhf{z>aB?LENzYth)bRbI?@CyiI+!Qoa61`c0I1YNJ z&xBTKI4%v*{sNaR7G+mtczT)Tfwm@TA7H(VG}iK>lG}z}N8~W@X{MpmO%fYKSDL;= zhDZ^NIEbJzxC9ep5*`HQdZdbiUHV3mFOPOg!Az&&rMXSZdo(Tt@!gadL^FTG%j&MY zp)rUq!)Yozz*0t1bkDz9=1bvP%og_d>~c>ozq!6|twZ4&A9$s34Y0zsGT?h7GY^^F z8GZus>@t+wzv4sWR3Cau269LPUzL?X8!o!uOnGHqZB;}}ESsDr)gx+@fLTqGl#8S| zCYX(mkjqDk6J5%S(dk5`TpbZuHeva=I=ww*t~b+=nI!pSH?>wi0&L~O5H1-7K?Vpx zDIXQ3Z$**v(J2Mx!|)pEQ=&+te8eD9cC9!yT@3{FOwDdopHnd@h6$Y}jFgw<%H@*v z+VX=Bu?tIX#U7~$mJ}``UX13+!X<{R%r@`^ONR_?3QBhx`(Yyx(?SMf{{vD1bh7q@o+nC0hsLs1#iZ*!1wr*j*ZLm_S8Pg^VW28J9{gEbuWJg-Xpj5%E zFcgD4unO`tKb5+H$-70wKt&S<`LR%Wc;X%4DJH_9Q5}Q}dOR?rxyl2mB@Tm)z~EC+ zE9&0CgG)tSQ!47C7|T}`b%((6c~;ctv-h%4Q6m~^6-mCLnp&%<0k(>22=B-lpjFh0 zLPxF?si>V&P*Dx96?Ol*BacB0FqcM-9Mw1m#r3=qVv98l_j>vvJ%|*^PARyu&+rmF z_PVPAMhGtXj~X67e}P^vCM6W%l0k0KpXU|s`Sg`k-kRxyCAmRmayQ8iW^#iBt+H>| zv@*fV*Da2cPrSn-kaGlC(FvjNi2J~d!6lLA7GBa{Q8=rrVe$iAom22_Ad_H%01Vbh zg0S2bTZS}{Qn#*K^b8W>?DR4u1m1ijuwh`58;dVQPe3fMqOqd`9ZO#J$&H4MWb~fi-5z(9*NzMLVBnrV;lNfeJFbo|DH}@DO7&)#No{MDvc@DVF*RWjBg1I)Z!i(xM!ucaCT~*(wfho-X!5=sn5D@xuxj!QgB476yV~)|Mx9G5F?HU%UjVsB zp-&y`TL=5qW#QQGv1vJ8fPw08mBPclw?=_A3~n^zXlytthTQ!WBol7Mba1OlOIy%K zTky#>V+$aOe*vHL`y7+`xRux$(*-986~WQiznC;J>|$xx;#lCNrS1feGxm2gZMAO&NPF(_teKUKWl$)SV)6Wr(8mIqiO8}q{3k;Qwv>r{t&yXB$l zE1kj^L=84jz1>}bS-f2gg4sZ=?!OJp;_YG(%m%8rdo(bMw~Ik|y8!xxlirl!DsPva zTy^k`stNmaP%jA^gHUg|pcNl;^oHr<1LVk9vxeVAov6dHU=P^tPIyf24r zmHjjZ^1wd&)du2dXC37B>T+L|mBV>42x?ZotWN*|Ad~EW; zsW)MeafZ=cE`o=ZT#i9?>W1pvsrNSd;MAKiVmSU3JLpysmmI}~i=)y-oD7)n7NwWA zVWf`lZ0@An5|-<=uYHp8J1X>+zrwIQM&Yrt^Qs2YC-7HX76Mw2o@YJGwoY{qls|06 zMu(5>^`@3DD7UT(lu%KGv!W}t7K?`NPN#-%ed z13fp)KtGzFg}ttjJ`BvNS$q=LDI40$)$ua41ZJa|puI+nmTsZk2 z=79l6iNd)h?+Ml95zm=pY#lPsmg_G+uETQuz%?*$`cd{ozDllT?ldgJyAK*C7OUht zvADn{S0y5q6^9^O84MnxY$B9_x0-H6wEr#GEOTP`KF0)iQvN)*Z`^^KEb&;`I4bN^ zJ0ft)tXRADh&zNk$%l)Ro{YpKA8we0z2JFEry-yX*$2JrkFryEZpnVdje!Nb*4;3k zh<+~nE7#)xn*A;7I0<`2;O7a1H@OWZOv3K-f(0jYzPmO}!X6gLy`X;e?eOPz?lRJ8 z*aHHYClDUs)u!Vya4EOa5QqB@l}ZwP|3wQ)5_1Mp@3!g%b%^1w212 zcUFq87V43Nn1c0rQZV(9l*?5@Pb3(~Qw23D+*X}A0?8bK!=V}8(^OG&1dV0xfta1uG&mlY-6oJ-NtH&u#HvED;QqSD;TKTSYr@f&=nepo>zD{3KRW_ z7-Vlldx+Yb4Pd^&pHz58rF%lU(F}@Le7Px()N#Maz5KA-bnsrrh7#?y8I2a7n+#E` z?$T&rA1KU=5x(D9F?bOuF%ebbs}fw)`=M^*B5gN#TWn{U@9xSTXAB<4dL&_S#1ZGV zFz+tVq`E*y&rpkbX`#ahU?py);aBrD$H0M*W4FC?ImE^oDHnm1qurg$p+3cOs80s+ z2q(6O#~|uc45B{8AnH>LqCQoi)+a-R`UIcEZQ+K;!aKKx8>sau22sZQYr3J7F~KnH zstD|NWvaU-1ZFz74Rub6MgXl=jZqD~MFYYJ2(4EE76#NLLs-oUus13xx2s#3lwVW? zYnSyySTTw>LhV}9m-jU{MtRs68^lqjPIEtS9{U4#F*gfd>~J|J{J93m+XmlP7fHN>~l$Ntk(|{soBGeFp)ZlB%s%=2oi#4F^8K~6_ z#jgp264-=6A#B2+95!K46axmP$_WKSgrcY?6b!E?6b#g&7=tJ#ZR!T9?a#dwV-CZW zO&FBMq+S{WD5Vi)YqaX za>;bB=*=mvDWay&mYeHR!0jal@+{H!!$yL!ba6G4{N`|K#s*-`~#$ynbCJAcj2Ph)A@j3z(XHvc51kl|0i>e{G@qkb_9$?8>R5e4G8xOEBpw_%rw=yZ;QUogv zQhl)wBsp1#NW~!3$6!kxY_tR_)2FC|IM-prT5cNbT?e7rhN8oK{YD-dMm>*w+{1A4 zagS%vm1^+3PirOK%ZuYYi?OOW&a*UOFuAozBda{9n}+GBjw!%uR>dJHj5IKg*5H`V zRjr)k#PnODJz$L)(zpqOWHyYNkMuB1<%t{ClMVs(QcMpl^spCM8X`W2VmO={X#rd9 z7>d#K7>a?_F_b2ZG|`6Zpb+senw&zx39h=y@LNq7aXA03Qy?x`JwB;&VR~sNCsit5 z4CBbco_|*UQ1Lp$bD@HIG9(5u9b}-+<6RM$WgagEVP9VSF@(83T;;)Y*c-@8!*XDQ zr2msLtI0H5481%ixIPlI?!h93bQ*jMjUZYug8G}gU z9hKV8=fIu{wiZWVn#kX28gOt>$TI`6)t2Bsw$>I&1e}*JP=;ic1VLo0QJpD>aZ~`0 zAEF?Is0QN9no_l3t`nH0V8$Sd{1Bz;ilE7Ak&nSV3*lDht)`oD?@lmv--KZSK@mAx zCp%HyF_F}|1@?1ou^Z+tCoT5$nSn0zG1z6oWdOsnwH7s}g$0c*Fjcn2`}`(GrymC| zZV#N;JT~4fPM_q>CQs&1uC>@bh4V(Byq@31?|j_VIHdq|N^vf?xtv?vLFkU+ zo(>=XxGN}rl1H?j%pT7NK;!E8#|Mu7Y`oq&X)>ViV)uA{14$fPZ-72|B5O#@J+9+ z7rWaV_c!=_vhf#r{-C(E02~B5h;4}2Z}_bqvy#g{*VexF<)0gJd9v7j>*%x>G2N4A z-)SiB_QpMp4oC*mB>RKnTBhi=2)IsBA7rT#nZ6+>yEpt+Hbz3uwqi8yY49o00Gdk4 zM6F;8sv;#v!;K!|6F^=lDlbd|zH~0++Wwq-DgQ<>|3*1^>q@YFZ4>017v!54#2cJ- zj(_}HRE1}7UT(m`^A|Wjyxix0@8pHWNM7D{3t{;Ne#5EvvQ)ueq^1?;o^Ubh z_zhm{cq$cYpUzrmW`=v3yOVfu=r37Msdl3RiNUqbERFMR_aVTb>_c}v_f;R?SlCcO zBOy9)f%xYmR^?p_KepB_1-99h`|M^PYW<1D;+-oWM zUujCwYL&}E&P^>>gdD;S&+se08*IRM6{l=@712cZtMpAmE3>zF*!K7CkD-5apQ?1p z(v%MO#Ozer$LBRh>fU2hvogcch4Eg2zX2&riV;D@m(k-~k*%Nt9PGU*=MX^^RZLm8 zBa%5udC2ggJjOa~O_Y>1zZ~NrQO?xZ#ixFY%hC4m#}C;|bVCk8Xa{{wT1oe{Bhkx6 zXTn&HEIw!qNfS6{7jTK;FkfhV0f+H(2b`=(8&(4yE%WH80xNACR+JL5;FYX23ZZVKij^hxFV51Rvp9W`RH zWXof5HnHMR1i7%!Pj%qLO~s*c!J7I*A@;m$daW_|Gi8Qa-bBW|Zn%ihO*sT^k+z6~ zj^)RZVVs+C7#0E#o6&-MHRmQneUn{u9gwzea6kATT|^ zT0&rE_!ax8Dwj+`Ihb@8Z#%dvzn}Lh;8uqF^B?nDdp~Ym%}*}^adqQ)_7R?MJca{i zb+kd1GI~Wt$(7zaWMmheB()E8PEhe8)PQ&Zz z+49`pm*e0A-^p@+etE<2S2y02cjDhf{1sm%f+CRQ@vr!gkivaiW+x+fF5C4Tz}Fdk z9k4!MncHstFSpFq*B>>I@cSU)Kg6=tk_GO%@*W(pT(Uqkmxrp#<*mgB+r643iz6dE zBDNsB7bfSD1&uSx{Sc7_Kg;np6>rz(XEgNnoW@Co(oZU`EERiY`2=4n^+dV6Rk6!k z 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

        6UQ{ECYM!c*^V%>0ItG=#AuB(|-BcImX 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 ILGrfof9_EaYXATM From fdf8e429a09cf6d6aeaf51cd7a5c179785669380 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 28 Aug 2023 10:57:04 +0200 Subject: [PATCH 654/909] dnsdist: Add ChangeLog and secpoll update for 1.8.1 --- docs/secpoll.zone | 3 +- pdns/dnsdistdist/docs/changelog.rst | 160 ++++++++++++++++++++++++++++ 2 files changed, 162 insertions(+), 1 deletion(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 1a6a35ba13a3..e3e021ea3120 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023090701 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023090801 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -514,3 +514,4 @@ dnsdist-1.8.0-rc1.security-status 60 IN TXT "2 Unsuppor dnsdist-1.8.0-rc2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" dnsdist-1.8.0-rc3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" dnsdist-1.8.0.security-status 60 IN TXT "1 OK" +dnsdist-1.8.1.security-status 60 IN TXT "1 OK" diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index f04e449cac31..bb1089d4d677 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -1,6 +1,166 @@ Changelog ========= +.. changelog:: + :version: 1.8.1 + :released: TBD + + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.8.x. + + .. change:: + :tags: Bug Fixes + :pullreq: 12820 + + Print the received, invalid health-check response ID + + .. change:: + :tags: Bug Fixes + :pullreq: 12821 + + Account for the health-check run time between two runs + + .. change:: + :tags: Bug Fixes + :pullreq: 12822 + + Properly set the size of the UDP health-check response + + .. change:: + :tags: Bug Fixes + :pullreq: 12823 + + Add the query ID to health-check log messages, fix nits + + .. change:: + :tags: Bug Fixes + :pullreq: 12824 + + Stop setting SO_REUSEADDR on outgoing UDP client sockets + + .. change:: + :tags: Bug Fixes, DNS over HTTPS + :pullreq: 12977 + + Fix a crash when X-Forwarded-For overrides the initial source IP + + .. change:: + :tags: Bug Fixes + :pullreq: 13116 + + Properly handle short reads on backend upgrade discovery + + .. change:: + :tags: Bug Fixes + :pullreq: 13117 + + Undo an accidentally change of disableZeroScope to disableZeroScoping (Winfried Angele) + + .. change:: + :tags: Bug Fixes + :pullreq: 13118 + :tickets: 13027 + + Fix the group of the dnsdist.conf file when installed via RPM + + .. change:: + :tags: Bug Fixes + :pullreq: 13119 + :tickets: 12926 + + Work around Red Hat 8 messing up OpenSSL's headers and refusing to fix it + + .. change:: + :tags: Bug Fixes + :pullreq: 13120 + + fix typo libeditr -> libedit + + .. change:: + :tags: Improvements + :pullreq: 13121 + + Stop using the now deprecated ERR_load_CRYPTO_strings() to detect OpenSSL + + .. change:: + :tags: Improvements + :pullreq: 13122 + + Automatically load Lua FFI inspection functions + + .. change:: + :tags: New Features + :pullreq: 13123 + + Allow declaring custom metrics at runtime + + .. change:: + :tags: Bug Fixes + :pullreq: 13124 + + Fix webserver config template for our docker container (Houtworm) + + .. change:: + :tags: Improvements + :pullreq: 13125 + + Increment the "dyn blocked" counter for eBPF blocks as well + + .. change:: + :tags: Bug Fixes + :pullreq: 13127 + + YaHTTP: Prevent integer overflow on very large chunks + + .. change:: + :tags: Bug Fixes + :pullreq: 13128 + + Fix the console description of PoolAction and QPSPoolAction (phonedph1) + + .. change:: + :tags: Bug Fixes + :pullreq: 13129 + :tickets: 12711 + + Properly handle reconnection failure for backend UDP sockets + + .. change:: + :tags: Bug Fixes, DNS over HTTPS, DNS over TLS + :pullreq: 13130 + + Fix a memory leak when processing TLS tickets w/ OpenSSL 3.x + + .. change:: + :tags: Bug Fixes, DNS over HTTPS + :pullreq: 13131 + :tickets: 12762 + + Fix cache hit and miss metrics with DoH queries + + .. change:: + :tags: Bug Fixes + :pullreq: 13132 + + SpoofAction: copy the QClass from the request (Christof Chen) + + .. change:: + :tags: Improvements + :pullreq: 13133 + + Make DNSQType.TSIG available (Jacob Bunk) + + .. change:: + :tags: Bug Fixes + :pullreq: 13150 + + Properly record self-answered UDP responses with recvmmsg + + .. change:: + :tags: Bug Fixes, DNS over TLS + :pullreq: 13178 + + Fix a race when creating the first TLS connections + .. changelog:: :version: 1.7.4 :released: 14th of April 2023 From 5673c23578331bb3444e0d6f7fab0968333a3a1b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 28 Aug 2023 11:03:36 +0200 Subject: [PATCH 655/909] dnsdist: Fix spell checking issues --- .github/actions/spell-check/expect.txt | 1 + pdns/dnsdistdist/docs/changelog.rst | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index b451e038dc8e..41c2c2f8ad8c 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -550,6 +550,7 @@ Hofstaedtler Holger Hooimeijer Hotmail +Houtworm howto hpecorp hpiers diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index bb1089d4d677..124d39169a9a 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -73,7 +73,7 @@ Changelog :tags: Bug Fixes :pullreq: 13120 - fix typo libeditr -> libedit + Fix a typo for libedit in the dnsdist features list .. change:: :tags: Improvements From d512e5d3048fe7edd5dd1a1d033ffb6d8529ab34 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 7 Sep 2023 12:09:20 +0200 Subject: [PATCH 656/909] dnsdist: Set the release date for 1.8.1 in the ChangeLog --- pdns/dnsdistdist/docs/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index 124d39169a9a..6801e82cb837 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -3,7 +3,7 @@ Changelog .. changelog:: :version: 1.8.1 - :released: TBD + :released: 8th of September 2023 Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.8.x. From 4d1767d1cd0191032e2add33cd87394985eaeb76 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 7 Sep 2023 13:08:27 +0200 Subject: [PATCH 657/909] dnsdist: dnsdist's fuzzing target needs to link against arc4random On systems that do not provide arc4random we actually need to link the internal library in. --- pdns/dnsdistdist/Makefile.am | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 03dfda66e1b8..c39015d50f93 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -483,6 +483,7 @@ bin_PROGRAMS += \ fuzz_targets_libs = \ $(LIBCRYPTO_LIBS) \ + $(ARC4RANDOM_LIBS) \ $(LIB_FUZZING_ENGINE) fuzz_targets_ldflags = \ From ec19e6418453bc6e6ee12467ef9add262cd4b0ed Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 8 Sep 2023 12:09:57 +0200 Subject: [PATCH 658/909] build-packages: Upload provenance attestations to the correct dir --- .github/workflows/build-packages.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build-packages.yml b/.github/workflows/build-packages.yml index 1b45d241168e..e967a3e32f3b 100644 --- a/.github/workflows/build-packages.yml +++ b/.github/workflows/build-packages.yml @@ -201,6 +201,8 @@ jobs: SSHKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_SECRET }} RSYNCTARGET: ${{ secrets.DOWNLOADS_AUTOBUILT_RSYNCTARGET }} HOSTKEY: ${{ secrets.DOWNLOADS_AUTOBUILT_HOSTKEY }} + PRODUCT: ${{ inputs.product }} + VERSION: ${{ needs.build.outputs.version }} if: "${{ env.SSHKEY != '' }}" shell: bash @@ -209,4 +211,4 @@ jobs: echo "$SSHKEY" > ~/.ssh/id_ed25519 chmod 600 ~/.ssh/id_ed25519 echo "$HOSTKEY" > ~/.ssh/known_hosts - rsync -4rlptD ${{steps.download-src-provenance.outputs.download-path}}/*.jsonl ${{steps.download-provenance.outputs.download-path}}/*.jsonl "${RSYNCTARGET}/${{ inputs.product }}/${{ needs.build.outputs.version }}/" + rsync -4rlptD ${{steps.download-src-provenance.outputs.download-path}}/*.jsonl ${{steps.download-provenance.outputs.download-path}}/*.jsonl "${RSYNCTARGET}/${PRODUCT}/${VERSION}/" From d879fd59e5c9935eaa521384bb44eb78486830cb Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Fri, 8 Sep 2023 07:59:27 -0400 Subject: [PATCH 659/909] Fix GitHub Action log title reporting Follow-up to #13068 --- regression-tests/recursor-test | 2 +- regression-tests/runtests | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/regression-tests/recursor-test b/regression-tests/recursor-test index ce4d41b716c4..ec58cfe90b40 100755 --- a/regression-tests/recursor-test +++ b/regression-tests/recursor-test @@ -90,7 +90,7 @@ then echo recursor-bulktest >> passed_tests RETVAL=0 else - echo "::error ::title=Recursor-bulktest::Bulk test failed: less than ${THRESHOLD}% of queries answered successfully" + echo "::error title=Recursor-bulktest::Bulk test failed: less than ${THRESHOLD}% of queries answered successfully" echo recursor-bulktest >> failed_tests RETVAL=1 fi diff --git a/regression-tests/runtests b/regression-tests/runtests index 6ebf474edbb6..162d15f0d4bf 100755 --- a/regression-tests/runtests +++ b/regression-tests/runtests @@ -147,7 +147,7 @@ do done if [ $failed -gt 0 ]; then - echo -n "::error ::title=Regression-tests::Tests failed. " + echo -n "::error title=Regression-tests::Tests failed. " fi echo -n $passed out of $[$passed+$failed] echo -n " (" From 9eaa6332084badc63db023d6d1a8ffc1a1001d31 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 8 Sep 2023 16:19:41 +0200 Subject: [PATCH 660/909] dnsdist: Fix unit tests for incoming DoH w/ nghttp2 These tests were failing on EL with LTO enabled, and passing everywhere else. It turns out that we did not properly reset the `s_processQuery` hack that we used in these tests to simulate the policy decision (rules and actions), and thus inherited what the last test set it to instead of the default (dropping queries), which was very unexpected. --- pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc index b02b86d67ecc..2c98427c0693 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc @@ -500,6 +500,10 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) pwR.xfr32BitInt(0x01020304); pwR.commit(); + /* we _NEED_ to set this function to empty otherwise we might get what was set + by the last test, and we might not like it at all */ + s_processQuery = nullptr; + { /* dnsdist drops the query right away after receiving it, client closes the connection */ s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, {403U}}; From c1cf7bed7a19d41987954016e980d38260106edc Mon Sep 17 00:00:00 2001 From: appliedprivacy <33653399+appliedprivacy@users.noreply.github.com> Date: Sat, 9 Sep 2023 10:51:54 +0000 Subject: [PATCH 661/909] latency-doh-avg 100k -> 1M typo --- pdns/dnsdistdist/docs/statistics.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/docs/statistics.rst b/pdns/dnsdistdist/docs/statistics.rst index 9f9203f4ebf1..6f3c93236b10 100644 --- a/pdns/dnsdistdist/docs/statistics.rst +++ b/pdns/dnsdistdist/docs/statistics.rst @@ -141,9 +141,9 @@ latency-doh-avg10000 -------------------- Average response latency, in microseconds, of the last 10000 packets received over DoH. -latency-doh-avg100000 +latency-doh-avg1000000 --------------------- -Average response latency, in microseconds, of the last 100000 packets received over DoH. +Average response latency, in microseconds, of the last 1000000 packets received over DoH. latency-dot-avg100 ------------------ From 7a341a8910b901146a841db290f40c749f57f896 Mon Sep 17 00:00:00 2001 From: Mike Damm Date: Sun, 10 Sep 2023 17:30:59 -0700 Subject: [PATCH 662/909] Update documentation to point to proper function Additional parameters to webserver() are now depreciated. Update documentation to refer to setWebserverConfig() --- pdns/dnsdistdist/docs/guides/webserver.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/docs/guides/webserver.rst b/pdns/dnsdistdist/docs/guides/webserver.rst index 453f6d1bcab8..4a15a8c1e09b 100755 --- a/pdns/dnsdistdist/docs/guides/webserver.rst +++ b/pdns/dnsdistdist/docs/guides/webserver.rst @@ -30,7 +30,7 @@ By default, our web server sends some security-related headers:: X-XSS-Protection: 1; mode=block Content-Security-Policy: default-src 'self'; style-src 'self' 'unsafe-inline' -You can override those headers, or add custom headers by using the last parameter to :func:`webserver`. +You can override those headers, or add custom headers by using the last parameter to :func:`setWebserverConfig`. For example, to remove the X-Frame-Options header and add a X-Custom one: .. code-block:: lua @@ -42,7 +42,7 @@ Credentials can be changed at run time using the :func:`setWebserverConfig` func dnsdist API ----------- -To access the API, the `apikey` must be set in the :func:`webserver` function. +To access the API, the `apikey` must be set in the :func:`setWebserverConfig` function. Use the API, this key will need to be sent to dnsdist in the ``X-API-Key`` request header. An HTTP 401 response is returned when a wrong or no API key is received. A 404 response is generated is the requested endpoint does not exist. From 83dc6a3887d53637547658a8d709271d605b3366 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 24 Aug 2023 17:28:10 +0200 Subject: [PATCH 663/909] dnsdist: Log Extended DNS Errors (EDE) to protobuf --- pdns/dnscrypt.hh | 2 +- pdns/dnsdist-ecs.hh | 1 + pdns/dnsdist-idstate.hh | 1 + pdns/dnsdist-lua-actions.cc | 87 ++++++++++++++++++------- pdns/dnsdist-protobuf.cc | 13 ++-- pdns/dnsdist-protobuf.hh | 9 ++- pdns/dnsdistdist/Makefile.am | 2 + pdns/dnsdistdist/dnsdist-edns.cc | 57 ++++++++++++++++ pdns/dnsdistdist/dnsdist-edns.hh | 33 ++++++++++ pdns/dnsdistdist/docs/rules-actions.rst | 4 ++ 10 files changed, 176 insertions(+), 33 deletions(-) create mode 100644 pdns/dnsdistdist/dnsdist-edns.cc create mode 100644 pdns/dnsdistdist/dnsdist-edns.hh diff --git a/pdns/dnscrypt.hh b/pdns/dnscrypt.hh index 356b4c47d4c3..a42be6ab2b77 100644 --- a/pdns/dnscrypt.hh +++ b/pdns/dnscrypt.hh @@ -21,6 +21,7 @@ */ #pragma once #include "config.h" +#include #ifndef HAVE_DNSCRYPT @@ -43,7 +44,6 @@ private: #else /* HAVE_DNSCRYPT */ -#include #include #include #include diff --git a/pdns/dnsdist-ecs.hh b/pdns/dnsdist-ecs.hh index 653052df8196..f5d215f1a065 100644 --- a/pdns/dnsdist-ecs.hh +++ b/pdns/dnsdist-ecs.hh @@ -58,6 +58,7 @@ bool getEDNS0Record(const PacketBuffer& packet, EDNS0Record& edns0); bool setEDNSOption(DNSQuestion& dq, uint16_t ednsCode, const std::string& data); +struct InternalQueryState; namespace dnsdist { bool setInternalQueryRCode(InternalQueryState& state, PacketBuffer& buffer, uint8_t rcode, bool clearAnswers); } diff --git a/pdns/dnsdist-idstate.hh b/pdns/dnsdist-idstate.hh index 456e703fb3db..313e434ea825 100644 --- a/pdns/dnsdist-idstate.hh +++ b/pdns/dnsdist-idstate.hh @@ -27,6 +27,7 @@ #include "dnsdist-protocols.hh" #include "gettime.hh" #include "iputils.hh" +#include "noinitvector.hh" #include "uuid-utils.hh" struct ClientState; diff --git a/pdns/dnsdist-lua-actions.cc b/pdns/dnsdist-lua-actions.cc index 0f1d854a8fad..b81600fe8c92 100644 --- a/pdns/dnsdist-lua-actions.cc +++ b/pdns/dnsdist-lua-actions.cc @@ -24,6 +24,7 @@ #include "dnsdist.hh" #include "dnsdist-async.hh" #include "dnsdist-ecs.hh" +#include "dnsdist-edns.hh" #include "dnsdist-lua.hh" #include "dnsdist-lua-ffi.hh" #include "dnsdist-mac-address.hh" @@ -1484,14 +1485,16 @@ class DnstapLogAction : public DNSAction, public boost::noncopyable boost::optional > d_alterFunc; }; -static void addMetaDataToProtobuf(DNSDistProtoBufMessage& message, const DNSQuestion& dq, const std::vector>& metas) +namespace +{ +void addMetaDataToProtobuf(DNSDistProtoBufMessage& message, const DNSQuestion& dq, const std::vector>& metas) { for (const auto& [name, meta] : metas) { - message.addMeta(name, meta.getValues(dq)); + message.addMeta(name, meta.getValues(dq), {}); } } -static void addTagsToProtobuf(DNSDistProtoBufMessage& message, const DNSQuestion& dq, const std::unordered_set& allowed) +void addTagsToProtobuf(DNSDistProtoBufMessage& message, const DNSQuestion& dq, const std::unordered_set& allowed) { if (!dq.ids.qTag) { return; @@ -1511,11 +1514,40 @@ static void addTagsToProtobuf(DNSDistProtoBufMessage& message, const DNSQuestion } } +void addExtendedDNSErrorToProtobuf(DNSDistProtoBufMessage& message, const DNSResponse& dr, const std::string& metaKey) +{ + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(dr.getData()); + if (!infoCode) { + return; + } + + if (extraText) { + message.addMeta(metaKey, {*extraText}, {*infoCode}); + } + else { + message.addMeta(metaKey, {}, {*infoCode}); + } +} +} + +struct RemoteLogActionConfiguration +{ + std::vector> metas; + std::optional> tagsToExport{std::nullopt}; + boost::optional > alterQueryFunc{boost::none}; + boost::optional > alterResponseFunc{boost::none}; + std::shared_ptr logger; + std::string serverID; + std::string ipEncryptKey; + std::optional exportExtendedErrorsToMeta{std::nullopt}; + bool includeCNAME{false}; +}; + class RemoteLogAction : public DNSAction, public boost::noncopyable { public: // this action does not stop the processing - RemoteLogAction(std::shared_ptr& logger, boost::optional > alterFunc, const std::string& serverID, const std::string& ipEncryptKey, std::vector>&& metas, std::optional>&& tagsToExport): d_tagsToExport(std::move(tagsToExport)), d_metas(std::move(metas)), d_logger(logger), d_alterFunc(std::move(alterFunc)), d_serverID(serverID), d_ipEncryptKey(ipEncryptKey) + RemoteLogAction(RemoteLogActionConfiguration& config): d_tagsToExport(std::move(config.tagsToExport)), d_metas(std::move(config.metas)), d_logger(config.logger), d_alterFunc(std::move(config.alterQueryFunc)), d_serverID(config.serverID), d_ipEncryptKey(config.ipEncryptKey) { } @@ -1660,7 +1692,7 @@ class RemoteLogResponseAction : public DNSResponseAction, public boost::noncopya { public: // this action does not stop the processing - RemoteLogResponseAction(std::shared_ptr& logger, boost::optional > alterFunc, const std::string& serverID, const std::string& ipEncryptKey, bool includeCNAME, std::vector>&& metas, std::optional>&& tagsToExport): d_tagsToExport(std::move(tagsToExport)), d_metas(std::move(metas)), d_logger(logger), d_alterFunc(std::move(alterFunc)), d_serverID(serverID), d_ipEncryptKey(ipEncryptKey), d_includeCNAME(includeCNAME) + RemoteLogResponseAction(RemoteLogActionConfiguration& config): d_tagsToExport(std::move(config.tagsToExport)), d_metas(std::move(config.metas)), d_logger(config.logger), d_alterFunc(std::move(config.alterResponseFunc)), d_serverID(config.serverID), d_ipEncryptKey(config.ipEncryptKey), d_exportExtendedErrorsToMeta(std::move(config.exportExtendedErrorsToMeta)), d_includeCNAME(config.includeCNAME) { } DNSResponseAction::Action operator()(DNSResponse* dr, std::string* ruleresult) const override @@ -1690,6 +1722,10 @@ class RemoteLogResponseAction : public DNSResponseAction, public boost::noncopya addMetaDataToProtobuf(message, *dr, d_metas); + if (d_exportExtendedErrorsToMeta) { + addExtendedDNSErrorToProtobuf(message, *dr, *d_exportExtendedErrorsToMeta); + } + if (d_alterFunc) { auto lock = g_lua.lock(); (*d_alterFunc)(dr, &message); @@ -1713,6 +1749,7 @@ class RemoteLogResponseAction : public DNSResponseAction, public boost::noncopya boost::optional > d_alterFunc; std::string d_serverID; std::string d_ipEncryptKey; + std::optional d_exportExtendedErrorsToMeta{std::nullopt}; bool d_includeCNAME; }; @@ -2510,35 +2547,34 @@ void setupLuaActions(LuaContext& luaCtx) } } - std::string serverID; - std::string ipEncryptKey; std::string tags; - getOptionalValue(vars, "serverID", serverID); - getOptionalValue(vars, "ipEncryptKey", ipEncryptKey); + RemoteLogActionConfiguration config; + config.logger = logger; + config.alterQueryFunc = std::move(alterFunc); + getOptionalValue(vars, "serverID", config.serverID); + getOptionalValue(vars, "ipEncryptKey", config.ipEncryptKey); getOptionalValue(vars, "exportTags", tags); - std::vector> metaOptions; if (metas) { for (const auto& [key, value] : *metas) { - metaOptions.push_back({key, ProtoBufMetaKey(value)}); + config.metas.push_back({key, ProtoBufMetaKey(value)}); } } - std::optional> tagsToExport{std::nullopt}; if (!tags.empty()) { - tagsToExport = std::unordered_set(); + config.tagsToExport = std::unordered_set(); if (tags != "*") { std::vector tokens; stringtok(tokens, tags, ","); for (auto& token : tokens) { - tagsToExport->insert(std::move(token)); + config.tagsToExport->insert(std::move(token)); } } } checkAllParametersConsumed("RemoteLogAction", vars); - return std::shared_ptr(new RemoteLogAction(logger, std::move(alterFunc), serverID, ipEncryptKey, std::move(metaOptions), std::move(tagsToExport))); + return std::shared_ptr(new RemoteLogAction(config)); }); luaCtx.writeFunction("RemoteLogResponseAction", [](std::shared_ptr logger, boost::optional > alterFunc, boost::optional includeCNAME, boost::optional> vars, boost::optional> metas) { @@ -2551,35 +2587,36 @@ void setupLuaActions(LuaContext& luaCtx) } } - std::string serverID; - std::string ipEncryptKey; std::string tags; - getOptionalValue(vars, "serverID", serverID); - getOptionalValue(vars, "ipEncryptKey", ipEncryptKey); + RemoteLogActionConfiguration config; + config.logger = logger; + config.alterResponseFunc = alterFunc; + config.includeCNAME = includeCNAME ? *includeCNAME : false; + getOptionalValue(vars, "serverID", config.serverID); + getOptionalValue(vars, "ipEncryptKey", config.ipEncryptKey); getOptionalValue(vars, "exportTags", tags); + getOptionalValue(vars, "exportExtendedErrorsToMeta", config.exportExtendedErrorsToMeta); - std::vector> metaOptions; if (metas) { for (const auto& [key, value] : *metas) { - metaOptions.push_back({key, ProtoBufMetaKey(value)}); + config.metas.push_back({key, ProtoBufMetaKey(value)}); } } - std::optional> tagsToExport{std::nullopt}; if (!tags.empty()) { - tagsToExport = std::unordered_set(); + config.tagsToExport = std::unordered_set(); if (tags != "*") { std::vector tokens; stringtok(tokens, tags, ","); for (auto& token : tokens) { - tagsToExport->insert(std::move(token)); + config.tagsToExport->insert(std::move(token)); } } } checkAllParametersConsumed("RemoteLogResponseAction", vars); - return std::shared_ptr(new RemoteLogResponseAction(logger, std::move(alterFunc), serverID, ipEncryptKey, includeCNAME ? *includeCNAME : false, std::move(metaOptions), std::move(tagsToExport))); + return std::shared_ptr(new RemoteLogResponseAction(config)); }); luaCtx.writeFunction("DnstapLogAction", [](const std::string& identity, std::shared_ptr logger, boost::optional > alterFunc) { diff --git a/pdns/dnsdist-protobuf.cc b/pdns/dnsdist-protobuf.cc index c38529cb67a0..453cba87f554 100644 --- a/pdns/dnsdist-protobuf.cc +++ b/pdns/dnsdist-protobuf.cc @@ -104,11 +104,14 @@ void DNSDistProtoBufMessage::addTag(const std::string& strValue) d_additionalTags.push_back(strValue); } -void DNSDistProtoBufMessage::addMeta(const std::string& key, std::vector&& values) +void DNSDistProtoBufMessage::addMeta(const std::string& key, std::vector&& strValues, const std::vector& intValues) { auto& entry = d_metaTags[key]; - for (auto& value : values) { - entry.insert(std::move(value)); + for (auto& value : strValues) { + entry.d_strings.insert(std::move(value)); + } + for (const auto& value : intValues) { + entry.d_integers.insert(value); } } @@ -210,8 +213,8 @@ void DNSDistProtoBufMessage::serialize(std::string& data) const } for (const auto& [key, values] : d_metaTags) { - if (!values.empty()) { - m.setMeta(key, values, {}); + if (!values.d_strings.empty() || !values.d_integers.empty()) { + m.setMeta(key, values.d_strings, values.d_integers); } else { /* the MetaValue field is _required_ to exist, even if we have no value */ diff --git a/pdns/dnsdist-protobuf.hh b/pdns/dnsdist-protobuf.hh index 39305383d396..1e30f2658254 100644 --- a/pdns/dnsdist-protobuf.hh +++ b/pdns/dnsdist-protobuf.hh @@ -47,7 +47,7 @@ public: void setEDNSSubnet(const Netmask& nm); void addTag(const std::string& strValue); - void addMeta(const std::string& key, std::vector&& values); + void addMeta(const std::string& key, std::vector&& strValues, const std::vector& intValues); void addRR(DNSName&& qname, uint16_t uType, uint16_t uClass, uint32_t uTTL, const std::string& data); void serialize(std::string& data) const; @@ -76,7 +76,12 @@ private: std::vector d_additionalRRs; std::vector d_additionalTags; - std::unordered_map> d_metaTags; + struct MetaValue + { + std::unordered_set d_strings; + std::unordered_set d_integers; + }; + std::unordered_map d_metaTags; const DNSQuestion& d_dq; const DNSResponse* d_dr{nullptr}; diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index c39015d50f93..1a80477586f7 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -157,6 +157,7 @@ dnsdist_SOURCES = \ dnsdist-dynblocks.cc dnsdist-dynblocks.hh \ dnsdist-dynbpf.cc dnsdist-dynbpf.hh \ dnsdist-ecs.cc dnsdist-ecs.hh \ + dnsdist-edns.cc dnsdist-edns.hh \ dnsdist-healthchecks.cc dnsdist-healthchecks.hh \ dnsdist-idstate.hh \ dnsdist-internal-queries.cc dnsdist-internal-queries.hh \ @@ -268,6 +269,7 @@ testrunner_SOURCES = \ dnsdist-dynblocks.cc dnsdist-dynblocks.hh \ dnsdist-dynbpf.cc dnsdist-dynbpf.hh \ dnsdist-ecs.cc dnsdist-ecs.hh \ + dnsdist-edns.cc dnsdist-edns.hh \ dnsdist-idstate.hh \ dnsdist-kvs.cc dnsdist-kvs.hh \ dnsdist-lbpolicies.cc dnsdist-lbpolicies.hh \ diff --git a/pdns/dnsdistdist/dnsdist-edns.cc b/pdns/dnsdistdist/dnsdist-edns.cc new file mode 100644 index 000000000000..794d11e6bdd0 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-edns.cc @@ -0,0 +1,57 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "dnsdist-ecs.hh" +#include "dnsdist-edns.hh" +#include "ednsoptions.hh" + +namespace dnsdist::edns +{ +std::pair, std::optional> getExtendedDNSError(const PacketBuffer& packet) +{ + uint16_t optStart; + size_t optLen = 0; + bool last = false; + + int res = locateEDNSOptRR(packet, &optStart, &optLen, &last); + + if (res != 0) { + return std::make_pair(std::nullopt, std::nullopt); + } + + size_t optContentStart = 0; + uint16_t optContentLen = 0; + uint16_t infoCode{0}; + std::string extraText; + /* we need at least 2 bytes after the option length (info-code) */ + if (!isEDNSOptionInOpt(packet, optStart, optLen, EDNSOptionCode::EXTENDEDERROR, &optContentStart, &optContentLen) || optContentLen < sizeof(infoCode)) { + return std::make_pair(std::nullopt, std::nullopt); + } + memcpy(&infoCode, &packet.at(optContentStart), sizeof(infoCode)); + infoCode = ntohs(infoCode); + + if (optContentLen > sizeof(infoCode)) { + extraText.resize(optContentLen - sizeof(infoCode)); + memcpy(extraText.data(), &packet.at(optContentStart + sizeof(infoCode)), optContentLen - sizeof(infoCode)); + } + return std::make_pair(infoCode, std::move(extraText)); +} +} diff --git a/pdns/dnsdistdist/dnsdist-edns.hh b/pdns/dnsdistdist/dnsdist-edns.hh new file mode 100644 index 000000000000..75c92c143ac1 --- /dev/null +++ b/pdns/dnsdistdist/dnsdist-edns.hh @@ -0,0 +1,33 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +#include +#include +#include + +#include "noinitvector.hh" + +namespace dnsdist::edns +{ +std::pair, std::optional> getExtendedDNSError(const PacketBuffer& packet); +} diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index 2dae14279294..19c4ed51b4ae 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -1420,6 +1420,9 @@ The following actions exist. ``metas`` optional parameter added. ``exportTags`` optional key added to the options table. + .. versionchanged:: 1.9.0 + ``exportExtendedErrorsToMeta`` optional key added to the options table. + Send the content of this response to a remote logger via Protocol Buffer. ``alterFunction`` is the same callback that receiving a :class:`DNSQuestion` and a :class:`DNSDistProtoBufMessage`, that can be used to modify the Protocol Buffer content, for example for anonymization purposes. ``includeCNAME`` indicates whether CNAME records inside the response should be parsed and exported. @@ -1438,6 +1441,7 @@ The following actions exist. * ``serverID=""``: str - Set the Server Identity field. * ``ipEncryptKey=""``: str - A key, that can be generated via the :func:`makeIPCipherKey` function, to encrypt the IP address of the requestor for anonymization purposes. The encryption is done using ipcrypt for IPv4 and a 128-bit AES ECB operation for IPv6. * ``exportTags=""``: str - The comma-separated list of keys of internal tags to export into the ``tags`` Protocol Buffer field, as "key:value" strings. Note that a tag with an empty value will be exported as "", not ":". An empty string means that no internal tag will be exported. The special value ``*`` means that all tags will be exported. + * ``exportExtendedErrorsToMeta=""``: str - Export Extended DNS Errors present in the DNS response, if any, into the specified ``tags`` Protocol Buffer field. The EDE info code will be exported as an integer value, and the EDE extra text, if present, as a string value. .. function:: SetAdditionalProxyProtocolValueAction(type, value) From d8f4c308afabe812a9d7cede96bca121a57cea80 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 28 Aug 2023 17:59:18 +0200 Subject: [PATCH 664/909] ProtobufLogger.py: Fix an issue with meta containing both integer and string values --- contrib/ProtobufLogger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ProtobufLogger.py b/contrib/ProtobufLogger.py index c6bb0269dfbc..7493211b470c 100644 --- a/contrib/ProtobufLogger.py +++ b/contrib/ProtobufLogger.py @@ -269,7 +269,7 @@ def printSummary(self, msg, typestr): for entry in mt.value.stringVal: values = ', '.join([values, entry]) if values != '' else entry for entry in mt.value.intVal: - values = ', '.join([values, entry]) if values != '' else entry + values = ', '.join([values, str(entry)]) if values != '' else str(entry) print('- %s -> %s' % (mt.key, values)) From a610b7af65c92a75b8482bbce5290c0ca9a076f4 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 28 Aug 2023 17:59:51 +0200 Subject: [PATCH 665/909] ProtobufLogger.py: Fix the use of the deprecated setDaemon() method --- contrib/ProtobufLogger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/ProtobufLogger.py b/contrib/ProtobufLogger.py index 7493211b470c..dbba1822c83b 100644 --- a/contrib/ProtobufLogger.py +++ b/contrib/ProtobufLogger.py @@ -312,7 +312,7 @@ def run(self): thread = threading.Thread(name='Connection Handler', target=PDNSPBConnHandler.run, args=[handler]) - thread.setDaemon(True) + thread.daemon = True thread.start() self._sock.close() From b341ebf9e15a4938ee94c208af97f17b99bd9534 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 29 Aug 2023 11:03:07 +0200 Subject: [PATCH 666/909] dnsdist: Add unit tests for Extended Error parsing --- pdns/dnsdistdist/Makefile.am | 2 + pdns/dnsdistdist/dnsdist-edns.cc | 7 +- pdns/dnsdistdist/ednsextendederror.cc | 1 + pdns/dnsdistdist/ednsextendederror.hh | 1 + pdns/dnsdistdist/test-dnsdistedns.cc | 199 +++++++++++++++++++++++++ pdns/dnswriter.hh | 2 +- pdns/ednsextendederror.cc | 65 ++++++++ pdns/ednsextendederror.hh | 66 ++++++++ pdns/recursordist/ednsextendederror.cc | 66 +------- pdns/recursordist/ednsextendederror.hh | 67 +-------- 10 files changed, 341 insertions(+), 135 deletions(-) create mode 120000 pdns/dnsdistdist/ednsextendederror.cc create mode 120000 pdns/dnsdistdist/ednsextendederror.hh create mode 100644 pdns/dnsdistdist/test-dnsdistedns.cc create mode 100644 pdns/ednsextendederror.cc create mode 100644 pdns/ednsextendederror.hh mode change 100644 => 120000 pdns/recursordist/ednsextendederror.cc mode change 100644 => 120000 pdns/recursordist/ednsextendederror.hh diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index 1a80477586f7..770a5ccfe44f 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -301,6 +301,7 @@ testrunner_SOURCES = \ dnswriter.cc dnswriter.hh \ dolog.hh \ ednscookies.cc ednscookies.hh \ + ednsextendederror.cc ednsextendederror.hh \ ednsoptions.cc ednsoptions.hh \ ednssubnet.cc ednssubnet.hh \ ext/luawrapper/include/LuaContext.hpp \ @@ -332,6 +333,7 @@ testrunner_SOURCES = \ test-dnsdistasync.cc \ test-dnsdistbackend_cc.cc \ test-dnsdistdynblocks_hh.cc \ + test-dnsdistedns.cc \ test-dnsdistkvs_cc.cc \ test-dnsdistlbpolicies_cc.cc \ test-dnsdistluanetwork.cc \ diff --git a/pdns/dnsdistdist/dnsdist-edns.cc b/pdns/dnsdistdist/dnsdist-edns.cc index 794d11e6bdd0..982fe3efef91 100644 --- a/pdns/dnsdistdist/dnsdist-edns.cc +++ b/pdns/dnsdistdist/dnsdist-edns.cc @@ -40,7 +40,7 @@ std::pair, std::optional> getExtendedDNSErr size_t optContentStart = 0; uint16_t optContentLen = 0; uint16_t infoCode{0}; - std::string extraText; + std::optional extraText{std::nullopt}; /* we need at least 2 bytes after the option length (info-code) */ if (!isEDNSOptionInOpt(packet, optStart, optLen, EDNSOptionCode::EXTENDEDERROR, &optContentStart, &optContentLen) || optContentLen < sizeof(infoCode)) { return std::make_pair(std::nullopt, std::nullopt); @@ -49,8 +49,9 @@ std::pair, std::optional> getExtendedDNSErr infoCode = ntohs(infoCode); if (optContentLen > sizeof(infoCode)) { - extraText.resize(optContentLen - sizeof(infoCode)); - memcpy(extraText.data(), &packet.at(optContentStart + sizeof(infoCode)), optContentLen - sizeof(infoCode)); + extraText = std::string(); + extraText->resize(optContentLen - sizeof(infoCode)); + memcpy(extraText->data(), &packet.at(optContentStart + sizeof(infoCode)), optContentLen - sizeof(infoCode)); } return std::make_pair(infoCode, std::move(extraText)); } diff --git a/pdns/dnsdistdist/ednsextendederror.cc b/pdns/dnsdistdist/ednsextendederror.cc new file mode 120000 index 000000000000..4f6ced0eb166 --- /dev/null +++ b/pdns/dnsdistdist/ednsextendederror.cc @@ -0,0 +1 @@ +../ednsextendederror.cc \ No newline at end of file diff --git a/pdns/dnsdistdist/ednsextendederror.hh b/pdns/dnsdistdist/ednsextendederror.hh new file mode 120000 index 000000000000..2e5eee192724 --- /dev/null +++ b/pdns/dnsdistdist/ednsextendederror.hh @@ -0,0 +1 @@ +../ednsextendederror.hh \ No newline at end of file diff --git a/pdns/dnsdistdist/test-dnsdistedns.cc b/pdns/dnsdistdist/test-dnsdistedns.cc new file mode 100644 index 000000000000..93e0e0080bca --- /dev/null +++ b/pdns/dnsdistdist/test-dnsdistedns.cc @@ -0,0 +1,199 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#define BOOST_TEST_DYN_LINK +#define BOOST_TEST_NO_MAIN + +#include + +#include "dnsdist-edns.hh" +#include "dnsname.hh" +#include "dnswriter.hh" +#include "ednscookies.hh" +#include "ednsextendederror.hh" +#include "ednsoptions.hh" +#include "ednssubnet.hh" + +BOOST_AUTO_TEST_SUITE(test_dnsdist_edns) + +BOOST_AUTO_TEST_CASE(getExtendedDNSError) +{ + const DNSName name("www.powerdns.com."); + + { + /* no EDNS */ + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(!infoCode); + BOOST_CHECK(!extraText); + } + + { + /* EDNS but no EDE */ + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + pw.addOpt(512, 0, 0); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(!infoCode); + BOOST_CHECK(!extraText); + } + + { + /* EDE with a numerical code but no text */ + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter::optvect_t opts; + const EDNSExtendedError ede{ + .infoCode = static_cast(EDNSExtendedError::code::NetworkError), + .extraText = ""}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(infoCode); + BOOST_CHECK_EQUAL(*infoCode, ede.infoCode); + BOOST_CHECK(!extraText); + } + + { + /* EDE with both code and text */ + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter::optvect_t opts; + const EDNSExtendedError ede{ + .infoCode = static_cast(EDNSExtendedError::code::Synthesized), + .extraText = "Synthesized from aggressive NSEC cache"}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(infoCode); + BOOST_CHECK_EQUAL(*infoCode, ede.infoCode); + BOOST_CHECK(extraText); + BOOST_CHECK_EQUAL(*extraText, ede.extraText); + } + + { + /* EDE with truncated text */ + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter::optvect_t opts; + const EDNSExtendedError ede{ + .infoCode = static_cast(EDNSExtendedError::code::Synthesized), + .extraText = "Synthesized from aggressive NSEC cache"}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + /* truncate the EDE text by one byte */ + query.resize(query.size() - 1U); + + BOOST_CHECK_THROW(dnsdist::edns::getExtendedDNSError(query), std::range_error); + } + + { + /* EDE before ECS */ + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter::optvect_t opts; + const EDNSExtendedError ede{ + .infoCode = static_cast(EDNSExtendedError::code::Synthesized), + .extraText = "Synthesized from aggressive NSEC cache"}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + EDNSSubnetOpts ecsOpt; + ecsOpt.source = Netmask(ComboAddress("192.0.2.1"), 24U); + const auto ecsOptStr = makeEDNSSubnetOptsString(ecsOpt); + opts.emplace_back(EDNSOptionCode::ECS, ecsOptStr); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(infoCode); + BOOST_CHECK_EQUAL(*infoCode, ede.infoCode); + BOOST_CHECK(extraText); + BOOST_CHECK_EQUAL(*extraText, ede.extraText); + } + + { + /* EDE after ECS */ + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter::optvect_t opts; + EDNSSubnetOpts ecsOpt; + ecsOpt.source = Netmask(ComboAddress("192.0.2.1"), 24U); + const auto ecsOptStr = makeEDNSSubnetOptsString(ecsOpt); + opts.emplace_back(EDNSOptionCode::ECS, ecsOptStr); + const EDNSExtendedError ede{ + .infoCode = static_cast(EDNSExtendedError::code::Synthesized), + .extraText = "Synthesized from aggressive NSEC cache"}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(infoCode); + BOOST_CHECK_EQUAL(*infoCode, ede.infoCode); + BOOST_CHECK(extraText); + BOOST_CHECK_EQUAL(*extraText, ede.extraText); + } + + { + /* Cookie, EDE, padding */ + PacketBuffer query; + GenericDNSPacketWriter pw(query, name, QType::A, QClass::IN, 0); + pw.getHeader()->rd = 1; + GenericDNSPacketWriter::optvect_t opts; + const EDNSCookiesOpt cookieOpt("deadbeefdeadbeef"); + const auto cookieOptStr = cookieOpt.makeOptString(); + opts.emplace_back(EDNSOptionCode::COOKIE, cookieOptStr); + const EDNSExtendedError ede{ + .infoCode = static_cast(EDNSExtendedError::code::Synthesized), + .extraText = "Synthesized from aggressive NSEC cache"}; + opts.emplace_back(EDNSOptionCode::EXTENDEDERROR, makeEDNSExtendedErrorOptString(ede)); + std::string paddingOptStr; + paddingOptStr.resize(42U); + opts.emplace_back(EDNSOptionCode::PADDING, paddingOptStr); + pw.addOpt(512, 0, 0, opts); + pw.commit(); + + auto [infoCode, extraText] = dnsdist::edns::getExtendedDNSError(query); + BOOST_CHECK(infoCode); + BOOST_CHECK_EQUAL(*infoCode, ede.infoCode); + BOOST_CHECK(extraText); + BOOST_CHECK_EQUAL(*extraText, ede.extraText); + } +} + +BOOST_AUTO_TEST_SUITE_END(); diff --git a/pdns/dnswriter.hh b/pdns/dnswriter.hh index cfa4eb994750..4d6d28618242 100644 --- a/pdns/dnswriter.hh +++ b/pdns/dnswriter.hh @@ -69,7 +69,7 @@ public: void startRecord(const DNSName& name, uint16_t qtype, uint32_t ttl=3600, uint16_t qclass=QClass::IN, DNSResourceRecord::Place place=DNSResourceRecord::ANSWER, bool compress=true); /** Shorthand way to add an Opt-record, for example for EDNS0 purposes */ - typedef vector > optvect_t; + using optvect_t = vector >; void addOpt(const uint16_t udpsize, const uint16_t extRCode, const uint16_t ednsFlags, const optvect_t& options=optvect_t(), const uint8_t version=0); /** needs to be called after the last record is added, but can be called again and again later on. Is called internally by startRecord too. diff --git a/pdns/ednsextendederror.cc b/pdns/ednsextendederror.cc new file mode 100644 index 000000000000..5010e3dba52d --- /dev/null +++ b/pdns/ednsextendederror.cc @@ -0,0 +1,65 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include + +#include "ednsextendederror.hh" + +static bool getEDNSExtendedErrorOptFromStringView(const std::string_view& option, EDNSExtendedError& eee) +{ + if (option.size() < sizeof(uint16_t)) { + return false; + } + eee.infoCode = static_cast(option.at(0)) * 256 + static_cast(option.at(1)); + + if (option.size() > sizeof(uint16_t)) { + eee.extraText = std::string(&option.at(sizeof(uint16_t)), option.size() - sizeof(uint16_t)); + } + + return true; +} + +bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee) +{ + return getEDNSExtendedErrorOptFromStringView(std::string_view(option), eee); +} + +bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee) +{ + return getEDNSExtendedErrorOptFromStringView(std::string_view(option, len), eee); +} + +string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee) +{ + if (eee.extraText.size() > static_cast(std::numeric_limits::max() - 2)) { + throw std::runtime_error("Trying to create an EDNS Extended Error option with an extra text of size " + std::to_string(eee.extraText.size())); + } + + string ret; + ret.reserve(sizeof(uint16_t) + eee.extraText.size()); + ret.resize(sizeof(uint16_t)); + + ret[0] = static_cast(static_cast(eee.infoCode) / 256); + ret[1] = static_cast(static_cast(eee.infoCode) % 256); + ret.append(eee.extraText); + + return ret; +} diff --git a/pdns/ednsextendederror.hh b/pdns/ednsextendederror.hh new file mode 100644 index 000000000000..5b264fcf69b6 --- /dev/null +++ b/pdns/ednsextendederror.hh @@ -0,0 +1,66 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once +#include "namespaces.hh" + +struct EDNSExtendedError +{ + enum class code : uint16_t + { + Other = 0, + UnsupportedDNSKEYAlgorithm = 1, + UnsupportedDSDigestType = 2, + StaleAnswer = 3, + ForgedAnswer = 4, + DNSSECIndeterminate = 5, + DNSSECBogus = 6, + SignatureExpired = 7, + SignatureNotYetValid = 8, + DNSKEYMissing = 9, + RRSIGsMissing = 10, + NoZoneKeyBitSet = 11, + NSECMissing = 12, + CachedError = 13, + NotReady = 14, + Blocked = 15, + Censored = 16, + Filtered = 17, + Prohibited = 18, + StaleNXDOMAINAnswer = 19, + NotAuthoritative = 20, + NotSupported = 21, + NoReachableAuthority = 22, + NetworkError = 23, + InvalidData = 24, + SignatureExpiredBeforeValid = 25, + TooEarly = 26, + UnsupportedNSEC3IterationsValue = 27, + UnableToConformToPolicy = 28, + Synthesized = 29, + }; + uint16_t infoCode; + std::string extraText; +}; + +bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee); +bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee); +string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee); diff --git a/pdns/recursordist/ednsextendederror.cc b/pdns/recursordist/ednsextendederror.cc deleted file mode 100644 index 5010e3dba52d..000000000000 --- a/pdns/recursordist/ednsextendederror.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#include - -#include "ednsextendederror.hh" - -static bool getEDNSExtendedErrorOptFromStringView(const std::string_view& option, EDNSExtendedError& eee) -{ - if (option.size() < sizeof(uint16_t)) { - return false; - } - eee.infoCode = static_cast(option.at(0)) * 256 + static_cast(option.at(1)); - - if (option.size() > sizeof(uint16_t)) { - eee.extraText = std::string(&option.at(sizeof(uint16_t)), option.size() - sizeof(uint16_t)); - } - - return true; -} - -bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee) -{ - return getEDNSExtendedErrorOptFromStringView(std::string_view(option), eee); -} - -bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee) -{ - return getEDNSExtendedErrorOptFromStringView(std::string_view(option, len), eee); -} - -string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee) -{ - if (eee.extraText.size() > static_cast(std::numeric_limits::max() - 2)) { - throw std::runtime_error("Trying to create an EDNS Extended Error option with an extra text of size " + std::to_string(eee.extraText.size())); - } - - string ret; - ret.reserve(sizeof(uint16_t) + eee.extraText.size()); - ret.resize(sizeof(uint16_t)); - - ret[0] = static_cast(static_cast(eee.infoCode) / 256); - ret[1] = static_cast(static_cast(eee.infoCode) % 256); - ret.append(eee.extraText); - - return ret; -} diff --git a/pdns/recursordist/ednsextendederror.cc b/pdns/recursordist/ednsextendederror.cc new file mode 120000 index 000000000000..4f6ced0eb166 --- /dev/null +++ b/pdns/recursordist/ednsextendederror.cc @@ -0,0 +1 @@ +../ednsextendederror.cc \ No newline at end of file diff --git a/pdns/recursordist/ednsextendederror.hh b/pdns/recursordist/ednsextendederror.hh deleted file mode 100644 index 5b264fcf69b6..000000000000 --- a/pdns/recursordist/ednsextendederror.hh +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#pragma once -#include "namespaces.hh" - -struct EDNSExtendedError -{ - enum class code : uint16_t - { - Other = 0, - UnsupportedDNSKEYAlgorithm = 1, - UnsupportedDSDigestType = 2, - StaleAnswer = 3, - ForgedAnswer = 4, - DNSSECIndeterminate = 5, - DNSSECBogus = 6, - SignatureExpired = 7, - SignatureNotYetValid = 8, - DNSKEYMissing = 9, - RRSIGsMissing = 10, - NoZoneKeyBitSet = 11, - NSECMissing = 12, - CachedError = 13, - NotReady = 14, - Blocked = 15, - Censored = 16, - Filtered = 17, - Prohibited = 18, - StaleNXDOMAINAnswer = 19, - NotAuthoritative = 20, - NotSupported = 21, - NoReachableAuthority = 22, - NetworkError = 23, - InvalidData = 24, - SignatureExpiredBeforeValid = 25, - TooEarly = 26, - UnsupportedNSEC3IterationsValue = 27, - UnableToConformToPolicy = 28, - Synthesized = 29, - }; - uint16_t infoCode; - std::string extraText; -}; - -bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee); -bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee); -string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee); diff --git a/pdns/recursordist/ednsextendederror.hh b/pdns/recursordist/ednsextendederror.hh new file mode 120000 index 000000000000..2e5eee192724 --- /dev/null +++ b/pdns/recursordist/ednsextendederror.hh @@ -0,0 +1 @@ +../ednsextendederror.hh \ No newline at end of file From e3762c2e919fc5538d9b8fcd2b8d7d96117ea300 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 29 Aug 2023 13:53:22 +0200 Subject: [PATCH 667/909] dnsdist: Add regression test for EDE export to protobuf --- regression-tests.dnsdist/extendederrors.py | 1 + regression-tests.dnsdist/test_Protobuf.py | 105 +++++++++++++++++---- 2 files changed, 87 insertions(+), 19 deletions(-) create mode 120000 regression-tests.dnsdist/extendederrors.py diff --git a/regression-tests.dnsdist/extendederrors.py b/regression-tests.dnsdist/extendederrors.py new file mode 120000 index 000000000000..6ed0ebae7d63 --- /dev/null +++ b/regression-tests.dnsdist/extendederrors.py @@ -0,0 +1 @@ +../regression-tests.recursor-dnssec/extendederrors.py \ No newline at end of file diff --git a/regression-tests.dnsdist/test_Protobuf.py b/regression-tests.dnsdist/test_Protobuf.py index 99a97183de7a..31f7b6c3f814 100644 --- a/regression-tests.dnsdist/test_Protobuf.py +++ b/regression-tests.dnsdist/test_Protobuf.py @@ -10,6 +10,7 @@ import dns import dnsmessage_pb2 +import extendederrors class DNSDistProtobufTest(DNSDistTest): _protobufServerPort = pickAvailablePort() @@ -295,8 +296,9 @@ def testProtobuf(self): self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - # let the protobuf messages the time to get there - time.sleep(1) + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) # check the protobuf message corresponding to the UDP query msg = self.getFirstProtobufMessage() @@ -323,8 +325,9 @@ def testProtobuf(self): self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - # let the protobuf messages the time to get there - time.sleep(1) + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) # check the protobuf message corresponding to the TCP query msg = self.getFirstProtobufMessage() @@ -368,9 +371,9 @@ def testLuaProtobuf(self): self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - - # let the protobuf messages the time to get there - time.sleep(1) + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) # check the protobuf message corresponding to the UDP query msg = self.getFirstProtobufMessage() @@ -394,8 +397,9 @@ def testLuaProtobuf(self): self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - # let the protobuf messages the time to get there - time.sleep(1) + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) # check the protobuf message corresponding to the TCP query msg = self.getFirstProtobufMessage() @@ -445,8 +449,9 @@ def testProtobufMeta(self): self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - # let the protobuf messages the time to get there - time.sleep(1) + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) # check the protobuf message corresponding to the UDP query msg = self.getFirstProtobufMessage() @@ -485,6 +490,64 @@ def testProtobufMeta(self): # no ':' when the value is empty self.assertIn('my-empty-key', msg.meta[0].value.stringVal) +class TestProtobufExtendedDNSErrorTags(DNSDistProtobufTest): + _config_params = ['_testServerPort', '_protobufServerPort'] + _config_template = """ + newServer{address="127.0.0.1:%s"} + rl = newRemoteLogger('127.0.0.1:%d') + + addAction(AllRule(), RemoteLogAction(rl, nil, {serverID='dnsdist-server-1'})) + addResponseAction(AllRule(), RemoteLogResponseAction(rl, nil, false, {serverID='dnsdist-server-1', exportExtendedErrorsToMeta='extended-error'})) + """ + + def testProtobufExtendedError(self): + """ + Protobuf: Extended Error + """ + name = 'extended-error.protobuf.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 3600, + dns.rdataclass.IN, + dns.rdatatype.A, + '127.0.0.1') + response.answer.append(rrset) + ede = extendederrors.ExtendedErrorOption(15, b'Blocked by RPZ!') + response.use_edns(edns=True, payload=4096, options=[ede]) + + (receivedQuery, receivedResponse) = self.sendUDPQuery(query, response) + self.assertTrue(receivedQuery) + self.assertTrue(receivedResponse) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(response, receivedResponse) + + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) + + # check the protobuf message corresponding to the UDP query + msg = self.getFirstProtobufMessage() + + self.checkProtobufQuery(msg, dnsmessage_pb2.PBDNSMessage.UDP, query, dns.rdataclass.IN, dns.rdatatype.A, name) + + # meta tags + self.assertEqual(len(msg.meta), 0) + + # check the protobuf message corresponding to the UDP response + msg = self.getFirstProtobufMessage() + self.checkProtobufResponse(msg, dnsmessage_pb2.PBDNSMessage.UDP, response) + + # meta tags + self.assertEqual(len(msg.meta), 1) + + self.assertEqual(msg.meta[0].key, 'extended-error') + self.assertEqual(len(msg.meta[0].value.intVal), 1) + self.assertEqual(len(msg.meta[0].value.stringVal), 1) + self.assertIn(15, msg.meta[0].value.intVal) + self.assertIn('Blocked by RPZ!', msg.meta[0].value.stringVal) + class TestProtobufMetaDOH(DNSDistProtobufTest): _serverKey = 'server.key' @@ -534,8 +597,9 @@ def testProtobufMetaDoH(self): self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - # let the protobuf messages the time to get there - time.sleep(1) + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) # check the protobuf message corresponding to the query msg = self.getFirstProtobufMessage() @@ -637,8 +701,9 @@ def testProtobufMetaProxy(self): self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - # let the protobuf messages the time to get there - time.sleep(1) + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) # check the protobuf message corresponding to the UDP query msg = self.getFirstProtobufMessage() @@ -698,8 +763,9 @@ def testProtobuf(self): self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - # let the protobuf messages the time to get there - time.sleep(1) + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) # check the protobuf message corresponding to the UDP query msg = self.getFirstProtobufMessage() @@ -726,8 +792,9 @@ def testProtobuf(self): self.assertEqual(query, receivedQuery) self.assertEqual(response, receivedResponse) - # let the protobuf messages the time to get there - time.sleep(1) + if self._protobufQueue.empty(): + # let the protobuf messages the time to get there + time.sleep(1) # check the protobuf message corresponding to the TCP query msg = self.getFirstProtobufMessage() From 1011aff1b65b977f3dde39b807200389bb9a8d59 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 29 Aug 2023 14:37:41 +0200 Subject: [PATCH 668/909] dnsdist: Make clang-tidy happy --- pdns/dnsdistdist/dnsdist-edns.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-edns.cc b/pdns/dnsdistdist/dnsdist-edns.cc index 982fe3efef91..a5aba4aae96b 100644 --- a/pdns/dnsdistdist/dnsdist-edns.cc +++ b/pdns/dnsdistdist/dnsdist-edns.cc @@ -27,7 +27,7 @@ namespace dnsdist::edns { std::pair, std::optional> getExtendedDNSError(const PacketBuffer& packet) { - uint16_t optStart; + uint16_t optStart = 0; size_t optLen = 0; bool last = false; From 198282a94774c021e520a3ee9383044e1d8292d9 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 11 Sep 2023 12:00:20 +0200 Subject: [PATCH 669/909] Apply typo-in-comment fixes from code review Co-authored-by: Remi Gacogne --- pdns/recursordist/test-aggressive_nsec_cc.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/test-aggressive_nsec_cc.cc b/pdns/recursordist/test-aggressive_nsec_cc.cc index 54bd7c043b3b..1809deea2371 100644 --- a/pdns/recursordist/test-aggressive_nsec_cc.cc +++ b/pdns/recursordist/test-aggressive_nsec_cc.cc @@ -1208,13 +1208,13 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_pruning) BOOST_CHECK_EQUAL(cache->getEntriesCount(), 3U); /* we have set a upper bound to 2 entries, so we are above, - and one entry are actually expired, so we will prune one entry + and one entry is actually expired, so we will prune one entry to get below the limit */ cache->prune(now.tv_sec + 15); BOOST_CHECK_EQUAL(cache->getEntriesCount(), 2U); - /* now we are at the limit, so we will scan 1/5th of all zones entries, rounded up, - and prune the expired ones, which mean we will also remoing twoe */ + /* now we are at the limit, so we will scan 1/10th of all zones entries, rounded up, + and prune the expired ones, which mean we will also be removing the remaining two */ cache->prune(now.tv_sec + 600); BOOST_CHECK_EQUAL(cache->getEntriesCount(), 0U); } From 9883d3f9f2f754f5102bbc1a5e7a4ccfae7b24b7 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 5 Jul 2023 15:48:59 +0200 Subject: [PATCH 670/909] Introduce structured YAML settings for Recursor. Mostly written in Rust, using CXX and Serde Code generation is used to generate both the old style config tables as the new Rust based code. The code generation also produces the code to covert old styel to new style and documentation. Th main entry point for code generationo is settings/generate.py, using the table table.py Existing configs continue to work as before. --- .github/actions/spell-check/expect.txt | 6 + .github/workflows/build-and-test-all.yml | 1 + .github/workflows/codeql-analysis.yml | 3 + .../debian/recursor/debian-buster/rules | 1 + .../dockerfiles/Dockerfile.debbuild-prepare | 7 +- .../dockerfiles/Dockerfile.rpmbuild | 9 +- builder-support/helpers/install_rust.sh | 45 + builder-support/specs/pdns-recursor.spec | 1 + pdns/arguments.cc | 52 +- pdns/arguments.hh | 27 +- pdns/recursordist/.gitignore | 1 + pdns/recursordist/Makefile.am | 34 +- pdns/recursordist/configure.ac | 9 +- .../docs/appendices/example/conversion | 48 + .../docs/appendices/example/fwzones.txt | 1 + .../docs/appendices/example/generate.sh | 1 + .../docs/appendices/example/recursor.conf | 5 + .../appendices/example/recursor.d/01.conf | 3 + .../docs/appendices/yamlconversion.rst | 61 + pdns/recursordist/docs/indexTOC.rst | 1 + .../recursordist/docs/lua-scripting/hooks.rst | 2 +- .../docs/manpages/rec_control.1.rst | 3 + pdns/recursordist/docs/settings.rst | 1630 ++++++--- pdns/recursordist/docs/upgrade.rst | 8 +- pdns/recursordist/docs/yamlsettings.rst | 3177 +++++++++++++++++ pdns/recursordist/rec-main.cc | 389 +- pdns/recursordist/rec-main.hh | 1 + pdns/recursordist/rec_channel_rec.cc | 7 +- pdns/recursordist/rec_control.cc | 174 +- pdns/recursordist/reczones.cc | 468 ++- pdns/recursordist/settings/.gitignore | 4 + pdns/recursordist/settings/Makefile.am | 19 + pdns/recursordist/settings/README.md | 227 ++ .../settings/cxxsettings-private.hh | 97 + pdns/recursordist/settings/cxxsettings.hh | 52 + pdns/recursordist/settings/cxxsupport.cc | 512 +++ .../settings/docs-new-preamble-in.rst | 185 + .../settings/docs-old-preamble-in.rst | 39 + pdns/recursordist/settings/generate.py | 743 ++++ pdns/recursordist/settings/rust-bridge-in.rs | 109 + .../recursordist/settings/rust-preamble-in.rs | 48 + pdns/recursordist/settings/rust/.gitignore | 6 + pdns/recursordist/settings/rust/Cargo.lock | 265 ++ pdns/recursordist/settings/rust/Cargo.toml | 19 + pdns/recursordist/settings/rust/Makefile.am | 20 + pdns/recursordist/settings/rust/build.rs | 6 + pdns/recursordist/settings/rust/src/bridge.rs | 471 +++ .../recursordist/settings/rust/src/helpers.rs | 73 + pdns/recursordist/settings/table.py | 2928 +++++++++++++++ pdns/recursordist/syncres.hh | 4 +- pdns/recursordist/test-settings.cc | 422 +++ pdns/recursordist/ws-recursor.cc | 146 +- regression-tests.api/.gitignore | 4 + regression-tests.api/runtests.py | 37 +- .../recursortests.py | 60 + .../test_SimpleYAML.py | 112 + tasks.py | 5 + 57 files changed, 11799 insertions(+), 989 deletions(-) create mode 100755 builder-support/helpers/install_rust.sh create mode 100644 pdns/recursordist/docs/appendices/example/conversion create mode 100644 pdns/recursordist/docs/appendices/example/fwzones.txt create mode 100755 pdns/recursordist/docs/appendices/example/generate.sh create mode 100644 pdns/recursordist/docs/appendices/example/recursor.conf create mode 100644 pdns/recursordist/docs/appendices/example/recursor.d/01.conf create mode 100644 pdns/recursordist/docs/appendices/yamlconversion.rst create mode 100644 pdns/recursordist/docs/yamlsettings.rst create mode 100644 pdns/recursordist/settings/.gitignore create mode 100644 pdns/recursordist/settings/Makefile.am create mode 100644 pdns/recursordist/settings/README.md create mode 100644 pdns/recursordist/settings/cxxsettings-private.hh create mode 100644 pdns/recursordist/settings/cxxsettings.hh create mode 100644 pdns/recursordist/settings/cxxsupport.cc create mode 100644 pdns/recursordist/settings/docs-new-preamble-in.rst create mode 100644 pdns/recursordist/settings/docs-old-preamble-in.rst create mode 100644 pdns/recursordist/settings/generate.py create mode 100644 pdns/recursordist/settings/rust-bridge-in.rs create mode 100644 pdns/recursordist/settings/rust-preamble-in.rs create mode 100644 pdns/recursordist/settings/rust/.gitignore create mode 100644 pdns/recursordist/settings/rust/Cargo.lock create mode 100644 pdns/recursordist/settings/rust/Cargo.toml create mode 100644 pdns/recursordist/settings/rust/Makefile.am create mode 100644 pdns/recursordist/settings/rust/build.rs create mode 100644 pdns/recursordist/settings/rust/src/bridge.rs create mode 100644 pdns/recursordist/settings/rust/src/helpers.rs create mode 100644 pdns/recursordist/settings/table.py create mode 100644 pdns/recursordist/test-settings.cc create mode 100644 regression-tests.recursor-dnssec/test_SimpleYAML.py diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index b451e038dc8e..4df2bcf119e7 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -451,6 +451,7 @@ fulltoc fullycapable Furnell Fusl +fwzones FYhvws FZq gaba @@ -1121,7 +1122,9 @@ rdata rdqueries rdynamic reconnections +recordcache recursor +recursord recursordist Recursordoc Recuweb @@ -1512,6 +1515,7 @@ webbased webdocs webhandler webpassword +webservice Webspider Wegener Weimer @@ -1559,6 +1563,8 @@ xpf XRecord XXXXXX yahttp +yamlconversion +yamlsettings Yehuda yeswehack Yiu diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 7d2a75fd49e2..cc239d47243c 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -120,6 +120,7 @@ jobs: path: ~/.ccache key: recursor-${{ matrix.sanitizers }}-ccache-${{ steps.get-stamp.outputs.stamp }} restore-keys: recursor-${{ matrix.sanitizers }}-ccache- + - run: inv ci-install-rust ${{ env.REPO_HOME }} - run: inv ci-autoconf - run: inv ci-rec-configure - run: inv ci-rec-make-bear diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 874ec85e773a..8188bd63f29c 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -104,6 +104,7 @@ jobs: libwslay-dev \ libyaml-cpp-dev \ ragel \ + rustc \ unixodbc-dev - name: Build auth @@ -133,6 +134,8 @@ jobs: autoreconf -vfi ./configure --enable-unit-tests --enable-nod --enable-dnstap CFLAGS='-O0' CXXFLAGS='-O0' make -j8 -C ext + make -j8 -C settings + make -j8 -C settings/rust make htmlfiles.h make -j4 pdns_recursor rec_control diff --git a/builder-support/debian/recursor/debian-buster/rules b/builder-support/debian/recursor/debian-buster/rules index bcfd5f65a17e..9e122d632667 100755 --- a/builder-support/debian/recursor/debian-buster/rules +++ b/builder-support/debian/recursor/debian-buster/rules @@ -40,6 +40,7 @@ override_dh_auto_install: install -d debian/pdns-recursor/usr/share/pdns-recursor/snmp install -m 644 -t debian/pdns-recursor/usr/share/pdns-recursor/snmp RECURSOR-MIB.txt rm -f debian/pdns-recursor/etc/powerdns/recursor.conf-dist + rm -f debian/pdns-recursor/etc/powerdns/recursor.yml-dist ./pdns_recursor --no-config --config=default | sed \ -e 's!^# config-dir=.*!config-dir=/etc/powerdns!' \ -e 's!^# hint-file=.*!&\nhint-file=/usr/share/dns/root.hints!' \ diff --git a/builder-support/dockerfiles/Dockerfile.debbuild-prepare b/builder-support/dockerfiles/Dockerfile.debbuild-prepare index 7f03177fe684..bf86ab18bd36 100644 --- a/builder-support/dockerfiles/Dockerfile.debbuild-prepare +++ b/builder-support/dockerfiles/Dockerfile.debbuild-prepare @@ -1,11 +1,16 @@ FROM dist-base as package-builder ARG APT_URL -RUN DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends devscripts dpkg-dev build-essential python3-venv equivs +RUN DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends devscripts dpkg-dev build-essential python3-venv equivs curl RUN mkdir /dist /pdns WORKDIR /pdns ADD builder/helpers/ /pdns/builder/helpers/ +ADD builder-support/helpers/ /pdns/builder-support/helpers/ + +@IF [ -n "$M_recursor$M_all" ] +RUN /pdns/builder-support/helpers/install_rust.sh +@ENDIF # Used for -p option to only build specific packages ARG BUILDER_PACKAGE_MATCH diff --git a/builder-support/dockerfiles/Dockerfile.rpmbuild b/builder-support/dockerfiles/Dockerfile.rpmbuild index d98a6826c63d..48bd68eb76b4 100644 --- a/builder-support/dockerfiles/Dockerfile.rpmbuild +++ b/builder-support/dockerfiles/Dockerfile.rpmbuild @@ -1,10 +1,10 @@ FROM dist-base as package-builder RUN touch /var/lib/rpm/* && if $(grep -q 'release 7' /etc/redhat-release); then \ yum upgrade -y && \ - yum install -y rpm-build rpmdevtools python2 python3 "@Development Tools"; \ + yum install -y rpm-build rpmdevtools python2 python3 curl "@Development Tools"; \ else \ yum upgrade -y && \ - yum install -y rpm-build rpmdevtools python3 "@Development Tools"; \ + yum install -y rpm-build rpmdevtools python3 curl "@Development Tools"; \ fi RUN mkdir /dist /pdns @@ -13,6 +13,11 @@ RUN rpmdev-setuptree # Only ADD/COPY the files you really need for efficient docker caching. ADD builder/helpers/ /pdns/builder/helpers/ +ADD builder-support/helpers/ /pdns/builder-support/helpers/ + +@IF [ -n "$M_recursor$M_all" ] +RUN /pdns/builder-support/helpers/install_rust.sh +@ENDIF # Used for -p option to only build specific spec files ARG BUILDER_PACKAGE_MATCH diff --git a/builder-support/helpers/install_rust.sh b/builder-support/helpers/install_rust.sh new file mode 100755 index 000000000000..97a766b63e22 --- /dev/null +++ b/builder-support/helpers/install_rust.sh @@ -0,0 +1,45 @@ +#!/bin/sh + +set -e + +ARCH=$(arch) + +# Default version +RUST_VERSION=rust-1.72.0-$ARCH-unknown-linux-gnu + +if [ $# -ge 1 ]; then + RUST_VERSION=$1 + shift +fi + +SITE=https://downloads.powerdns.com/rust +RUST_TARBALL=$RUST_VERSION.tar.gz + +SHA256SUM_x86_64=f2bbe23e685852104fd48d0e34ac981b0917e76c62cfcd6d0ac5283e4710c7b9 + +NAME=SHA256SUM_$ARCH +eval VALUE=\$$NAME +if [ -z "$VALUE" ]; then + echo "$0: No SHA256 defined for $ARCH" > /dev/stderr + exit 1 +fi + +# Procedure to update the Rust tarball: +# 1. Download tarball and signature (.asc) file from +# https://forge.rust-lang.org/infra/other-installation-methods.html "Standalone installers" section +# 2. Import Rust signing key into your gpg if not already done so +# 3. Run gpg --verify $RUST_TARBALL.asc and make sure it is OK +# 4. Run sha256sum $RUST_TARBALL and set SHA256SUM above, don't forget to update RUST_VERSION as well +# 5. Make $RUST_TARBALL available from https://downloads.powerdns.com/rust +# +cd /tmp +echo $0: Downloading $RUST_TARBALL + +curl -o $RUST_TARBALL $SITE/$RUST_TARBALL +# Line below should echo two spaces between digest and name +echo $VALUE" "$RUST_TARBALL | sha256sum -c - +tar -zxf $RUST_TARBALL +cd $RUST_VERSION +./install.sh --prefix=/usr +cd .. +rm -rf $RUST_TARBALL $RUST_VERSION diff --git a/builder-support/specs/pdns-recursor.spec b/builder-support/specs/pdns-recursor.spec index 75a2690f7ec9..8408500e98a8 100644 --- a/builder-support/specs/pdns-recursor.spec +++ b/builder-support/specs/pdns-recursor.spec @@ -125,4 +125,5 @@ systemctl daemon-reload ||: %dir %{_sysconfdir}/%{name} %dir %{_sysconfdir}/%{name}/recursor.d %config(noreplace) %{_sysconfdir}/%{name}/recursor.conf +%config %{_sysconfdir}/%{name}/recursor.yml-dist %doc README diff --git a/pdns/arguments.cc b/pdns/arguments.cc index a1081ddd704e..1831d7d07fe1 100644 --- a/pdns/arguments.cc +++ b/pdns/arguments.cc @@ -81,11 +81,6 @@ vector ArgvMap::list() return ret; } -string ArgvMap::getHelp(const string& item) -{ - return helpmap[item]; -} - string& ArgvMap::set(const string& var, const string& help) { helpmap[var] = help; @@ -366,7 +361,8 @@ static const map deprecateList = { {"xpf-rr-code", "Proxy Protocol"}, }; -void ArgvMap::warnIfDeprecated(const string& var) +// NOLINTNEXTLINE(readability-convert-member-functions-to-static): accesses d_log (compiled out in auth, hence clang-tidy message) +void ArgvMap::warnIfDeprecated(const string& var) const { const auto msg = deprecateList.find(var); if (msg != deprecateList.end()) { @@ -375,6 +371,12 @@ void ArgvMap::warnIfDeprecated(const string& var) } } +string ArgvMap::isDeprecated(const string& var) +{ + const auto msg = deprecateList.find(var); + return msg != deprecateList.end() ? msg->second : ""; +} + void ArgvMap::parseOne(const string& arg, const string& parseOnly, bool lax) { string var; @@ -475,7 +477,7 @@ void ArgvMap::preParse(int& argc, char** argv, const string& arg) } } -bool ArgvMap::parseFile(const char* fname, const string& arg, bool lax) +bool ArgvMap::parseFile(const string& fname, const string& arg, bool lax) { string line; string pline; @@ -523,19 +525,19 @@ bool ArgvMap::parseFile(const char* fname, const string& arg, bool lax) return true; } -bool ArgvMap::preParseFile(const char* fname, const string& arg, const string& theDefault) +bool ArgvMap::preParseFile(const string& fname, const string& arg, const string& theDefault) { d_params[arg] = theDefault; return parseFile(fname, arg, false); } -bool ArgvMap::file(const char* fname, bool lax) +bool ArgvMap::file(const string& fname, bool lax) { return file(fname, lax, false); } -bool ArgvMap::file(const char* fname, bool lax, bool included) +bool ArgvMap::file(const string& fname, bool lax, bool included) { if (!parmIsset("include-dir")) { // inject include-dir set("include-dir", "Directory to include configuration files from"); @@ -550,7 +552,7 @@ bool ArgvMap::file(const char* fname, bool lax, bool included) // handle include here (avoid re-include) if (!included && !d_params["include-dir"].empty()) { std::vector extraConfigs; - gatherIncludes(extraConfigs); + gatherIncludes(d_params["include-dir"], ".conf", extraConfigs); for (const std::string& filename : extraConfigs) { if (!file(filename.c_str(), lax, true)) { SLOG(g_log << Logger::Error << filename << " could not be parsed" << std::endl, @@ -563,30 +565,31 @@ bool ArgvMap::file(const char* fname, bool lax, bool included) return true; } -void ArgvMap::gatherIncludes(std::vector& extraConfigs) +// NOLINTNEXTLINE(readability-convert-member-functions-to-static): accesses d_log (compiled out in auth, hence clang-tidy message) +void ArgvMap::gatherIncludes(const std::string& directory, const std::string& suffix, std::vector& extraConfigs) { - extraConfigs.clear(); - if (d_params["include-dir"].empty()) { + if (directory.empty()) { return; // nothing to do } - DIR* dir = nullptr; - if ((dir = opendir(d_params["include-dir"].c_str())) == nullptr) { + auto dir = std::unique_ptr(opendir(directory.c_str()), closedir); + if (dir == nullptr) { int err = errno; - string msg = d_params["include-dir"] + " is not accessible: " + stringerror(err); + string msg = directory + " is not accessible: " + stringerror(err); SLOG(g_log << Logger::Error << msg << std::endl, - d_log->error(Logr::Error, err, "Directory is not accessible", "name", Logging::Loggable(d_params["include-dir"]))); + d_log->error(Logr::Error, err, "Directory is not accessible", "name", Logging::Loggable(directory))); throw ArgException(msg); } + std::vector vec; struct dirent* ent = nullptr; - while ((ent = readdir(dir)) != nullptr) { // NOLINT(concurrency-mt-unsafe): see Linux man page + while ((ent = readdir(dir.get())) != nullptr) { // NOLINT(concurrency-mt-unsafe): see Linux man page if (ent->d_name[0] == '.') { continue; // skip any dots } - if (boost::ends_with(ent->d_name, ".conf")) { + if (boost::ends_with(ent->d_name, suffix)) { // build name - string name = d_params["include-dir"] + "/" + ent->d_name; // NOLINT: Posix API + string name = directory + "/" + ent->d_name; // NOLINT: Posix API // ensure it's readable file struct stat statInfo { @@ -595,12 +598,11 @@ void ArgvMap::gatherIncludes(std::vector& extraConfigs) string msg = name + " is not a regular file"; SLOG(g_log << Logger::Error << msg << std::endl, d_log->info(Logr::Error, "Unable to open non-regular file", "name", Logging::Loggable(name))); - closedir(dir); throw ArgException(msg); } - extraConfigs.push_back(name); + vec.emplace_back(name); } } - std::sort(extraConfigs.begin(), extraConfigs.end(), CIStringComparePOSIX()); - closedir(dir); + std::sort(vec.begin(), vec.end(), CIStringComparePOSIX()); + extraConfigs.insert(extraConfigs.end(), vec.begin(), vec.end()); } diff --git a/pdns/arguments.hh b/pdns/arguments.hh index fa5bfcf35547..cbc834be74b5 100644 --- a/pdns/arguments.hh +++ b/pdns/arguments.hh @@ -81,15 +81,15 @@ public: parse(argc, argv, true); } void preParse(int& argc, char** argv, const string& arg); //!< use this to preparse a single var - bool preParseFile(const char* fname, const string& arg, const string& theDefault = ""); //!< use this to preparse a single var in configuration + bool preParseFile(const string& fname, const string& arg, const string& theDefault = ""); //!< use this to preparse a single var in configuration - bool file(const char* fname, bool lax = false); //!< Parses a file with parameters - bool file(const char* fname, bool lax, bool included); - bool laxFile(const char* fname) + bool file(const string& fname, bool lax = false); //!< Parses a file with parameters + bool file(const string& fname, bool lax, bool included); + bool laxFile(const string& fname) { return file(fname, true); } - bool parseFile(const char* fname, const string& arg, bool lax); // list(); - string getHelp(const string& item); - + [[nodiscard]] string getHelp(const string& item) const + { + auto iter = helpmap.find(item); + return iter == helpmap.end() ? "" : iter->second; + } + [[nodiscard]] string getDefault(const string& item) const + { + auto iter = defaultmap.find(item); + return iter == defaultmap.end() ? "" : iter->second; + } using param_t = map; //!< use this if you need to know the content of the map param_t::const_iterator begin(); //!< iterator semantics param_t::const_iterator end(); //!< iterator semantics const string& operator[](const string&); //!< iterator semantics const vector& getCommands(); - void gatherIncludes(std::vector& extraConfigs); + void gatherIncludes(const std::string& dir, const std::string& suffix, std::vector& extraConfigs); + void warnIfDeprecated(const string& var) const; + [[nodiscard]] static string isDeprecated(const string& var); #ifdef RECURSOR void setSLog(Logr::log_t log) { @@ -125,7 +135,6 @@ public: } #endif private: - void warnIfDeprecated(const string& var); void parseOne(const string& arg, const string& parseOnly = "", bool lax = false); static string formatOne(bool running, bool full, const string& var, const string& help, const string& theDefault, const string& current); map d_params; diff --git a/pdns/recursordist/.gitignore b/pdns/recursordist/.gitignore index 70cde4a1c216..bb7e771610f7 100644 --- a/pdns/recursordist/.gitignore +++ b/pdns/recursordist/.gitignore @@ -34,6 +34,7 @@ /rec_control /pdns-recursor-* /recursor.conf-dist +/recursor.yml-dist /ext/Makefile /ext/Makefile.in /dnsmessage.pb.cc diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index fc330b3c6d2a..e231ea2b0203 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -1,6 +1,7 @@ JSON11_LIBS = $(top_srcdir)/ext/json11/libjson11.la PROBDS_LIBS = $(top_srcdir)/ext/probds/libprobds.la ARC4RANDOM_LIBS = $(top_srcdir)/ext/arc4random/libarc4random.la +RUST_LIBS = $(top_srcdir)/settings/rust/libsettings.a $(LIBDL) AM_CPPFLAGS = $(LUA_CFLAGS) $(YAHTTP_CFLAGS) $(BOOST_CPPFLAGS) $(LIBSODIUM_CFLAGS) $(NET_SNMP_CFLAGS) $(LIBCAP_CFLAGS) $(SANITIZER_FLAGS) -O3 -Wall -pthread -DSYSCONFDIR=\"${sysconfdir}\" $(SYSTEMD_CFLAGS) @@ -40,12 +41,13 @@ BUILT_SOURCES=htmlfiles.h \ dnslabeltext.cc CLEANFILES = htmlfiles.h \ - recursor.conf-dist + recursor.conf-dist recursor.yml-dist htmlfiles.h: incfiles html/* html/js/* ./incfiles > $@ -SUBDIRS=ext +# We explicilt build settings in two steps, as settings modifies files in the settings/rust subdir +SUBDIRS=ext settings settings/rust if LUA AM_CPPFLAGS +=$(LUA_CFLAGS) @@ -192,6 +194,7 @@ pdns_recursor_SOURCES = \ rpzloader.cc rpzloader.hh \ secpoll-recursor.cc secpoll-recursor.hh \ secpoll.cc secpoll.hh \ + settings/cxxsupport.cc \ sha.hh \ sholder.hh \ shuffle.cc shuffle.hh \ @@ -220,9 +223,12 @@ pdns_recursor_SOURCES = \ zonemd.cc zonemd.hh \ zoneparser-tng.cc zoneparser-tng.hh +nodist_pdns_recursor_SOURCES = \ + settings/cxxsettings-generated.cc + if !HAVE_LUA_HPP BUILT_SOURCES += lua.hpp -nodist_pdns_recursor_SOURCES = lua.hpp +nodist_pdns_recursor_SOURCES += lua.hpp endif CLEANFILES += lua.hpp @@ -238,7 +244,8 @@ pdns_recursor_LDADD = \ $(BOOST_SYSTEM_LIBS) \ $(PROBDS_LIBS) \ $(LIBCAP_LIBS) \ - $(ARC4RANDOM_LIBS) + $(ARC4RANDOM_LIBS) \ + $(RUST_LIBS) pdns_recursor_LDFLAGS = $(AM_LDFLAGS) \ $(LIBCRYPTO_LDFLAGS) $(BOOST_CONTEXT_LDFLAGS) \ @@ -252,7 +259,7 @@ pdns_recursor_LDFLAGS += \ $(BOOST_FILESYSTEM_LDFLAGS) endif -rec_control_LDADD = $(LIBCRYPTO_LIBS) $(ARC4RANDOM_LIBS) +rec_control_LDADD = $(LIBCRYPTO_LIBS) $(ARC4RANDOM_LIBS) $(RUST_LIBS) rec_control_LDFLAGS = $(AM_LDFLAGS) \ $(LIBCRYPTO_LDFLAGS) @@ -309,6 +316,7 @@ testrunner_SOURCES = \ root-dnssec.hh \ rpzloader.cc rpzloader.hh \ secpoll.cc \ + settings/cxxsupport.cc \ sholder.hh \ sillyrecords.cc \ sstuff.hh \ @@ -347,6 +355,7 @@ testrunner_SOURCES = \ test-reczones-helpers.cc \ test-rpzloader_cc.cc \ test-secpoll_cc.cc \ + test-settings.cc \ test-signers.cc \ test-syncres_cc.cc \ test-syncres_cc.hh \ @@ -370,6 +379,9 @@ testrunner_SOURCES = \ zonemd.cc zonemd.hh \ zoneparser-tng.cc zoneparser-tng.hh +nodist_testrunner_SOURCES = \ + settings/cxxsettings-generated.cc + testrunner_LDFLAGS = \ $(AM_LDFLAGS) \ $(BOOST_CONTEXT_LDFLAGS) \ @@ -385,7 +397,8 @@ testrunner_LDADD = \ $(BOOST_SYSTEM_LIBS) \ $(PROBDS_LIBS) \ $(LIBCAP_LIBS) \ - $(ARC4RANDOM_LIBS) + $(ARC4RANDOM_LIBS) \ + $(RUST_LIBS) if NOD_ENABLED testrunner_SOURCES += nod.hh nod.cc \ @@ -497,8 +510,12 @@ rec_control_SOURCES = \ qtype.cc \ rec_channel.cc rec_channel.hh \ rec_control.cc \ + settings/cxxsupport.cc \ unix_utility.cc +nodist_rec_control_SOURCES = \ + settings/cxxsettings-generated.cc + dnslabeltext.cc: dnslabeltext.rl $(AM_V_GEN)$(RAGEL) $< -o dnslabeltext.cc @@ -512,11 +529,14 @@ pubsuffix.cc: $(srcdir)/effective_tld_names.dat $(AM_V_GEN)./mkpubsuffixcc ## Config file -sysconf_DATA = recursor.conf-dist +sysconf_DATA = recursor.conf-dist recursor.yml-dist recursor.conf-dist: pdns_recursor $(AM_V_GEN)./pdns_recursor --config=default > $@ +recursor.yml-dist: pdns_recursor + dir=$$(mktemp -d) && touch "$$dir/recursor.yml" && ./pdns_recursor --config-dir="$$dir" --config=default 2> /dev/null > $@ && rm "$$dir/recursor.yml" && rmdir "$$dir" + ## Manpages MANPAGES=pdns_recursor.1 \ rec_control.1 diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index 2e8f9351b35e..231f3ae7a264 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -35,7 +35,10 @@ AC_DEFINE([RECURSOR], [1], m4_pattern_forbid([^_?PKG_[A-Z_]+$], [*** pkg.m4 missing, please install pkg-config]) AX_CXX_COMPILE_STDCXX_17([noext], [mandatory]) -LT_INIT() + +# Rust runtime used dlopen from its static lib +LT_INIT([dlopen]) +AC_SUBST([LIBDL], [$lt_cv_dlopen_libs]) PDNS_CHECK_OS PDNS_CHECK_NETWORK_LIBS @@ -198,7 +201,9 @@ AC_CONFIG_FILES([Makefile ext/json11/Makefile ext/probds/Makefile ext/yahttp/Makefile - ext/yahttp/yahttp/Makefile]) + ext/yahttp/yahttp/Makefile + settings/Makefile + settings/rust/Makefile]) AC_OUTPUT diff --git a/pdns/recursordist/docs/appendices/example/conversion b/pdns/recursordist/docs/appendices/example/conversion new file mode 100644 index 000000000000..f4b4d3d73740 --- /dev/null +++ b/pdns/recursordist/docs/appendices/example/conversion @@ -0,0 +1,48 @@ +# THIS IS A PROOF OF CONCEPT! STRUCTURE, TYPES AND NAMES ARE SUBJECT TO CHANGE +# Start of converted recursor.yml based on recursor.conf +dnssec: + validation: validate +incoming: + listen: + - 128.66.23.4:5353 + - '[::1]:53' +recursor: + forward_zones: + - zone: example + recurse: false + forwarders: + - 127.0.0.1:1024 + forward_zones_file: fwzones.txt + include_dir: recursor.d +# Validation result: OK +# End of converted recursor.conf +# +# Found 1 .conf file in recursor.d +# Converted include-dir recursor.d/01.conf to YAML format: +incoming: + listen: !override + - 0.0.0.0 +recursor: + forward_zones: + - zone: example.com + recurse: false + forwarders: + - 128.66.9.99 + - zone: example.net + recurse: false + forwarders: + - 128.66.9.100 + - 128.66.9.101 +# Validation result: OK +# End of converted recursor.d/01.conf +# +# Converted fwzones.txt to YAML format for recursor.forward_zones_file: +- zone: example.org + forwarders: + - 127.0.0.1:1024 + recurse: true + notify_allowed: true +# Validation result: OK +# End of converted fwzones.txt +# + diff --git a/pdns/recursordist/docs/appendices/example/fwzones.txt b/pdns/recursordist/docs/appendices/example/fwzones.txt new file mode 100644 index 000000000000..2c6f95af07cf --- /dev/null +++ b/pdns/recursordist/docs/appendices/example/fwzones.txt @@ -0,0 +1 @@ +^+example.org=127.0.0.1:1024 \ No newline at end of file diff --git a/pdns/recursordist/docs/appendices/example/generate.sh b/pdns/recursordist/docs/appendices/example/generate.sh new file mode 100755 index 000000000000..ff91ec1461db --- /dev/null +++ b/pdns/recursordist/docs/appendices/example/generate.sh @@ -0,0 +1 @@ +../../../rec_control show-yaml recursor.conf > conversion diff --git a/pdns/recursordist/docs/appendices/example/recursor.conf b/pdns/recursordist/docs/appendices/example/recursor.conf new file mode 100644 index 000000000000..4e82073f68d9 --- /dev/null +++ b/pdns/recursordist/docs/appendices/example/recursor.conf @@ -0,0 +1,5 @@ +dnssec=validate +include-dir=recursor.d +forward-zones = example=127.0.0.1:1024 +forward-zones-file=fwzones.txt +local-address=128.66.23.4:5353, [::1]:53 diff --git a/pdns/recursordist/docs/appendices/example/recursor.d/01.conf b/pdns/recursordist/docs/appendices/example/recursor.d/01.conf new file mode 100644 index 000000000000..de62b205829e --- /dev/null +++ b/pdns/recursordist/docs/appendices/example/recursor.d/01.conf @@ -0,0 +1,3 @@ +forward-zones += example.com=128.66.9.99 +forward-zones += example.net=128.66.9.100;128.66.9.101 +local-address = 0.0.0.0 diff --git a/pdns/recursordist/docs/appendices/yamlconversion.rst b/pdns/recursordist/docs/appendices/yamlconversion.rst new file mode 100644 index 000000000000..d846eb6ff4c8 --- /dev/null +++ b/pdns/recursordist/docs/appendices/yamlconversion.rst @@ -0,0 +1,61 @@ +Conversion of old-style settings to YAML format +================================================ + +Running the command + +.. code-block:: sh + + rec_control show-yaml + +will show the conversion of existing old-style settings into the new YAML format. +The existing settings will be read from the default old-style settings file ``recursor.conf`` in the configuration directory. +It is also possible to show the conversion of a specific old-style settings file by running + +.. code-block:: sh + + rec_control show-yaml path/to/recursor.conf + +``rec_control show-yaml`` will also show the conversions of any included ``.conf`` file (if :ref:`setting-include-dir` is set) and other associated settings file, like :ref:`setting-forward-zones-file`. + +Example +------- + +Consider the old style configuration file ``recursor.conf``: + +.. literalinclude:: example/recursor.conf + +With the contents of ``recursor.d/01.conf``: + +.. literalinclude:: example/recursor.d/01.conf + +And ``fwzones.txt``: + +.. literalinclude:: example/fwzones.txt + +To show the conversion result, run: + +.. code-block:: sh + + cd example + rec_control show-yaml recursor.conf + +Produces the following conversion report: + +.. literalinclude:: example/conversion + +Note the ``!override`` tag for ``incoming.listen`` (corresponding to the ``=`` in ``recursor.d/01.conf``. +The ``recursor.forward_zones`` settings is extending the setting in the main ``recursord.yml`` file, as ``recursor.d/01.conf`` uses a ``+=`` for the ``forward-zones`` settings. +Consult :doc:`../yamlsettings` for details on how settings spread over multiple files are merged. + +The contents of the report can be used to produce YAML settings equivalent to the old-style settings. +This is a manual step and consists of copy-pasting the sections of the conversion report to individual files. +Any settings filename in the include directory should end with ``.yml``. +It is possible to put associated files (like a ``recursor.forward_zones_file``) into the include dir, but do *not* let these files end in ``.yml``, as ``.yml`` files will be interpreted as full configuration files, while the associated settings files are YAML sequences of a specific type. + +API Managed Files +----------------- +The format of API managed files was also changed to use YAML format. +Specifically, the list of API managed zones is now a single file containing a sequence of ``auth_zones`` and a sequence of ``forward_zones`` instead of a settings file per zone. +The list of ACLs is a YAML sequence of subnets or IP addresses. +There is no conversion of API managed files from old-style to YAML yet. +The intention is to add automatic conversion code before the final release of a YAML enabled :program:`Recursor`, diff --git a/pdns/recursordist/docs/indexTOC.rst b/pdns/recursordist/docs/indexTOC.rst index 07140ec57c3a..cf56e82f98ba 100644 --- a/pdns/recursordist/docs/indexTOC.rst +++ b/pdns/recursordist/docs/indexTOC.rst @@ -10,6 +10,7 @@ PowerDNS Recursor running dnssec settings + yamlsettings lua-config/index lua-scripting/index dns64 diff --git a/pdns/recursordist/docs/lua-scripting/hooks.rst b/pdns/recursordist/docs/lua-scripting/hooks.rst index 576393ab2e8e..1200019244b3 100644 --- a/pdns/recursordist/docs/lua-scripting/hooks.rst +++ b/pdns/recursordist/docs/lua-scripting/hooks.rst @@ -448,4 +448,4 @@ This function expects no argument and doesn't return any value. -- Perform here your maintenance end -The interval can be configured through the :ref:`setting-maintenance-interval` setting. +The interval can be configured through the :ref:`setting-lua-maintenance-interval` setting. diff --git a/pdns/recursordist/docs/manpages/rec_control.1.rst b/pdns/recursordist/docs/manpages/rec_control.1.rst index 928694a12203..99b4a8317f2a 100644 --- a/pdns/recursordist/docs/manpages/rec_control.1.rst +++ b/pdns/recursordist/docs/manpages/rec_control.1.rst @@ -338,6 +338,9 @@ wipe-cache *DOMAIN* [*DOMAIN*] [...] wipe-cache-typed *qtype* *DOMAIN* [*DOMAIN*] [...] Same as wipe-cache, but only wipe records of type *qtype*. +show-yaml [*FILE*] + Show Yaml representation of config. EXPERIMENTAL. + See also -------- :manpage:`pdns_recursor(1)` diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 85825b32bcb5..23682e1a01f8 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -1,8 +1,16 @@ +.. THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir + START INCLUDE docs-old-preamble-in.rst + PowerDNS Recursor Settings ========================== Each setting can appear on the command line, prefixed by ``--``, or in the configuration file. The command line overrides the configuration file. +.. note:: + Starting with version 5.0.0, :program:`Recursor` supports a new YAML syntax for configuration files. + A configuration using the old style syntax can be converted to a YAML configuration using the instructions in :doc:`appendices/yamlconversion`. + In a future release support for the "old-style" settings will be dropped. + .. note:: Settings marked as ``Boolean`` can either be set to an empty value, which means **on**, or to ``no`` or ``off`` which means **off**. Anything else means **on**. @@ -30,26 +38,34 @@ For example:: In this case the address ``128.66.1.2`` is excluded from the addresses allowed access. +The Settings +------------ +.. END INCLUDE docs-old-preamble-in.rst + .. _setting-aggressive-nsec-cache-size: ``aggressive-nsec-cache-size`` ------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 - Integer - Default: 100000 +- YAML setting: :ref:`setting-yaml-dnssec.aggressive_nsec_cache_size` + The number of records to cache in the aggressive cache. If set to a value greater than 0, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in :rfc:`8198`. -To use this, DNSSEC processing or validation must be enabled by setting `dnssec`_ to ``process``, ``log-fail`` or ``validate``. +To use this, DNSSEC processing or validation must be enabled by setting :ref:`setting-dnssec` to ``process``, ``log-fail`` or ``validate``. .. _setting-aggressive-cache-min-nsec3-hit-ratio: ``aggressive-cache-min-nsec3-hit-ratio`` ----------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.9.0 -- Integer -- Default: 2000 +- Integer +- Default: 2000 + +- YAML setting: :ref:`setting-yaml-dnssec.aggressive_cache_min_nsec3_hit_ratio` The limit for which to put NSEC3 records into the aggressive cache. A value of ``n`` means that an NSEC3 record is only put into the aggressive cache if the estimated probability of a random name hitting the NSEC3 record is higher than ``1/n``. @@ -62,38 +78,47 @@ This setting avoids doing unnecessary work for such large zones. .. _setting-allow-from: ``allow-from`` --------------- -- IP addresses or netmasks, separated by commas, negation supported +~~~~~~~~~~~~~~ + +- Comma separated list of IP addresses or subnets, negation supported - Default: 127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10 +- YAML setting: :ref:`setting-yaml-incoming.allow_from` + Netmasks (both IPv4 and IPv6) that are allowed to use the server. The default allows access only from :rfc:`1918` private IP addresses. An empty value means no checking is done, all clients are allowed. Due to the aggressive nature of the internet these days, it is highly recommended to not open up the recursor for the entire internet. Questions from IP addresses not listed here are ignored and do not get an answer. -When the Proxy Protocol is enabled (see `proxy-protocol-from`_), the recursor will check the address of the client IP advertised in the Proxy Protocol header instead of the one of the proxy. +When the Proxy Protocol is enabled (see :ref:`setting-proxy-protocol-from`), the recursor will check the address of the client IP advertised in the Proxy Protocol header instead of the one of the proxy. Note that specifying an IP address without a netmask uses an implicit netmask of /32 or /128. .. _setting-allow-from-file: ``allow-from-file`` -------------------- -- Path +~~~~~~~~~~~~~~~~~~~ + +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-incoming.allow_from_file` -Like `allow-from`_, except reading from file. -Overrides the `allow-from`_ setting. To use this feature, supply one netmask per line, with optional comments preceded by a "#". +Like :ref:`setting-allow-from`, except reading from file. +Overrides the :ref:`setting-allow-from` setting. To use this feature, supply one netmask per line, with optional comments preceded by a '#'. .. _setting-allow-notify-for: ``allow-notify-for`` ---------------------- +~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 -- Comma separated list of domain-names +- Comma separated list of strings - Default: (empty) +- YAML setting: :ref:`setting-yaml-incoming.allow_notify_for` + Domain names specified in this list are used to permit incoming NOTIFY operations to wipe any cache entries that match the domain name. If this list is empty, all NOTIFY operations will be ignored. @@ -101,31 +126,36 @@ name. If this list is empty, all NOTIFY operations will be ignored. .. _setting-allow-notify-for-file: ``allow-notify-for-file`` -------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 -- Path +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-incoming.allow_notify_for_file` -Like `allow-notify-for`_, except reading from file. To use this +Like :ref:`setting-allow-notify-for`, except reading from file. To use this feature, supply one domain name per line, with optional comments -preceded by a "#". +preceded by a '#'. -NOTIFY-allowed zones can also be specified using `forward-zones-file`_. +NOTIFY-allowed zones can also be specified using :ref:`setting-forward-zones-file`. .. _setting-allow-notify-from: ``allow-notify-from`` ---------------------- +~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 -- IP addresses or netmasks, separated by commas, negation supported -- Default: unset +- Comma separated list of IP addresses or subnets, negation supported +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-incoming.allow_notify_from` Netmasks (both IPv4 and IPv6) that are allowed to issue NOTIFY operations to the server. NOTIFY operations from IP addresses not listed here are ignored and do not get an answer. -When the Proxy Protocol is enabled (see `proxy-protocol-from`_), the +When the Proxy Protocol is enabled (see :ref:`setting-proxy-protocol-from`), the recursor will check the address of the client IP advertised in the Proxy Protocol header instead of the one of the proxy. @@ -135,50 +165,60 @@ netmask of /32 or /128. NOTIFY operations received from a client listed in one of these netmasks will be accepted and used to wipe any cache entries whose zones match the zone specified in the NOTIFY operation, but only if that zone (or -one of its parents) is included in `allow-notify-for`_, -`allow-notify-for-file`_, or `forward-zones-file`_ with a '^' prefix. +one of its parents) is included in :ref:`setting-allow-notify-for`, +:ref:`setting-allow-notify-for-file`, or :ref:`setting-forward-zones-file` with a '^' prefix. .. _setting-allow-notify-from-file: ``allow-notify-from-file`` --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 -- Path +- String +- Default: (empty) -Like `allow-notify-from`_, except reading from file. To use this +- YAML setting: :ref:`setting-yaml-incoming.allow_notify_from_file` + +Like :ref:`setting-allow-notify-from`, except reading from file. To use this feature, supply one netmask per line, with optional comments preceded -by a "#". +by a '#'. .. _setting-any-to-tcp: ``any-to-tcp`` --------------- +~~~~~~~~~~~~~~ + - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-recursor.any_to_tcp` + Answer questions for the ANY type on UDP with a truncated packet that refers the remote server to TCP. Useful for mitigating ANY reflection attacks. .. _setting-allow-trust-anchor-query: ``allow-trust-anchor-query`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.3.0 - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-recursor.allow_trust_anchor_query` + Allow ``trustanchor.server CH TXT`` and ``negativetrustanchor.server CH TXT`` queries to view the configured :doc:`DNSSEC ` (negative) trust anchors. .. _setting-api-config-dir: ``api-config-dir`` ------------------- +~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.0.0 -- Path -- Default: unset +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-webservice.api_dir` Directory where the REST API stores its configuration and zones. For configuration updates to work, :ref:`setting-include-dir` should have the same value. @@ -186,45 +226,28 @@ For configuration updates to work, :ref:`setting-include-dir` should have the sa .. _setting-api-key: ``api-key`` ------------ +~~~~~~~~~~~ .. versionadded:: 4.0.0 .. versionchanged:: 4.6.0 + This setting now accepts a hashed and salted version. - String -- Default: unset - -Static pre-shared authentication key for access to the REST API. Since 4.6.0 the key can be hashed and salted using ``rec_control hash-password`` instead of being stored in the configuration in plaintext, but the plaintext version is still supported. - -.. _setting-api-readonly: - -``api-readonly`` ----------------- -.. versionchanged:: 4.2.0 - This setting has been removed. - -- Boolean -- Default: no - -Disallow data modification through the REST API when set. - -.. _setting-api-logfile: - -``api-logfile`` ---------------- -.. versionchanged:: 4.2.0 - This setting has been removed. +- Default: (empty) -- Path -- Default: unset +- YAML setting: :ref:`setting-yaml-webservice.api_key` -Location of the server logfile (used by the REST API). +Static pre-shared authentication key for access to the REST API. Since 4.6.0 the key can be hashed and salted using ``rec_control hash-password`` instead of being stored in the configuration in plaintext, but the plaintext version is still supported. .. _setting-auth-zones: ``auth-zones`` --------------- +~~~~~~~~~~~~~~ + - Comma separated list of 'zonename=filename' pairs +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.auth_zones` Zones read from these files (in BIND format) are served authoritatively (but without the AA bit set in responses). DNSSEC is not supported. Example: @@ -236,28 +259,38 @@ DNSSEC is not supported. Example: .. _setting-carbon-interval: ``carbon-interval`` -------------------- +~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 30 +- YAML setting: :ref:`setting-yaml-carbon.interval` + If sending carbon updates, this is the interval between them in seconds. See :doc:`metrics`. .. _setting-carbon-namespace: ``carbon-namespace`` --------------------- +~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 - String +- Default: pdns + +- YAML setting: :ref:`setting-yaml-carbon.ns` Change the namespace or first string of the metric key. The default is pdns. .. _setting-carbon-ourname: ``carbon-ourname`` ------------------- +~~~~~~~~~~~~~~~~~~ + - String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-carbon.ourname` If sending carbon updates, if set, this will override our hostname. Be careful not to include any dots in this setting, unless you know what you are doing. @@ -266,18 +299,25 @@ See :ref:`metricscarbon`. .. _setting-carbon-instance: ``carbon-instance`` --------------------- +~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 - String +- Default: recursor + +- YAML setting: :ref:`setting-yaml-carbon.instance` Change the instance or third string of the metric key. The default is recursor. .. _setting-carbon-server: ``carbon-server`` ------------------ -- IP address +~~~~~~~~~~~~~~~~~ + +- Comma separated list or IPs of IP:port combinations +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-carbon.server` If set to an IP or IPv6 address, will send all available metrics to this server via the carbon protocol, which is used by graphite and metronome. Moreover you can specify more than one server using a comma delimited list, ex: carbon-server=10.10.10.10,10.10.10.20. You may specify an alternate port by appending :port, for example: ``127.0.0.1:2004``. @@ -286,8 +326,12 @@ See :doc:`metrics`. .. _setting-chroot: ``chroot`` ----------- -- Path to a Directory +~~~~~~~~~~ + +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.chroot` If set, chroot to this directory for more security. This is not recommended; instead, we recommend containing PowerDNS using operating system features. @@ -296,9 +340,7 @@ We ship systemd unit files with our packages to make this easy. Make sure that ``/dev/log`` is available from within the chroot. Logging will silently fail over time otherwise (on logrotate). -When using ``chroot``, all other paths (except for `config-dir`_) set in the configuration are relative to the new root. - -When using ``chroot`` and the API (`webserver`_), `api-readonly`_ **must** be set and `api-config-dir`_ unset. +When using ``chroot``, all other paths (except for :ref:`setting-config-dir`) set in the configuration are relative to the new root. When running on a system where systemd manages services, ``chroot`` does not work out of the box, as PowerDNS cannot use the ``NOTIFY_SOCKET``. Either do not ``chroot`` on these systems or set the 'Type' of this service to 'simple' instead of 'notify' (refer to the systemd documentation on how to modify unit-files). @@ -306,17 +348,24 @@ Either do not ``chroot`` on these systems or set the 'Type' of this service to ' .. _setting-client-tcp-timeout: ``client-tcp-timeout`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 2 +- YAML setting: :ref:`setting-yaml-incoming.tcp_timeout` + Time to wait for data from TCP clients. .. _setting-config-dir: ``config-dir`` --------------- -- Path +~~~~~~~~~~~~~~ + +- String +- Default: /etc/powerdns + +- YAML setting: :ref:`setting-yaml-recursor.config_dir` Location of configuration directory (``recursor.conf``). Usually ``/etc/powerdns``, but this depends on ``SYSCONFDIR`` during compile-time. @@ -324,25 +373,33 @@ Usually ``/etc/powerdns``, but this depends on ``SYSCONFDIR`` during compile-tim .. _setting-config-name: ``config-name`` ---------------- +~~~~~~~~~~~~~~~ + - String -- Default: unset +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.config_name` When running multiple recursors on the same server, read settings from :file:`recursor-{name}.conf`, this will also rename the binary image. .. _setting-cpu-map: ``cpu-map`` ------------ +~~~~~~~~~~~ -- String -- Default: unset +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.cpu_map` Set CPU affinity for threads, asking the scheduler to run those threads on a single CPU, or a set of CPUs. This parameter accepts a space separated list of thread-id=cpu-id, or thread-id=cpu-id-1,cpu-id-2,...,cpu-id-N. For example, to make the worker thread 0 run on CPU id 0 and the worker thread 1 on CPUs 1 and 2:: - cpu-map=0=0 1=1,2 +.. code-block:: yaml + + recursor: + cpu_map: 0=0 1=1,2 The thread handling the control channel, the webserver and other internal stuff has been assigned id 0, the distributor threads if any are assigned id 1 and counting, and the worker threads follow behind. @@ -357,25 +414,29 @@ These threads cannot be specified in this setting as their thread-ids are left u .. _setting-daemon: ``daemon`` ----------- +~~~~~~~~~~ +.. versionchanged:: 4.0.0 + + Default is now ``no``, was ``yes`` before. + - Boolean - Default: no -.. versionchanged:: 4.0.0 - - Default is now "no", was "yes" before. +- YAML setting: :ref:`setting-yaml-recursor.daemon` Operate in the background. .. _setting-dont-throttle-names: ``dont-throttle-names`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Comma separated list of domain-names +- Comma separated list of strings - Default: (empty) +- YAML setting: :ref:`setting-yaml-outgoing.dont_throttle_names` + When an authoritative server does not answer a query or sends a reply the recursor does not like, it is throttled. Any servers' name suffix-matching the supplied names will never be throttled. @@ -385,17 +446,19 @@ Any servers' name suffix-matching the supplied names will never be throttled. .. _setting-dont-throttle-netmasks: ``dont-throttle-netmasks`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Comma separated list of netmasks, negation not supported +- Comma separated list of IP addresses or subnets, negation supported - Default: (empty) +- YAML setting: :ref:`setting-yaml-outgoing.dont_throttle_netmasks` + When an authoritative server does not answer a query or sends a reply the recursor does not like, it is throttled. Any servers matching the supplied netmasks will never be throttled. This can come in handy on lossy networks when forwarding, where the same server is configured multiple times (e.g. with ``forward-zones-recurse=example.com=192.0.2.1;192.0.2.1``). -By default, the PowerDNS Recursor would throttle the "first" server on a timeout and hence not retry the "second" one. +By default, the PowerDNS Recursor would throttle the 'first' server on a timeout and hence not retry the 'second' one. In this case, ``dont-throttle-netmasks`` could be set to ``192.0.2.1``. .. warning:: @@ -404,33 +467,41 @@ In this case, ``dont-throttle-netmasks`` could be set to ``192.0.2.1``. .. _setting-disable-packetcache: ``disable-packetcache`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ + - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-packetcache.disable` + Turn off the packet cache. Useful when running with Lua scripts that can not be cached, though individual query caching can be controlled from Lua as well. .. _setting-disable-syslog: ``disable-syslog`` ------------------- +~~~~~~~~~~~~~~~~~~ + - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-logging.disable_syslog` + Do not log to syslog, only to stdout. Use this setting when running inside a supervisor that handles logging (like systemd). -**Note**: do not use this setting in combination with `daemon`_ as all logging will disappear. +**Note**: do not use this setting in combination with :ref:`setting-daemon` as all logging will disappear. .. _setting-distribution-load-factor: ``distribution-load-factor`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.12 - Double - Default: 0.0 -If `pdns-distributes-queries`_ is set and this setting is set to another value +- YAML setting: :ref:`setting-yaml-incoming.distribution_load_factor` + +If :ref:`setting-pdns-distributes-queries` is set and this setting is set to another value than 0, the distributor thread will use a bounded load-balancing algorithm while distributing queries to worker threads, making sure that no thread is assigned more queries than distribution-load-factor times the average number of queries @@ -443,12 +514,14 @@ number of requests asking for the same qname. .. _setting-distribution-pipe-buffer-size: ``distribution-pipe-buffer-size`` ---------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 - Integer - Default: 0 +- YAML setting: :ref:`setting-yaml-incoming.distribution_pipe_buffer_size` + Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread. Requires support for `F_SETPIPE_SZ` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used. @@ -458,23 +531,27 @@ overloaded, but it will be at the cost of an increased latency. .. _setting-distributor-threads: ``distributor-threads`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 - Integer -- Default: 1 if `pdns-distributes-queries`_ is set, 0 otherwise +- Default: 1 if :ref:`setting-pdns-distributes-queries` is set, 0 otherwise -If `pdns-distributes-queries`_ is set, spawn this number of distributor threads on startup. Distributor threads +- YAML setting: :ref:`setting-yaml-incoming.distributor_threads` + +If :ref:`setting-pdns-distributes-queries` is set, spawn this number of distributor threads on startup. Distributor threads handle incoming queries and distribute them to other threads based on a hash of the query. .. _setting-dot-to-auth-names: ``dot-to-auth-names`` ---------------------- +~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 -- Comma separated list of domain-names or suffixes -- Default: (empty). +- Comma separated list of strings +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-outgoing.dot_to_auth_names` Force DoT to the listed authoritative nameservers. For this to work, DoT support has to be compiled in. Currently, the certificate is not checked for validity in any way. @@ -482,22 +559,26 @@ Currently, the certificate is not checked for validity in any way. .. _setting-dot-to-port-853: ``dot-to-port-853`` -------------------- +~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 -- Boolean -- Default: ``yes`` if DoT support is compiled in, ``no`` otherwise. +- Boolean +- Default: yes + +- YAML setting: :ref:`setting-yaml-outgoing.dot_to_port_853` Enable DoT to forwarders that specify port 853. .. _setting-dns64-prefix: ``dns64-prefix`` ----------------- +~~~~~~~~~~~~~~~~ .. versionadded:: 4.4.0 -- Netmask, as a string -- Default: None +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.dns64_prefix` Enable DNS64 (:rfc:`6147`) support using the supplied /96 IPv6 prefix. This will generate 'fake' ``AAAA`` records for names with only ``A`` records, as well as 'fake' ``PTR`` records to make sure that reverse lookup of DNS64-generated IPv6 addresses @@ -507,14 +588,18 @@ See :doc:`dns64` for more flexible but slower alternatives using Lua. .. _setting-dnssec: ``dnssec`` ----------- +~~~~~~~~~~ .. versionadded:: 4.0.0 - .. versionchanged:: 4.5.0 - The default changed from ``process-no-validate`` to ``process`` -- One of ``off``, ``process-no-validate``, ``process``, ``log-fail``, ``validate``, String -- Default: ``process`` + The default changed from ``process-no-validate`` to ``process`` + +- String +- Default: process + +- YAML setting: :ref:`setting-yaml-dnssec.validation` + +One of ``off``, ``process-no-validate``, ``process``, ``log-fail``, ``validate`` Set the mode for DNSSEC processing, as detailed in :doc:`dnssec`. @@ -536,11 +621,13 @@ Set the mode for DNSSEC processing, as detailed in :doc:`dnssec`. .. _setting-dnssec-disabled-algorithms: ``dnssec-disabled-algorithms`` ------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.9.0 -- Comma separated list of DNSSEC algorithm numbers -- Default: (none) +- Comma separated list of strings +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-dnssec.disabled_algorithms` A list of DNSSEC algorithm numbers that should be considered disabled. These algorithms will not be used to validate DNSSEC signatures. @@ -555,123 +642,146 @@ On such systems not disabling some algorithms (or changing the security policy) .. _setting-dnssec-log-bogus: ``dnssec-log-bogus`` --------------------- +~~~~~~~~~~~~~~~~~~~~ + - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-dnssec.log_bogus` + Log every DNSSEC validation failure. **Note**: This is not logged per-query but every time records are validated as Bogus. .. _setting-dont-query: ``dont-query`` --------------- -- Netmasks, comma separated, negation supported +~~~~~~~~~~~~~~ + +- Comma separated list of IP addresses or subnets, negation supported - Default: 127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10, 0.0.0.0/8, 192.0.0.0/24, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::/96, ::ffff:0:0/96, 100::/64, 2001:db8::/32 +- YAML setting: :ref:`setting-yaml-outgoing.dont_query` + The DNS is a public database, but sometimes contains delegations to private IP addresses, like for example 127.0.0.1. This can have odd effects, depending on your network, and may even be a security risk. Therefore, the PowerDNS Recursor by default does not query private space IP addresses. This setting can be used to expand or reduce the limitations. -Queries for names in forward zones and to addresses as configured in any of the settings `forward-zones`_, `forward-zones-file`_ or `forward-zones-recurse`_ are performed regardless of these limitations. +Queries for names in forward zones and to addresses as configured in any of the settings :ref:`setting-forward-zones`, :ref:`setting-forward-zones-file` or :ref:`setting-forward-zones-recurse` are performed regardless of these limitations. .. _setting-ecs-add-for: ``ecs-add-for`` ---------------- +~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Comma separated list of netmasks, negation supported +- Comma separated list of IP addresses or subnets, negation supported - Default: 0.0.0.0/0, ::/0, !127.0.0.0/8, !10.0.0.0/8, !100.64.0.0/10, !169.254.0.0/16, !192.168.0.0/16, !172.16.0.0/12, !::1/128, !fc00::/7, !fe80::/10 -List of requestor netmasks for which the requestor IP Address should be used as the :rfc:`EDNS Client Subnet <7871>` for outgoing queries. Outgoing queries for requestors that do not match this list will use the `ecs-scope-zero-address`_ instead. -Valid incoming ECS values from `use-incoming-edns-subnet`_ are not replaced. +- YAML setting: :ref:`setting-yaml-ecs.add_for` -Regardless of the value of this setting, ECS values are only sent for outgoing queries matching the conditions in the `edns-subnet-allow-list`_ setting. This setting only controls the actual value being sent. +List of requestor netmasks for which the requestor IP Address should be used as the :rfc:`EDNS Client Subnet <7871>` for outgoing queries. Outgoing queries for requestors that do not match this list will use the :ref:`setting-ecs-scope-zero-address` instead. +Valid incoming ECS values from :ref:`setting-use-incoming-edns-subnet` are not replaced. -This defaults to not using the requestor address inside RFC1918 and similar "private" IP address spaces. +Regardless of the value of this setting, ECS values are only sent for outgoing queries matching the conditions in the :ref:`setting-edns-subnet-allow-list` setting. This setting only controls the actual value being sent. + +This defaults to not using the requestor address inside RFC1918 and similar 'private' IP address spaces. .. _setting-ecs-ipv4-bits: ``ecs-ipv4-bits`` ------------------ +~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 - Integer - Default: 24 +- YAML setting: :ref:`setting-yaml-ecs.ipv4_bits` + Number of bits of client IPv4 address to pass when sending EDNS Client Subnet address information. .. _setting-ecs-ipv4-cache-bits: ``ecs-ipv4-cache-bits`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.12 - Integer - Default: 24 +- YAML setting: :ref:`setting-yaml-ecs.ipv4_cache_bits` + Maximum number of bits of client IPv4 address used by the authoritative server (as indicated by the EDNS Client Subnet scope in the answer) for an answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-cache-limit-ttl``. That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. .. _setting-ecs-ipv6-bits: ``ecs-ipv6-bits`` ------------------ +~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 - Integer - Default: 56 +- YAML setting: :ref:`setting-yaml-ecs.ipv6_bits` + Number of bits of client IPv6 address to pass when sending EDNS Client Subnet address information. .. _setting-ecs-ipv6-cache-bits: ``ecs-ipv6-cache-bits`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.12 - Integer - Default: 56 +- YAML setting: :ref:`setting-yaml-ecs.ipv6_cache_bits` + Maximum number of bits of client IPv6 address used by the authoritative server (as indicated by the EDNS Client Subnet scope in the answer) for an answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-cache-limit-ttl``. That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. .. _setting-ecs-ipv4-never-cache: ``ecs-ipv4-never-cache`` ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-ecs.ipv4_never_cache` + When set, never cache replies carrying EDNS IPv4 Client Subnet scope in the record cache. In this case the decision made by ```ecs-ipv4-cache-bits`` and ``ecs-cache-limit-ttl`` is no longer relevant. .. _setting-ecs-ipv6-never-cache: ``ecs-ipv6-never-cache`` ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-ecs.ipv6_never_cache` + When set, never cache replies carrying EDNS IPv6 Client Subnet scope in the record cache. In this case the decision made by ```ecs-ipv6-cache-bits`` and ``ecs-cache-limit-ttl`` is no longer relevant. .. _setting-ecs-minimum-ttl-override: ``ecs-minimum-ttl-override`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 4.5.0 + Old versions used default 0. - Integer - Default: 1 +- YAML setting: :ref:`setting-yaml-ecs.minimum_ttl_override` + This setting artificially raises the TTLs of records in the ANSWER section of ECS-specific answers to be at least this long. Setting this to a value greater than 1 technically is an RFC violation, but might improve performance a lot. Using a value of 0 impacts performance of TTL 0 records greatly, since it forces the recursor to contact @@ -681,11 +791,13 @@ Can be set at runtime using ``rec_control set-ecs-minimum-ttl 3600``. .. _setting-ecs-cache-limit-ttl: ``ecs-cache-limit-ttl`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.12 - Integer -- Default: 0 (disabled) +- Default: 0 + +- YAML setting: :ref:`setting-yaml-ecs.cache_limit_ttl` The minimum TTL for an ECS-specific answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-ipv4-cache-bits`` or ``ecs-ipv6-cache-bits``. That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. @@ -693,29 +805,34 @@ That is, only if both the limits apply, the record will not be cached. This deci .. _setting-ecs-scope-zero-address: ``ecs-scope-zero-address`` --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 -- IPv4 or IPv6 Address -- Default: empty +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-ecs.scope_zero_address` The IP address sent via EDNS Client Subnet to authoritative servers listed in -`edns-subnet-allow-list`_ when `use-incoming-edns-subnet`_ is set and the query has +:ref:`setting-edns-subnet-allow-list` when :ref:`setting-use-incoming-edns-subnet` is set and the query has an ECS source prefix-length set to 0. The default is to look for the first usable (not an ``any`` one) address in -`query-local-address`_ (starting with IPv4). If no suitable address is +:ref:`setting-query-local-address` (starting with IPv4). If no suitable address is found, the recursor fallbacks to sending 127.0.0.1. .. _setting-edns-outgoing-bufsize: ``edns-outgoing-bufsize`` -------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 4.2.0 + Before 4.2.0, the default was 1680 - Integer - Default: 1232 +- YAML setting: :ref:`setting-yaml-outgoing.edns_bufsize` + .. note:: Why 1232? 1232 is the largest number of payload bytes that can fit in the smallest IPv6 packet. @@ -727,69 +844,89 @@ Lower this if you experience timeouts. .. _setting-edns-padding-from: ``edns-padding-from`` ---------------------- +~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- Comma separated list of netmasks, negation supported -- Default: (none) +- String +- Default: (empty) -List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that `edns-padding-mode`_ applies. +- YAML setting: :ref:`setting-yaml-incoming.edns_padding_from` + +List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that :ref:`setting-edns-padding-mode` applies. .. _setting-edns-padding-mode: ``edns-padding-mode`` ---------------------- +~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- One of ``always``, ``padded-queries-only``, String -- Default: ``padded-queries-only`` +- String +- Default: padded-queries-only + +- YAML setting: :ref:`setting-yaml-incoming.edns_padding_mode` +One of ``always``, ``padded-queries-only``. Whether to add EDNS padding to all responses (``always``) or only to responses for queries containing the EDNS padding option (``padded-queries-only``, the default). -In both modes, padding will only be added to responses for queries coming from `edns-padding-from`_ sources. +In both modes, padding will only be added to responses for queries coming from :ref:`setting-edns-padding-from` sources. .. _setting-edns-padding-out: ``edns-padding-out`` --------------------- +~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.8.0 -- Boolean -- Default: yes +- Boolean +- Default: yes + +- YAML setting: :ref:`setting-yaml-outgoing.edns_padding` Whether to add EDNS padding to outgoing DoT queries. .. _setting-edns-padding-tag: ``edns-padding-tag`` --------------------- +~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 - Integer - Default: 7830 -The packetcache tag to use for padded responses, to prevent a client not allowed by the `edns-padding-from`_ list to be served a cached answer generated for an allowed one. This -effectively divides the packet cache in two when `edns-padding-from`_ is used. Note that this will not override a tag set from one of the ``Lua`` hooks. +- YAML setting: :ref:`setting-yaml-incoming.edns_padding_tag` + +The packetcache tag to use for padded responses, to prevent a client not allowed by the :ref::`setting-edns-padding-from` list to be served a cached answer generated for an allowed one. This +effectively divides the packet cache in two when :ref:`setting-edns-padding-from` is used. Note that this will not override a tag set from one of the ``Lua`` hooks. .. _setting-edns-subnet-whitelist: ``edns-subnet-whitelist`` -------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~ .. deprecated:: 4.5.0 - Use :ref:`setting-edns-subnet-allow-list`. + + Use :ref:`setting-edns-subnet-allow-list`. + +- String +- Default: (empty) + +- YAML setting does not exist + + .. _setting-edns-subnet-allow-list: ``edns-subnet-allow-list`` --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- Comma separated list of domain names and netmasks, negation supported -- Default: (none) +- Comma separated list of strings +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-outgoing.edns_subnet_allow_list` List of netmasks and domains that :rfc:`EDNS Client Subnet <7871>` should be enabled for in outgoing queries. -For example, an EDNS Client Subnet option containing the address of the initial requestor (but see `ecs-add-for`_) will be added to an outgoing query sent to server 192.0.2.1 for domain X if 192.0.2.1 matches one of the supplied netmasks, or if X matches one of the supplied domains. -The initial requestor address will be truncated to 24 bits for IPv4 (see `ecs-ipv4-bits`_) and to 56 bits for IPv6 (see `ecs-ipv6-bits`_), as recommended in the privacy section of RFC 7871. +For example, an EDNS Client Subnet option containing the address of the initial requestor (but see :ref:`setting-ecs-add-for`) will be added to an outgoing query sent to server 192.0.2.1 for domain X if 192.0.2.1 matches one of the supplied netmasks, or if X matches one of the supplied domains. +The initial requestor address will be truncated to 24 bits for IPv4 (see :ref:`setting-ecs-ipv4-bits`) and to 56 bits for IPv6 (see :ref:`setting-ecs-ipv6-bits`), as recommended in the privacy section of RFC 7871. + Note that this setting describes the destination of outgoing queries, not the sources of incoming queries, nor the subnets described in the EDNS Client Subnet option. @@ -798,10 +935,13 @@ By default, this option is empty, meaning no EDNS Client Subnet information is s .. _setting-entropy-source: ``entropy-source`` ------------------- -- Path +~~~~~~~~~~~~~~~~~~ + +- String - Default: /dev/urandom +- YAML setting: :ref:`setting-yaml-recursor.entropy_source` + PowerDNS can read entropy from a (hardware) source. This is used for generating random numbers which are very hard to predict. Generally on UNIX platforms, this source will be ``/dev/urandom``, which will always supply random numbers, even if entropy is lacking. @@ -810,21 +950,26 @@ Change to ``/dev/random`` if PowerDNS should block waiting for enough entropy to .. _setting-etc-hosts-file: ``etc-hosts-file`` ------------------- -- Path +~~~~~~~~~~~~~~~~~~ + +- String - Default: /etc/hosts +- YAML setting: :ref:`setting-yaml-recursor.etc_hosts_file` + The path to the /etc/hosts file, or equivalent. -This file can be used to serve data authoritatively using `export-etc-hosts`_. +This file can be used to serve data authoritatively using :ref:`setting-export-etc-hosts`. .. _setting-event-trace-enabled: ``event-trace-enabled`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 -- Integer -- Default: 0 +- Integer +- Default: 0 + +- YAML setting: :ref:`setting-yaml-recursor.event_trace_enabled` Enable the recording and logging of ref:`event traces`. This is an experimental feature and subject to change. Possible values are 0: (disabled), 1 (add information to protobuf logging messages) and 2 (write to log) and 3 (both). @@ -832,38 +977,51 @@ Possible values are 0: (disabled), 1 (add information to protobuf logging messag .. _setting-export-etc-hosts: ``export-etc-hosts`` --------------------- +~~~~~~~~~~~~~~~~~~~~ + - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-recursor.export_etc_hosts` + If set, this flag will export the host names and IP addresses mentioned in ``/etc/hosts``. .. _setting-export-etc-hosts-search-suffix: ``export-etc-hosts-search-suffix`` ----------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + - String +- Default: (empty) -If set, all hostnames in the `export-etc-hosts`_ file are loaded in canonical form, based on this suffix, unless the name contains a '.', in which case the name is unchanged. +- YAML setting: :ref:`setting-yaml-recursor.export_etc_hosts_search_suffix` + +If set, all hostnames in the :ref:`setting-export-etc-hosts` file are loaded in canonical form, based on this suffix, unless the name contains a '.', in which case the name is unchanged. So an entry called 'pc' with ``export-etc-hosts-search-suffix='home.com'`` will lead to the generation of 'pc.home.com' within the recursor. An entry called 'server1.home' will be stored as 'server1.home', regardless of this setting. .. _setting-extended-resolution-errors: ``extended-resolution-errors`` ------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-recursor.extended_resolution_errors` + If set, the recursor will add an EDNS Extended Error (:rfc:`8914`) to responses when resolution failed, like DNSSEC validation errors, explaining the reason it failed. This setting is not needed to allow setting custom error codes from Lua or from a RPZ hit. .. _setting-forward-zones: ``forward-zones`` ------------------ -- 'zonename=IP' pairs, comma separated +~~~~~~~~~~~~~~~~~ + +- Comma separated list of 'zonename=IP' pairs +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.forward_zones` Queries for zones listed here will be forwarded to the IP address listed. i.e. @@ -882,75 +1040,83 @@ If an ``NS`` record set for a subzone of the forwarded zone is learned, that rec This allows e.g. a forward to a local authoritative server holding a copy of the root zone, delegations received from that server will work. **IMPORTANT**: When using DNSSEC validation (which is default), forwards to non-delegated (e.g. internal) zones that have a DNSSEC signed parent zone will validate as Bogus. -To prevent this, add a Negative Trust Anchor (NTA) for this zone in the `lua-config-file`_ with ``addNTA("your.zone", "A comment")``. -If this forwarded zone is signed, instead of adding NTA, add the DS record to the `lua-config-file`_. +To prevent this, add a Negative Trust Anchor (NTA) for this zone in the :ref:`setting-lua-config-file` with ``addNTA('your.zone', 'A comment')``. +If this forwarded zone is signed, instead of adding NTA, add the DS record to the :ref:`setting-lua-config-file`. See the :doc:`dnssec` information. .. _setting-forward-zones-file: ``forward-zones-file`` ----------------------- -- Path +~~~~~~~~~~~~~~~~~~~~~~ +.. versionchanged:: 4.0.0 -Same as `forward-zones`_, parsed from a file. Only 1 zone is allowed per line, specified as follows: + (Old style settings only) Comments are allowed, everything behind ``#`` is ignored. +.. versionchanged:: 4.6.0 -.. code-block:: none + (Old style settings only) Zones prefixed with a ``^`` are added to the :ref:`setting-allow-notify-for` list. Both prefix characters can be used if desired, in any order. - example.org=203.0.113.210, 192.0.2.4:5300 +- String +- Default: (empty) -Zones prefixed with a '+' are treated as with -`forward-zones-recurse`_. Default behaviour without '+' is as with -`forward-zones`_. +- YAML setting: :ref:`setting-yaml-recursor.forward_zones_file` -.. versionchanged:: 4.0.0 +Same as :ref:`setting-forward-zones`, parsed from a file. Only 1 zone is allowed per line, specified as follows: - Comments are allowed, everything behind '#' is ignored. +.. code-block:: none -The DNSSEC notes from `forward-zones`_ apply here as well. + example.org=203.0.113.210, 192.0.2.4:5300 -.. versionchanged:: 4.6.0 +Zones prefixed with a ``+`` are treated as with +:ref:`setting-forward-zones-recurse`. Default behaviour without ``+`` is as with +:ref:`setting-forward-zones`. -Zones prefixed with a '^' are added to the `allow-notify-for`_ -list. Both prefix characters can be used if desired, in any order. +The DNSSEC notes from :ref:`setting-forward-zones` apply here as well. .. _setting-forward-zones-recurse: ``forward-zones-recurse`` -------------------------- -- 'zonename=IP' pairs, comma separated +~~~~~~~~~~~~~~~~~~~~~~~~~ + +- Comma separated list of 'zonename=IP' pairs +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.forward_zones_recurse` -Like regular `forward-zones`_, but forwarded queries have the ``recursion desired (RD)`` bit set to ``1``, meaning that this setting is intended to forward queries to other recursive servers. +Like regular :ref:`setting-forward-zones`, but forwarded queries have the ``recursion desired (RD)`` bit set to ``1``, meaning that this setting is intended to forward queries to other recursive servers. In contrast to regular forwarding, the rule that delegations of the forwarded subzones are respected is not active. This is because we rely on the forwarder to resolve the query fully. -See `forward-zones`_ for additional options (such as supplying multiple recursive servers) and an important note about DNSSEC. +See :ref:`setting-forward-zones` for additional options (such as supplying multiple recursive servers) and an important note about DNSSEC. .. _setting-gettag-needs-edns-options: ``gettag-needs-edns-options`` ------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-incoming.gettag_needs_edns_options` + If set, EDNS options in incoming queries are extracted and passed to the :func:`gettag` hook in the ``ednsoptions`` table. .. _setting-hint-file: ``hint-file`` -------------- -- Path -- Default: empty - +~~~~~~~~~~~~~ .. versionchanged:: 4.6.2 Introduced the value ``no`` to disable root-hints processing. - .. versionchanged:: 4.9.0 Introduced the value ``no-refresh`` to disable both root-hints processing and periodic refresh of the cached root `NS` records. +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.hint_file` + If set, the root-hints are read from this file. If empty, the default built-in root hints are used. In some special cases, processing the root hints is not needed, for example when forwarding all queries to another recursor. @@ -960,12 +1126,12 @@ See :ref:`handling-of-root-hints` for more information on root hints handling. .. _setting-ignore-unknown-settings: ``ignore-unknown-settings`` ---------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 +- Comma separated list of strings +- Default: (empty) -- Setting names, separated by commas -- Default: empty +- YAML setting: :ref:`setting-yaml-recursor.ignore_unknown_settings` Names of settings to be ignored while parsing configuration files, if the setting name is unknown to PowerDNS. @@ -975,26 +1141,36 @@ Useful during upgrade testing. .. _setting-include-dir: ``include-dir`` ---------------- -- Path +~~~~~~~~~~~~~~~ + +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.include_dir` Directory to scan for additional config files. All files that end with .conf are loaded in order using ``POSIX`` as locale. .. _setting-latency-statistic-size: ``latency-statistic-size`` --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 10000 +- YAML setting: :ref:`setting-yaml-recursor.latency_statistic_size` + Indication of how many queries will be averaged to get the average latency reported by the 'qa-latency' metric. .. _setting-local-address: ``local-address`` ------------------ -- IPv4/IPv6 Addresses, with optional port numbers, separated by commas or whitespace -- Default: ``127.0.0.1`` +~~~~~~~~~~~~~~~~~ + +- Comma separated list or IPs of IP:port combinations +- Default: 127.0.0.1 + +- YAML setting: :ref:`setting-yaml-incoming.listen` Local IP addresses to which we bind. Each address specified can include a port number; if no port is included then the @@ -1013,75 +1189,91 @@ Examples:: .. _setting-local-port: ``local-port`` --------------- +~~~~~~~~~~~~~~ + - Integer - Default: 53 +- YAML setting: :ref:`setting-yaml-incoming.port` + Local port to bind to. -If an address in `local-address`_ does not have an explicit port, this port is used. +If an address in :ref:`setting-local-address` does not have an explicit port, this port is used. .. _setting-log-timestamp: ``log-timestamp`` ------------------ +~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 +- Boolean +- Default: yes -- Bool -- Default: yes +- YAML setting: :ref:`setting-yaml-logging.timestamp` -When printing log lines to stdout, prefix them with timestamps. -Disable this if the process supervisor timestamps these lines already. -.. note:: - The systemd unit file supplied with the source code already disables timestamp printing .. _setting-non-local-bind: ``non-local-bind`` ------------------- +~~~~~~~~~~~~~~~~~~ + - Boolean - Default: no -Bind to addresses even if one or more of the `local-address`_'s do not exist on this server. +- YAML setting: :ref:`setting-yaml-incoming.non_local_bind` + +Bind to addresses even if one or more of the :ref:`setting-local-address`'s do not exist on this server. Setting this option will enable the needed socket options to allow binding to non-local addresses. This feature is intended to facilitate ip-failover setups, but it may also mask configuration issues and for this reason it is disabled by default. .. _setting-loglevel: ``loglevel`` ------------- -- Integer between 0 and 9 +~~~~~~~~~~~~ + +- Integer - Default: 6 +- YAML setting: :ref:`setting-yaml-logging.loglevel` + Amount of logging. The higher the number, the more lines logged. -Corresponds to "syslog" level values (e.g. 0 = emergency, 1 = alert, 2 = critical, 3 = error, 4 = warning, 5 = notice, 6 = info, 7 = debug). +Corresponds to 'syslog' level values (e.g. 0 = emergency, 1 = alert, 2 = critical, 3 = error, 4 = warning, 5 = notice, 6 = info, 7 = debug). Each level includes itself plus the lower levels before it. Not recommended to set this below 3. .. _setting-log-common-errors: ``log-common-errors`` ---------------------- +~~~~~~~~~~~~~~~~~~~~~ + - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-logging.common_errors` + Some DNS errors occur rather frequently and are no cause for alarm. +.. _setting-log-rpz-changes: + ``log-rpz-changes`` -------------------- +~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-logging.rpz_changes` + Log additions and removals to RPZ zones at Info (6) level instead of Debug (7). .. _setting-logging-facility: ``logging-facility`` --------------------- -- Integer +~~~~~~~~~~~~~~~~~~~~ + +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-logging.facility` If set to a digit, logging is performed under this LOCAL facility. See :ref:`logging`. @@ -1090,10 +1282,13 @@ Do not pass names like 'local0'! .. _setting-lowercase-outgoing: ``lowercase-outgoing`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ + - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-outgoing.lowercase` + Set to true to lowercase the outgoing queries. When set to 'no' (the default) a query from a client using mixed case in the DNS labels (such as a user entering mixed-case names or `draft-vixie-dnsext-dns0x20-00 `_), PowerDNS preserves the case of the query. Broken authoritative servers might give a wrong or broken answer on this encoding. @@ -1102,8 +1297,12 @@ Setting ``lowercase-outgoing`` to 'yes' makes the PowerDNS Recursor lowercase al .. _setting-lua-config-file: ``lua-config-file`` -------------------- -- Filename +~~~~~~~~~~~~~~~~~~~ + +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.lua_config_file` If set, and Lua support is compiled in, this will load an additional configuration file for newer features and more complicated setups. See :doc:`lua-config/index` for the options that can be set in this file. @@ -1111,21 +1310,25 @@ See :doc:`lua-config/index` for the options that can be set in this file. .. _setting-lua-dns-script: ``lua-dns-script`` ------------------- -- Path -- Default: unset +~~~~~~~~~~~~~~~~~~ + +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.lua_dns_script` Path to a lua file to manipulate the Recursor's answers. See :doc:`lua-scripting/index` for more information. -.. _setting-maintenance-interval: +.. _setting-lua-maintenance-interval: ``lua-maintenance-interval`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 - Integer - Default: 1 +- YAML setting: :ref:`setting-yaml-recursor.lua_maintenance_interval` The interval between calls to the Lua user defined `maintenance()` function in seconds. See :ref:`hooks-maintenance-callback` @@ -1133,11 +1336,13 @@ See :ref:`hooks-maintenance-callback` .. _setting-max-busy-dot-probes: ``max-busy-dot-probes`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.7.0 -- Integer -- Default: 0 +- Integer +- Default: 0 + +- YAML setting: :ref:`setting-yaml-outgoing.max_busy_dot_probes` Limit the maximum number of simultaneous DoT probes the Recursor will schedule. The default value 0 means no DoT probes are scheduled. @@ -1150,7 +1355,6 @@ If the maximum number of pending probes is reached, no probes will be scheduled, If the result of a probe is not yet available, the Recursor will contact the authoritative server in the regular way, unless an authoritative server is configured to be contacted over DoT always using :ref:`setting-dot-to-auth-names`. In that case no probe will be scheduled. - .. note:: DoT probing is an experimental feature. Please test thoroughly to determine if it is suitable in your specific production environment before enabling. @@ -1158,21 +1362,26 @@ In that case no probe will be scheduled. .. _setting-max-cache-bogus-ttl: ``max-cache-bogus-ttl`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 - Integer - Default: 3600 +- YAML setting: :ref:`setting-yaml-recordcache.max_cache_bogus_ttl` + Maximum number of seconds to cache an item in the DNS cache (negative or positive) if its DNSSEC validation failed, no matter what the original TTL specified, to reduce the impact of a broken domain. .. _setting-max-cache-entries: ``max-cache-entries`` ---------------------- +~~~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 1000000 +- YAML setting: :ref:`setting-yaml-recordcache.max_entries` + Maximum number of DNS record cache entries, shared by all threads since 4.4.0. Each entry associates a name and type with a record set. The size of the negative cache is 10% of this number. @@ -1180,28 +1389,31 @@ The size of the negative cache is 10% of this number. .. _setting-max-cache-ttl: ``max-cache-ttl`` ------------------ +~~~~~~~~~~~~~~~~~ +.. versionchanged:: 4.1.0 + + The minimum value of this setting is 15. i.e. setting this to lower than 15 will make this value 15. + - Integer - Default: 86400 +- YAML setting: :ref:`setting-yaml-recordcache.max_ttl` + Maximum number of seconds to cache an item in the DNS cache, no matter what the original TTL specified. This value also controls the refresh period of cached root data. See :ref:`handling-of-root-hints` for more information on this. -.. versionchanged:: 4.1.0 - - The minimum value of this setting is 15. i.e. setting this to lower than 15 will make this value 15. - .. _setting-max-concurrent-requests-per-tcp-connection: ``max-concurrent-requests-per-tcp-connection`` ----------------------------------------------- - +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.3.0 - Integer - Default: 10 +- YAML setting: :ref:`setting-yaml-incoming.max_concurrent_requests_per_tcp_connection` + Maximum number of incoming requests handled concurrently per tcp connection. This number must be larger than 0 and smaller than 65536 and also smaller than `max-mthreads`. @@ -1209,26 +1421,28 @@ and also smaller than `max-mthreads`. .. _setting-max-include-depth: ``max-include-depth`` ----------------------- - +~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 - Integer - Default: 20 +- YAML setting: :ref:`setting-yaml-recursor.max_include_depth` + Maximum number of nested ``$INCLUDE`` directives while processing a zone file. Zero mean no ``$INCLUDE`` directives will be accepted. .. _setting-max-generate-steps: ``max-generate-steps`` ----------------------- - +~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.3.0 - Integer - Default: 0 +- YAML setting: :ref:`setting-yaml-recursor.max_generate_steps` + Maximum number of steps for a '$GENERATE' directive when parsing a zone file. This is a protection measure to prevent consuming a lot of CPU and memory when untrusted zones are loaded. Default to 0 which @@ -1237,28 +1451,37 @@ means unlimited. .. _setting-max-mthreads: ``max-mthreads`` ----------------- +~~~~~~~~~~~~~~~~ + - Integer - Default: 2048 +- YAML setting: :ref:`setting-yaml-recursor.max_mthreads` + Maximum number of simultaneous MTasker threads. .. _setting-max-packetcache-entries: ``max-packetcache-entries`` ---------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 500000 +- YAML setting: :ref:`setting-yaml-packetcache.max_entries` + Maximum number of Packet Cache entries. Sharded and shared by all threads since 4.9.0. .. _setting-max-qperq: ``max-qperq`` -------------- +~~~~~~~~~~~~~ + - Integer - Default: 60 +- YAML setting: :ref:`setting-yaml-recursor.max_qperq` + The maximum number of outgoing queries that will be sent out during the resolution of a single client query. This is used to limit endlessly chasing CNAME redirections. If qname-minimization is enabled, the number will be forced to be 100 @@ -1267,7 +1490,7 @@ at a minimum to allow for the extra queries qname-minimization generates when th .. _setting-max-ns-address-qperq: ``max-ns-address-qperq`` ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.16 .. versionadded:: 4.2.2 .. versionadded:: 4.3.1 @@ -1275,19 +1498,21 @@ at a minimum to allow for the extra queries qname-minimization generates when th - Integer - Default: 10 +- YAML setting: :ref:`setting-yaml-recursor.max_ns_address_qperq` + The maximum number of outgoing queries with empty replies for resolving nameserver names to addresses we allow during the resolution of a single client query. If IPv6 is enabled, an A and a AAAA query for a name counts as 1. If a zone publishes more than this number of NS records, the limit is further reduced for that zone by lowering it by the number of NS records found above the -`max-ns-address-qperq`_ value. The limit wil not be reduced to a +:ref:`setting-max-ns-address-qperq` value. The limit wil not be reduced to a number lower than 5. .. _setting-max-ns-per-resolve: ``max-ns-per-resolve`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.8.0 .. versionadded:: 4.7.3 .. versionadded:: 4.6.4 @@ -1296,17 +1521,22 @@ number lower than 5. - Integer - Default: 13 +- YAML setting: :ref:`setting-yaml-recursor.max_ns_per_resolve` + The maximum number of NS records that will be considered to select a nameserver to contact to resolve a name. -If a zone has more than `max-ns-per-resolve`_ NS records, a random sample of this size will be used. -If `max-ns-per-resolve`_ is zero, no limit applies. +If a zone has more than :ref:`setting-max-ns-per-resolve` NS records, a random sample of this size will be used. +If :ref:`setting-max-ns-per-resolve` is zero, no limit applies. .. _setting-max-negative-ttl: ``max-negative-ttl`` --------------------- +~~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 3600 +- YAML setting: :ref:`setting-yaml-recordcache.max_negative_ttl` + A query for which there is authoritatively no answer is cached to quickly deny a record's existence later on, without putting a heavy load on the remote server. In practice, caches can become saturated with hundreds of thousands of hosts which are tried only once. This setting, which defaults to 3600 seconds, puts a maximum on the amount of time negative entries are cached. @@ -1314,71 +1544,87 @@ This setting, which defaults to 3600 seconds, puts a maximum on the amount of ti .. _setting-max-recursion-depth: ``max-recursion-depth`` ------------------------ -- Integer -- Default: 16 - -Total maximum number of internal recursion calls the server may use to answer a single query. -0 means unlimited. -The value of `stack-size`_ should be increased together with this one to prevent the stack from overflowing. -If `qname-minimization`_ is enabled, the fallback code in case of a failing resolve is allowed an additional `max-recursion-depth/2`. +~~~~~~~~~~~~~~~~~~~~~~~ +.. versionchanged:: 4.1.0 + Before 4.1.0, this settings was unlimited. +.. versionchanged:: 4.9.0 -.. versionchanged:: 4.1.0 + Before 4.9.0 this setting's default was 40 and the limit on ``CNAME`` chains (fixed at 16) acted as a bound on he recursion depth. - Before 4.1.0, this settings was unlimited. +- Integer +- Default: 16 -.. versionchanged:: 4.9.0 +- YAML setting: :ref:`setting-yaml-recursor.max_recursion_depth` - Before 4.9.0 this setting's default was 40 and the limit on ``CNAME`` chains (fixed at 16) acted as a bound on he recursion depth. +Total maximum number of internal recursion calls the server may use to answer a single query. +0 means unlimited. +The value of :ref:`setting-stack-size` should be increased together with this one to prevent the stack from overflowing. +If :ref:`setting-qname-minimization` is enabled, the fallback code in case of a failing resolve is allowed an additional `max-recursion-depth/2`. .. _setting-max-tcp-clients: ``max-tcp-clients`` -------------------- +~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 128 +- YAML setting: :ref:`setting-yaml-incoming.max_tcp_clients` + Maximum number of simultaneous incoming TCP connections allowed. .. _setting-max-tcp-per-client: ``max-tcp-per-client`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ + - Integer -- Default: 0 (unlimited) +- Default: 0 + +- YAML setting: :ref:`setting-yaml-incoming.max_tcp_per_client` Maximum number of simultaneous incoming TCP connections allowed per client (remote IP address). + 0 means unlimited. .. _setting-max-tcp-queries-per-connection: ``max-tcp-queries-per-connection`` ----------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 - Integer -- Default: 0 (unlimited) +- Default: 0 + +- YAML setting: :ref:`setting-yaml-incoming.max_tcp_queries_per_connection` Maximum number of DNS queries in a TCP connection. +0 means unlimited. .. _setting-max-total-msec: ``max-total-msec`` ------------------- +~~~~~~~~~~~~~~~~~~ + - Integer - Default: 7000 +- YAML setting: :ref:`setting-yaml-recursor.max_total_msec` + Total maximum number of milliseconds of wallclock time the server may use to answer a single query. +0 means unlimited. .. _setting-max-udp-queries-per-round: ``max-udp-queries-per-round`` ----------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.4 - Integer - Default: 10000 +- YAML setting: :ref:`setting-yaml-incoming.max_udp_queries_per_round` + Under heavy load the recursor might be busy processing incoming UDP queries for a long while before there is no more of these, and might therefore neglect scheduling new ``mthreads``, handling responses from authoritative servers or responding to :doc:`rec_control ` requests. @@ -1388,13 +1634,16 @@ returning back to normal processing and handling other events. .. _setting-minimum-ttl-override: ``minimum-ttl-override`` ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 4.5.0 + Old versions used default 0. - Integer - Default: 1 +- YAML setting: :ref:`setting-yaml-recursor.minimum_ttl_override` + This setting artificially raises all TTLs to be at least this long. Setting this to a value greater than 1 technically is an RFC violation, but might improve performance a lot. Using a value of 0 impacts performance of TTL 0 records greatly, since it forces the recursor to contact @@ -1404,11 +1653,13 @@ Can be set at runtime using ``rec_control set-minimum-ttl 3600``. .. _setting-new-domain-tracking: ``new-domain-tracking`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Boolean -- Default: no (disabled) +- Boolean +- Default: no + +- YAML setting: :ref:`setting-yaml-nod.tracking` Whether to track newly observed domains, i.e. never seen before. This is a probabilistic algorithm, using a stable bloom filter to store @@ -1423,29 +1674,33 @@ status will appear as a flag in Response messages. .. _setting-new-domain-log: ``new-domain-log`` ------------------- +~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Boolean -- Default: yes (enabled) +- Boolean +- Default: yes + +- YAML setting: :ref:`setting-yaml-nod.log` If a newly observed domain is detected, log that domain in the recursor log file. The log line looks something like:: - Jul 18 11:31:25 Newly observed domain nod=sdfoijdfio.com + Jul 18 11:31:25 Newly observed domain nod=sdfoijdfio.com .. _setting-new-domain-lookup: ``new-domain-lookup`` ---------------------- +~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Domain Name -- Example: nod.powerdns.com +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-nod.lookup` If a domain is specified, then each time a newly observed domain is -detected, the recursor will perform an A record lookup of ".". For example if 'new-domain-lookup' +detected, the recursor will perform an A record lookup of '.'. For example if 'new-domain-lookup' is configured as 'nod.powerdns.com', and a new domain 'xyz123.tv' is detected, then an A record lookup will be made for 'xyz123.tv.nod.powerdns.com'. This feature gives a way to share the @@ -1455,11 +1710,13 @@ result of the DNS lookup will be ignored by the recursor. .. _setting-new-domain-db-size: ``new-domain-db-size`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Integer -- Example: 67108864 +- Integer +- Default: 67108864 + +- YAML setting: :ref:`setting-yaml-nod.db_size` The default size of the stable bloom filter used to store previously observed domains is 67108864. To change the number of cells, use this @@ -1471,10 +1728,13 @@ have no effect unless you remove the existing files. .. _setting-new-domain-history-dir: ``new-domain-history-dir`` --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Path +- String +- Default: /usr/local/var/lib/pdns-recursor/nod + +- YAML setting: :ref:`setting-yaml-nod.history_dir` This setting controls which directory is used to store the on-disk cache of previously observed domains. @@ -1493,19 +1753,29 @@ from this directory. .. _setting-new-domain-whitelist: ``new-domain-whitelist`` ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 .. deprecated:: 4.5.0 + Use :ref:`setting-new-domain-ignore-list`. +- String +- Default: (empty) + +- YAML setting does not exist + + + .. _setting-new-domain-ignore-list: ``new-domain-ignore-list`` --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- List of Domain Names, comma separated -- Example: xyz.com, abc.com +- Comma separated list of strings +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-nod.ignore_list` This setting is a list of all domains (and implicitly all subdomains) that will never be considered a new domain. For example, if the domain @@ -1517,11 +1787,13 @@ feature. .. _setting-new-domain-pb-tag: ``new-domain-pb-tag`` ---------------------- +~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- String -- Default: pnds-nod +- String +- Default: pdns-nod + +- YAML setting: :ref:`setting-yaml-nod.pb_tag` If protobuf is configured, then this tag will be added to all protobuf response messages when a new domain is observed. @@ -1529,44 +1801,54 @@ a new domain is observed. .. _setting-network-timeout: ``network-timeout`` -------------------- +~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 1500 +- YAML setting: :ref:`setting-yaml-outgoing.network_timeout` + Number of milliseconds to wait for a remote authoritative server to respond. .. _setting-non-resolving-ns-max-fails: ``non-resolving-ns-max-fails`` ------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- Integer -- Default: 5 +- Integer +- Default: 5 + +- YAML setting: :ref:`setting-yaml-recursor.non_resolving_ns_max_fails` Number of failed address resolves of a nameserver name to start throttling it, 0 is disabled. Nameservers matching :ref:`setting-dont-throttle-names` will not be throttled. - .. _setting-non-resolving-ns-throttle-time: -``non-resolving-ns-max-throttle-time`` --------------------------------------- +``non-resolving-ns-throttle-time`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- Integer -- Default: 60 +- Integer +- Default: 60 + +- YAML setting: :ref:`setting-yaml-recursor.non_resolving_ns_throttle_time` Number of seconds to throttle a nameserver with a name failing to resolve. .. _setting-nothing-below-nxdomain: ``nothing-below-nxdomain`` --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.3.0 -- One of ``no``, ``dnssec``, ``yes``, String -- Default: ``dnssec`` +- String +- Default: dnssec + +- YAML setting: :ref:`setting-yaml-recursor.nothing_below_nxdomain` + +- One of ``no``, ``dnssec``, ``yes``. The type of :rfc:`8020` handling using cached NXDOMAIN responses. This RFC specifies that NXDOMAIN means that the DNS tree under the denied name MUST be empty. @@ -1590,200 +1872,210 @@ without consulting authoritative servers. .. _setting-nsec3-max-iterations: ``nsec3-max-iterations`` ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 +.. versionchanged:: 4.5.2 + + Default is now 150, was 2500 before. - Integer - Default: 150 +- YAML setting: :ref:`setting-yaml-dnssec.nsec3_max_iterations` + Maximum number of iterations allowed for an NSEC3 record. If an answer containing an NSEC3 record with more iterations is received, its DNSSEC validation status is treated as Insecure. -.. versionchanged:: 4.5.2 - - Default is now 150, was 2500 before. - .. _setting-packetcache-ttl: ``packetcache-ttl`` -------------------- +~~~~~~~~~~~~~~~~~~~ +.. versionchanged:: 4.9.0 + + The default was changed from 3600 (1 hour) to 86400 (24 hours). + - Integer - Default: 86400 -Maximum number of seconds to cache an item in the packet cache, no matter what the original TTL specified. +- YAML setting: :ref:`setting-yaml-packetcache.ttl` -.. versionchanged:: 4.9.0 - - The default was changed from 3600 (1 hour) to 86400 (24 hours). +Maximum number of seconds to cache an item in the packet cache, no matter what the original TTL specified. .. _setting-packetcache-negative-ttl: ``packetcache-negative-ttl`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.9.0 - Integer - Default: 60 +- YAML setting: :ref:`setting-yaml-packetcache.negative_ttl` + Maximum number of seconds to cache an ``NxDomain`` or ``NoData`` answer in the packetcache. -This setting's maximum is capped to `packetcache-ttl`_. +This setting's maximum is capped to :ref:`setting-packetcache-ttl`. i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-negative-ttl`` at the default will lower ``packetcache-negative-ttl`` to ``15``. .. _setting-packetcache-servfail-ttl: ``packetcache-servfail-ttl`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +'versionchanged': ('4.0.0', "This setting's maximum is capped to :ref:`setting-packetcache-ttl`. + i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-servfail-ttl`` at the default will lower ``packetcache-servfail-ttl`` to ``15``.") + - Integer - Default: 60 +- YAML setting: :ref:`setting-yaml-packetcache.servfail_ttl` + Maximum number of seconds to cache an answer indicating a failure to resolve in the packet cache. Before version 4.6.0 only ``ServFail`` answers were considered as such. Starting with 4.6.0, all responses with a code other than ``NoError`` and ``NXDomain``, or without records in the answer and authority sections, are considered as a failure to resolve. Since 4.9.0, negative answers are handled separately from resolving failures. -.. versionchanged:: 4.0.0 - - This setting's maximum is capped to `packetcache-ttl`_. - i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-servfail-ttl`` at the default will lower ``packetcache-servfail-ttl`` to ``15``. - - .. _setting-packetcache-shards: ``packetcache-shards`` ------------------------- +~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.9.0 - Integer - Default: 1024 +- YAML setting: :ref:`setting-yaml-packetcache.shards` + Sets the number of shards in the packet cache. If you have high contention as reported by ``packetcache-contented/packetcache-acquired``, you can try to enlarge this value or run with fewer threads. .. _setting-pdns-distributes-queries: ``pdns-distributes-queries`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.. versionchanged:: 4.9.0 + + Default changed to ``no``, previously it was ``yes``. + - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-incoming.pdns_distributes_queries` + If set, PowerDNS will use distinct threads to listen to client sockets and distribute that work to worker-threads using a hash of the query. This feature should maximize the cache hit ratio on versions before 4.9.0. -To use more than one thread set `distributor-threads`_ in version 4.2.0 or newer. -Enabling should improve performance on systems where `reuseport`_ does not have the effect of +To use more than one thread set :ref:`setting-distributor-threads` in version 4.2.0 or newer. +Enabling should improve performance on systems where :ref:`setting-reuseport` does not have the effect of balancing the queries evenly over multiple worker threads. -.. versionchanged:: 4.9.0 - - Default changed to ``no``, previously it was ``yes``. - .. _setting-protobuf-use-kernel-timestamp: ``protobuf-use-kernel-timestamp`` ---------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Boolean -- Default: false +- Boolean +- Default: no + +- YAML setting: :ref:`setting-yaml-logging.protobuf_use_kernel_timestamp` Whether to compute the latency of responses in protobuf messages using the timestamp set by the kernel when the query packet was received (when available), instead of computing it based on the moment we start processing the query. .. _setting-proxy-protocol-from: ``proxy-protocol-from`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.4.0 -- IP addresses or netmasks, separated by commas, negation supported -- Default: empty +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-incoming.proxy_protocol_from` Ranges that are required to send a Proxy Protocol version 2 header in front of UDP and TCP queries, to pass the original source and destination addresses and ports to the recursor, as well as custom values. Queries that are not prefixed with such a header will not be accepted from clients in these ranges. Queries prefixed by headers from clients that are not listed in these ranges will be dropped. -Note that once a Proxy Protocol header has been received, the source address from the proxy header instead of the address of the proxy will be checked against the `allow-from`_ ACL. +Note that once a Proxy Protocol header has been received, the source address from the proxy header instead of the address of the proxy will be checked against the :ref:`setting-allow-from` ACL. The dnsdist docs have `more information about the PROXY protocol `_. .. _setting-proxy-protocol-maximum-size: ``proxy-protocol-maximum-size`` -------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.4.0 - Integer - Default: 512 +- YAML setting: :ref:`setting-yaml-incoming.proxy_protocol_maximum_size` + The maximum size, in bytes, of a Proxy Protocol payload (header, addresses and ports, and TLV values). Queries with a larger payload will be dropped. .. _setting-public-suffix-list-file: ``public-suffix-list-file`` ---------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Path -- Default: unset +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.public_suffix_list_file` Path to the Public Suffix List file, if any. If set, PowerDNS will try to load the Public Suffix List from this file instead of using the built-in list. The PSL is used to group the queries by relevant domain names when displaying the top queries. .. _setting-qname-minimization: ``qname-minimization`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.3.0 - Boolean - Default: yes +- YAML setting: :ref:`setting-yaml-recursor.qname_minimization` + Enable Query Name Minimization. This implements a relaxed form of Query Name Mimimization as described in :rfc:`7816`. .. _setting-query-local-address: ``query-local-address`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 4.4.0 + IPv6 addresses can be set with this option as well. -- IP addresses, comma separated +- Comma separated list of IP addresses or subnets, negation supported - Default: 0.0.0.0 +- YAML setting: :ref:`setting-yaml-outgoing.source_address` + Send out local queries from this address, or addresses. By adding multiple addresses, increased spoofing resilience is achieved. When no address of a certain address family is configured, there are *no* queries sent with that address family. In the default configuration this means that IPv6 is not used for outgoing queries. -.. _setting-query-local-address6: - -``query-local-address6`` ------------------------- -.. deprecated:: 4.4.0 - Use :ref:`setting-query-local-address` for IPv4 and IPv6. - -.. deprecated:: 4.5.0 - Removed, use :ref:`setting-query-local-address`. - -- IPv6 addresses, comma separated -- Default: unset - -Send out local IPv6 queries from this address or addresses. -Disabled by default, which also disables outgoing IPv6 support. - .. _setting-quiet: ``quiet`` ---------- +~~~~~~~~~ + - Boolean - Default: yes +- YAML setting: :ref:`setting-yaml-logging.quiet` + Don't log queries. .. _setting-record-cache-locked-ttl-perc: ``record-cache-locked-ttl-perc`` --------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.8.0 -- Integer -- Default: 0 +- Integer +- Default: 0 + +- YAML setting: :ref:`setting-yaml-recordcache.locked_ttl_perc` Replace record sets in the record cache only after this percentage of the original TTL has passed. The PowerDNS Recursor already has several mechanisms to protect against spoofing attempts. @@ -1803,12 +2095,14 @@ There are a few cases where records will be replaced anyway: .. _setting-record-cache-shards: ``record-cache-shards`` ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.4.0 - Integer - Default: 1024 +- YAML setting: :ref:`setting-yaml-recordcache.shards` + Sets the number of shards in the record cache. If you have high contention as reported by ``record-cache-contented/record-cache-acquired``, you can try to @@ -1817,13 +2111,15 @@ enlarge this value or run with fewer threads. .. _setting-refresh-on-ttl-perc: ``refresh-on-ttl-perc`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 - Integer - Default: 0 -Sets the "refresh almost expired" percentage of the record cache. Whenever a record is fetched from the packet or record cache +- YAML setting: :ref:`setting-yaml-recordcache.refresh_on_ttl_perc` + +Sets the 'refresh almost expired' percentage of the record cache. Whenever a record is fetched from the packet or record cache and only ``refresh-on-ttl-perc`` percent or less of its original TTL is left, a task is queued to refetch the name/type combination to update the record cache. In most cases this causes future queries to always see a non-expired record cache entry. A typical value is 10. If the value is zero, this functionality is disabled. @@ -1831,23 +2127,29 @@ A typical value is 10. If the value is zero, this functionality is disabled. .. _setting-reuseport: ``reuseport`` -------------- +~~~~~~~~~~~~~ +.. versionchanged:: 4.9.0 + + The default is changed to ``yes``, previously it was ``no``. If ``SO_REUSEPORT`` support is not available, the setting defaults to ``no``. + - Boolean - Default: yes -If ``SO_REUSEPORT`` support is available, allows multiple threads and processes to open listening sockets for the same port. +- YAML setting: :ref:`setting-yaml-incoming.reuseport` -Since 4.1.0, when `pdns-distributes-queries`_ is disabled and `reuseport`_ is enabled, every worker-thread will open a separate listening socket to let the kernel distribute the incoming queries instead of running a distributor thread (which could otherwise be a bottleneck) and avoiding thundering herd issues, thus leading to much higher performance on multi-core boxes. - -.. versionchanged:: 4.9.0 +If ``SO_REUSEPORT`` support is available, allows multiple threads and processes to open listening sockets for the same port. - The default is changed to ``yes``, previously it was ``no``. - If ``SO_REUSEPORT`` support is not available, the setting defaults to ``no``. +Since 4.1.0, when :ref:`setting-pdns-distributes-queries` is disabled and :ref:`setting-reuseport` is enabled, every worker-thread will open a separate listening socket to let the kernel distribute the incoming queries instead of running a distributor thread (which could otherwise be a bottleneck) and avoiding thundering herd issues, thus leading to much higher performance on multi-core boxes. .. _setting-rng: ``rng`` -------- +~~~~~~~ + +- String +- Default: auto + +- YAML setting: :ref:`setting-yaml-recursor.rng` - String - Default: auto @@ -1861,31 +2163,32 @@ Specify which random number generator to use. Permissible choices are - urandom - Use ``/dev/urandom`` - kiss - Use simple settable deterministic RNG. **FOR TESTING PURPOSES ONLY!** -.. note:: - Not all choices are available on all systems. - .. _setting-root-nx-trust: ``root-nx-trust`` ------------------ +~~~~~~~~~~~~~~~~~ +.. versionchanged:: 4.0.0 + + Default is ``yes`` now, was ``no`` before 4.0.0 + - Boolean - Default: yes +- YAML setting: :ref:`setting-yaml-recursor.root_nx_trust` + If set, an NXDOMAIN from the root-servers will serve as a blanket NXDOMAIN for the entire TLD the query belonged to. The effect of this is far fewer queries to the root-servers. -.. versionchanged:: 4.0.0 - - Default is 'yes' now, was 'no' before 4.0.0 - .. _setting-save-parent-ns-set: ``save-parent-ns-set`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.7.0 -- Boolean -- Default: yes +- Boolean +- Default: yes + +- YAML setting: :ref:`setting-yaml-recursor.save_parent_ns_set` If set, a parent (non-authoritative) ``NS`` set is saved if it contains more entries than a newly encountered child (authoritative) ``NS`` set for the same domain. The saved parent ``NS`` set is tried if resolution using the child ``NS`` set fails. @@ -1893,31 +2196,39 @@ The saved parent ``NS`` set is tried if resolution using the child ``NS`` set fa .. _setting-security-poll-suffix: ``security-poll-suffix`` ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ + - String - Default: secpoll.powerdns.com. +- YAML setting: :ref:`setting-yaml-recursor.security_poll_suffix` + Domain name from which to query security update notifications. Setting this to an empty string disables secpoll. .. _setting-serve-rfc1918: ``serve-rfc1918`` ------------------ +~~~~~~~~~~~~~~~~~ + - Boolean - Default: yes +- YAML setting: :ref:`setting-yaml-recursor.serve_rfc1918` + This makes the server authoritatively aware of: ``10.in-addr.arpa``, ``168.192.in-addr.arpa``, ``16-31.172.in-addr.arpa``, which saves load on the AS112 servers. Individual parts of these zones can still be loaded or forwarded. .. _setting-serve-stale-extensions: ``serve-stale-extensions`` --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.8.0 -- Integer -- Default: 0 +- Integer +- Default: 0 + +- YAML setting: :ref:`setting-yaml-recursor.serve_stale_extensions` Maximum number of times an expired record's TTL is extended by 30s when serving stale. Extension only occurs if a record cannot be refreshed. @@ -1928,35 +2239,44 @@ See :ref:`serve-stale` for a description of the Serve Stale mechanism. .. _setting-server-down-max-fails: ``server-down-max-fails`` -------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 64 -If a server has not responded in any way this many times in a row, no longer send it any queries for `server-down-throttle-time`_ seconds. -Afterwards, we will try a new packet, and if that also gets no response at all, we again throttle for `server-down-throttle-time`_ seconds. +- YAML setting: :ref:`setting-yaml-recursor.server_down_max_fails` + +If a server has not responded in any way this many times in a row, no longer send it any queries for :ref:`setting-server-down-throttle-time` seconds. +Afterwards, we will try a new packet, and if that also gets no response at all, we again throttle for :ref:`setting-server-down-throttle-time` seconds. Even a single response packet will drop the block. .. _setting-server-down-throttle-time: ``server-down-throttle-time`` ------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 60 -Throttle a server that has failed to respond `server-down-max-fails`_ times for this many seconds. +- YAML setting: :ref:`setting-yaml-recursor.server_down_throttle_time` + +Throttle a server that has failed to respond :ref:`setting-server-down-max-fails` times for this many seconds. .. _setting-server-id: ``server-id`` -------------- +~~~~~~~~~~~~~ + - String -- Default: The hostname of the server +- Default: *runtime determined* + +- YAML setting: :ref:`setting-yaml-recursor.server_id` The reply given by The PowerDNS recursor to a query for 'id.server' with its hostname, useful for in clusters. When a query contains the :rfc:`NSID EDNS0 Option <5001>`, this value is returned in the response as the NSID value. This setting can be used to override the answer given to these queries. -Set to "disabled" to disable NSID and 'id.server' answers. +Set to 'disabled' to disable NSID and 'id.server' answers. Query example (where 192.0.2.14 is your server): @@ -1965,10 +2285,28 @@ Query example (where 192.0.2.14 is your server): dig @192.0.2.14 CHAOS TXT id.server. dig @192.0.2.14 example.com IN A +nsid -``setgid``, ``setuid`` ----------------------- +.. _setting-setgid: + +``setgid`` +~~~~~~~~~~ + +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.setgid` + +PowerDNS can change its user and group id after binding to its socket. +Can be used for better :doc:`security `. + +.. _setting-setuid: + +``setuid`` +~~~~~~~~~~ + - String -- Default: unset +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.setuid` PowerDNS can change its user and group id after binding to its socket. Can be used for better :doc:`security `. @@ -1976,135 +2314,208 @@ Can be used for better :doc:`security `. .. _setting-signature-inception-skew: ``signature-inception-skew`` ----------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.5 +.. versionchanged:: 4.2.0 + + Default is now 60, was 0 before. - Integer - Default: 60 -Allow the signature inception to be off by this number of seconds. Negative values are not allowed. - -.. versionchanged:: 4.2.0 +- YAML setting: :ref:`setting-yaml-dnssec.signature_inception_skew` - Default is now 60, was 0 before. +Allow the signature inception to be off by this number of seconds. Negative values are not allowed. .. _setting-single-socket: ``single-socket`` ------------------ +~~~~~~~~~~~~~~~~~ + - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-outgoing.single_socket` + Use only a single socket for outgoing queries. .. _setting-snmp-agent: ``snmp-agent`` --------------- +~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-snmp.agent` + If set to true and PowerDNS has been compiled with SNMP support, it will register as an SNMP agent to provide statistics and be able to send traps. .. _setting-snmp-master-socket: ``snmp-master-socket`` ----------------------- - +~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 .. deprecated:: 4.5.0 + Use :ref:`setting-snmp-daemon-socket`. +- String +- Default: (empty) + +- YAML setting does not exist + + + .. _setting-snmp-daemon-socket: ``snmp-daemon-socket`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 - String -- Default: empty +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-snmp.daemon_socket` If not empty and ``snmp-agent`` is set to true, indicates how PowerDNS should contact the SNMP daemon to register as an SNMP agent. .. _setting-socket-dir: ``socket-dir`` --------------- -- Path +~~~~~~~~~~~~~~ + +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.socket_dir` Where to store the control socket and pidfile. The default depends on ``LOCALSTATEDIR`` or the ``--with-socketdir`` setting when building (usually ``/var/run`` or ``/run``). -When using `chroot`_ the default becomes to ``/``. +When using :ref:`setting-chroot` the default becomes ``/``. + +.. _setting-socket-group: + +``socket-group`` +~~~~~~~~~~~~~~~~ -``socket-owner``, ``socket-group``, ``socket-mode`` ---------------------------------------------------- -Owner, group and mode of the controlsocket. +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.socket_group` + +Group and mode of the controlsocket. +Owner and group can be specified by name, mode is in octal. + +.. _setting-socket-mode: + +``socket-mode`` +~~~~~~~~~~~~~~~ + +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.socket_mode` + +Mode of the controlsocket. +Owner and group can be specified by name, mode is in octal. + +.. _setting-socket-owner: + +``socket-owner`` +~~~~~~~~~~~~~~~~ + +- String +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-recursor.socket_owner` + +Owner of the controlsocket. Owner and group can be specified by name, mode is in octal. .. _setting-spoof-nearmiss-max: ``spoof-nearmiss-max`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 4.5.0 + Older versions used 20 as the default value. - Integer - Default: 1 +- YAML setting: :ref:`setting-yaml-recursor.spoof_nearmiss_max` + If set to non-zero, PowerDNS will assume it is being spoofed after seeing this many answers with the wrong id. .. _setting-stack-cache-size: ``stack-cache-size`` --------------------- +~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.9.0 - Integer - Default: 100 +- YAML setting: :ref:`setting-yaml-recursor.stack_cache_size` + Maximum number of mthread stacks that can be cached for later reuse, per thread. Caching these stacks reduces the CPU load at the cost of a slightly higher memory usage, each cached stack consuming `stack-size` bytes of memory. It makes no sense to cache more stacks than the value of `max-mthreads`, since there will never be more stacks than that in use at a given time. .. _setting-stack-size: ``stack-size`` --------------- +~~~~~~~~~~~~~~ + - Integer - Default: 200000 +- YAML setting: :ref:`setting-yaml-recursor.stack_size` + Size in bytes of the stack of each mthread. .. _setting-statistics-interval: ``statistics-interval`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 - Integer - Default: 1800 +- YAML setting: :ref:`setting-yaml-logging.statistics_interval` + Interval between logging statistical summary on recursor performance. Use 0 to disable. .. _setting-stats-api-blacklist: ``stats-api-blacklist`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 .. deprecated:: 4.5.0 + Use :ref:`setting-stats-api-disabled-list`. +- Comma separated list of strings +- Default: + +- YAML setting does not exist + + + .. _setting-stats-api-disabled-list: ``stats-api-disabled-list`` ---------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- String -- Default: "cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-*, ecs-v6-response-bits-*" +- Comma separated list of strings +- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\* + +- YAML setting: :ref:`setting-yaml-recursor.stats_api_disabled_list` A list of comma-separated statistic names, that are disabled when retrieving the complete list of statistics via the API for performance reasons. These statistics can still be retrieved individually by specifically asking for it. @@ -2112,38 +2523,58 @@ These statistics can still be retrieved individually by specifically asking for .. _setting-stats-carbon-blacklist: ``stats-carbon-blacklist`` --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 .. deprecated:: 4.5.0 + Use :ref:`setting-stats-carbon-disabled-list`. +- Comma separated list of strings +- Default: + +- YAML setting does not exist + + + .. _setting-stats-carbon-disabled-list: ``stats-carbon-disabled-list`` ------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- String -- Default: "cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\*" +- Comma separated list of strings +- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\* + +- YAML setting: :ref:`setting-yaml-recursor.stats_carbon_disabled_list` A list of comma-separated statistic names, that are prevented from being exported via carbon for performance reasons. .. _setting-stats-rec-control-blacklist: ``stats-rec-control-blacklist`` -------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 .. deprecated:: 4.5.0 + Use :ref:`setting-stats-rec-control-disabled-list`. +- Comma separated list of strings +- Default: + +- YAML setting does not exist + + + .. _setting-stats-rec-control-disabled-list: ``stats-rec-control-disabled-list`` ------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- String -- Default: "cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\*" +- Comma separated list of strings +- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\* + +- YAML setting: :ref:`setting-yaml-recursor.stats_rec_control_disabled_list` A list of comma-separated statistic names, that are disabled when retrieving the complete list of statistics via `rec_control get-all`, for performance reasons. These statistics can still be retrieved individually. @@ -2151,51 +2582,68 @@ These statistics can still be retrieved individually. .. _setting-stats-ringbuffer-entries: ``stats-ringbuffer-entries`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + - Integer - Default: 10000 +- YAML setting: :ref:`setting-yaml-recursor.stats_ringbuffer_entries` + Number of entries in the remotes ringbuffer, which keeps statistics on who is querying your server. Can be read out using ``rec_control top-remotes``. .. _setting-stats-snmp-blacklist: ``stats-snmp-blacklist`` ------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 .. deprecated:: 4.5.0 + Use :ref:`setting-stats-snmp-disabled-list`. +- Comma separated list of strings +- Default: + +- YAML setting does not exist + + + .. _setting-stats-snmp-disabled-list: ``stats-snmp-disabled-list`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- String -- Default: "cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-*, ecs-v6-response-bits-*" +- Comma separated list of strings +- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\* + +- YAML setting: :ref:`setting-yaml-recursor.stats_snmp_disabled_list` A list of comma-separated statistic names, that are prevented from being exported via SNMP, for performance reasons. .. _setting-structured-logging: ``structured-logging`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 -- Boolean -- Default: yes +- Boolean +- Default: yes + +- YAML setting: :ref:`setting-yaml-logging.structured_logging` Prefer structured logging when both an old style and a structured log messages is available. .. _setting-structured-logging-backend: ``structured-logging-backend`` ------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.8.0 -- String -- Default: "default" +- String +- Default: default + +- YAML setting: :ref:`setting-yaml-logging.structured_logging_backend` The backend used for structured logging output. This setting must be set on the command line (``--structured-logging-backend=...``) to be effective. @@ -2208,11 +2656,13 @@ Available backends are: .. _setting-tcp-fast-open: ``tcp-fast-open`` ------------------ +~~~~~~~~~~~~~~~~~ .. versionadded:: 4.1.0 - Integer -- Default: 0 (Disabled) +- Default: 0 + +- YAML setting: :ref:`setting-yaml-incoming.tcp_fast_open` Enable TCP Fast Open support, if available, on the listening sockets. The numerical value supplied is used as the queue size, 0 meaning disabled. See :ref:`tcp-fast-open-support`. @@ -2220,75 +2670,91 @@ The numerical value supplied is used as the queue size, 0 meaning disabled. See .. _setting-tcp-fast-open-connect: ``tcp-fast-open-connect`` -------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 - Boolean -- Default: no (disabled) +- Default: no + +- YAML setting: :ref:`setting-yaml-outgoing.tcp_fast_open_connect` Enable TCP Fast Open Connect support, if available, on the outgoing connections to authoritative servers. See :ref:`tcp-fast-open-support`. .. _setting-tcp-out-max-idle-ms: ``tcp-out-max-idle-ms`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 - Integer -- Default : 10000 +- Default: 10000 + +- YAML setting: :ref:`setting-yaml-outgoing.tcp_max_idle_ms` Time outgoing TCP/DoT connections are left idle in milliseconds or 0 if no limit. After having been idle for this time, the connection is eligible for closing. .. _setting-tcp-out-max-idle-per-auth: ``tcp-out-max-idle-per-auth`` ------------------------------ +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 - Integer -- Default : 10 +- Default: 10 + +- YAML setting: :ref:`setting-yaml-outgoing.tcp_max_idle_per_auth` Maximum number of idle outgoing TCP/DoT connections to a specific IP per thread, 0 means do not keep idle connections open. .. _setting-tcp-out-max-queries: ``tcp-out-max-queries`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ + - Integer -- Default : 0 +- Default: 0 + +- YAML setting: :ref:`setting-yaml-outgoing.tcp_max_queries` Maximum total number of queries per outgoing TCP/DoT connection, 0 means no limit. After this number of queries, the connection is closed and a new one will be created if needed. -.. versionadded:: 4.6.0 - .. _setting-tcp-out-max-idle-per-thread: ``tcp-out-max-idle-per-thread`` -------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 - Integer -- Default : 100 +- Default: 100 + +- YAML setting: :ref:`setting-yaml-outgoing.tcp_max_idle_per_thread` Maximum number of idle outgoing TCP/DoT connections per thread, 0 means do not keep idle connections open. .. _setting-threads: ``threads`` ------------ +~~~~~~~~~~~ + - Integer - Default: 2 +- YAML setting: :ref:`setting-yaml-recursor.threads` + Spawn this number of threads on startup. .. _setting-trace: ``trace`` ---------- -- String, one of ``no``, ``yes`` or ``fail`` -- Default: ``no`` +~~~~~~~~~ + +- String +- Default: no + +- YAML setting: :ref:`setting-yaml-logging.trace` +One of ``no``, ``yes`` or ``fail``. If turned on, output impressive heaps of logging. May destroy performance under load. To log only queries resulting in a ``ServFail`` answer from the resolving process, this value can be set to ``fail``, but note that the performance impact is still large. @@ -2297,55 +2763,64 @@ Also note that queries that do produce a result but with a failing DNSSEC valida .. _setting-udp-source-port-min: ``udp-source-port-min`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 - Integer - Default: 1024 +- YAML setting: :ref:`setting-yaml-outgoing.udp_source_port_min` + This option sets the low limit of UDP port number to bind on. -In combination with `udp-source-port-max`_ it configures the UDP +In combination with :ref:`setting-udp-source-port-max` it configures the UDP port range to use. Port numbers are randomized within this range on -initialization, and exceptions can be configured with `udp-source-port-avoid`_ +initialization, and exceptions can be configured with :ref:`setting-udp-source-port-avoid` .. _setting-udp-source-port-max: ``udp-source-port-max`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 - Integer - Default: 65535 +- YAML setting: :ref:`setting-yaml-outgoing.udp_source_port_max` + This option sets the maximum limit of UDP port number to bind on. -See `udp-source-port-min`_. +See :ref:`setting-udp-source-port-min`. .. _setting-udp-source-port-avoid: ``udp-source-port-avoid`` -------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- String +- Comma separated list of strings - Default: 11211 +- YAML setting: :ref:`setting-yaml-outgoing.udp_source_port_avoid` + A list of comma-separated UDP port numbers to avoid when binding. Ex: `5300,11211` -See `udp-source-port-min`_. +See :ref:`setting-udp-source-port-min`. .. _setting-udp-truncation-threshold: ``udp-truncation-threshold`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 4.2.0 - Before 4.2.0, the default was 1680 + + Before 4.2.0, the default was 1680. - Integer - Default: 1232 +- YAML setting: :ref:`setting-yaml-incoming.udp_truncation_threshold` + EDNS0 allows for large UDP response datagrams, which can potentially raise performance. Large responses however also have downsides in terms of reflection attacks. This setting limits the accepted size. @@ -2356,11 +2831,13 @@ To know why 1232, see the note at :ref:`setting-edns-outgoing-bufsize`. .. _setting-unique-response-tracking: ``unique-response-tracking`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Boolean -- Default: no (disabled) +- Boolean +- Default: no + +- YAML setting: :ref:`setting-yaml-nod.unique_response_tracking` Whether to track unique DNS responses, i.e. never seen before combinations of the triplet (query name, query type, RR[rrname, rrtype, rrdata]). @@ -2377,11 +2854,13 @@ in the SBF using the unique-response-db-size setting can reduce FPs and FNs. .. _setting-unique-response-log: ``unique-response-log`` ------------------------ +~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Boolean -- Default: no (disabled) +- Boolean +- Default: yes + +- YAML setting: :ref:`setting-yaml-nod.unique_response_log` Whether to log when a unique response is detected. The log line looks something like: @@ -2391,11 +2870,13 @@ Oct 24 12:11:27 Unique response observed: qname=foo.com qtype=A rrtype=AAAA rrna .. _setting-unique-response-db-size: ``unique-response-db-size`` ---------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Integer -- Example: 67108864 +- Integer +- Default: 67108864 + +- YAML setting: :ref:`setting-yaml-nod.unique_response_db_size` The default size of the stable bloom filter used to store previously observed responses is 67108864. To change the number of cells, use this @@ -2407,10 +2888,13 @@ have no effect unless you remove the existing files. .. _setting-unique-response-history-dir: ``unique-response-history-dir`` -------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- Path +- String +- Default: /usr/local/var/lib/pdns-recursor/udr + +- YAML setting: :ref:`setting-yaml-nod.unique_response_history_dir` This setting controls which directory is used to store the on-disk cache of previously observed responses. @@ -2428,11 +2912,13 @@ unique-response-db-size, you must remove any files from this directory. .. _setting-unique-response-pb-tag: ``unique-response-pb-tag`` --------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- String -- Default: pnds-udr +- String +- Default: pdns-udr + +- YAML setting: :ref:`setting-yaml-nod.unique_response_pb_tag` If protobuf is configured, then this tag will be added to all protobuf response messages when a unique DNS response is observed. @@ -2440,25 +2926,25 @@ a unique DNS response is observed. .. _setting-use-incoming-edns-subnet: ``use-incoming-edns-subnet`` ----------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + - Boolean - Default: no -Whether to process and pass along a received EDNS Client Subnet to authoritative servers. -The ECS information will only be sent for netmasks and domains listed in `edns-subnet-allow-list`_ and will be truncated if the received scope exceeds `ecs-ipv4-bits`_ for IPv4 or `ecs-ipv6-bits`_ for IPv6. - -.. _setting-version: +- YAML setting: :ref:`setting-yaml-incoming.use_incoming_edns_subnet` -``version`` ------------ -Print version of this binary. Useful for checking which version of the PowerDNS recursor is installed on a system. +Whether to process and pass along a received EDNS Client Subnet to authoritative servers. +The ECS information will only be sent for netmasks and domains listed in :ref:`setting-edns-subnet-allow-list` and will be truncated if the received scope exceeds :ref:`setting-ecs-ipv4-bits` for IPv4 or :ref:`setting-ecs-ipv6-bits` for IPv6. .. _setting-version-string: ``version-string`` ------------------- +~~~~~~~~~~~~~~~~~~ + - String -- Default: PowerDNS Recursor version number +- Default: *runtime determined* + +- YAML setting: :ref:`setting-yaml-recursor.version_string` By default, PowerDNS replies to the 'version.bind' query with its version number. Security conscious users may wish to override the reply PowerDNS issues. @@ -2466,31 +2952,39 @@ Security conscious users may wish to override the reply PowerDNS issues. .. _setting-webserver: ``webserver`` -------------- +~~~~~~~~~~~~~ + - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-webservice.webserver` + Start the webserver (for REST API). .. _setting-webserver-address: ``webserver-address`` ---------------------- -- IP Address +~~~~~~~~~~~~~~~~~~~~~ + +- String - Default: 127.0.0.1 +- YAML setting: :ref:`setting-yaml-webservice.address` + IP address for the webserver to listen on. .. _setting-webserver-allow-from: ``webserver-allow-from`` ------------------------- -- IP addresses or netmasks, comma separated, negation supported -- Default: 127.0.0.1,::1 - +~~~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 4.1.0 - Default is now 127.0.0.1,::1, was 0.0.0.0/0,::/0 before. + Default is now 127.0.0.1,::1, was 0.0.0.0/0,::/0 before. + +- Comma separated list of IP addresses or subnets, negation supported +- Default: 127.0.0.1, ::1 + +- YAML setting: :ref:`setting-yaml-webservice.allow_from` These IPs and subnets are allowed to access the webserver. Note that specifying an IP address without a netmask uses an implicit netmask @@ -2499,30 +2993,35 @@ of /32 or /128. .. _setting-webserver-hash-plaintext-credentials: ``webserver-hash-plaintext-credentials`` ----------------------------------------- +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.6.0 - Boolean - Default: no +- YAML setting: :ref:`setting-yaml-webservice.hash_plaintext_credentials` + Whether passwords and API keys supplied in the configuration as plaintext should be hashed during startup, to prevent the plaintext versions from staying in memory. Doing so increases significantly the cost of verifying credentials and is thus disabled by default. Note that this option only applies to credentials stored in the configuration as plaintext, but hashed credentials are supported without enabling this option. .. _setting-webserver-loglevel: ``webserver-loglevel`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.2.0 -- String, one of "none", "normal", "detailed" +- String - Default: normal -The amount of logging the webserver must do. "none" means no useful webserver information will be logged. -When set to "normal", the webserver will log a line per request that should be familiar:: +- YAML setting: :ref:`setting-yaml-webservice.loglevel` + +One of ``one``, ``normal``, ``detailed``. +The amount of logging the webserver must do. 'none' means no useful webserver information will be logged. +When set to 'normal', the webserver will log a line per request that should be familiar:: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 "GET /api/v1/servers/localhost/bla HTTP/1.1" 404 196 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 'GET /api/v1/servers/localhost/bla HTTP/1.1' 404 196 -When set to "detailed", all information about the request and response are logged:: +When set to 'detailed', all information about the request and response are logged:: [webserver] e235780e-a5cf-415e-9326-9d33383e739e Request Details: [webserver] e235780e-a5cf-415e-9326-9d33383e739e Headers: @@ -2543,7 +3042,7 @@ When set to "detailed", all information about the request and response are logge [webserver] e235780e-a5cf-415e-9326-9d33383e739e Server: PowerDNS/0.0.15896.0.gaba8bab3ab [webserver] e235780e-a5cf-415e-9326-9d33383e739e Full body: [webserver] e235780e-a5cf-415e-9326-9d33383e739e Not Found

        Not Found

        - [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 "GET /api/v1/servers/localhost/bla HTTP/1.1" 404 196 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 'GET /api/v1/servers/localhost/bla HTTP/1.1' 404 196 The value between the hooks is a UUID that is generated for each request. This can be used to find all lines related to a single request. @@ -2553,86 +3052,55 @@ The value between the hooks is a UUID that is generated for each request. This c .. _setting-webserver-password: ``webserver-password`` ----------------------- +~~~~~~~~~~~~~~~~~~~~~~ .. versionchanged:: 4.6.0 + This setting now accepts a hashed and salted version. - String -- Default: unset +- Default: (empty) + +- YAML setting: :ref:`setting-yaml-webservice.password` Password required to access the webserver. Since 4.6.0 the password can be hashed and salted using ``rec_control hash-password`` instead of being present in the configuration in plaintext, but the plaintext version is still supported. .. _setting-webserver-port: ``webserver-port`` ------------------- +~~~~~~~~~~~~~~~~~~ + - Integer - Default: 8082 +- YAML setting: :ref:`setting-yaml-webservice.port` + TCP port where the webserver should listen on. .. _setting-write-pid: ``write-pid`` -------------- +~~~~~~~~~~~~~ + - Boolean - Default: yes -If a PID file should be written to `socket-dir`_ - -.. _setting-xpf-allow-from: - -``xpf-allow-from`` ------------------- -.. versionadded:: 4.2.0 -.. deprecated:: 4.7.0 - -.. versionchanged:: 4.8.0 - This setting was removed. - -- IP addresses or netmasks, separated by commas -- Default: empty - -.. note:: - This is an experimental implementation of `draft-bellis-dnsop-xpf `_. - This deprecated feature was removed in version 4.8.0. - -The server will trust XPF records found in queries sent from those netmasks (both IPv4 and IPv6), -and will adjust queries' source and destination accordingly. This is especially useful when the recursor -is placed behind a proxy like `dnsdist `_. -Note that the :ref:`setting-allow-from` setting is still applied to the original source address, and thus access restriction -should be done on the proxy. - -.. _setting-xpf-rr-code: +- YAML setting: :ref:`setting-yaml-recursor.write_pid` -``xpf-rr-code`` ---------------- -.. versionadded:: 4.2.0 -.. deprecated:: 4.7.0 - -.. versionchanged:: 4.8.0 - This setting was removed. - -- Integer -- Default: 0 - -.. note:: - This is an experimental implementation of `draft-bellis-dnsop-xpf `_. - This deprecated feature was removed in version 4.8.0. - -This option sets the resource record code to use for XPF records, as long as an official code has not been assigned to it. -0 means that XPF is disabled. +If a PID file should be written to :ref:`setting-socket-dir` .. _setting-x-dnssec-names: ``x-dnssec-names`` ------------------- +~~~~~~~~~~~~~~~~~~ .. versionadded:: 4.5.0 -- Comma separated list of domain-names +- Comma separated list of strings - Default: (empty) +- YAML setting: :ref:`setting-yaml-dnssec.x_dnssec_names` + List of names whose DNSSEC validation metrics will be counted in a separate set of metrics that start with ``x-dnssec-result-``. The names are suffix-matched. This can be used to not count known failing (test) name validations in the ordinary DNSSEC metrics. + diff --git a/pdns/recursordist/docs/upgrade.rst b/pdns/recursordist/docs/upgrade.rst index 8d3f19be7f01..f1c43ed50f6a 100644 --- a/pdns/recursordist/docs/upgrade.rst +++ b/pdns/recursordist/docs/upgrade.rst @@ -246,7 +246,7 @@ Deprecated and changed settings Removed settings ^^^^^^^^^^^^^^^^ -- The :ref:`setting-query-local-address6` has been removed. It already was deprecated. +- The ``query-local-address6`` setting has been removed. It already was deprecated. 4.3.x to 4.4.0 -------------- @@ -272,7 +272,7 @@ inconsistent results. Deprecated and changed settings ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - The :ref:`setting-query-local-address` setting has been modified to be able to include both IPv4 and IPv6 addresses. -- The :ref:`setting-query-local-address6` settings is now deprecated. +- The ``query-local-address6`` setting is now deprecated. New settings ^^^^^^^^^^^^ @@ -324,8 +324,8 @@ New settings Two new settings have been added: -- :ref:`setting-xpf-allow-from` can contain a list of IP addresses ranges from which `XPF (X-Proxied-For) `_ records will be trusted. -- :ref:`setting-xpf-rr-code` should list the number of the XPF record to use (in lieu of an assigned code). +- ``xpf-allow-from`` can contain a list of IP addresses ranges from which `XPF (X-Proxied-For) `_ records will be trusted. +- ``setting-xpf-rr-code`` should list the number of the XPF record to use (in lieu of an assigned code). 4.0.x to 4.1.0 -------------- diff --git a/pdns/recursordist/docs/yamlsettings.rst b/pdns/recursordist/docs/yamlsettings.rst new file mode 100644 index 000000000000..c81f1dc87837 --- /dev/null +++ b/pdns/recursordist/docs/yamlsettings.rst @@ -0,0 +1,3177 @@ +.. THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir + START INCLUDE docs-new-preamble-in.rst + +PowerDNS Recursor New Style (YAML) Settings +=========================================== + +Each setting can appear on the command line, prefixed by ``--`` and using the old style name, or in configuration files. +Settings on the command line are processed after the file-based settings are processed. + +.. note:: + Starting with version 5.0.0., :program:`Recursor` supports a new YAML syntax for configuration files + as described here. + A configuration using the old style syntax can be converted to a YAML configuration using the instructions in :doc:`appendices/yamlconversion`. + In a future release support for the "old-style" settings will be dropped. + + +YAML settings file +------------------ +Please refer to e.g. ``_ +for a description of YAML syntax. + +A :program:`Recursor` configuration file has several sections. For example, ``incoming`` for +settings related to receiving queries and ``dnssec`` for settings related to DNSSEC processing. + +An example :program:`Recursor` YAML configuration file looks like: + +.. code-block:: yaml + + dnssec: + log_bogus: true + incoming: + listen: + - 0.0.0.0:5301 + - '[::]:5301' + recursor: + extended_resolution_errors: true + forward_zones: + - zone: example.com + forwarders: + - 127.0.0.1:5301 + outgoing: + query_local_address: + - 0.0.0.0 + - '::' + logging: + loglevel: 6 + +Take care when listing IPv6 addresses, as characters used for these are special to YAML. +If in doubt, quote any string containing ``:``, ``[`` or ``]`` and use (online) tools to check your YAML syntax. +Specify an empty sequence using ``[]``. + +The main setting file is called ``recursor.yml`` and will be processed first. +This settings file might refer to other files via the `recursor.include_dir`_ setting. +The next section will describe how settings specified in multiple files are merged. + +Merging multiple setting files +------------------------------ +If `recursor.include_dir`_ is set, all ``.yml`` files in it will be processed in alphabetical order, modifying the settings processed so far. + +For simple values like an boolean or number setting, a value in the processed file will overwrite an existing setting. + +For values of type sequence, the new value will *replace* the existing value if the existing value is equal to the ``default`` or if the new value is marked with the ``!override`` tag. +Otherwise, the existing value will be *extended* with the new value by appending the new sequence to the existing. + +For example, with the above example ``recursor.yml`` and an include directory containing a file ``extra.yml``: + +.. code-block:: yaml + + dnssec: + log_bogus: false + recursor: + forward_zones: + - zone: example.net + forwarders: + - '::1' + outgoing: + query_local_address: !override + - 0.0.0.0 + dont_query: [] + +After merging, ``dnssec.log_bogus`` will be ``false``, the sequence of ``recursor.forward_zones`` will contain 2 zones and the ``outgoing`` addresses used will contain one entry, as the ``extra.yml`` entry has overwritten the existing one. + +``outgoing.dont-query`` has a non-empty sequence as default value. The main ``recursor.yml`` did not set it, so before processing ``extra.yml`` had the default value. +After processing ``extra.yml`` the value will be set to the empty sequence, as existing default values are overwritten by new values. + +.. warning:: + The merging process does not process values deeper than the second level. + For example if the main ``recursor.yml`` specified a forward zone + + .. code-block:: yaml + + forward_zones: + - zone: example.net + forwarders: + - '::1' + + and another settings file contains + + .. code-block:: yaml + + forward_zones: + - zone: example.net + forwarders: + - '::2' + + The result will *not* be a a single forward with two IP addresses, but two entries for ``example.net``. + It depends on the specific setting how the sequence is processed further. + In the future we might add a check for this case. + +Socket Address +^^^^^^^^^^^^^^ +A socket address is either an IP or and IP:port combination +For example: + +.. code-block:: yaml + + some_key: 127.0.0.1 + another_key: '[::1]:8080' + +Subnet +^^^^^^ +A subnet is a single IP address or an IP address followed by a slash and a prefix length. +If no prefix length is specified, ``/32`` or ``/128`` is assumed, indicating a single IP address. +Subnets can also be prefixed with a ``!``, specifying negation. +This can be used to deny addresses from a previously allowed range. + +For example, ``alow-from`` takes a sequence of subnets: + +.. code-block:: yaml + + allow_from: + - '2001:DB8::/32' + - 128.66.0.0/16 + - !128.66.1.2 + +In this case the address ``128.66.1.2`` is excluded from the addresses allowed access. + +Forward Zone +^^^^^^^^^^^^ +A forward zone is defined as: + +.. code-block:: yaml + + zone: zonename + forwarders: + - Socket Address + - ... + recurse: Boolean, default false + allow_notify: Boolean, default false + +An example of a ``forward_zones`` entry, which consists of a sequence of forward zone entries: + +.. code-block:: yaml + + - zone: example1.com + forwarders: + - 127.0.0.1 + - 127.0.0.1:5353 + - '[::1]53' + - zone: example2.com + forwarders: + - '::1' + recurse: true + notify_allowed: true + + +Auth Zone +^^^^^^^^^ +A auth zone is defined as: + +.. code-block:: yaml + + zone: name + file: filename + +An example of a ``auth_zones`` entry, consisting of a sequence of auth zones: + +.. code-block:: yaml + + auth_zones: + - zone: example.com + file: zones/example.com.zone + - zone: example.net + file: zones/example.net.zone + +The YAML settings +----------------- + +.. END INCLUDE docs-new-preamble-in.rst + +.. _setting-yaml-carbon.instance: + +``carbon.instance`` +^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- String +- Default: ``recursor`` + +- Old style setting: :ref:`setting-carbon-instance` + +Change the instance or third string of the metric key. The default is recursor. + +.. _setting-yaml-carbon.interval: + +``carbon.interval`` +^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``30`` + +- Old style setting: :ref:`setting-carbon-interval` + +If sending carbon updates, this is the interval between them in seconds. +See :doc:`metrics`. + +.. _setting-yaml-carbon.ns: + +``carbon.ns`` +^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- String +- Default: ``pdns`` + +- Old style setting: :ref:`setting-carbon-namespace` + +Change the namespace or first string of the metric key. The default is pdns. + +.. _setting-yaml-carbon.ourname: + +``carbon.ourname`` +^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-carbon-ourname` + +If sending carbon updates, if set, this will override our hostname. +Be careful not to include any dots in this setting, unless you know what you are doing. +See :ref:`metricscarbon`. + +.. _setting-yaml-carbon.server: + +``carbon.server`` +^^^^^^^^^^^^^^^^^ + +- Sequence of `Socket Address`_ (IP or IP:port combinations) +- Default: ``[]`` + +- Old style setting: :ref:`setting-carbon-server` + +Will send all available metrics to these servers via the carbon protocol, which is used by graphite and metronome. +See :doc:`metrics`. + +.. _setting-yaml-dnssec.aggressive_cache_min_nsec3_hit_ratio: + +``dnssec.aggressive_cache_min_nsec3_hit_ratio`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.9.0 + +- Integer +- Default: ``2000`` + +- Old style setting: :ref:`setting-aggressive-cache-min-nsec3-hit-ratio` + +The limit for which to put NSEC3 records into the aggressive cache. +A value of ``n`` means that an NSEC3 record is only put into the aggressive cache if the estimated probability of a random name hitting the NSEC3 record is higher than ``1/n``. +A higher ``n`` will cause more records to be put into the aggressive cache, e.g. a value of 4000 will cause records to be put in the aggressive cache even if the estimated probability of hitting them is twice as low as would be the case for ``n=2000``. +A value of 0 means no NSEC3 records will be put into the aggressive cache. + +For large zones the effectiveness of the NSEC3 cache is reduced since each NSEC3 record only covers a randomly distributed subset of all possible names. +This setting avoids doing unnecessary work for such large zones. + +.. _setting-yaml-dnssec.aggressive_nsec_cache_size: + +``dnssec.aggressive_nsec_cache_size`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Integer +- Default: ``100000`` + +- Old style setting: :ref:`setting-aggressive-nsec-cache-size` + +The number of records to cache in the aggressive cache. If set to a value greater than 0, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in :rfc:`8198`. +To use this, DNSSEC processing or validation must be enabled by setting :ref:`setting-yaml-dnssec.validation` to ``process``, ``log-fail`` or ``validate``. + +.. _setting-yaml-dnssec.disabled_algorithms: + +``dnssec.disabled_algorithms`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.9.0 + +- Sequence of strings +- Default: ``[]`` + +- Old style setting: :ref:`setting-dnssec-disabled-algorithms` + +A list of DNSSEC algorithm numbers that should be considered disabled. +These algorithms will not be used to validate DNSSEC signatures. +Zones (only) signed with these algorithms will be considered ``Insecure``. + +If this setting is empty (the default), :program:`Recursor` will determine which algorithms to disable automatically. +This is done for specific algorithms only, currently algorithms 5 (``RSASHA1``) and 7 (``RSASHA1NSEC3SHA1``). + +This is important on systems that have a default strict crypto policy, like RHEL9 derived systems. +On such systems not disabling some algorithms (or changing the security policy) will make affected zones to be considered ``Bogus`` as using these algorithms fails. + +.. _setting-yaml-dnssec.log_bogus: + +``dnssec.log_bogus`` +^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-dnssec-log-bogus` + +Log every DNSSEC validation failure. +**Note**: This is not logged per-query but every time records are validated as Bogus. + +.. _setting-yaml-dnssec.nsec3_max_iterations: + +``dnssec.nsec3_max_iterations`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.0 +.. versionchanged:: 4.5.2 + + Default is now 150, was 2500 before. + +- Integer +- Default: ``150`` + +- Old style setting: :ref:`setting-nsec3-max-iterations` + +Maximum number of iterations allowed for an NSEC3 record. +If an answer containing an NSEC3 record with more iterations is received, its DNSSEC validation status is treated as Insecure. + +.. _setting-yaml-dnssec.signature_inception_skew: + +``dnssec.signature_inception_skew`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.5 +.. versionchanged:: 4.2.0 + + Default is now 60, was 0 before. + +- Integer +- Default: ``60`` + +- Old style setting: :ref:`setting-signature-inception-skew` + +Allow the signature inception to be off by this number of seconds. Negative values are not allowed. + +.. _setting-yaml-dnssec.validation: + +``dnssec.validation`` +^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.0.0 +.. versionchanged:: 4.5.0 + + The default changed from ``process-no-validate`` to ``process`` + +- String +- Default: ``process`` + +- Old style setting: :ref:`setting-dnssec` + +One of ``off``, ``process-no-validate``, ``process``, ``log-fail``, ``validate`` + +Set the mode for DNSSEC processing, as detailed in :doc:`dnssec`. + +``off`` + No DNSSEC processing whatsoever. + Ignore DO-bits in queries, don't request any DNSSEC information from authoritative servers. + This behaviour is similar to PowerDNS Recursor pre-4.0. +``process-no-validate`` + Respond with DNSSEC records to clients that ask for it, set the DO bit on all outgoing queries. + Don't do any validation. +``process`` + Respond with DNSSEC records to clients that ask for it, set the DO bit on all outgoing queries. + Do validation for clients that request it (by means of the AD- bit or DO-bit in the query). +``log-fail`` + Similar behaviour to ``process``, but validate RRSIGs on responses and log bogus responses. +``validate`` + Full blown DNSSEC validation. Send SERVFAIL to clients on bogus responses. + +.. _setting-yaml-dnssec.x_dnssec_names: + +``dnssec.x_dnssec_names`` +^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Sequence of strings +- Default: ``[]`` + +- Old style setting: :ref:`setting-x-dnssec-names` + +List of names whose DNSSEC validation metrics will be counted in a separate set of metrics that start +with ``x-dnssec-result-``. +The names are suffix-matched. +This can be used to not count known failing (test) name validations in the ordinary DNSSEC metrics. + +.. _setting-yaml-ecs.add_for: + +``ecs.add_for`` +^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) +- Default: ``[0.0.0.0/0, ::/0, !127.0.0.0/8, !10.0.0.0/8, !100.64.0.0/10, !169.254.0.0/16, !192.168.0.0/16, !172.16.0.0/12, !::1/128, !fc00::/7, !fe80::/10]`` + +- Old style setting: :ref:`setting-ecs-add-for` + +List of requestor netmasks for which the requestor IP Address should be used as the :rfc:`EDNS Client Subnet <7871>` for outgoing queries. Outgoing queries for requestors that do not match this list will use the :ref:`setting-yaml-ecs.scope_zero_address` instead. +Valid incoming ECS values from :ref:`setting-yaml-incoming.use_incoming_edns_subnet` are not replaced. + +Regardless of the value of this setting, ECS values are only sent for outgoing queries matching the conditions in the :ref:`setting-yaml-outgoing.edns_subnet_allow_list` setting. This setting only controls the actual value being sent. + +This defaults to not using the requestor address inside RFC1918 and similar 'private' IP address spaces. + +.. _setting-yaml-ecs.cache_limit_ttl: + +``ecs.cache_limit_ttl`` +^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.12 + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-ecs-cache-limit-ttl` + +The minimum TTL for an ECS-specific answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-ipv4-cache-bits`` or ``ecs-ipv6-cache-bits``. +That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. + +.. _setting-yaml-ecs.ipv4_bits: + +``ecs.ipv4_bits`` +^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.0 + +- Integer +- Default: ``24`` + +- Old style setting: :ref:`setting-ecs-ipv4-bits` + +Number of bits of client IPv4 address to pass when sending EDNS Client Subnet address information. + +.. _setting-yaml-ecs.ipv4_cache_bits: + +``ecs.ipv4_cache_bits`` +^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.12 + +- Integer +- Default: ``24`` + +- Old style setting: :ref:`setting-ecs-ipv4-cache-bits` + +Maximum number of bits of client IPv4 address used by the authoritative server (as indicated by the EDNS Client Subnet scope in the answer) for an answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-cache-limit-ttl``. +That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. + +.. _setting-yaml-ecs.ipv4_never_cache: + +``ecs.ipv4_never_cache`` +^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-ecs-ipv4-never-cache` + +When set, never cache replies carrying EDNS IPv4 Client Subnet scope in the record cache. +In this case the decision made by ```ecs-ipv4-cache-bits`` and ``ecs-cache-limit-ttl`` is no longer relevant. + +.. _setting-yaml-ecs.ipv6_bits: + +``ecs.ipv6_bits`` +^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.0 + +- Integer +- Default: ``56`` + +- Old style setting: :ref:`setting-ecs-ipv6-bits` + +Number of bits of client IPv6 address to pass when sending EDNS Client Subnet address information. + +.. _setting-yaml-ecs.ipv6_cache_bits: + +``ecs.ipv6_cache_bits`` +^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.12 + +- Integer +- Default: ``56`` + +- Old style setting: :ref:`setting-ecs-ipv6-cache-bits` + +Maximum number of bits of client IPv6 address used by the authoritative server (as indicated by the EDNS Client Subnet scope in the answer) for an answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-cache-limit-ttl``. +That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. + +.. _setting-yaml-ecs.ipv6_never_cache: + +``ecs.ipv6_never_cache`` +^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-ecs-ipv6-never-cache` + +When set, never cache replies carrying EDNS IPv6 Client Subnet scope in the record cache. +In this case the decision made by ```ecs-ipv6-cache-bits`` and ``ecs-cache-limit-ttl`` is no longer relevant. + +.. _setting-yaml-ecs.minimum_ttl_override: + +``ecs.minimum_ttl_override`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.5.0 + + Old versions used default 0. + +- Integer +- Default: ``1`` + +- Old style setting: :ref:`setting-ecs-minimum-ttl-override` + +This setting artificially raises the TTLs of records in the ANSWER section of ECS-specific answers to be at least this long. +Setting this to a value greater than 1 technically is an RFC violation, but might improve performance a lot. +Using a value of 0 impacts performance of TTL 0 records greatly, since it forces the recursor to contact +authoritative servers every time a client requests them. +Can be set at runtime using ``rec_control set-ecs-minimum-ttl 3600``. + +.. _setting-yaml-ecs.scope_zero_address: + +``ecs.scope_zero_address`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.0 + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-ecs-scope-zero-address` + +The IP address sent via EDNS Client Subnet to authoritative servers listed in +:ref:`setting-yaml-outgoing.edns_subnet_allow_list` when :ref:`setting-yaml-incoming.use_incoming_edns_subnet` is set and the query has +an ECS source prefix-length set to 0. +The default is to look for the first usable (not an ``any`` one) address in +:ref:`setting-yaml-outgoing.source_address` (starting with IPv4). If no suitable address is +found, the recursor fallbacks to sending 127.0.0.1. + +.. _setting-yaml-incoming.allow_from: + +``incoming.allow_from`` +^^^^^^^^^^^^^^^^^^^^^^^ + +- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) +- Default: ``[127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10]`` + +- Old style setting: :ref:`setting-allow-from` + +Netmasks (both IPv4 and IPv6) that are allowed to use the server. +The default allows access only from :rfc:`1918` private IP addresses. +An empty value means no checking is done, all clients are allowed. +Due to the aggressive nature of the internet these days, it is highly recommended to not open up the recursor for the entire internet. +Questions from IP addresses not listed here are ignored and do not get an answer. + +When the Proxy Protocol is enabled (see :ref:`setting-yaml-incoming.proxy_protocol_from`), the recursor will check the address of the client IP advertised in the Proxy Protocol header instead of the one of the proxy. + +Note that specifying an IP address without a netmask uses an implicit netmask of /32 or /128. + +.. _setting-yaml-incoming.allow_from_file: + +``incoming.allow_from_file`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-allow-from-file` + +Like :ref:`setting-yaml-incoming.allow_from`, except reading a sequence of `Subnet`_ from file. +Overrides the :ref:`setting-yaml-incoming.allow_from` setting. Example content of th specified file: + +.. code-block:: yaml + + - 127.0.01 + - ::1 + +.. _setting-yaml-incoming.allow_notify_for: + +``incoming.allow_notify_for`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Sequence of strings +- Default: ``[]`` + +- Old style setting: :ref:`setting-allow-notify-for` + +Domain names specified in this list are used to permit incoming +NOTIFY operations to wipe any cache entries that match the domain +name. If this list is empty, all NOTIFY operations will be ignored. + +.. _setting-yaml-incoming.allow_notify_for_file: + +``incoming.allow_notify_for_file`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-allow-notify-for-file` + +Like :ref:`setting-yaml-incoming.allow_notify_for`, except reading a sequence of names from file. Example contents of specified file: + +.. code-block:: yaml + + - example.com + - example.org + +.. _setting-yaml-incoming.allow_notify_from: + +``incoming.allow_notify_from`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) +- Default: ``[]`` + +- Old style setting: :ref:`setting-allow-notify-from` + +Subnets (both IPv4 and IPv6) that are allowed to issue NOTIFY operations +to the server. NOTIFY operations from IP addresses not listed here are +ignored and do not get an answer. + +When the Proxy Protocol is enabled (see :ref:`setting-yaml-incoming.proxy_protocol_from`), the +recursor will check the address of the client IP advertised in the +Proxy Protocol header instead of the one of the proxy. + +Note that specifying an IP address without a netmask uses an implicit +netmask of /32 or /128. + +NOTIFY operations received from a client listed in one of these netmasks +will be accepted and used to wipe any cache entries whose zones match +the zone specified in the NOTIFY operation, but only if that zone (or +one of its parents) is included in :ref:`setting-yaml-incoming.allow_notify_for`, +:ref:`setting-yaml-incoming.allow_notify_for_file`, or :ref:`setting-yaml-recursor.forward_zones_file` with a ``allow_notify`` set to ``true``. + +.. _setting-yaml-incoming.allow_notify_from_file: + +``incoming.allow_notify_from_file`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-allow-notify-from-file` + +Like :ref:`setting-yaml-incoming.allow_notify_from`, except reading a sequence of `Subnet`_ from file. + +.. _setting-yaml-incoming.distribution_load_factor: + +``incoming.distribution_load_factor`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.12 + +- Double +- Default: ``0.0`` + +- Old style setting: :ref:`setting-distribution-load-factor` + +If :ref:`setting-yaml-incoming.pdns_distributes_queries` is set and this setting is set to another value +than 0, the distributor thread will use a bounded load-balancing algorithm while +distributing queries to worker threads, making sure that no thread is assigned +more queries than distribution-load-factor times the average number of queries +currently processed by all the workers. +For example, with a value of 1.25, no server should get more than 125 % of the +average load. This helps making sure that all the workers have roughly the same +share of queries, even if the incoming traffic is very skewed, with a larger +number of requests asking for the same qname. + +.. _setting-yaml-incoming.distribution_pipe_buffer_size: + +``incoming.distribution_pipe_buffer_size`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-distribution-pipe-buffer-size` + +Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread. +Requires support for `F_SETPIPE_SZ` which is present in Linux since 2.6.35. The actual size might be rounded up to +a multiple of a page size. 0 means that the OS default size is used. +A large buffer might allow the recursor to deal with very short-lived load spikes during which a worker thread gets +overloaded, but it will be at the cost of an increased latency. + +.. _setting-yaml-incoming.distributor_threads: + +``incoming.distributor_threads`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Integer +- Default: 1 if :ref:`setting-pdns-distributes-queries` is set, 0 otherwise + +- Old style setting: :ref:`setting-distributor-threads` + +If :ref:`setting-yaml-incoming.pdns_distributes_queries` is set, spawn this number of distributor threads on startup. Distributor threads +handle incoming queries and distribute them to other threads based on a hash of the query. + +.. _setting-yaml-incoming.edns_padding_from: + +``incoming.edns_padding_from`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-edns-padding-from` + +List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that :ref:`setting-yaml-incoming.edns_padding_mode` applies. + +.. _setting-yaml-incoming.edns_padding_mode: + +``incoming.edns_padding_mode`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- String +- Default: ``padded-queries-only`` + +- Old style setting: :ref:`setting-edns-padding-mode` + +One of ``always``, ``padded-queries-only``. +Whether to add EDNS padding to all responses (``always``) or only to responses for queries containing the EDNS padding option (``padded-queries-only``, the default). +In both modes, padding will only be added to responses for queries coming from :ref:`setting-yaml-incoming.edns_padding_from` sources. + +.. _setting-yaml-incoming.edns_padding_tag: + +``incoming.edns_padding_tag`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Integer +- Default: ``7830`` + +- Old style setting: :ref:`setting-edns-padding-tag` + +The packetcache tag to use for padded responses, to prevent a client not allowed by the :ref::`setting-edns-padding-from` list to be served a cached answer generated for an allowed one. This +effectively divides the packet cache in two when :ref:`setting-yaml-incoming.edns_padding_from` is used. Note that this will not override a tag set from one of the ``Lua`` hooks. + +.. _setting-yaml-incoming.gettag_needs_edns_options: + +``incoming.gettag_needs_edns_options`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-gettag-needs-edns-options` + +If set, EDNS options in incoming queries are extracted and passed to the :func:`gettag` hook in the ``ednsoptions`` table. + +.. _setting-yaml-incoming.listen: + +``incoming.listen`` +^^^^^^^^^^^^^^^^^^^ + +- Sequence of `Socket Address`_ (IP or IP:port combinations) +- Default: ``[127.0.0.1]`` + +- Old style setting: :ref:`setting-local-address` + +Local IP addresses to which we bind. Each address specified can +include a port number; if no port is included then the +:ref:`setting-yaml-incoming.port` port will be used for that address. If a +port number is specified, it must be separated from the address with a +':'; for an IPv6 address the address must be enclosed in square +brackets. + +Examples:: + + local-address=127.0.0.1 ::1 + local-address=0.0.0.0:5353 + local-address=[::]:8053 + local-address=127.0.0.1:53, [::1]:5353 + +.. _setting-yaml-incoming.max_concurrent_requests_per_tcp_connection: + +``incoming.max_concurrent_requests_per_tcp_connection`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.3.0 + +- Integer +- Default: ``10`` + +- Old style setting: :ref:`setting-max-concurrent-requests-per-tcp-connection` + +Maximum number of incoming requests handled concurrently per tcp +connection. This number must be larger than 0 and smaller than 65536 +and also smaller than `max-mthreads`. + +.. _setting-yaml-incoming.max_tcp_clients: + +``incoming.max_tcp_clients`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``128`` + +- Old style setting: :ref:`setting-max-tcp-clients` + +Maximum number of simultaneous incoming TCP connections allowed. + +.. _setting-yaml-incoming.max_tcp_per_client: + +``incoming.max_tcp_per_client`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-max-tcp-per-client` + +Maximum number of simultaneous incoming TCP connections allowed per client (remote IP address). + 0 means unlimited. + +.. _setting-yaml-incoming.max_tcp_queries_per_connection: + +``incoming.max_tcp_queries_per_connection`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.0 + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-max-tcp-queries-per-connection` + +Maximum number of DNS queries in a TCP connection. +0 means unlimited. + +.. _setting-yaml-incoming.max_udp_queries_per_round: + +``incoming.max_udp_queries_per_round`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.4 + +- Integer +- Default: ``10000`` + +- Old style setting: :ref:`setting-max-udp-queries-per-round` + +Under heavy load the recursor might be busy processing incoming UDP queries for a long while before there is no more of these, and might therefore +neglect scheduling new ``mthreads``, handling responses from authoritative servers or responding to :doc:`rec_control ` +requests. +This setting caps the maximum number of incoming UDP DNS queries processed in a single round of looping on ``recvmsg()`` after being woken up by the multiplexer, before +returning back to normal processing and handling other events. + +.. _setting-yaml-incoming.non_local_bind: + +``incoming.non_local_bind`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-non-local-bind` + +Bind to addresses even if one or more of the :ref:`setting-yaml-incoming.listen`'s do not exist on this server. +Setting this option will enable the needed socket options to allow binding to non-local addresses. +This feature is intended to facilitate ip-failover setups, but it may also mask configuration issues and for this reason it is disabled by default. + +.. _setting-yaml-incoming.pdns_distributes_queries: + +``incoming.pdns_distributes_queries`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.9.0 + + Default changed to ``no``, previously it was ``yes``. + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-pdns-distributes-queries` + +If set, PowerDNS will use distinct threads to listen to client sockets and distribute that work to worker-threads using a hash of the query. +This feature should maximize the cache hit ratio on versions before 4.9.0. +To use more than one thread set :ref:`setting-yaml-incoming.distributor_threads` in version 4.2.0 or newer. +Enabling should improve performance on systems where :ref:`setting-yaml-incoming.reuseport` does not have the effect of +balancing the queries evenly over multiple worker threads. + +.. _setting-yaml-incoming.port: + +``incoming.port`` +^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``53`` + +- Old style setting: :ref:`setting-local-port` + +Local port to bind to. +If an address in :ref:`setting-yaml-incoming.listen` does not have an explicit port, this port is used. + +.. _setting-yaml-incoming.proxy_protocol_from: + +``incoming.proxy_protocol_from`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.4.0 + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-proxy-protocol-from` + +Ranges that are required to send a Proxy Protocol version 2 header in front of UDP and TCP queries, to pass the original source and destination addresses and ports to the recursor, as well as custom values. +Queries that are not prefixed with such a header will not be accepted from clients in these ranges. Queries prefixed by headers from clients that are not listed in these ranges will be dropped. + +Note that once a Proxy Protocol header has been received, the source address from the proxy header instead of the address of the proxy will be checked against the :ref:`setting-yaml-incoming.allow_from` ACL. + +The dnsdist docs have `more information about the PROXY protocol `_. + +.. _setting-yaml-incoming.proxy_protocol_maximum_size: + +``incoming.proxy_protocol_maximum_size`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.4.0 + +- Integer +- Default: ``512`` + +- Old style setting: :ref:`setting-proxy-protocol-maximum-size` + +The maximum size, in bytes, of a Proxy Protocol payload (header, addresses and ports, and TLV values). Queries with a larger payload will be dropped. + +.. _setting-yaml-incoming.reuseport: + +``incoming.reuseport`` +^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.9.0 + + The default is changed to ``yes``, previously it was ``no``. If ``SO_REUSEPORT`` support is not available, the setting defaults to ``no``. + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-reuseport` + +If ``SO_REUSEPORT`` support is available, allows multiple threads and processes to open listening sockets for the same port. + +Since 4.1.0, when :ref:`setting-yaml-incoming.pdns_distributes_queries` is disabled and :ref:`setting-yaml-incoming.reuseport` is enabled, every worker-thread will open a separate listening socket to let the kernel distribute the incoming queries instead of running a distributor thread (which could otherwise be a bottleneck) and avoiding thundering herd issues, thus leading to much higher performance on multi-core boxes. + +.. _setting-yaml-incoming.tcp_fast_open: + +``incoming.tcp_fast_open`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.0 + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-tcp-fast-open` + +Enable TCP Fast Open support, if available, on the listening sockets. +The numerical value supplied is used as the queue size, 0 meaning disabled. See :ref:`tcp-fast-open-support`. + +.. _setting-yaml-incoming.tcp_timeout: + +``incoming.tcp_timeout`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``2`` + +- Old style setting: :ref:`setting-client-tcp-timeout` + +Time to wait for data from TCP clients. + +.. _setting-yaml-incoming.udp_truncation_threshold: + +``incoming.udp_truncation_threshold`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.2.0 + + Before 4.2.0, the default was 1680. + +- Integer +- Default: ``1232`` + +- Old style setting: :ref:`setting-udp-truncation-threshold` + +EDNS0 allows for large UDP response datagrams, which can potentially raise performance. +Large responses however also have downsides in terms of reflection attacks. +This setting limits the accepted size. +Maximum value is 65535, but values above 4096 should probably not be attempted. + +To know why 1232, see the note at :ref:`setting-yaml-outgoing.edns_bufsize`. + +.. _setting-yaml-incoming.use_incoming_edns_subnet: + +``incoming.use_incoming_edns_subnet`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-use-incoming-edns-subnet` + +Whether to process and pass along a received EDNS Client Subnet to authoritative servers. +The ECS information will only be sent for netmasks and domains listed in :ref:`setting-yaml-outgoing.edns_subnet_allow_list` and will be truncated if the received scope exceeds :ref:`setting-yaml-ecs.ipv4_bits` for IPv4 or :ref:`setting-yaml-ecs.ipv6_bits` for IPv6. + +.. _setting-yaml-logging.common_errors: + +``logging.common_errors`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-log-common-errors` + +Some DNS errors occur rather frequently and are no cause for alarm. + +.. _setting-yaml-logging.disable_syslog: + +``logging.disable_syslog`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-disable-syslog` + +Do not log to syslog, only to stdout. +Use this setting when running inside a supervisor that handles logging (like systemd). +**Note**: do not use this setting in combination with :ref:`setting-yaml-recursor.daemon` as all logging will disappear. + +.. _setting-yaml-logging.facility: + +``logging.facility`` +^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-logging-facility` + +If set to a digit, logging is performed under this LOCAL facility. +See :ref:`logging`. +Do not pass names like 'local0'! + +.. _setting-yaml-logging.loglevel: + +``logging.loglevel`` +^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``6`` + +- Old style setting: :ref:`setting-loglevel` + +Amount of logging. The higher the number, the more lines logged. +Corresponds to 'syslog' level values (e.g. 0 = emergency, 1 = alert, 2 = critical, 3 = error, 4 = warning, 5 = notice, 6 = info, 7 = debug). +Each level includes itself plus the lower levels before it. +Not recommended to set this below 3. + +.. _setting-yaml-logging.protobuf_use_kernel_timestamp: + +``logging.protobuf_use_kernel_timestamp`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-protobuf-use-kernel-timestamp` + +Whether to compute the latency of responses in protobuf messages using the timestamp set by the kernel when the query packet was received (when available), instead of computing it based on the moment we start processing the query. + +.. _setting-yaml-logging.quiet: + +``logging.quiet`` +^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``yes`` + +- Old style setting: :ref:`setting-quiet` + +Don't log queries. + +.. _setting-yaml-logging.rpz_changes: + +``logging.rpz_changes`` +^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-log-rpz-changes` + +Log additions and removals to RPZ zones at Info (6) level instead of Debug (7). + +.. _setting-yaml-logging.statistics_interval: + +``logging.statistics_interval`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.0 + +- Integer +- Default: ``1800`` + +- Old style setting: :ref:`setting-statistics-interval` + +Interval between logging statistical summary on recursor performance. +Use 0 to disable. + +.. _setting-yaml-logging.structured_logging: + +``logging.structured_logging`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-structured-logging` + +Prefer structured logging when both an old style and a structured log messages is available. + +.. _setting-yaml-logging.structured_logging_backend: + +``logging.structured_logging_backend`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.8.0 + +- String +- Default: ``default`` + +- Old style setting: :ref:`setting-structured-logging-backend` + +The backend used for structured logging output. +This setting must be set on the command line (``--structured-logging-backend=...``) to be effective. +Available backends are: + +- ``default``: use the traditional logging system to output structured logging information. +- ``systemd-journal``: use systemd-journal. + When using this backend, provide ``-o verbose`` or simular output option to ``journalctl`` to view the full information. + +.. _setting-yaml-logging.timestamp: + +``logging.timestamp`` +^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-log-timestamp` + + + +.. _setting-yaml-logging.trace: + +``logging.trace`` +^^^^^^^^^^^^^^^^^ + +- String +- Default: ``no`` + +- Old style setting: :ref:`setting-trace` + +One of ``no``, ``yes`` or ``fail``. +If turned on, output impressive heaps of logging. +May destroy performance under load. +To log only queries resulting in a ``ServFail`` answer from the resolving process, this value can be set to ``fail``, but note that the performance impact is still large. +Also note that queries that do produce a result but with a failing DNSSEC validation are not written to the log + +.. _setting-yaml-nod.db_size: + +``nod.db_size`` +^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Integer +- Default: ``67108864`` + +- Old style setting: :ref:`setting-new-domain-db-size` + +The default size of the stable bloom filter used to store previously +observed domains is 67108864. To change the number of cells, use this +setting. For each cell, the SBF uses 1 bit of memory, and one byte of +disk for the persistent file. +If there are already persistent files saved to disk, this setting will +have no effect unless you remove the existing files. + +.. _setting-yaml-nod.history_dir: + +``nod.history_dir`` +^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- String +- Default: ``/usr/local/var/lib/pdns-recursor/nod`` + +- Old style setting: :ref:`setting-new-domain-history-dir` + +This setting controls which directory is used to store the on-disk +cache of previously observed domains. + +The default depends on ``LOCALSTATEDIR`` when building the software. +Usually this comes down to ``/var/lib/pdns-recursor/nod`` or ``/usr/local/var/lib/pdns-recursor/nod``). + +The newly observed domain feature uses a stable bloom filter to store +a history of previously observed domains. The data structure is +synchronized to disk every 10 minutes, and is also initialized from +disk on startup. This ensures that previously observed domains are +preserved across recursor restarts. +If you change the new-domain-db-size setting, you must remove any files +from this directory. + +.. _setting-yaml-nod.ignore_list: + +``nod.ignore_list`` +^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Sequence of strings +- Default: ``[]`` + +- Old style setting: :ref:`setting-new-domain-ignore-list` + +This setting is a list of all domains (and implicitly all subdomains) +that will never be considered a new domain. For example, if the domain +'xyz123.tv' is in the list, then 'foo.bar.xyz123.tv' will never be +considered a new domain. One use-case for the ignore list is to never +reveal details of internal subdomains via the new-domain-lookup +feature. + +.. _setting-yaml-nod.log: + +``nod.log`` +^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-new-domain-log` + +If a newly observed domain is detected, log that domain in the +recursor log file. The log line looks something like:: + + Jul 18 11:31:25 Newly observed domain nod=sdfoijdfio.com + +.. _setting-yaml-nod.lookup: + +``nod.lookup`` +^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-new-domain-lookup` + +If a domain is specified, then each time a newly observed domain is +detected, the recursor will perform an A record lookup of '.'. For example if 'new-domain-lookup' +is configured as 'nod.powerdns.com', and a new domain 'xyz123.tv' is +detected, then an A record lookup will be made for +'xyz123.tv.nod.powerdns.com'. This feature gives a way to share the +newly observed domain with partners, vendors or security teams. The +result of the DNS lookup will be ignored by the recursor. + +.. _setting-yaml-nod.pb_tag: + +``nod.pb_tag`` +^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- String +- Default: ``pdns-nod`` + +- Old style setting: :ref:`setting-new-domain-pb-tag` + +If protobuf is configured, then this tag will be added to all protobuf response messages when +a new domain is observed. + +.. _setting-yaml-nod.tracking: + +``nod.tracking`` +^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-new-domain-tracking` + +Whether to track newly observed domains, i.e. never seen before. This +is a probabilistic algorithm, using a stable bloom filter to store +records of previously seen domains. When enabled for the first time, +all domains will appear to be newly observed, so the feature is best +left enabled for e.g. a week or longer before using the results. Note +that this feature is optional and must be enabled at compile-time, +thus it may not be available in all pre-built packages. +If protobuf is enabled and configured, then the newly observed domain +status will appear as a flag in Response messages. + +.. _setting-yaml-nod.unique_response_db_size: + +``nod.unique_response_db_size`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Integer +- Default: ``67108864`` + +- Old style setting: :ref:`setting-unique-response-db-size` + +The default size of the stable bloom filter used to store previously +observed responses is 67108864. To change the number of cells, use this +setting. For each cell, the SBF uses 1 bit of memory, and one byte of +disk for the persistent file. +If there are already persistent files saved to disk, this setting will +have no effect unless you remove the existing files. + +.. _setting-yaml-nod.unique_response_history_dir: + +``nod.unique_response_history_dir`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- String +- Default: ``/usr/local/var/lib/pdns-recursor/udr`` + +- Old style setting: :ref:`setting-unique-response-history-dir` + +This setting controls which directory is used to store the on-disk +cache of previously observed responses. + +The default depends on ``LOCALSTATEDIR`` when building the software. +Usually this comes down to ``/var/lib/pdns-recursor/udr`` or ``/usr/local/var/lib/pdns-recursor/udr``). + +The newly observed domain feature uses a stable bloom filter to store +a history of previously observed responses. The data structure is +synchronized to disk every 10 minutes, and is also initialized from +disk on startup. This ensures that previously observed responses are +preserved across recursor restarts. If you change the +unique-response-db-size, you must remove any files from this directory. + +.. _setting-yaml-nod.unique_response_log: + +``nod.unique_response_log`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-unique-response-log` + +Whether to log when a unique response is detected. The log line +looks something like: + +Oct 24 12:11:27 Unique response observed: qname=foo.com qtype=A rrtype=AAAA rrname=foo.com rrcontent=1.2.3.4 + +.. _setting-yaml-nod.unique_response_pb_tag: + +``nod.unique_response_pb_tag`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- String +- Default: ``pdns-udr`` + +- Old style setting: :ref:`setting-unique-response-pb-tag` + +If protobuf is configured, then this tag will be added to all protobuf response messages when +a unique DNS response is observed. + +.. _setting-yaml-nod.unique_response_tracking: + +``nod.unique_response_tracking`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-unique-response-tracking` + +Whether to track unique DNS responses, i.e. never seen before combinations +of the triplet (query name, query type, RR[rrname, rrtype, rrdata]). +This can be useful for tracking potentially suspicious domains and +behaviour, e.g. DNS fast-flux. +If protobuf is enabled and configured, then the Protobuf Response message +will contain a flag with udr set to true for each RR that is considered +unique, i.e. never seen before. +This feature uses a probabilistic data structure (stable bloom filter) to +track unique responses, which can have false positives as well as false +negatives, thus it is a best-effort feature. Increasing the number of cells +in the SBF using the unique-response-db-size setting can reduce FPs and FNs. + +.. _setting-yaml-outgoing.dont_query: + +``outgoing.dont_query`` +^^^^^^^^^^^^^^^^^^^^^^^ + +- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) +- Default: ``[127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10, 0.0.0.0/8, 192.0.0.0/24, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::/96, ::ffff:0:0/96, 100::/64, 2001:db8::/32]`` + +- Old style setting: :ref:`setting-dont-query` + +The DNS is a public database, but sometimes contains delegations to private IP addresses, like for example 127.0.0.1. +This can have odd effects, depending on your network, and may even be a security risk. +Therefore, the PowerDNS Recursor by default does not query private space IP addresses. +This setting can be used to expand or reduce the limitations. + +Queries for names in forward zones and to addresses as configured in any of the settings :ref:`setting-yaml-recursor.forward_zones`, :ref:`setting-yaml-recursor.forward_zones_file` or :ref:`setting-yaml-recursor.forward_zones_recurse` are performed regardless of these limitations. + +.. _setting-yaml-outgoing.dont_throttle_names: + +``outgoing.dont_throttle_names`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Sequence of strings +- Default: ``[]`` + +- Old style setting: :ref:`setting-dont-throttle-names` + +When an authoritative server does not answer a query or sends a reply the recursor does not like, it is throttled. +Any servers' name suffix-matching the supplied names will never be throttled. + +.. warning:: + Most servers on the internet do not respond for a good reason (overloaded or unreachable), ``dont-throttle-names`` could make this load on the upstream server even higher, resulting in further service degradation. + +.. _setting-yaml-outgoing.dont_throttle_netmasks: + +``outgoing.dont_throttle_netmasks`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) +- Default: ``[]`` + +- Old style setting: :ref:`setting-dont-throttle-netmasks` + +When an authoritative server does not answer a query or sends a reply the recursor does not like, it is throttled. +Any servers matching the supplied netmasks will never be throttled. + +This can come in handy on lossy networks when forwarding, where the same server is configured multiple times (e.g. with ``forward-zones-recurse=example.com=192.0.2.1;192.0.2.1``). +By default, the PowerDNS Recursor would throttle the 'first' server on a timeout and hence not retry the 'second' one. +In this case, ``dont-throttle-netmasks`` could be set to ``192.0.2.1``. + +.. warning:: + Most servers on the internet do not respond for a good reason (overloaded or unreachable), ``dont-throttle-netmasks`` could make this load on the upstream server even higher, resulting in further service degradation. + +.. _setting-yaml-outgoing.dot_to_auth_names: + +``outgoing.dot_to_auth_names`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Sequence of strings +- Default: ``[]`` + +- Old style setting: :ref:`setting-dot-to-auth-names` + +Force DoT to the listed authoritative nameservers. For this to work, DoT support has to be compiled in. +Currently, the certificate is not checked for validity in any way. + +.. _setting-yaml-outgoing.dot_to_port_853: + +``outgoing.dot_to_port_853`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-dot-to-port-853` + +Enable DoT to forwarders that specify port 853. + +.. _setting-yaml-outgoing.edns_bufsize: + +``outgoing.edns_bufsize`` +^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.2.0 + + Before 4.2.0, the default was 1680 + +- Integer +- Default: ``1232`` + +- Old style setting: :ref:`setting-edns-outgoing-bufsize` + +.. note:: Why 1232? + + 1232 is the largest number of payload bytes that can fit in the smallest IPv6 packet. + IPv6 has a minimum MTU of 1280 bytes (:rfc:`RFC 8200, section 5 <8200#section-5>`), minus 40 bytes for the IPv6 header, minus 8 bytes for the UDP header gives 1232, the maximum payload size for the DNS response. + +This is the value set for the EDNS0 buffer size in outgoing packets. +Lower this if you experience timeouts. + +.. _setting-yaml-outgoing.edns_padding: + +``outgoing.edns_padding`` +^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.8.0 + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-edns-padding-out` + +Whether to add EDNS padding to outgoing DoT queries. + +.. _setting-yaml-outgoing.edns_subnet_allow_list: + +``outgoing.edns_subnet_allow_list`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Sequence of strings +- Default: ``[]`` + +- Old style setting: :ref:`setting-edns-subnet-allow-list` + +List of netmasks and domains that :rfc:`EDNS Client Subnet <7871>` should be enabled for in outgoing queries. + +For example, an EDNS Client Subnet option containing the address of the initial requestor (but see :ref:`setting-yaml-ecs.add_for`) will be added to an outgoing query sent to server 192.0.2.1 for domain X if 192.0.2.1 matches one of the supplied netmasks, or if X matches one of the supplied domains. +The initial requestor address will be truncated to 24 bits for IPv4 (see :ref:`setting-yaml-ecs.ipv4_bits`) and to 56 bits for IPv6 (see :ref:`setting-yaml-ecs.ipv6_bits`), as recommended in the privacy section of RFC 7871. + + +Note that this setting describes the destination of outgoing queries, not the sources of incoming queries, nor the subnets described in the EDNS Client Subnet option. + +By default, this option is empty, meaning no EDNS Client Subnet information is sent. + +.. _setting-yaml-outgoing.lowercase: + +``outgoing.lowercase`` +^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-lowercase-outgoing` + +Set to true to lowercase the outgoing queries. +When set to 'no' (the default) a query from a client using mixed case in the DNS labels (such as a user entering mixed-case names or `draft-vixie-dnsext-dns0x20-00 `_), PowerDNS preserves the case of the query. +Broken authoritative servers might give a wrong or broken answer on this encoding. +Setting ``lowercase-outgoing`` to 'yes' makes the PowerDNS Recursor lowercase all the labels in the query to the authoritative servers, but still return the proper case to the client requesting. + +.. _setting-yaml-outgoing.max_busy_dot_probes: + +``outgoing.max_busy_dot_probes`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.7.0 + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-max-busy-dot-probes` + +Limit the maximum number of simultaneous DoT probes the Recursor will schedule. +The default value 0 means no DoT probes are scheduled. + +DoT probes are used to check if an authoritative server's IP address supports DoT. +If the probe determines an IP address supports DoT, the Recursor will use DoT to contact it for subsequent queries until a failure occurs. +After a failure, the Recursor will stop using DoT for that specific IP address for a while. +The results of probes are remembered and can be viewed by the ``rec_control dump-dot-probe-map`` command. +If the maximum number of pending probes is reached, no probes will be scheduled, even if no DoT status is known for an address. +If the result of a probe is not yet available, the Recursor will contact the authoritative server in the regular way, unless an authoritative server is configured to be contacted over DoT always using :ref:`setting-yaml-outgoing.dot_to_auth_names`. +In that case no probe will be scheduled. + +.. note:: + DoT probing is an experimental feature. + Please test thoroughly to determine if it is suitable in your specific production environment before enabling. + +.. _setting-yaml-outgoing.network_timeout: + +``outgoing.network_timeout`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``1500`` + +- Old style setting: :ref:`setting-network-timeout` + +Number of milliseconds to wait for a remote authoritative server to respond. + +.. _setting-yaml-outgoing.single_socket: + +``outgoing.single_socket`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-single-socket` + +Use only a single socket for outgoing queries. + +.. _setting-yaml-outgoing.source_address: + +``outgoing.source_address`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.4.0 + + IPv6 addresses can be set with this option as well. + +- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) +- Default: ``[0.0.0.0]`` + +- Old style setting: :ref:`setting-query-local-address` + +Send out local queries from this address, or addresses. By adding multiple +addresses, increased spoofing resilience is achieved. When no address of a certain +address family is configured, there are *no* queries sent with that address family. +In the default configuration this means that IPv6 is not used for outgoing queries. + +.. _setting-yaml-outgoing.tcp_fast_open_connect: + +``outgoing.tcp_fast_open_connect`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-tcp-fast-open-connect` + +Enable TCP Fast Open Connect support, if available, on the outgoing connections to authoritative servers. See :ref:`tcp-fast-open-support`. + +.. _setting-yaml-outgoing.tcp_max_idle_ms: + +``outgoing.tcp_max_idle_ms`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Integer +- Default: ``10000`` + +- Old style setting: :ref:`setting-tcp-out-max-idle-ms` + +Time outgoing TCP/DoT connections are left idle in milliseconds or 0 if no limit. After having been idle for this time, the connection is eligible for closing. + +.. _setting-yaml-outgoing.tcp_max_idle_per_auth: + +``outgoing.tcp_max_idle_per_auth`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Integer +- Default: ``10`` + +- Old style setting: :ref:`setting-tcp-out-max-idle-per-auth` + +Maximum number of idle outgoing TCP/DoT connections to a specific IP per thread, 0 means do not keep idle connections open. + +.. _setting-yaml-outgoing.tcp_max_idle_per_thread: + +``outgoing.tcp_max_idle_per_thread`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Integer +- Default: ``100`` + +- Old style setting: :ref:`setting-tcp-out-max-idle-per-thread` + +Maximum number of idle outgoing TCP/DoT connections per thread, 0 means do not keep idle connections open. + +.. _setting-yaml-outgoing.tcp_max_queries: + +``outgoing.tcp_max_queries`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-tcp-out-max-queries` + +Maximum total number of queries per outgoing TCP/DoT connection, 0 means no limit. After this number of queries, the connection is +closed and a new one will be created if needed. + +.. _setting-yaml-outgoing.udp_source_port_avoid: + +``outgoing.udp_source_port_avoid`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Sequence of strings +- Default: ``[11211]`` + +- Old style setting: :ref:`setting-udp-source-port-avoid` + +A sequence of UDP port numbers to avoid when binding. For example: + +.. code-block:: yaml + + outgoing: + udp_source_port_avoid: + - 5300 + - 11211 + +See :ref:`setting-yaml-outgoing.udp_source_port_min`. + +.. _setting-yaml-outgoing.udp_source_port_max: + +``outgoing.udp_source_port_max`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Integer +- Default: ``65535`` + +- Old style setting: :ref:`setting-udp-source-port-max` + +This option sets the maximum limit of UDP port number to bind on. + +See :ref:`setting-yaml-outgoing.udp_source_port_min`. + +.. _setting-yaml-outgoing.udp_source_port_min: + +``outgoing.udp_source_port_min`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Integer +- Default: ``1024`` + +- Old style setting: :ref:`setting-udp-source-port-min` + +This option sets the low limit of UDP port number to bind on. + +In combination with :ref:`setting-yaml-outgoing.udp_source_port_max` it configures the UDP +port range to use. Port numbers are randomized within this range on +initialization, and exceptions can be configured with :ref:`setting-yaml-outgoing.udp_source_port_avoid` + +.. _setting-yaml-packetcache.disable: + +``packetcache.disable`` +^^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-disable-packetcache` + +Turn off the packet cache. Useful when running with Lua scripts that can not be cached, though individual query caching can be controlled from Lua as well. + +.. _setting-yaml-packetcache.max_entries: + +``packetcache.max_entries`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``500000`` + +- Old style setting: :ref:`setting-max-packetcache-entries` + +Maximum number of Packet Cache entries. Sharded and shared by all threads since 4.9.0. + +.. _setting-yaml-packetcache.negative_ttl: + +``packetcache.negative_ttl`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.9.0 + +- Integer +- Default: ``60`` + +- Old style setting: :ref:`setting-packetcache-negative-ttl` + +Maximum number of seconds to cache an ``NxDomain`` or ``NoData`` answer in the packetcache. +This setting's maximum is capped to :ref:`setting-yaml-packetcache.ttl`. +i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-negative-ttl`` at the default will lower ``packetcache-negative-ttl`` to ``15``. + +.. _setting-yaml-packetcache.servfail_ttl: + +``packetcache.servfail_ttl`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +'versionchanged': ('4.0.0', "This setting's maximum is capped to :ref:`setting-yaml-packetcache.ttl`. + i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-servfail-ttl`` at the default will lower ``packetcache-servfail-ttl`` to ``15``.") + +- Integer +- Default: ``60`` + +- Old style setting: :ref:`setting-packetcache-servfail-ttl` + +Maximum number of seconds to cache an answer indicating a failure to resolve in the packet cache. +Before version 4.6.0 only ``ServFail`` answers were considered as such. Starting with 4.6.0, all responses with a code other than ``NoError`` and ``NXDomain``, or without records in the answer and authority sections, are considered as a failure to resolve. +Since 4.9.0, negative answers are handled separately from resolving failures. + +.. _setting-yaml-packetcache.shards: + +``packetcache.shards`` +^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.9.0 + +- Integer +- Default: ``1024`` + +- Old style setting: :ref:`setting-packetcache-shards` + +Sets the number of shards in the packet cache. If you have high contention as reported by ``packetcache-contented/packetcache-acquired``, +you can try to enlarge this value or run with fewer threads. + +.. _setting-yaml-packetcache.ttl: + +``packetcache.ttl`` +^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.9.0 + + The default was changed from 3600 (1 hour) to 86400 (24 hours). + +- Integer +- Default: ``86400`` + +- Old style setting: :ref:`setting-packetcache-ttl` + +Maximum number of seconds to cache an item in the packet cache, no matter what the original TTL specified. + +.. _setting-yaml-recordcache.locked_ttl_perc: + +``recordcache.locked_ttl_perc`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.8.0 + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-record-cache-locked-ttl-perc` + +Replace record sets in the record cache only after this percentage of the original TTL has passed. +The PowerDNS Recursor already has several mechanisms to protect against spoofing attempts. +This adds an extra layer of protection---as it limits the window of time cache updates are accepted---at the cost of a less efficient record cache. + +The default value of 0 means no extra locking occurs. +When non-zero, record sets received (e.g. in the Additional Section) will not replace existing record sets in the record cache until the given percentage of the original TTL has expired. +A value of 100 means only expired record sets will be replaced. + +There are a few cases where records will be replaced anyway: + +- Record sets that are expired will always be replaced. +- Authoritative record sets will replace unauthoritative record sets unless DNSSEC validation of the new record set failed. +- If the new record set belongs to a DNSSEC-secure zone and successfully passed validation it will replace an existing entry. +- Record sets produced by :ref:`setting-yaml-recordcache.refresh_on_ttl_perc` tasks will also replace existing record sets. + +.. _setting-yaml-recordcache.max_cache_bogus_ttl: + +``recordcache.max_cache_bogus_ttl`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Integer +- Default: ``3600`` + +- Old style setting: :ref:`setting-max-cache-bogus-ttl` + +Maximum number of seconds to cache an item in the DNS cache (negative or positive) if its DNSSEC validation failed, no matter what the original TTL specified, to reduce the impact of a broken domain. + +.. _setting-yaml-recordcache.max_entries: + +``recordcache.max_entries`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``1000000`` + +- Old style setting: :ref:`setting-max-cache-entries` + +Maximum number of DNS record cache entries, shared by all threads since 4.4.0. +Each entry associates a name and type with a record set. +The size of the negative cache is 10% of this number. + +.. _setting-yaml-recordcache.max_negative_ttl: + +``recordcache.max_negative_ttl`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``3600`` + +- Old style setting: :ref:`setting-max-negative-ttl` + +A query for which there is authoritatively no answer is cached to quickly deny a record's existence later on, without putting a heavy load on the remote server. +In practice, caches can become saturated with hundreds of thousands of hosts which are tried only once. +This setting, which defaults to 3600 seconds, puts a maximum on the amount of time negative entries are cached. + +.. _setting-yaml-recordcache.max_ttl: + +``recordcache.max_ttl`` +^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.1.0 + + The minimum value of this setting is 15. i.e. setting this to lower than 15 will make this value 15. + +- Integer +- Default: ``86400`` + +- Old style setting: :ref:`setting-max-cache-ttl` + +Maximum number of seconds to cache an item in the DNS cache, no matter what the original TTL specified. +This value also controls the refresh period of cached root data. +See :ref:`handling-of-root-hints` for more information on this. + +.. _setting-yaml-recordcache.refresh_on_ttl_perc: + +``recordcache.refresh_on_ttl_perc`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-refresh-on-ttl-perc` + +Sets the 'refresh almost expired' percentage of the record cache. Whenever a record is fetched from the packet or record cache +and only ``refresh-on-ttl-perc`` percent or less of its original TTL is left, a task is queued to refetch the name/type combination to +update the record cache. In most cases this causes future queries to always see a non-expired record cache entry. +A typical value is 10. If the value is zero, this functionality is disabled. + +.. _setting-yaml-recordcache.shards: + +``recordcache.shards`` +^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.4.0 + +- Integer +- Default: ``1024`` + +- Old style setting: :ref:`setting-record-cache-shards` + +Sets the number of shards in the record cache. If you have high +contention as reported by +``record-cache-contented/record-cache-acquired``, you can try to +enlarge this value or run with fewer threads. + +.. _setting-yaml-recursor.allow_trust_anchor_query: + +``recursor.allow_trust_anchor_query`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.3.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-allow-trust-anchor-query` + +Allow ``trustanchor.server CH TXT`` and ``negativetrustanchor.server CH TXT`` queries to view the configured :doc:`DNSSEC ` (negative) trust anchors. + +.. _setting-yaml-recursor.any_to_tcp: + +``recursor.any_to_tcp`` +^^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-any-to-tcp` + +Answer questions for the ANY type on UDP with a truncated packet that refers the remote server to TCP. +Useful for mitigating ANY reflection attacks. + +.. _setting-yaml-recursor.auth_zones: + +``recursor.auth_zones`` +^^^^^^^^^^^^^^^^^^^^^^^ + +- Sequence of `Auth Zone`_ +- Default: ``[]`` + +- Old style setting: :ref:`setting-auth-zones` + +Zones read from these files (in BIND format) are served authoritatively (but without the AA bit set in responses). +DNSSEC is not supported. Example: + +.. code-block:: yaml + + recursor: + auth-zones: + - zone: example.org + file: /var/zones/example.org + - zone: powerdns.com + file: /var/zones/powerdns.com + +.. _setting-yaml-recursor.chroot: + +``recursor.chroot`` +^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-chroot` + +If set, chroot to this directory for more security. +This is not recommended; instead, we recommend containing PowerDNS using operating system features. +We ship systemd unit files with our packages to make this easy. + +Make sure that ``/dev/log`` is available from within the chroot. +Logging will silently fail over time otherwise (on logrotate). + +When using ``chroot``, all other paths (except for :ref:`setting-yaml-recursor.config_dir`) set in the configuration are relative to the new root. + +When running on a system where systemd manages services, ``chroot`` does not work out of the box, as PowerDNS cannot use the ``NOTIFY_SOCKET``. +Either do not ``chroot`` on these systems or set the 'Type' of this service to 'simple' instead of 'notify' (refer to the systemd documentation on how to modify unit-files). + +.. _setting-yaml-recursor.config_dir: + +``recursor.config_dir`` +^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: ``/etc/powerdns`` + +- Old style setting: :ref:`setting-config-dir` + +Location of configuration directory (``recursor.conf``). +Usually ``/etc/powerdns``, but this depends on ``SYSCONFDIR`` during compile-time. + +.. _setting-yaml-recursor.config_name: + +``recursor.config_name`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-config-name` + +When running multiple recursors on the same server, read settings from :file:`recursor-{name}.conf`, this will also rename the binary image. + +.. _setting-yaml-recursor.cpu_map: + +``recursor.cpu_map`` +^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-cpu-map` + +Set CPU affinity for threads, asking the scheduler to run those threads on a single CPU, or a set of CPUs. +This parameter accepts a space separated list of thread-id=cpu-id, or thread-id=cpu-id-1,cpu-id-2,...,cpu-id-N. +For example, to make the worker thread 0 run on CPU id 0 and the worker thread 1 on CPUs 1 and 2:: + +.. code-block:: yaml + + recursor: + cpu_map: 0=0 1=1,2 + +The thread handling the control channel, the webserver and other internal stuff has been assigned id 0, the distributor +threads if any are assigned id 1 and counting, and the worker threads follow behind. +The number of distributor threads is determined by :ref:`setting-yaml-incoming.distributor_threads`, the number of worker threads is determined by the :ref:`setting-yaml-recursor.threads` setting. + +This parameter is only available if the OS provides the ``pthread_setaffinity_np()`` function. + +Note that depending on the configuration the Recursor can start more threads. +Typically these threads will sleep most of the time. +These threads cannot be specified in this setting as their thread-ids are left unspecified. + +.. _setting-yaml-recursor.daemon: + +``recursor.daemon`` +^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.0.0 + + Default is now ``no``, was ``yes`` before. + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-daemon` + +Operate in the background. + +.. _setting-yaml-recursor.dns64_prefix: + +``recursor.dns64_prefix`` +^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.4.0 + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-dns64-prefix` + +Enable DNS64 (:rfc:`6147`) support using the supplied /96 IPv6 prefix. This will generate 'fake' ``AAAA`` records for names +with only ``A`` records, as well as 'fake' ``PTR`` records to make sure that reverse lookup of DNS64-generated IPv6 addresses +generate the right name. +See :doc:`dns64` for more flexible but slower alternatives using Lua. + +.. _setting-yaml-recursor.entropy_source: + +``recursor.entropy_source`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: ``/dev/urandom`` + +- Old style setting: :ref:`setting-entropy-source` + +PowerDNS can read entropy from a (hardware) source. +This is used for generating random numbers which are very hard to predict. +Generally on UNIX platforms, this source will be ``/dev/urandom``, which will always supply random numbers, even if entropy is lacking. +Change to ``/dev/random`` if PowerDNS should block waiting for enough entropy to arrive. + +.. _setting-yaml-recursor.etc_hosts_file: + +``recursor.etc_hosts_file`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: ``/etc/hosts`` + +- Old style setting: :ref:`setting-etc-hosts-file` + +The path to the /etc/hosts file, or equivalent. +This file can be used to serve data authoritatively using :ref:`setting-yaml-recursor.export_etc_hosts`. + +.. _setting-yaml-recursor.event_trace_enabled: + +``recursor.event_trace_enabled`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-event-trace-enabled` + +Enable the recording and logging of ref:`event traces`. This is an experimental feature and subject to change. +Possible values are 0: (disabled), 1 (add information to protobuf logging messages) and 2 (write to log) and 3 (both). + +.. _setting-yaml-recursor.export_etc_hosts: + +``recursor.export_etc_hosts`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-export-etc-hosts` + +If set, this flag will export the host names and IP addresses mentioned in ``/etc/hosts``. + +.. _setting-yaml-recursor.export_etc_hosts_search_suffix: + +``recursor.export_etc_hosts_search_suffix`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-export-etc-hosts-search-suffix` + +If set, all hostnames in the :ref:`setting-yaml-recursor.export_etc_hosts` file are loaded in canonical form, based on this suffix, unless the name contains a '.', in which case the name is unchanged. +So an entry called 'pc' with ``export-etc-hosts-search-suffix='home.com'`` will lead to the generation of 'pc.home.com' within the recursor. +An entry called 'server1.home' will be stored as 'server1.home', regardless of this setting. + +.. _setting-yaml-recursor.extended_resolution_errors: + +``recursor.extended_resolution_errors`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-extended-resolution-errors` + +If set, the recursor will add an EDNS Extended Error (:rfc:`8914`) to responses when resolution failed, like DNSSEC validation errors, explaining the reason it failed. This setting is not needed to allow setting custom error codes from Lua or from a RPZ hit. + +.. _setting-yaml-recursor.forward_zones: + +``recursor.forward_zones`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Sequence of `Forward Zone`_ +- Default: ``[]`` + +- Old style setting: :ref:`setting-forward-zones` + +Queries for zones listed here will be forwarded to the IP address listed. i.e. + +.. code-block:: yaml + + recursor: + forward-zones: + - zone: example.org + forwarders: + - 203.0.113.210 + - zone: powerdns.com + forwarders: + - 2001:DB8::BEEF:5 + +Multiple IP addresses can be specified and port numbers other than 53 can be configured: + +.. code-block:: yaml + + recursor: + forward-zones: + - zone: example.org + forwarders: + - 203.0.113.210:5300 + - 127.0.0.1 + - zone: powerdns.com + forwarders: + - 127.0.0.1 + - 198.51.100.10:530 + - '[2001:DB8::1:3]:5300' + +Forwarded queries have the ``recursion desired (RD)`` bit set to ``0``, meaning that this setting is intended to forward queries to authoritative servers. +If an ``NS`` record set for a subzone of the forwarded zone is learned, that record set will be used to determine addresses for name servers of the subzone. +This allows e.g. a forward to a local authoritative server holding a copy of the root zone, delegations received from that server will work. + +**IMPORTANT**: When using DNSSEC validation (which is default), forwards to non-delegated (e.g. internal) zones that have a DNSSEC signed parent zone will validate as Bogus. +To prevent this, add a Negative Trust Anchor (NTA) for this zone in the :ref:`setting-yaml-recursor.lua_config_file` with ``addNTA('your.zone', 'A comment')``. +If this forwarded zone is signed, instead of adding NTA, add the DS record to the :ref:`setting-yaml-recursor.lua_config_file`. +See the :doc:`dnssec` information. + +.. _setting-yaml-recursor.forward_zones_file: + +``recursor.forward_zones_file`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.0.0 + + (Old style settings only) Comments are allowed, everything behind ``#`` is ignored. +.. versionchanged:: 4.6.0 + + (Old style settings only) Zones prefixed with a ``^`` are added to the :ref:`setting-allow-notify-for` list. Both prefix characters can be used if desired, in any order. + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-forward-zones-file` + +Same as :ref:`setting-yaml-recursor.forward_zones`, parsed from a file as a sequence of `ZoneForward`. + +.. code-block:: yaml + + - zone: example1.com + forwarders: + - 127.0.0.1 + - 127.0.0.1:5353 + - '[::1]53' + - zone: example2.com + forwarders: + - ::1 + recurse: true + notify_allowed: true + +The DNSSEC notes from :ref:`setting-yaml-recursor.forward_zones` apply here as well. + +.. _setting-yaml-recursor.forward_zones_recurse: + +``recursor.forward_zones_recurse`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Sequence of `Forward Zone`_ +- Default: ``[]`` + +- Old style setting: :ref:`setting-forward-zones-recurse` + +Like regular :ref:`setting-yaml-recursor.forward_zones`, but forwarded queries have the ``recursion desired (RD)`` bit set to ``1``, meaning that this setting is intended to forward queries to other recursive servers. +In contrast to regular forwarding, the rule that delegations of the forwarded subzones are respected is not active. +This is because we rely on the forwarder to resolve the query fully. + +See :ref:`setting-yaml-recursor.forward_zones` for additional options (such as supplying multiple recursive servers) and an important note about DNSSEC. + +.. _setting-yaml-recursor.hint_file: + +``recursor.hint_file`` +^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.6.2 + + Introduced the value ``no`` to disable root-hints processing. +.. versionchanged:: 4.9.0 + + Introduced the value ``no-refresh`` to disable both root-hints processing and periodic refresh of the cached root `NS` records. + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-hint-file` + +If set, the root-hints are read from this file. If empty, the default built-in root hints are used. + +In some special cases, processing the root hints is not needed, for example when forwarding all queries to another recursor. +For these special cases, it is possible to disable the processing of root hints by setting the value to ``no`` or ``no-refresh``. +See :ref:`handling-of-root-hints` for more information on root hints handling. + +.. _setting-yaml-recursor.ignore_unknown_settings: + +``recursor.ignore_unknown_settings`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Sequence of strings +- Default: ``[]`` + +- Old style setting: :ref:`setting-ignore-unknown-settings` + +Names of settings to be ignored while parsing configuration files, if the setting +name is unknown to PowerDNS. + +Useful during upgrade testing. + +.. _setting-yaml-recursor.include_dir: + +``recursor.include_dir`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-include-dir` + +Directory to scan for additional config files. All files that end with .conf are loaded in order using ``POSIX`` as locale. + +.. _setting-yaml-recursor.latency_statistic_size: + +``recursor.latency_statistic_size`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``10000`` + +- Old style setting: :ref:`setting-latency-statistic-size` + +Indication of how many queries will be averaged to get the average latency reported by the 'qa-latency' metric. + +.. _setting-yaml-recursor.lua_config_file: + +``recursor.lua_config_file`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-lua-config-file` + +If set, and Lua support is compiled in, this will load an additional configuration file for newer features and more complicated setups. +See :doc:`lua-config/index` for the options that can be set in this file. + +.. _setting-yaml-recursor.lua_dns_script: + +``recursor.lua_dns_script`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-lua-dns-script` + +Path to a lua file to manipulate the Recursor's answers. See :doc:`lua-scripting/index` for more information. + +.. _setting-yaml-recursor.lua_maintenance_interval: + +``recursor.lua_maintenance_interval`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- Integer +- Default: ``1`` + +- Old style setting: :ref:`setting-lua-maintenance-interval` + +The interval between calls to the Lua user defined `maintenance()` function in seconds. +See :ref:`hooks-maintenance-callback` + +.. _setting-yaml-recursor.max_generate_steps: + +``recursor.max_generate_steps`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.3.0 + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-max-generate-steps` + +Maximum number of steps for a '$GENERATE' directive when parsing a +zone file. This is a protection measure to prevent consuming a lot of +CPU and memory when untrusted zones are loaded. Default to 0 which +means unlimited. + +.. _setting-yaml-recursor.max_include_depth: + +``recursor.max_include_depth`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Integer +- Default: ``20`` + +- Old style setting: :ref:`setting-max-include-depth` + +Maximum number of nested ``$INCLUDE`` directives while processing a zone file. +Zero mean no ``$INCLUDE`` directives will be accepted. + +.. _setting-yaml-recursor.max_mthreads: + +``recursor.max_mthreads`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``2048`` + +- Old style setting: :ref:`setting-max-mthreads` + +Maximum number of simultaneous MTasker threads. + +.. _setting-yaml-recursor.max_ns_address_qperq: + +``recursor.max_ns_address_qperq`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.1.16 +.. versionadded:: 4.2.2 +.. versionadded:: 4.3.1 + +- Integer +- Default: ``10`` + +- Old style setting: :ref:`setting-max-ns-address-qperq` + +The maximum number of outgoing queries with empty replies for +resolving nameserver names to addresses we allow during the resolution +of a single client query. If IPv6 is enabled, an A and a AAAA query +for a name counts as 1. If a zone publishes more than this number of +NS records, the limit is further reduced for that zone by lowering +it by the number of NS records found above the +:ref:`setting-yaml-recursor.max_ns_address_qperq` value. The limit wil not be reduced to a +number lower than 5. + +.. _setting-yaml-recursor.max_ns_per_resolve: + +``recursor.max_ns_per_resolve`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.8.0 +.. versionadded:: 4.7.3 +.. versionadded:: 4.6.4 +.. versionadded:: 4.5.11 + +- Integer +- Default: ``13`` + +- Old style setting: :ref:`setting-max-ns-per-resolve` + +The maximum number of NS records that will be considered to select a nameserver to contact to resolve a name. +If a zone has more than :ref:`setting-yaml-recursor.max_ns_per_resolve` NS records, a random sample of this size will be used. +If :ref:`setting-yaml-recursor.max_ns_per_resolve` is zero, no limit applies. + +.. _setting-yaml-recursor.max_qperq: + +``recursor.max_qperq`` +^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``60`` + +- Old style setting: :ref:`setting-max-qperq` + +The maximum number of outgoing queries that will be sent out during the resolution of a single client query. +This is used to limit endlessly chasing CNAME redirections. +If qname-minimization is enabled, the number will be forced to be 100 +at a minimum to allow for the extra queries qname-minimization generates when the cache is empty. + +.. _setting-yaml-recursor.max_recursion_depth: + +``recursor.max_recursion_depth`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.1.0 + + Before 4.1.0, this settings was unlimited. +.. versionchanged:: 4.9.0 + + Before 4.9.0 this setting's default was 40 and the limit on ``CNAME`` chains (fixed at 16) acted as a bound on he recursion depth. + +- Integer +- Default: ``16`` + +- Old style setting: :ref:`setting-max-recursion-depth` + +Total maximum number of internal recursion calls the server may use to answer a single query. +0 means unlimited. +The value of :ref:`setting-yaml-recursor.stack_size` should be increased together with this one to prevent the stack from overflowing. +If :ref:`setting-yaml-recursor.qname_minimization` is enabled, the fallback code in case of a failing resolve is allowed an additional `max-recursion-depth/2`. + +.. _setting-yaml-recursor.max_total_msec: + +``recursor.max_total_msec`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``7000`` + +- Old style setting: :ref:`setting-max-total-msec` + +Total maximum number of milliseconds of wallclock time the server may use to answer a single query. +0 means unlimited. + +.. _setting-yaml-recursor.minimum_ttl_override: + +``recursor.minimum_ttl_override`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.5.0 + + Old versions used default 0. + +- Integer +- Default: ``1`` + +- Old style setting: :ref:`setting-minimum-ttl-override` + +This setting artificially raises all TTLs to be at least this long. +Setting this to a value greater than 1 technically is an RFC violation, but might improve performance a lot. +Using a value of 0 impacts performance of TTL 0 records greatly, since it forces the recursor to contact +authoritative servers each time a client requests them. +Can be set at runtime using ``rec_control set-minimum-ttl 3600``. + +.. _setting-yaml-recursor.non_resolving_ns_max_fails: + +``recursor.non_resolving_ns_max_fails`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Integer +- Default: ``5`` + +- Old style setting: :ref:`setting-non-resolving-ns-max-fails` + +Number of failed address resolves of a nameserver name to start throttling it, 0 is disabled. +Nameservers matching :ref:`setting-yaml-outgoing.dont_throttle_names` will not be throttled. + +.. _setting-yaml-recursor.non_resolving_ns_throttle_time: + +``recursor.non_resolving_ns_throttle_time`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Integer +- Default: ``60`` + +- Old style setting: :ref:`setting-non-resolving-ns-throttle-time` + +Number of seconds to throttle a nameserver with a name failing to resolve. + +.. _setting-yaml-recursor.nothing_below_nxdomain: + +``recursor.nothing_below_nxdomain`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.3.0 + +- String +- Default: ``dnssec`` + +- Old style setting: :ref:`setting-nothing-below-nxdomain` + +- One of ``no``, ``dnssec``, ``yes``. + +The type of :rfc:`8020` handling using cached NXDOMAIN responses. +This RFC specifies that NXDOMAIN means that the DNS tree under the denied name MUST be empty. +When an NXDOMAIN exists in the cache for a shorter name than the qname, no lookup is done and an NXDOMAIN is sent to the client. + +For instance, when ``foo.example.net`` is negatively cached, any query +matching ``*.foo.example.net`` will be answered with NXDOMAIN directly +without consulting authoritative servers. + +``no`` + No :rfc:`8020` processing is done. + +``dnssec`` + :rfc:`8020` processing is only done using cached NXDOMAIN records that are + DNSSEC validated. + +``yes`` + :rfc:`8020` processing is done using any non-Bogus NXDOMAIN record + available in the cache. + +.. _setting-yaml-recursor.public_suffix_list_file: + +``recursor.public_suffix_list_file`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-public-suffix-list-file` + +Path to the Public Suffix List file, if any. If set, PowerDNS will try to load the Public Suffix List from this file instead of using the built-in list. The PSL is used to group the queries by relevant domain names when displaying the top queries. + +.. _setting-yaml-recursor.qname_minimization: + +``recursor.qname_minimization`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.3.0 + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-qname-minimization` + +Enable Query Name Minimization. This implements a relaxed form of Query Name Mimimization as +described in :rfc:`7816`. + +.. _setting-yaml-recursor.rng: + +``recursor.rng`` +^^^^^^^^^^^^^^^^ + +- String +- Default: ``auto`` + +- Old style setting: :ref:`setting-rng` + +- String +- Default: auto + +Specify which random number generator to use. Permissible choices are + - auto - choose automatically + - sodium - Use libsodium ``randombytes_uniform`` + - openssl - Use libcrypto ``RAND_bytes`` + - getrandom - Use libc getrandom, falls back to urandom if it does not really work + - arc4random - Use BSD ``arc4random_uniform`` + - urandom - Use ``/dev/urandom`` + - kiss - Use simple settable deterministic RNG. **FOR TESTING PURPOSES ONLY!** + +.. _setting-yaml-recursor.root_nx_trust: + +``recursor.root_nx_trust`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.0.0 + + Default is ``yes`` now, was ``no`` before 4.0.0 + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-root-nx-trust` + +If set, an NXDOMAIN from the root-servers will serve as a blanket NXDOMAIN for the entire TLD the query belonged to. +The effect of this is far fewer queries to the root-servers. + +.. _setting-yaml-recursor.save_parent_ns_set: + +``recursor.save_parent_ns_set`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.7.0 + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-save-parent-ns-set` + +If set, a parent (non-authoritative) ``NS`` set is saved if it contains more entries than a newly encountered child (authoritative) ``NS`` set for the same domain. +The saved parent ``NS`` set is tried if resolution using the child ``NS`` set fails. + +.. _setting-yaml-recursor.security_poll_suffix: + +``recursor.security_poll_suffix`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: ``secpoll.powerdns.com.`` + +- Old style setting: :ref:`setting-security-poll-suffix` + +Domain name from which to query security update notifications. +Setting this to an empty string disables secpoll. + +.. _setting-yaml-recursor.serve_rfc1918: + +``recursor.serve_rfc1918`` +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-serve-rfc1918` + +This makes the server authoritatively aware of: ``10.in-addr.arpa``, ``168.192.in-addr.arpa``, ``16-31.172.in-addr.arpa``, which saves load on the AS112 servers. +Individual parts of these zones can still be loaded or forwarded. + +.. _setting-yaml-recursor.serve_stale_extensions: + +``recursor.serve_stale_extensions`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.8.0 + +- Integer +- Default: ``0`` + +- Old style setting: :ref:`setting-serve-stale-extensions` + +Maximum number of times an expired record's TTL is extended by 30s when serving stale. +Extension only occurs if a record cannot be refreshed. +A value of 0 means the ``Serve Stale`` mechanism is not used. +To allow records becoming stale to be served for an hour, use a value of 120. +See :ref:`serve-stale` for a description of the Serve Stale mechanism. + +.. _setting-yaml-recursor.server_down_max_fails: + +``recursor.server_down_max_fails`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``64`` + +- Old style setting: :ref:`setting-server-down-max-fails` + +If a server has not responded in any way this many times in a row, no longer send it any queries for :ref:`setting-yaml-recursor.server_down_throttle_time` seconds. +Afterwards, we will try a new packet, and if that also gets no response at all, we again throttle for :ref:`setting-yaml-recursor.server_down_throttle_time` seconds. +Even a single response packet will drop the block. + +.. _setting-yaml-recursor.server_down_throttle_time: + +``recursor.server_down_throttle_time`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``60`` + +- Old style setting: :ref:`setting-server-down-throttle-time` + +Throttle a server that has failed to respond :ref:`setting-yaml-recursor.server_down_max_fails` times for this many seconds. + +.. _setting-yaml-recursor.server_id: + +``recursor.server_id`` +^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: ``*runtime determined*`` + +- Old style setting: :ref:`setting-server-id` + +The reply given by The PowerDNS recursor to a query for 'id.server' with its hostname, useful for in clusters. +When a query contains the :rfc:`NSID EDNS0 Option <5001>`, this value is returned in the response as the NSID value. + +This setting can be used to override the answer given to these queries. +Set to 'disabled' to disable NSID and 'id.server' answers. + +Query example (where 192.0.2.14 is your server): + +.. code-block:: sh + + dig @192.0.2.14 CHAOS TXT id.server. + dig @192.0.2.14 example.com IN A +nsid + +.. _setting-yaml-recursor.setgid: + +``recursor.setgid`` +^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-setgid` + +PowerDNS can change its user and group id after binding to its socket. +Can be used for better :doc:`security `. + +.. _setting-yaml-recursor.setuid: + +``recursor.setuid`` +^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-setuid` + +PowerDNS can change its user and group id after binding to its socket. +Can be used for better :doc:`security `. + +.. _setting-yaml-recursor.socket_dir: + +``recursor.socket_dir`` +^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-socket-dir` + +Where to store the control socket and pidfile. +The default depends on ``LOCALSTATEDIR`` or the ``--with-socketdir`` setting when building (usually ``/var/run`` or ``/run``). + +When using :ref:`setting-yaml-recursor.chroot` the default becomes ``/``. + +.. _setting-yaml-recursor.socket_group: + +``recursor.socket_group`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-socket-group` + +Group and mode of the controlsocket. +Owner and group can be specified by name, mode is in octal. + +.. _setting-yaml-recursor.socket_mode: + +``recursor.socket_mode`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-socket-mode` + +Mode of the controlsocket. +Owner and group can be specified by name, mode is in octal. + +.. _setting-yaml-recursor.socket_owner: + +``recursor.socket_owner`` +^^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-socket-owner` + +Owner of the controlsocket. +Owner and group can be specified by name, mode is in octal. + +.. _setting-yaml-recursor.spoof_nearmiss_max: + +``recursor.spoof_nearmiss_max`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.5.0 + + Older versions used 20 as the default value. + +- Integer +- Default: ``1`` + +- Old style setting: :ref:`setting-spoof-nearmiss-max` + +If set to non-zero, PowerDNS will assume it is being spoofed after seeing this many answers with the wrong id. + +.. _setting-yaml-recursor.stack_cache_size: + +``recursor.stack_cache_size`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.9.0 + +- Integer +- Default: ``100`` + +- Old style setting: :ref:`setting-stack-cache-size` + +Maximum number of mthread stacks that can be cached for later reuse, per thread. Caching these stacks reduces the CPU load at the cost of a slightly higher memory usage, each cached stack consuming `stack-size` bytes of memory. +It makes no sense to cache more stacks than the value of `max-mthreads`, since there will never be more stacks than that in use at a given time. + +.. _setting-yaml-recursor.stack_size: + +``recursor.stack_size`` +^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``200000`` + +- Old style setting: :ref:`setting-stack-size` + +Size in bytes of the stack of each mthread. + +.. _setting-yaml-recursor.stats_api_disabled_list: + +``recursor.stats_api_disabled_list`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Sequence of strings +- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\* + +- Old style setting: :ref:`setting-stats-api-disabled-list` + +A sequence of statistic names, that are disabled when retrieving the complete list of statistics via the API for performance reasons. +These statistics can still be retrieved individually by specifically asking for it. + +.. _setting-yaml-recursor.stats_carbon_disabled_list: + +``recursor.stats_carbon_disabled_list`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Sequence of strings +- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\* + +- Old style setting: :ref:`setting-stats-carbon-disabled-list` + +A sequence of statistic names, that are prevented from being exported via carbon for performance reasons. + +.. _setting-yaml-recursor.stats_rec_control_disabled_list: + +``recursor.stats_rec_control_disabled_list`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Sequence of strings +- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\* + +- Old style setting: :ref:`setting-stats-rec-control-disabled-list` + +A sequence of statistic names, that are disabled when retrieving the complete list of statistics via `rec_control get-all`, for performance reasons. +These statistics can still be retrieved individually. + +.. _setting-yaml-recursor.stats_ringbuffer_entries: + +``recursor.stats_ringbuffer_entries`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``10000`` + +- Old style setting: :ref:`setting-stats-ringbuffer-entries` + +Number of entries in the remotes ringbuffer, which keeps statistics on who is querying your server. +Can be read out using ``rec_control top-remotes``. + +.. _setting-yaml-recursor.stats_snmp_disabled_list: + +``recursor.stats_snmp_disabled_list`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- Sequence of strings +- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\* + +- Old style setting: :ref:`setting-stats-snmp-disabled-list` + +A sequence of statistic names, that are prevented from being exported via SNMP, for performance reasons. + +.. _setting-yaml-recursor.threads: + +``recursor.threads`` +^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``2`` + +- Old style setting: :ref:`setting-threads` + +Spawn this number of threads on startup. + +.. _setting-yaml-recursor.version_string: + +``recursor.version_string`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: ``*runtime determined*`` + +- Old style setting: :ref:`setting-version-string` + +By default, PowerDNS replies to the 'version.bind' query with its version number. +Security conscious users may wish to override the reply PowerDNS issues. + +.. _setting-yaml-recursor.write_pid: + +``recursor.write_pid`` +^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``true`` + +- Old style setting: :ref:`setting-write-pid` + +If a PID file should be written to :ref:`setting-yaml-recursor.socket_dir` + +.. _setting-yaml-snmp.agent: + +``snmp.agent`` +^^^^^^^^^^^^^^ +.. versionadded:: 4.1.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-snmp-agent` + +If set to true and PowerDNS has been compiled with SNMP support, it will register as an SNMP agent to provide statistics and be able to send traps. + +.. _setting-yaml-snmp.daemon_socket: + +``snmp.daemon_socket`` +^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.5.0 + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-snmp-daemon-socket` + +If not empty and ``snmp-agent`` is set to true, indicates how PowerDNS should contact the SNMP daemon to register as an SNMP agent. + +.. _setting-yaml-webservice.address: + +``webservice.address`` +^^^^^^^^^^^^^^^^^^^^^^ + +- String +- Default: ``127.0.0.1`` + +- Old style setting: :ref:`setting-webserver-address` + +IP address for the webserver to listen on. + +.. _setting-yaml-webservice.allow_from: + +``webservice.allow_from`` +^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.1.0 + + Default is now 127.0.0.1,::1, was 0.0.0.0/0,::/0 before. + +- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) +- Default: ``[127.0.0.1, ::1]`` + +- Old style setting: :ref:`setting-webserver-allow-from` + +These IPs and subnets are allowed to access the webserver. Note that +specifying an IP address without a netmask uses an implicit netmask +of /32 or /128. + +.. _setting-yaml-webservice.api_dir: + +``webservice.api_dir`` +^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.0.0 + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-api-config-dir` + +Directory where the REST API stores its configuration and zones. +For configuration updates to work, :ref:`setting-yaml-recursor.include_dir` should have the same value. + +.. _setting-yaml-webservice.api_key: + +``webservice.api_key`` +^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.0.0 +.. versionchanged:: 4.6.0 + + This setting now accepts a hashed and salted version. + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-api-key` + +Static pre-shared authentication key for access to the REST API. Since 4.6.0 the key can be hashed and salted using ``rec_control hash-password`` instead of being stored in the configuration in plaintext, but the plaintext version is still supported. + +.. _setting-yaml-webservice.hash_plaintext_credentials: + +``webservice.hash_plaintext_credentials`` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.6.0 + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-webserver-hash-plaintext-credentials` + +Whether passwords and API keys supplied in the configuration as plaintext should be hashed during startup, to prevent the plaintext versions from staying in memory. Doing so increases significantly the cost of verifying credentials and is thus disabled by default. +Note that this option only applies to credentials stored in the configuration as plaintext, but hashed credentials are supported without enabling this option. + +.. _setting-yaml-webservice.loglevel: + +``webservice.loglevel`` +^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 4.2.0 + +- String +- Default: ``normal`` + +- Old style setting: :ref:`setting-webserver-loglevel` + +One of ``one``, ``normal``, ``detailed``. +The amount of logging the webserver must do. 'none' means no useful webserver information will be logged. +When set to 'normal', the webserver will log a line per request that should be familiar:: + + [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 'GET /api/v1/servers/localhost/bla HTTP/1.1' 404 196 + +When set to 'detailed', all information about the request and response are logged:: + + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Request Details: + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Headers: + [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept-encoding: gzip, deflate + [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept-language: en-US,en;q=0.5 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e connection: keep-alive + [webserver] e235780e-a5cf-415e-9326-9d33383e739e dnt: 1 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e host: 127.0.0.1:8081 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e upgrade-insecure-requests: 1 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e No body + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Response details: + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Headers: + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Connection: close + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Content-Length: 49 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Content-Type: text/html; charset=utf-8 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Server: PowerDNS/0.0.15896.0.gaba8bab3ab + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Full body: + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Not Found

        Not Found

        + [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 'GET /api/v1/servers/localhost/bla HTTP/1.1' 404 196 + +The value between the hooks is a UUID that is generated for each request. This can be used to find all lines related to a single request. + +.. note:: + The webserver logs these line on the NOTICE level. The :ref:`setting-yaml-logging.loglevel` seting must be 5 or higher for these lines to end up in the log. + +.. _setting-yaml-webservice.password: + +``webservice.password`` +^^^^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 4.6.0 + + This setting now accepts a hashed and salted version. + +- String +- Default: (empty) + +- Old style setting: :ref:`setting-webserver-password` + +Password required to access the webserver. Since 4.6.0 the password can be hashed and salted using ``rec_control hash-password`` instead of being present in the configuration in plaintext, but the plaintext version is still supported. + +.. _setting-yaml-webservice.port: + +``webservice.port`` +^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``8082`` + +- Old style setting: :ref:`setting-webserver-port` + +TCP port where the webserver should listen on. + +.. _setting-yaml-webservice.webserver: + +``webservice.webserver`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-webserver` + +Start the webserver (for REST API). + diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 36b8517013d1..10469fb44508 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -39,6 +39,7 @@ #include "secpoll-recursor.hh" #include "logging.hh" #include "dnsseckeeper.hh" +#include "settings/cxxsettings.hh" #ifdef NOD_ENABLED #include "nod.hh" @@ -67,6 +68,7 @@ string g_programname = "pdns_recursor"; string g_pidfname; RecursorControlChannel g_rcc; // only active in the handler thread bool g_regressionTestMode; +bool g_yamlSettings; #ifdef NOD_ENABLED bool g_nodEnabled; @@ -754,7 +756,7 @@ static void setupNODThread(Logr::log_t log) } catch (const PDNSException& e) { SLOG(g_log << Logger::Error << "new-domain-history-dir (" << ::arg()["new-domain-history-dir"] << ") is not readable or does not exist" << endl, - log->error(Logr::Error, e.reason, "new-domain-history-dir is not readbale or does not exists", "dir", Logging::Loggable(::arg()["new-domain-history-dir"]))); + log->error(Logr::Error, e.reason, "new-domain-history-dir is not readable or does not exists", "dir", Logging::Loggable(::arg()["new-domain-history-dir"]))); _exit(1); } if (!t_nodDBp->init()) { @@ -854,7 +856,7 @@ static void usr2Handler([[maybe_unused]] int arg) { g_quiet = !g_quiet; SyncRes::setDefaultLogMode(g_quiet ? SyncRes::LogNone : SyncRes::Log); - ::arg().set("quiet") = g_quiet ? "" : "no"; + ::arg().set("quiet") = g_quiet ? "yes" : "no"; } static void checkLinuxIPv6Limits([[maybe_unused]] Logr::log_t log) @@ -1147,28 +1149,40 @@ static std::shared_ptr parseACL(const std::string& aclFile, const { auto result = std::make_shared(); - if (!::arg()[aclFile].empty()) { - string line; - ifstream ifs(::arg()[aclFile].c_str()); - if (!ifs) { - throw runtime_error("Could not open '" + ::arg()[aclFile] + "': " + stringerror()); - } + const string file = ::arg()[aclFile]; - while (getline(ifs, line)) { - auto pos = line.find('#'); - if (pos != string::npos) { - line.resize(pos); + if (!file.empty()) { + if (boost::ends_with(file, ".yml")) { + ::rust::vec<::rust::string> vec; + pdns::settings::rec::readYamlAllowFromFile(file, vec, log); + for (const auto& subnet : vec) { + result->addMask(string(subnet)); } - boost::trim(line); - if (line.empty()) { - continue; + } + else { + string line; + ifstream ifs(file); + if (!ifs) { + int err = errno; + throw runtime_error("Could not open '" + file + "': " + stringerror(err)); } - result->addMask(line); + while (getline(ifs, line)) { + auto pos = line.find('#'); + if (pos != string::npos) { + line.resize(pos); + } + boost::trim(line); + if (line.empty()) { + continue; + } + + result->addMask(line); + } } - SLOG(g_log << Logger::Info << "Done parsing " << result->size() << " " << aclSetting << " ranges from file '" << ::arg()[aclFile] << "' - overriding '" << aclSetting << "' setting" << endl, + SLOG(g_log << Logger::Info << "Done parsing " << result->size() << " " << aclSetting << " ranges from file '" << file << "' - overriding '" << aclSetting << "' setting" << endl, log->info(Logr::Info, "Done parsing ranges from file, will override setting", "setting", Logging::Loggable(aclSetting), - "number", Logging::Loggable(result->size()), "file", Logging::Loggable(::arg()[aclFile]))); + "number", Logging::Loggable(result->size()), "file", Logging::Loggable(file))); } else if (!::arg()[aclSetting].empty()) { vector ips; @@ -1220,51 +1234,75 @@ void parseACLs() static bool l_initialized; if (l_initialized) { // only reload configuration file on second call - string configName = ::arg()["config-dir"] + "/recursor.conf"; + + string configName = ::arg()["config-dir"] + "/recursor"; if (!::arg()["config-name"].empty()) { - configName = ::arg()["config-dir"] + "/recursor-" + ::arg()["config-name"] + ".conf"; + configName = ::arg()["config-dir"] + "/recursor-" + ::arg()["config-name"]; } cleanSlashes(configName); - if (!::arg().preParseFile(configName.c_str(), "allow-from-file")) { - throw runtime_error("Unable to re-parse configuration file '" + configName + "'"); + if (g_yamlSettings) { + configName += ".yml"; + string msg; + pdns::rust::settings::rec::Recursorsettings settings; + // XXX Does ::arg()["include-dir"] have the right value, i.e. potentially overriden by command line? + auto yamlstatus = pdns::settings::rec::readYamlSettings(configName, ::arg()["include-dir"], settings, msg, log); + + switch (yamlstatus) { + case pdns::settings::rec::YamlSettingsStatus::CannotOpen: + throw runtime_error("Unable to open '" + configName + "': " + msg); + break; + case pdns::settings::rec::YamlSettingsStatus::PresentButFailed: + throw runtime_error("Error processing '" + configName + "': " + msg); + break; + case pdns::settings::rec::YamlSettingsStatus::OK: + // Does *not* set include-dir + pdns::settings::rec::setArgsForACLRelatedSettings(settings); + break; + } } - ::arg().preParseFile(configName.c_str(), "allow-from", LOCAL_NETS); + else { + configName += ".conf"; + if (!::arg().preParseFile(configName, "allow-from-file")) { + throw runtime_error("Unable to re-parse configuration file '" + configName + "'"); + } + ::arg().preParseFile(configName, "allow-from", LOCAL_NETS); - if (!::arg().preParseFile(configName.c_str(), "allow-notify-from-file")) { - throw runtime_error("Unable to re-parse configuration file '" + configName + "'"); - } - ::arg().preParseFile(configName.c_str(), "allow-notify-from"); + if (!::arg().preParseFile(configName, "allow-notify-from-file")) { + throw runtime_error("Unable to re-parse configuration file '" + configName + "'"); + } + ::arg().preParseFile(configName, "allow-notify-from"); - ::arg().preParseFile(configName.c_str(), "include-dir"); - ::arg().preParse(g_argc, g_argv, "include-dir"); + ::arg().preParseFile(configName, "include-dir"); + ::arg().preParse(g_argc, g_argv, "include-dir"); - // then process includes - std::vector extraConfigs; - ::arg().gatherIncludes(extraConfigs); + // then process includes + std::vector extraConfigs; + ::arg().gatherIncludes(::arg()["include-dir"], ".conf", extraConfigs); - for (const std::string& fileName : extraConfigs) { - if (!::arg().preParseFile(fileName.c_str(), "allow-from-file", ::arg()["allow-from-file"])) { - throw runtime_error("Unable to re-parse configuration file include '" + fileName + "'"); - } - if (!::arg().preParseFile(fileName.c_str(), "allow-from", ::arg()["allow-from"])) { - throw runtime_error("Unable to re-parse configuration file include '" + fileName + "'"); - } + for (const std::string& fileName : extraConfigs) { + if (!::arg().preParseFile(fileName, "allow-from-file", ::arg()["allow-from-file"])) { + throw runtime_error("Unable to re-parse configuration file include '" + fileName + "'"); + } + if (!::arg().preParseFile(fileName, "allow-from", ::arg()["allow-from"])) { + throw runtime_error("Unable to re-parse configuration file include '" + fileName + "'"); + } - if (!::arg().preParseFile(fileName.c_str(), "allow-notify-from-file", ::arg()["allow-notify-from-file"])) { - throw runtime_error("Unable to re-parse configuration file include '" + fileName + "'"); - } - if (!::arg().preParseFile(fileName.c_str(), "allow-notify-from", ::arg()["allow-notify-from"])) { - throw runtime_error("Unable to re-parse configuration file include '" + fileName + "'"); + if (!::arg().preParseFile(fileName, "allow-notify-from-file", ::arg()["allow-notify-from-file"])) { + throw runtime_error("Unable to re-parse configuration file include '" + fileName + "'"); + } + if (!::arg().preParseFile(fileName, "allow-notify-from", ::arg()["allow-notify-from"])) { + throw runtime_error("Unable to re-parse configuration file include '" + fileName + "'"); + } } } - - ::arg().preParse(g_argc, g_argv, "allow-from-file"); - ::arg().preParse(g_argc, g_argv, "allow-from"); - - ::arg().preParse(g_argc, g_argv, "allow-notify-from-file"); - ::arg().preParse(g_argc, g_argv, "allow-notify-from"); } + // Process command line args potentially overriding settings read from file + ::arg().preParse(g_argc, g_argv, "allow-from-file"); + ::arg().preParse(g_argc, g_argv, "allow-from"); + + ::arg().preParse(g_argc, g_argv, "allow-notify-from-file"); + ::arg().preParse(g_argc, g_argv, "allow-notify-from"); auto allowFrom = parseACL("allow-from-file", "allow-from", log); @@ -1556,7 +1594,7 @@ static void initDontQuery(Logr::log_t log) } } -static int initSyncRes(Logr::log_t log, const std::optional& myHostname) +static int initSyncRes(Logr::log_t log) { SyncRes::s_minimumTTL = ::arg().asNum("minimum-ttl-override"); SyncRes::s_minimumECSTTL = ::arg().asNum("ecs-minimum-ttl-override"); @@ -1605,11 +1643,6 @@ static int initSyncRes(Logr::log_t log, const std::optional& myHost checkFastOpenSysctl(true, log); checkTFOconnect(log); } - - if (SyncRes::s_serverID.empty()) { - SyncRes::s_serverID = myHostname.has_value() ? *myHostname : ""; - } - SyncRes::s_ecsipv4limit = ::arg().asNum("ecs-ipv4-bits"); SyncRes::s_ecsipv6limit = ::arg().asNum("ecs-ipv6-bits"); SyncRes::clearECSStats(); @@ -2020,13 +2053,8 @@ static int serviceMain(Logr::log_t log) ::arg().set("quiet") = "no"; g_quiet = false; } - auto myHostname = getHostname(); - if (!myHostname.has_value()) { - SLOG(g_log << Logger::Warning << "Unable to get the hostname, NSID and id.server values will be empty" << endl, - log->info(Logr::Warning, "Unable to get the hostname, NSID and id.server values will be empty")); - } - ret = initSyncRes(log, myHostname); + ret = initSyncRes(log); if (ret != 0) { return ret; } @@ -2040,7 +2068,7 @@ static int serviceMain(Logr::log_t log) } g_networkTimeoutMsec = ::arg().asNum("network-timeout"); - std::tie(g_initialDomainMap, g_initialAllowNotifyFor) = parseZoneConfiguration(); + std::tie(g_initialDomainMap, g_initialAllowNotifyFor) = parseZoneConfiguration(g_yamlSettings); g_latencyStatSize = ::arg().asNum("latency-statistic-size"); @@ -2137,10 +2165,6 @@ static int serviceMain(Logr::log_t log) openssl_thread_setup(); openssl_seed(); - if (::arg()["server-id"].empty()) { - ::arg().set("server-id") = myHostname.has_value() ? *myHostname : ""; - } - gid_t newgid = 0; if (!::arg()["setgid"].empty()) { newgid = strToGID(::arg()["setgid"]); @@ -2798,6 +2822,8 @@ static void recursorThread() } } +#if 0 +// THIS FUNCTION IS REPLACED BY GENERATED CODE IN settings/cxxsettings-generated.cc static void initArgs() { #if HAVE_FIBER_SANITIZER @@ -2810,21 +2836,21 @@ static void initArgs() // This mode forces metrics snap updates and disable root-refresh, to get consistent counters ::arg().setSwitch("devonly-regression-test-mode", "internal use only") = "no"; ::arg().set("soa-minimum-ttl", "Don't change") = "0"; - ::arg().set("no-shuffle", "Don't change") = "off"; + ::arg().setSwitch("no-shuffle", "Don't change") = "off"; ::arg().set("local-port", "port to listen on") = "53"; ::arg().set("local-address", "IP addresses to listen on, separated by spaces or commas. Also accepts ports.") = "127.0.0.1"; ::arg().setSwitch("non-local-bind", "Enable binding to non-local addresses by using FREEBIND / BINDANY socket options") = "no"; ::arg().set("trace", "if we should output heaps of logging. set to 'fail' to only log failing domains") = "off"; ::arg().set("dnssec", "DNSSEC mode: off/process-no-validate/process (default)/log-fail/validate") = "process"; - ::arg().set("dnssec-log-bogus", "Log DNSSEC bogus validations") = "no"; + ::arg().setSwitch("dnssec-log-bogus", "Log DNSSEC bogus validations") = "no"; ::arg().set("signature-inception-skew", "Allow the signature inception to be off by this number of seconds") = "60"; ::arg().set("dnssec-disabled-algorithms", "List of DNSSEC algorithm numbers that are considered unsupported") = ""; - ::arg().set("daemon", "Operate as a daemon") = "no"; + ::arg().setSwitch("daemon", "Operate as a daemon") = "no"; ::arg().setSwitch("write-pid", "Write a PID file") = "yes"; ::arg().set("loglevel", "Amount of logging. Higher is more. Do not set below 3") = "6"; - ::arg().set("disable-syslog", "Disable logging to syslog, useful when running inside a supervisor that logs stdout") = "no"; - ::arg().set("log-timestamp", "Print timestamps in log lines, useful to disable when running with a tool that timestamps stdout already") = "yes"; - ::arg().set("log-common-errors", "If we should log rather common errors") = "no"; + ::arg().setSwitch("disable-syslog", "Disable logging to syslog, useful when running inside a supervisor that logs stdout") = "no"; + ::arg().setSwitch("log-timestamp", "Print timestamps in log lines, useful to disable when running with a tool that timestamps stdout already") = "yes"; + ::arg().setSwitch("log-common-errors", "If we should log rather common errors") = "no"; ::arg().set("chroot", "switch to chroot jail") = ""; ::arg().set("setgid", "If set, change group id to this gid for more security" #ifdef HAVE_SYSTEMD @@ -2860,7 +2886,7 @@ static void initArgs() ::arg().set("carbon-instance", "If set overwrites the instance name default") = "recursor"; ::arg().set("statistics-interval", "Number of seconds between printing of recursor statistics, 0 to disable") = "1800"; - ::arg().set("quiet", "Suppress logging of questions and answers") = ""; + ::arg().setSwitch("quiet", "Suppress logging of questions and answers") = "yes"; ::arg().set("logging-facility", "Facility to log messages as. 0 corresponds to local0") = ""; ::arg().set("config-dir", "Location of configuration directory (recursor.conf)") = SYSCONFDIR; ::arg().set("socket-owner", "Owner of socket") = ""; @@ -2914,7 +2940,7 @@ static void initArgs() ::arg().set("max-tcp-per-client", "If set, maximum number of TCP sessions per client (IP address)") = "0"; ::arg().set("max-tcp-queries-per-connection", "If set, maximum number of TCP queries in a TCP connection") = "0"; ::arg().set("spoof-nearmiss-max", "If non-zero, assume spoofing after this many near misses") = "1"; - ::arg().set("single-socket", "If set, only use a single socket for outgoing queries") = "off"; + ::arg().setSwitch("single-socket", "If set, only use a single socket for outgoing queries") = "off"; ::arg().set("auth-zones", "Zones for which we have authoritative data, comma separated domain=file pairs ") = ""; ::arg().set("lua-config-file", "More powerful configuration options") = ""; ::arg().setSwitch("allow-trust-anchor-query", "Allow queries for trustanchor.server CH TXT and negativetrustanchor.server CH TXT") = "no"; @@ -2922,10 +2948,10 @@ static void initArgs() ::arg().set("forward-zones", "Zones for which we forward queries, comma separated domain=ip pairs") = ""; ::arg().set("forward-zones-recurse", "Zones for which we forward queries with recursion bit, comma separated domain=ip pairs") = ""; ::arg().set("forward-zones-file", "File with (+)domain=ip pairs for forwarding") = ""; - ::arg().set("export-etc-hosts", "If we should serve up contents from /etc/hosts") = "off"; + ::arg().setSwitch("export-etc-hosts", "If we should serve up contents from /etc/hosts") = "off"; ::arg().set("export-etc-hosts-search-suffix", "Also serve up the contents of /etc/hosts with this suffix") = ""; ::arg().set("etc-hosts-file", "Path to 'hosts' file") = "/etc/hosts"; - ::arg().set("serve-rfc1918", "If we should be authoritative for RFC 1918 private IP space") = "yes"; + ::arg().setSwitch("serve-rfc1918", "If we should be authoritative for RFC 1918 private IP space") = "yes"; ::arg().set("lua-dns-script", "Filename containing an optional 'lua' script that will be used to modify dns answers") = ""; ::arg().set("lua-maintenance-interval", "Number of seconds between calls to the lua user defined maintenance() function") = "1"; ::arg().set("latency-statistic-size", "Number of latency values to calculate the qa-latency average") = "10000"; @@ -2992,7 +3018,7 @@ static void initArgs() ::arg().set("stats-snmp-disabled-list", "List of statistics that are prevented from being exported via SNMP") = defaultDisabledStats; ::arg().set("tcp-fast-open", "Enable TCP Fast Open support on the listening sockets, using the supplied numerical value as the queue size") = "0"; - ::arg().set("tcp-fast-open-connect", "Enable TCP Fast Open support on outgoing sockets") = "no"; + ::arg().setSwitch("tcp-fast-open-connect", "Enable TCP Fast Open support on outgoing sockets") = "no"; ::arg().set("nsec3-max-iterations", "Maximum number of iterations allowed for an NSEC3 record") = "150"; ::arg().set("cpu-map", "Thread to CPU mapping, space separated thread-id=cpu1,cpu2..cpuN pairs") = ""; @@ -3012,7 +3038,7 @@ static void initArgs() ::arg().set("distribution-load-factor", "The load factor used when PowerDNS is distributing queries to worker threads") = "0.0"; ::arg().setSwitch("qname-minimization", "Use Query Name Minimization") = "yes"; - ::arg().setSwitch("nothing-below-nxdomain", "When an NXDOMAIN exists in cache for a name with fewer labels than the qname, send NXDOMAIN without doing a lookup (see RFC 8020)") = "dnssec"; + ::arg().set("nothing-below-nxdomain", "When an NXDOMAIN exists in cache for a name with fewer labels than the qname, send NXDOMAIN without doing a lookup (see RFC 8020)") = "dnssec"; ::arg().set("max-generate-steps", "Maximum number of $GENERATE steps when loading a zone from a file") = "0"; ::arg().set("max-include-depth", "Maximum nested $INCLUDE depth when loading a zone from a file") = "20"; @@ -3025,16 +3051,16 @@ static void initArgs() ::arg().set("x-dnssec-names", "Collect DNSSEC statistics for names or suffixes in this list in separate x-dnssec counters") = ""; #ifdef NOD_ENABLED - ::arg().set("new-domain-tracking", "Track newly observed domains (i.e. never seen before).") = "no"; - ::arg().set("new-domain-log", "Log newly observed domains.") = "yes"; + ::arg().setSwitch("new-domain-tracking", "Track newly observed domains (i.e. never seen before).") = "no"; + ::arg().setSwitch("new-domain-log", "Log newly observed domains.") = "yes"; ::arg().set("new-domain-lookup", "Perform a DNS lookup newly observed domains as a subdomain of the configured domain") = ""; ::arg().set("new-domain-history-dir", "Persist new domain tracking data here to persist between restarts") = string(NODCACHEDIR) + "/nod"; ::arg().set("new-domain-whitelist", "List of domains (and implicitly all subdomains) which will never be considered a new domain (deprecated)") = ""; ::arg().set("new-domain-ignore-list", "List of domains (and implicitly all subdomains) which will never be considered a new domain") = ""; ::arg().set("new-domain-db-size", "Size of the DB used to track new domains in terms of number of cells. Defaults to 67108864") = "67108864"; ::arg().set("new-domain-pb-tag", "If protobuf is configured, the tag to use for messages containing newly observed domains. Defaults to 'pdns-nod'") = "pdns-nod"; - ::arg().set("unique-response-tracking", "Track unique responses (tuple of query name, type and RR).") = "no"; - ::arg().set("unique-response-log", "Log unique responses") = "yes"; + ::arg().setSwitch("unique-response-tracking", "Track unique responses (tuple of query name, type and RR).") = "no"; + ::arg().setSwitch("unique-response-log", "Log unique responses") = "yes"; ::arg().set("unique-response-history-dir", "Persist unique response tracking data here to persist between restarts") = string(NODCACHEDIR) + "/udr"; ::arg().set("unique-response-db-size", "Size of the DB used to track unique responses in terms of number of cells. Defaults to 67108864") = "67108864"; ::arg().set("unique-response-pb-tag", "If protobuf is configured, the tag to use for messages containing unique DNS responses. Defaults to 'pdns-udr'") = "pdns-udr"; @@ -3069,6 +3095,58 @@ static void initArgs() ::arg().setCmd("config", "Output blank configuration. You can use --config=check to test the config file and command line arguments."); ::arg().setDefaults(); g_log.toConsole(Logger::Info); + + if (s_generateConfigTable) { + auto file = ofstream("settings/table.py"); + const std::map overrideMap = { + {"allow-from", "LType.ListSubnets"}, + {"allow-notify-for", "LType.ListStrings"}, + {"allow-notify-from", "LType.ListSubnets"}, + {"auth-zones", "LType.ListStrings"}, + {"dnssec-disabled-algorithms", "LType.ListStrings"}, + {"dont-query", "LType.ListSubnets"}, + {"dont-throttle-names", "LType.ListStrings"}, + {"dont-throttle-netmasks", "LType.ListSubnets"}, + {"dot-to-auth-names", "LType.ListStrings"}, + {"ecs-add-for", "LType.ListSubnets"}, + {"edbs-padding-from", "LType.ListSubnets"}, + {"edns-subnet-allow-list", "LType.ListSubnets"}, + {"forwad-zones", "LType.ListStrings"}, + {"forwad-zones-recurse", "LType.Strings"}, + {"local-address", "LType.ListSocketAddresses"}, + {"new-domain-ignore-list", "LType.ListStrings"}, + {"query-local-address", "LType.ListSubnets"}, + {"stats-api-disabled-list", "LType.ListStrings"}, + {"stats-carbon-disabled-list", "LType.ListStrings"}, + {"stats-rec-control-disabled-list", "LType.ListStrings"}, + {"stats-snmp-disabled-list", "LType.ListStrings"}, + {"webserver-allow-from", "LType.ListSubnets"}, + {"x-dnssec-names", "LType.ListStrings"}, + }; + file << ::arg().table(overrideMap); + file.close(); + } +} +#endif + +static pair doYamlConfig(Logr::log_t /* startupLog */, int argc, char* argv[]) // NOLINT: Posix API +{ + if (!::arg().mustDo("config")) { + return {0, false}; + } + const string config = ::arg()["config"]; + if (config == "diff" || config.empty()) { + ::arg().parse(argc, argv); + pdns::rust::settings::rec::Recursorsettings settings; + pdns::settings::rec::oldStyleSettingsToBridgeStruct(settings); + auto yaml = settings.to_yaml_string(); + cout << yaml << endl; + } + else if (config == "default") { + auto yaml = pdns::settings::rec::defaultsToYaml(); + cout << yaml << endl; + } + return {0, true}; } static pair doConfig(Logr::log_t startupLog, const string& configname, int argc, char* argv[]) // NOLINT: Posix API @@ -3077,7 +3155,7 @@ static pair doConfig(Logr::log_t startupLog, const string& configname string config = ::arg()["config"]; if (config == "check") { try { - if (!::arg().file(configname.c_str())) { + if (!::arg().file(configname)) { SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); return {1, true}; @@ -3095,7 +3173,7 @@ static pair doConfig(Logr::log_t startupLog, const string& configname cout << ::arg().configstring(false, true); } else if (config == "diff") { - if (!::arg().laxFile(configname.c_str())) { + if (!::arg().laxFile(configname)) { SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); return {1, true}; @@ -3104,7 +3182,7 @@ static pair doConfig(Logr::log_t startupLog, const string& configname cout << ::arg().configstring(true, false); } else { - if (!::arg().laxFile(configname.c_str())) { + if (!::arg().laxFile(configname)) { SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); return {1, true}; @@ -3117,6 +3195,59 @@ static pair doConfig(Logr::log_t startupLog, const string& configname return {0, false}; } +static void handleRuntimeDefaults(Logr::log_t log) +{ +#if HAVE_FIBER_SANITIZER + // Asan needs more stack + if (::arg().asNum("stack-size") == 200000) { // the default in table.py + ::arg().set("stack-size", "stack size per mthread") = "600000"; + } +#endif + + const string RUNTIME = "*runtime determined*"; + if (::arg()["version-string"] == RUNTIME) { // i.e. not set explicitly + ::arg().set("version-string") = fullVersionString(); + } + + if (::arg()["server-id"] == RUNTIME) { // i.e. not set explicitly + auto myHostname = getHostname(); + if (!myHostname.has_value()) { + SLOG(g_log << Logger::Warning << "Unable to get the hostname, NSID and id.server values will be empty" << endl, + log->info(Logr::Warning, "Unable to get the hostname, NSID and id.server values will be empty")); + } + ::arg().set("server-id") = myHostname.has_value() ? *myHostname : ""; + } + + if (::arg()["socket-dir"].empty()) { + if (::arg()["chroot"].empty()) { + ::arg().set("socket-dir") = std::string(LOCALSTATEDIR) + "/pdns-recursor"; + } + else { + ::arg().set("socket-dir") = "/"; + } + } + + if (::arg().asNum("threads") == 1) { + if (::arg().mustDo("pdns-distributes-queries")) { + SLOG(g_log << Logger::Warning << "Only one thread, no need to distribute queries ourselves" << endl, + log->info(Logr::Warning, "Only one thread, no need to distribute queries ourselves")); + ::arg().set("pdns-distributes-queries") = "no"; + } + } + + if (::arg().mustDo("pdns-distributes-queries") && ::arg().asNum("distributor-threads") == 0) { + SLOG(g_log << Logger::Warning << "Asked to run with pdns-distributes-queries set but no distributor threads, raising to 1" << endl, + log->info(Logr::Warning, "Asked to run with pdns-distributes-queries set but no distributor threads, raising to 1")); + ::arg().set("distributor-threads") = "1"; + } + + if (!::arg().mustDo("pdns-distributes-queries") && ::arg().asNum("distributor-threads") > 0) { + SLOG(g_log << Logger::Warning << "Not distributing queries, setting distributor threads to 0" << endl, + log->info(Logr::Warning, "Not distributing queries, setting distributor threads to 0")); + ::arg().set("distributor-threads") = "0"; + } +} + int main(int argc, char** argv) { g_argc = argc; @@ -3128,7 +3259,9 @@ int main(int argc, char** argv) int ret = EXIT_SUCCESS; try { - initArgs(); + pdns::settings::rec::defineOldStyleSettings(); + ::arg().setDefaults(); + g_log.toConsole(Logger::Info); ::arg().laxParse(argc, argv); // do a lax parse if (::arg().mustDo("version")) { @@ -3158,9 +3291,10 @@ int main(int argc, char** argv) g_log.setLoglevel(s_logUrgency); g_log.toConsole(s_logUrgency); - string configname = ::arg()["config-dir"] + "/recursor.conf"; + g_yamlSettings = false; + string configname = ::arg()["config-dir"] + "/recursor"; if (!::arg()["config-name"].empty()) { - configname = ::arg()["config-dir"] + "/recursor-" + ::arg()["config-name"] + ".conf"; + configname = ::arg()["config-dir"] + "/recursor-" + ::arg()["config-name"]; g_programname += "-" + ::arg()["config-name"]; } cleanSlashes(configname); @@ -3207,18 +3341,52 @@ int main(int argc, char** argv) ::arg().setSLog(startupLog); - bool mustExit = false; - std::tie(ret, mustExit) = doConfig(startupLog, configname, argc, argv); - if (ret != 0 || mustExit) { - return ret; + const string yamlconfigname = configname + ".yml"; + string msg; + pdns::rust::settings::rec::Recursorsettings settings; + // TODO: handle include-dir on command line + auto yamlstatus = pdns::settings::rec::readYamlSettings(yamlconfigname, ::arg()["include-dir"], settings, msg, startupLog); + + switch (yamlstatus) { + case pdns::settings::rec::YamlSettingsStatus::CannotOpen: + SLOG(g_log << Logger::Debug << "No YAML config found for configname '" << yamlconfigname << "': " << msg << endl, + startupLog->error(Logr::Debug, msg, "No YAML config found", "configname", Logging::Loggable(yamlconfigname))); + break; + case pdns::settings::rec::YamlSettingsStatus::PresentButFailed: + SLOG(g_log << Logger::Error << "YAML config found for configname '" << yamlconfigname << "' but error ocurred processing it" << endl, + startupLog->error(Logr::Error, msg, "YAML config found, but error occurred processsing it", "configname", Logging::Loggable(yamlconfigname))); + return 1; + break; + case pdns::settings::rec::YamlSettingsStatus::OK: + g_yamlSettings = true; + SLOG(g_log << Logger::Notice << "YAML config found and processed for configname '" << yamlconfigname << "'" << endl, + startupLog->info(Logr::Notice, "YAML config found and processed", "configname", Logging::Loggable(yamlconfigname))); + pdns::settings::rec::bridgeStructToOldStyleSettings(settings); + break; } - if (!::arg().file(configname.c_str())) { - SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, - startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); + if (g_yamlSettings) { + bool mustExit = false; + std::tie(ret, mustExit) = doYamlConfig(startupLog, argc, argv); + if (ret != 0 || mustExit) { + return ret; + } + } + + if (yamlstatus == pdns::settings::rec::YamlSettingsStatus::CannotOpen) { + configname += ".conf"; + bool mustExit = false; + std::tie(ret, mustExit) = doConfig(startupLog, configname, argc, argv); + if (ret != 0 || mustExit) { + return ret; + } + if (!::arg().file(configname)) { + SLOG(g_log << Logger::Warning << "Unable to open configuration file '" << configname << "'" << endl, + startupLog->error("No such file", "Unable to open configuration file", "config_file", Logging::Loggable(configname))); + } } - // Reparse, now with config file as well + // Reparse, now with config file as well, both for old-style as for YAML settings ::arg().parse(argc, argv); g_quiet = ::arg().mustDo("quiet"); @@ -3240,32 +3408,7 @@ int main(int argc, char** argv) return EXIT_FAILURE; } - if (::arg()["socket-dir"].empty()) { - if (::arg()["chroot"].empty()) { - ::arg().set("socket-dir") = std::string(LOCALSTATEDIR) + "/pdns-recursor"; - } - else { - ::arg().set("socket-dir") = "/"; - } - } - - if (::arg().asNum("threads") == 1) { - if (::arg().mustDo("pdns-distributes-queries")) { - SLOG(g_log << Logger::Warning << "Asked to run with pdns-distributes-queries set but no distributor threads, raising to 1" << endl, - startupLog->v(1)->info("Only one thread, no need to distribute queries ourselves")); - ::arg().set("pdns-distributes-queries") = "no"; - } - } - - if (::arg().mustDo("pdns-distributes-queries") && ::arg().asNum("distributor-threads") <= 0) { - SLOG(g_log << Logger::Warning << "Asked to run with pdns-distributes-queries set but no distributor threads, raising to 1" << endl, - startupLog->v(1)->info("Asked to run with pdns-distributes-queries set but no distributor threads, raising to 1")); - ::arg().set("distributor-threads") = "1"; - } - - if (!::arg().mustDo("pdns-distributes-queries")) { - ::arg().set("distributor-threads") = "0"; - } + handleRuntimeDefaults(startupLog); g_recCache = std::make_unique(::arg().asNum("record-cache-shards")); g_negCache = std::make_unique(::arg().asNum("record-cache-shards") / 8); diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index da2cd43cfa20..b048da71a7ff 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -192,6 +192,7 @@ extern std::unique_ptr g_packetCache; using RemoteLoggerStats_t = std::unordered_map; +extern bool g_yamlSettings; extern bool g_logCommonErrors; extern size_t g_proxyProtocolMaximumSize; extern std::atomic g_quiet; diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index 34305559f546..dd290bb1d621 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -38,6 +38,8 @@ #include "rec-tcpout.hh" #include "rec-main.hh" +#include "settings/cxxsettings.hh" + std::pair PrefixDashNumberCompare::prefixAndTrailingNum(const std::string& a) { auto i = a.length(); @@ -2077,7 +2079,8 @@ static RecursorControlChannel::Answer help() "unload-lua-script unload Lua script\n" "version return Recursor version number\n" "wipe-cache domain0 [domain1] .. wipe domain data from cache\n" - "wipe-cache-typed type domain0 [domain1] .. wipe domain data with qtype from cache\n"}; + "wipe-cache-typed type domain0 [domain1] .. wipe domain data with qtype from cache\n" + "show-yaml [file] EXPERIMENTAL command to show yaml config derived from old-style config\n"}; } template @@ -2267,7 +2270,7 @@ RecursorControlChannel::Answer RecursorControlParser::getAnswer(int socket, cons g_log << Logger::Error << "Unable to reload zones and forwards when chroot()'ed, requested via control channel" << endl; return {1, "Unable to reload zones and forwards when chroot()'ed, please restart\n"}; } - return {0, reloadZoneConfiguration()}; + return {0, reloadZoneConfiguration(g_yamlSettings)}; } if (cmd == "set-ecs-minimum-ttl") { return {0, setMinimumECSTTL(begin, end)}; diff --git a/pdns/recursordist/rec_control.cc b/pdns/recursordist/rec_control.cc index 6e2ae91dc191..6264ae51220a 100644 --- a/pdns/recursordist/rec_control.cc +++ b/pdns/recursordist/rec_control.cc @@ -31,6 +31,7 @@ #include "credentials.hh" #include "namespaces.hh" #include "rec_channel.hh" +#include "settings/cxxsettings.hh" ArgvMap& arg() { @@ -63,27 +64,178 @@ static void initArguments(int argc, char** argv) exit(arg().mustDo("help") ? 0 : 99); } - string configname = ::arg()["config-dir"] + "/recursor.conf"; - if (::arg()["config-name"] != "") - configname = ::arg()["config-dir"] + "/recursor-" + ::arg()["config-name"] + ".conf"; + string configname = ::arg()["config-dir"] + "/recursor"; + if (!::arg()["config-name"].empty()) { + configname = ::arg()["config-dir"] + "/recursor-" + ::arg()["config-name"]; + } cleanSlashes(configname); - arg().laxFile(configname.c_str()); + const string yamlconfigname = configname + ".yml"; + string msg; + pdns::rust::settings::rec::Recursorsettings settings; - arg().laxParse(argc, argv); // make sure the commandline wins + auto yamlstatus = pdns::settings::rec::readYamlSettings(yamlconfigname, "", settings, msg, g_slog); + + switch (yamlstatus) { + case pdns::settings::rec::YamlSettingsStatus::CannotOpen: + break; + case pdns::settings::rec::YamlSettingsStatus::PresentButFailed: + cerr << "YAML config found for configname '" << yamlconfigname << "' but error ocurred processing it" << endl; + exit(1); // NOLINT(concurrency-mt-unsafe) + break; + case pdns::settings::rec::YamlSettingsStatus::OK: + cerr << "YAML config found and processed for configname '" << yamlconfigname << "'" << endl; + pdns::settings::rec::bridgeStructToOldStyleSettings(settings); + break; + } + if (yamlstatus == pdns::settings::rec::YamlSettingsStatus::CannotOpen) { + configname += ".conf"; + arg().laxFile(configname); + } + arg().laxParse(argc, argv); // make sure the commandline wins if (::arg()["socket-dir"].empty()) { - if (::arg()["chroot"].empty()) + if (::arg()["chroot"].empty()) { ::arg().set("socket-dir") = std::string(LOCALSTATEDIR) + "/pdns-recursor"; - else + } + else { ::arg().set("socket-dir") = ::arg()["chroot"] + "/"; + } } else if (!::arg()["chroot"].empty()) { ::arg().set("socket-dir") = ::arg()["chroot"] + "/" + ::arg()["socket-dir"]; } } +static std::string showIncludeYAML(::rust::String& rdirname) +{ + std::string msg; + if (rdirname.empty()) { + return msg; + } + const auto dirname = string(rdirname); + + std::vector confFiles; + ::arg().gatherIncludes(dirname, ".conf", confFiles); + msg += "# Found " + std::to_string(confFiles.size()) + " .conf file" + addS(confFiles.size()) + " in " + dirname + "\n"; + for (const auto& confFile : confFiles) { + auto converted = pdns::settings::rec::oldStyleSettingsFileToYaml(confFile, false); + msg += "# Converted include-dir " + confFile + " to YAML format:\n"; + msg += converted; + msg += "# Validation result: "; + try { + // Parse back and validate + auto settings = pdns::rust::settings::rec::parse_yaml_string(converted); + settings.validate(); + msg += "OK"; + } + catch (const rust::Error& err) { + msg += err.what(); + } + msg += "\n# End of converted " + confFile + "\n#\n"; + } + return msg; +} + +static std::string showForwardFileYAML(const ::rust::string& rfilename) +{ + std::string msg; + if (rfilename.empty() || boost::ends_with(rfilename, ".yml")) { + return msg; + } + const std::string filename = string(rfilename); + + msg += "# Converted " + filename + " to YAML format for recursor.forward_zones_file: \n"; + rust::Vec forwards; + pdns::settings::rec::oldStyleForwardsFileToBridgeStruct(filename, forwards); + auto yaml = pdns::rust::settings::rec::forward_zones_to_yaml_string(forwards); + msg += std::string(yaml); + msg += "# Validation result: "; + try { + pdns::rust::settings::rec::validate_forward_zones("forward_zones", forwards); + msg += "OK"; + } + catch (const rust::Error& err) { + msg += err.what(); + } + msg += "\n# End of converted " + filename + "\n#\n"; + return msg; +} + +static std::string showAllowYAML(const ::rust::String& rfilename, const string& section, const string& key, const std::function&)>& func) +{ + std::string msg; + if (rfilename.empty() || boost::ends_with(rfilename, ".yml")) { + return msg; + } + const std::string filename = string(rfilename); + + msg += "# Converted " + filename + " to YAML format for " + section + "." + key + ": \n"; + rust::Vec<::rust::String> allows; + pdns::settings::rec::oldStyleAllowFileToBridgeStruct(filename, allows); + auto yaml = pdns::rust::settings::rec::allow_from_to_yaml_string(allows); + msg += std::string(yaml); + msg += "# Validation result: "; + try { + func(key, allows); + msg += "OK"; + } + catch (const rust::Error& err) { + msg += err.what(); + } + msg += "\n# End of converted " + filename + "\n#\n"; + return msg; +} + +static RecursorControlChannel::Answer showYAML(const std::string& path) +{ + string configName = ::arg()["config-dir"] + "/recursor.conf"; + if (!::arg()["config-name"].empty()) { + configName = ::arg()["config-dir"] + "/recursor-" + ::arg()["config-name"] + ".conf"; + } + if (!path.empty()) { + configName = path; + } + cleanSlashes(configName); + + try { + std::string msg; + auto converted = pdns::settings::rec::oldStyleSettingsFileToYaml(configName, true); + msg += "# THIS IS A PROOF OF CONCEPT! STRUCTURE, TYPES AND NAMES ARE SUBJECT TO CHANGE\n"; + msg += "# Start of converted recursor.yml based on " + configName + "\n"; + msg += converted; + msg += "# Validation result: "; + pdns::rust::settings::rec::Recursorsettings mainsettings; + try { + // Parse back and validate + mainsettings = pdns::rust::settings::rec::parse_yaml_string(converted); + mainsettings.validate(); + msg += "OK"; + } + catch (const rust::Error& err) { + msg += err.what(); + } + msg += "\n# End of converted " + configName + "\n#\n"; + + msg += showIncludeYAML(mainsettings.recursor.include_dir); + msg += showForwardFileYAML(mainsettings.recursor.forward_zones_file); + msg += showAllowYAML(mainsettings.incoming.allow_from_file, "incoming", "allow_from_file", pdns::rust::settings::rec::validate_allow_from); + msg += showAllowYAML(mainsettings.incoming.allow_notify_from_file, "incoming", "allow_notify_from_file", pdns::rust::settings::rec::validate_allow_from); + msg += showAllowYAML(mainsettings.incoming.allow_notify_for_file, "incoming", "allow_notify_for_file", pdns::rust::settings::rec::validate_allow_for); + return {0, msg}; + } + catch (const rust::Error& err) { + return {1, std::string(err.what())}; + } + catch (const PDNSException& err) { + return {1, std::string(err.reason)}; + } + catch (const std::exception& err) { + return {1, std::string(err.what())}; + } +} + int main(int argc, char** argv) { g_slogStructured = false; @@ -114,7 +266,13 @@ int main(int argc, char** argv) const vector& commands = arg().getCommands(); - if (commands.size() >= 1 && commands.at(0) == "hash-password") { + if (!commands.empty() && commands.at(0) == "show-yaml") { + auto [ret, str] = showYAML(commands.size() > 1 ? commands.at(1) : ""); + cout << str << endl; + return ret; + } + + if (!commands.empty() && commands.at(0) == "hash-password") { uint64_t workFactor = CredentialsHolder::s_defaultWorkFactor; if (commands.size() > 1) { try { diff --git a/pdns/recursordist/reczones.cc b/pdns/recursordist/reczones.cc index 907a89fbe4b0..5b603c4da4db 100644 --- a/pdns/recursordist/reczones.cc +++ b/pdns/recursordist/reczones.cc @@ -24,12 +24,15 @@ #include "config.h" #endif +#include + #include "reczones-helpers.hh" #include "arguments.hh" #include "dnsrecords.hh" #include "logger.hh" #include "syncres.hh" #include "zoneparser-tng.hh" +#include "settings/cxxsettings.hh" extern int g_argc; extern char** g_argv; @@ -104,49 +107,75 @@ static void* pleaseUseNewSDomainsMap(std::shared_ptr newma return 0; } -string reloadZoneConfiguration() +string reloadZoneConfiguration(bool yaml) { std::shared_ptr original = SyncRes::getDomainMap(); auto log = g_slog->withName("config"); + string configname = ::arg()["config-dir"] + "/recursor"; + if (!::arg()["config-name"].empty()) { + configname = ::arg()["config-dir"] + "/recursor-" + ::arg()["config-name"]; + } + cleanSlashes(configname); + try { SLOG(g_log << Logger::Warning << "Reloading zones, purging data from cache" << endl, log->info(Logr::Notice, "Reloading zones, purging data from cache")); - string configname = ::arg()["config-dir"] + "/recursor.conf"; - if (::arg()["config-name"] != "") { - configname = ::arg()["config-dir"] + "/recursor-" + ::arg()["config-name"] + ".conf"; - } - cleanSlashes(configname); - - if (!::arg().preParseFile(configname.c_str(), "forward-zones")) - throw runtime_error("Unable to re-parse configuration file '" + configname + "'"); - ::arg().preParseFile(configname.c_str(), "forward-zones-file"); - ::arg().preParseFile(configname.c_str(), "forward-zones-recurse"); - ::arg().preParseFile(configname.c_str(), "auth-zones"); - ::arg().preParseFile(configname.c_str(), "allow-notify-for"); - ::arg().preParseFile(configname.c_str(), "allow-notify-for-file"); - ::arg().preParseFile(configname.c_str(), "export-etc-hosts", "off"); - ::arg().preParseFile(configname.c_str(), "serve-rfc1918"); - ::arg().preParseFile(configname.c_str(), "include-dir"); - ::arg().preParse(g_argc, g_argv, "include-dir"); - - // then process includes - std::vector extraConfigs; - ::arg().gatherIncludes(extraConfigs); - - for (const std::string& fn : extraConfigs) { - if (!::arg().preParseFile(fn.c_str(), "forward-zones", ::arg()["forward-zones"])) - throw runtime_error("Unable to re-parse configuration file include '" + fn + "'"); - ::arg().preParseFile(fn.c_str(), "forward-zones-file", ::arg()["forward-zones-file"]); - ::arg().preParseFile(fn.c_str(), "forward-zones-recurse", ::arg()["forward-zones-recurse"]); - ::arg().preParseFile(fn.c_str(), "auth-zones", ::arg()["auth-zones"]); - ::arg().preParseFile(fn.c_str(), "allow-notify-for", ::arg()["allow-notify-for"]); - ::arg().preParseFile(fn.c_str(), "allow-notify-for-file", ::arg()["allow-notify-for-file"]); - ::arg().preParseFile(fn.c_str(), "export-etc-hosts", ::arg()["export-etc-hosts"]); - ::arg().preParseFile(fn.c_str(), "serve-rfc1918", ::arg()["serve-rfc1918"]); + if (yaml) { + configname += ".yml"; + string msg; + pdns::rust::settings::rec::Recursorsettings settings; + // XXX Does ::arg()["include-dir"] have the right value, i.e. potentially overriden by command line? + auto yamlstatus = pdns::settings::rec::readYamlSettings(configname, ::arg()["include-dir"], settings, msg, log); + + switch (yamlstatus) { + case pdns::settings::rec::YamlSettingsStatus::CannotOpen: + throw runtime_error("Unable to open '" + configname + "': " + msg); + break; + case pdns::settings::rec::YamlSettingsStatus::PresentButFailed: + throw runtime_error("Error processing '" + configname + "': " + msg); + break; + case pdns::settings::rec::YamlSettingsStatus::OK: + // Does *not* set include-dir + pdns::settings::rec::setArgsForZoneRelatedSettings(settings); + break; + } } + else { + configname += ".conf"; + if (!::arg().preParseFile(configname, "forward-zones")) { + throw runtime_error("Unable to re-parse configuration file '" + configname + "'"); + } + ::arg().preParseFile(configname, "forward-zones-file"); + ::arg().preParseFile(configname, "forward-zones-recurse"); + ::arg().preParseFile(configname, "auth-zones"); + ::arg().preParseFile(configname, "allow-notify-for"); + ::arg().preParseFile(configname, "allow-notify-for-file"); + ::arg().preParseFile(configname, "export-etc-hosts", "off"); + ::arg().preParseFile(configname, "serve-rfc1918"); + ::arg().preParseFile(configname, "include-dir"); + ::arg().preParse(g_argc, g_argv, "include-dir"); + + // then process includes + std::vector extraConfigs; + ::arg().gatherIncludes(::arg()["include-dir"], ".conf", extraConfigs); + + for (const std::string& filename : extraConfigs) { + if (!::arg().preParseFile(filename, "forward-zones", ::arg()["forward-zones"])) { + throw runtime_error("Unable to re-parse configuration file include '" + filename + "'"); + } + ::arg().preParseFile(filename, "forward-zones-file", ::arg()["forward-zones-file"]); + ::arg().preParseFile(filename, "forward-zones-recurse", ::arg()["forward-zones-recurse"]); + ::arg().preParseFile(filename, "auth-zones", ::arg()["auth-zones"]); + ::arg().preParseFile(filename, "allow-notify-for", ::arg()["allow-notify-for"]); + ::arg().preParseFile(filename, "allow-notify-for-file", ::arg()["allow-notify-for-file"]); + ::arg().preParseFile(filename, "export-etc-hosts", ::arg()["export-etc-hosts"]); + ::arg().preParseFile(filename, "serve-rfc1918", ::arg()["serve-rfc1918"]); + } + } + // Process command line args potentially overriding what we read from config files ::arg().preParse(g_argc, g_argv, "forward-zones"); ::arg().preParse(g_argc, g_argv, "forward-zones-file"); ::arg().preParse(g_argc, g_argv, "forward-zones-recurse"); @@ -156,31 +185,31 @@ string reloadZoneConfiguration() ::arg().preParse(g_argc, g_argv, "export-etc-hosts"); ::arg().preParse(g_argc, g_argv, "serve-rfc1918"); - auto [newDomainMap, newNotifySet] = parseZoneConfiguration(); + auto [newDomainMap, newNotifySet] = parseZoneConfiguration(yaml); // purge both original and new names std::set oldAndNewDomains; - for (const auto& i : *newDomainMap) { - oldAndNewDomains.insert(i.first); + for (const auto& entry : *newDomainMap) { + oldAndNewDomains.insert(entry.first); } if (original) { - for (const auto& i : *original) { - oldAndNewDomains.insert(i.first); + for (const auto& entry : *original) { + oldAndNewDomains.insert(entry.first); } } // these explicitly-named captures should not be necessary, as lambda // capture of tuple-like structured bindings is permitted, but some // compilers still don't allow it - broadcastFunction([dm = newDomainMap] { return pleaseUseNewSDomainsMap(dm); }); - broadcastFunction([ns = newNotifySet] { return pleaseSupplantAllowNotifyFor(ns); }); + broadcastFunction([dmap = newDomainMap] { return pleaseUseNewSDomainsMap(dmap); }); + broadcastFunction([nsset = newNotifySet] { return pleaseSupplantAllowNotifyFor(nsset); }); // Wipe the caches *after* the new auth domain info has been set // up, as a query during setting up might fill the caches // again. Old code did the clear before, exposing a race. - for (const auto& i : oldAndNewDomains) { - wipeCaches(i, true, 0xffff); + for (const auto& entry : oldAndNewDomains) { + wipeCaches(entry, true, 0xffff); } return "ok\n"; } @@ -199,77 +228,149 @@ string reloadZoneConfiguration() return "reloading failed, see log\n"; } -std::tuple, std::shared_ptr> parseZoneConfiguration() +static void readAuthZoneData(SyncRes::AuthDomain& authDomain, const pair& headers, Logr::log_t log) { - auto log = g_slog->withName("config"); - - TXTRecordContent::report(); - OPTRecordContent::report(); + SLOG(g_log << Logger::Notice << "Parsing authoritative data for zone '" << headers.first << "' from file '" << headers.second << "'" << endl, + log->info(Logr::Notice, "Parsing authoritative data from file", "zone", Logging::Loggable(headers.first), "file", Logging::Loggable(headers.second))); + ZoneParserTNG zpt(headers.second, DNSName(headers.first)); + zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps")); + zpt.setMaxIncludes(::arg().asNum("max-include-depth")); + DNSResourceRecord resourceRecord; + DNSRecord dnsrecord; + while (zpt.get(resourceRecord)) { + try { + dnsrecord = DNSRecord(resourceRecord); + dnsrecord.d_place = DNSResourceRecord::ANSWER; + } + catch (std::exception& e) { + throw PDNSException("Error parsing record '" + resourceRecord.qname.toLogString() + "' of type " + resourceRecord.qtype.toString() + " in zone '" + headers.first + "' from file '" + headers.second + "': " + e.what()); + } + catch (...) { + throw PDNSException("Error parsing record '" + resourceRecord.qname.toLogString() + "' of type " + resourceRecord.qtype.toString() + " in zone '" + headers.first + "' from file '" + headers.second + "'"); + } - auto newMap = std::make_shared(); - auto newSet = std::make_shared(); + authDomain.d_records.insert(dnsrecord); + } +} - typedef vector parts_t; - parts_t parts; - const char* option_names[3] = {"auth-zones", "forward-zones", "forward-zones-recurse"}; - for (int n = 0; n < 3; ++n) { - parts.clear(); - stringtok(parts, ::arg()[option_names[n]], " ,\t\n\r"); - for (parts_t::const_iterator iter = parts.begin(); iter != parts.end(); ++iter) { - SyncRes::AuthDomain ad; - if ((*iter).find('=') == string::npos) - throw PDNSException("Error parsing '" + *iter + "', missing ="); - pair headers = splitField(*iter, '='); +static void processForwardZones(shared_ptr& newMap, Logr::log_t log) +{ + const std::array option_names = {"auth-zones", "forward-zones", "forward-zones-recurse"}; + + for (size_t option = 0; option < option_names.size(); ++option) { + vector parts; + stringtok(parts, ::arg()[option_names.at(option)], " ,\t\n\r"); + for (const auto& part : parts) { + SyncRes::AuthDomain authDomain; + if (part.find('=') == string::npos) { + throw PDNSException("Error parsing '" + part + "', missing ="); + } + pair headers = splitField(part, '='); boost::trim(headers.first); boost::trim(headers.second); - // headers.first=toCanonic("", headers.first); - if (n == 0) { - ad.d_rdForward = false; - SLOG(g_log << Logger::Notice << "Parsing authoritative data for zone '" << headers.first << "' from file '" << headers.second << "'" << endl, - log->info(Logr::Notice, "Parsing authoritative data from file", "zone", Logging::Loggable(headers.first), "file", Logging::Loggable(headers.second))); - ZoneParserTNG zpt(headers.second, DNSName(headers.first)); - zpt.setMaxGenerateSteps(::arg().asNum("max-generate-steps")); - zpt.setMaxIncludes(::arg().asNum("max-include-depth")); - DNSResourceRecord rr; - DNSRecord dr; - while (zpt.get(rr)) { - try { - dr = DNSRecord(rr); - dr.d_place = DNSResourceRecord::ANSWER; - } - catch (std::exception& e) { - throw PDNSException("Error parsing record '" + rr.qname.toLogString() + "' of type " + rr.qtype.toString() + " in zone '" + headers.first + "' from file '" + headers.second + "': " + e.what()); - } - catch (...) { - throw PDNSException("Error parsing record '" + rr.qname.toLogString() + "' of type " + rr.qtype.toString() + " in zone '" + headers.first + "' from file '" + headers.second + "'"); - } - - ad.d_records.insert(dr); - } + + if (option == 0) { + authDomain.d_rdForward = false; + readAuthZoneData(authDomain, headers, log); } else { - ad.d_rdForward = (n == 2); - convertServersForAD(headers.first, headers.second, ad, ";", log); + authDomain.d_rdForward = (option == 2); + convertServersForAD(headers.first, headers.second, authDomain, ";", log); } - ad.d_name = DNSName(headers.first); - (*newMap)[ad.d_name] = ad; + authDomain.d_name = DNSName(headers.first); + (*newMap)[authDomain.d_name] = authDomain; } } +} + +static void processApiZonesFile(shared_ptr& newMap, shared_ptr& newSet, Logr::log_t log) +{ + if (::arg()["api-config-dir"].empty()) { + return; + } + const auto filename = ::arg()["api-config-dir"] + "/apizones"; + struct stat statStruct + { + }; + // It's a TOCTU, but a harmless one + if (stat(filename.c_str(), &statStruct) != 0) { + return; + } + + SLOG(g_log << Logger::Notice << "Processing ApiZones YAML settings from " << filename << endl, + log->info(Logr::Notice, "Processing ApiZones YAML settings", "path", Logging::Loggable(filename))); + + const uint64_t before = newMap->size(); - if (!::arg()["forward-zones-file"].empty()) { - SLOG(g_log << Logger::Warning << "Reading zone forwarding information from '" << ::arg()["forward-zones-file"] << "'" << endl, - log->info(Logr::Notice, "Reading zone forwarding information", "file", Logging::Loggable(::arg()["forward-zones-file"]))); - auto fp = std::unique_ptr(fopen(::arg()["forward-zones-file"].c_str(), "r"), fclose); - if (!fp) { - throw PDNSException("Error opening forward-zones-file '" + ::arg()["forward-zones-file"] + "': " + stringerror()); + std::unique_ptr zones = pdns::rust::settings::rec::api_read_zones(filename); + zones->validate("apizones"); + + for (const auto& forward : zones->forward_zones) { + SyncRes::AuthDomain authDomain; + authDomain.d_name = DNSName(string(forward.zone)); + authDomain.d_rdForward = forward.recurse; + for (const auto& forwarder : forward.forwarders) { + ComboAddress addr = parseIPAndPort(string(forwarder), 53); + authDomain.d_servers.emplace_back(addr); + } + (*newMap)[authDomain.d_name] = authDomain; + if (forward.notify_allowed) { + newSet->insert(authDomain.d_name); + } + } + for (const auto& auth : zones->auth_zones) { + SyncRes::AuthDomain authDomain; + authDomain.d_name = DNSName(string(auth.zone)); + readAuthZoneData(authDomain, {string(auth.zone), string(auth.file)}, log); + (*newMap)[authDomain.d_name] = authDomain; + } + SLOG(g_log << Logger::Warning << "Done parsing " << newMap->size() - before + << " ApiZones YAML settings from file '" + << filename << "'" << endl, + log->info(Logr::Notice, "Done parsing ApiZones YAML from file", "file", + Logging::Loggable(filename), "count", + Logging::Loggable(newMap->size() - before))); +} + +static void processForwardZonesFile(shared_ptr& newMap, shared_ptr& newSet, Logr::log_t log) +{ + const auto filename = ::arg()["forward-zones-file"]; + if (filename.empty()) { + return; + } + const uint64_t before = newMap->size(); + + if (boost::ends_with(filename, ".yml")) { + ::rust::Vec vec; + pdns::settings::rec::readYamlForwardZonesFile(filename, vec, log); + for (const auto& forward : vec) { + SyncRes::AuthDomain authDomain; + authDomain.d_name = DNSName(string(forward.zone)); + authDomain.d_rdForward = forward.recurse; + for (const auto& forwarder : forward.forwarders) { + ComboAddress addr = parseIPAndPort(string(forwarder), 53); + authDomain.d_servers.emplace_back(addr); + } + (*newMap)[authDomain.d_name] = authDomain; + if (forward.notify_allowed) { + newSet->insert(authDomain.d_name); + } + } + } + else { + SLOG(g_log << Logger::Warning << "Reading zone forwarding information from '" << filename << "'" << endl, + log->info(Logr::Notice, "Reading zone forwarding information", "file", Logging::Loggable(filename))); + auto filePtr = std::unique_ptr(fopen(filename.c_str(), "r"), fclose); + if (!filePtr) { + int err = errno; + throw PDNSException("Error opening forward-zones-file '" + filename + "': " + stringerror(err)); } string line; int linenum = 0; - uint64_t before = newMap->size(); - while (linenum++, stringfgets(fp.get(), line)) { - SyncRes::AuthDomain ad; + while (linenum++, stringfgets(filePtr.get(), line)) { + SyncRes::AuthDomain authDomain; boost::trim(line); if (line[0] == '#') { // Comment line, skip to the next line continue; @@ -284,7 +385,7 @@ std::tuple, std::shared_ptr> if (instructions.empty()) { // empty line continue; } - throw PDNSException("Error parsing line " + std::to_string(linenum) + " of " + ::arg()["forward-zones-file"]); + throw PDNSException("Error parsing line " + std::to_string(linenum) + " of " + filename); } bool allowNotifyFor = false; @@ -292,7 +393,7 @@ std::tuple, std::shared_ptr> for (; !domain.empty(); domain.erase(0, 1)) { switch (domain[0]) { case '+': - ad.d_rdForward = true; + authDomain.d_rdForward = true; continue; case '^': allowNotifyFor = true; @@ -302,101 +403,148 @@ std::tuple, std::shared_ptr> } if (domain.empty()) { - throw PDNSException("Error parsing line " + std::to_string(linenum) + " of " + ::arg()["forward-zones-file"]); + throw PDNSException("Error parsing line " + std::to_string(linenum) + " of " + filename); } try { - convertServersForAD(domain, instructions, ad, ",; ", log, false); + convertServersForAD(domain, instructions, authDomain, ",; ", log, false); } catch (...) { - throw PDNSException("Conversion error parsing line " + std::to_string(linenum) + " of " + ::arg()["forward-zones-file"]); + throw PDNSException("Conversion error parsing line " + std::to_string(linenum) + " of " + filename); } - ad.d_name = DNSName(domain); - (*newMap)[ad.d_name] = ad; + authDomain.d_name = DNSName(domain); + (*newMap)[authDomain.d_name] = authDomain; if (allowNotifyFor) { - newSet->insert(ad.d_name); + newSet->insert(authDomain.d_name); } } - SLOG(g_log << Logger::Warning << "Done parsing " << newMap->size() - before - << " forwarding instructions from file '" - << ::arg()["forward-zones-file"] << "'" << endl, - log->info(Logr::Notice, "Done parsing forwarding instructions from file", "file", - Logging::Loggable(::arg()["forward-zones-file"]), "count", - Logging::Loggable(newMap->size() - before))); } + SLOG(g_log << Logger::Warning << "Done parsing " << newMap->size() - before + << " forwarding instructions from file '" + << filename << "'" << endl, + log->info(Logr::Notice, "Done parsing forwarding instructions from file", "file", + Logging::Loggable(filename), "count", + Logging::Loggable(newMap->size() - before))); +} - if (::arg().mustDo("export-etc-hosts")) { - string fname = ::arg()["etc-hosts-file"]; - ifstream ifs(fname.c_str()); - if (!ifs) { - SLOG(g_log << Logger::Warning << "Could not open " << fname << " for reading" << endl, - log->error(Logr::Warning, "Could not open file for reading", "file", Logging::Loggable(fname))); +static void processExportEtcHosts(std::shared_ptr& newMap, Logr::log_t log) +{ + if (!::arg().mustDo("export-etc-hosts")) { + return; + } + string fname = ::arg()["etc-hosts-file"]; + ifstream ifs(fname); + if (!ifs) { + SLOG(g_log << Logger::Warning << "Could not open " << fname << " for reading" << endl, + log->error(Logr::Warning, "Could not open file for reading", "file", Logging::Loggable(fname))); + return; + } + vector parts; + std::string line{}; + while (getline(ifs, line)) { + if (!parseEtcHostsLine(parts, line)) { + continue; } - else { - std::string line{}; - while (getline(ifs, line)) { - if (!parseEtcHostsLine(parts, line)) { - continue; - } - try { - string searchSuffix = ::arg()["export-etc-hosts-search-suffix"]; - addForwardAndReverseLookupEntries(*newMap, searchSuffix, parts, log); - } - catch (const PDNSException& ex) { - SLOG(g_log << Logger::Warning - << "The line `" << line << "` " - << "in the provided etc-hosts file `" << fname << "` " - << "could not be added: " << ex.reason << ". Going to skip it." - << endl, - log->info(Logr::Notice, "Skipping line in etc-hosts file", - "line", Logging::Loggable(line), - "hosts-file", Logging::Loggable(fname), - "reason", Logging::Loggable(ex.reason))); - } - } + try { + string searchSuffix = ::arg()["export-etc-hosts-search-suffix"]; + addForwardAndReverseLookupEntries(*newMap, searchSuffix, parts, log); + } + catch (const PDNSException& ex) { + SLOG(g_log << Logger::Warning + << "The line `" << line << "` " + << "in the provided etc-hosts file `" << fname << "` " + << "could not be added: " << ex.reason << ". Going to skip it." + << endl, + log->info(Logr::Notice, "Skipping line in etc-hosts file", + "line", Logging::Loggable(line), + "hosts-file", Logging::Loggable(fname), + "reason", Logging::Loggable(ex.reason))); } } +} - if (::arg().mustDo("serve-rfc1918")) { - SLOG(g_log << Logger::Warning << "Inserting rfc 1918 private space zones" << endl, - log->info(Logr::Notice, "Inserting rfc 1918 private space zones")); +static void processServeRFC1918(std::shared_ptr& newMap, Logr::log_t log) +{ + if (!::arg().mustDo("serve-rfc1918")) { + return; + } + SLOG(g_log << Logger::Warning << "Inserting rfc 1918 private space zones" << endl, + log->info(Logr::Notice, "Inserting rfc 1918 private space zones")); - makePartialIPZone(*newMap, {"127"}, log); - makePartialIPZone(*newMap, {"10"}, log); - makePartialIPZone(*newMap, {"192", "168"}, log); + makePartialIPZone(*newMap, {"127"}, log); + makePartialIPZone(*newMap, {"10"}, log); + makePartialIPZone(*newMap, {"192", "168"}, log); - for (int n = 16; n < 32; n++) { - makePartialIPZone(*newMap, {"172", std::to_string(n).c_str()}, log); - } + for (int count = 16; count < 32; count++) { + makePartialIPZone(*newMap, {"172", std::to_string(count).c_str()}, log); } +} - parts.clear(); +static void processAllowNotifyFor(shared_ptr& newSet) +{ + vector parts; stringtok(parts, ::arg()["allow-notify-for"], " ,\t\n\r"); for (auto& part : parts) { newSet->insert(DNSName(part)); } +} - if (auto anff = ::arg()["allow-notify-for-file"]; !anff.empty()) { - SLOG(g_log << Logger::Warning << "Reading NOTIFY-allowed zones from '" << anff << "'" << endl, - log->info(Logr::Notice, "Reading NOTIFY-allowed zones from file", "file", Logging::Loggable(anff))); - auto fp = std::unique_ptr(fopen(anff.c_str(), "r"), fclose); - if (!fp) { - throw PDNSException("Error opening allow-notify-for-file '" + anff + "': " + stringerror()); +static void processAllowNotifyForFile(shared_ptr& newSet, Logr::log_t log) +{ + const auto filename = ::arg()["allow-notify-for-file"]; + if (filename.empty()) { + return; + } + const uint64_t before = newSet->size(); + if (boost::ends_with(filename, ".yml")) { + ::rust::Vec<::rust::String> vec; + pdns::settings::rec::readYamlAllowNotifyForFile(filename, vec, log); + for (const auto& name : vec) { + newSet->insert(DNSName(string(name))); + } + } + else { + SLOG(g_log << Logger::Warning << "Reading NOTIFY-allowed zones from '" << filename << "'" << endl, + log->info(Logr::Notice, "Reading NOTIFY-allowed zones from file", "file", Logging::Loggable(filename))); + auto filePtr = std::unique_ptr(fopen(filename.c_str(), "r"), fclose); + if (!filePtr) { + throw PDNSException("Error opening allow-notify-for-file '" + filename + "': " + stringerror()); } string line; - uint64_t before = newSet->size(); - while (stringfgets(fp.get(), line)) { + while (stringfgets(filePtr.get(), line)) { boost::trim(line); - if (line[0] == '#') // Comment line, skip to the next line + if (line[0] == '#') { // Comment line, skip to the next line continue; + } newSet->insert(DNSName(line)); } - SLOG(g_log << Logger::Warning << "Done parsing " << newSet->size() - before << " NOTIFY-allowed zones from file '" << anff << "'" << endl, - log->info(Logr::Notice, "Done parsing NOTIFY-allowed zones from file", "file", Logging::Loggable(anff), "count", Logging::Loggable(newSet->size() - before))); } + SLOG(g_log << Logger::Warning << "Done parsing " << newSet->size() - before << " NOTIFY-allowed zones from file '" << filename << "'" << endl, + log->info(Logr::Notice, "Done parsing NOTIFY-allowed zones from file", "file", Logging::Loggable(filename), "count", Logging::Loggable(newSet->size() - before))); +} + +std::tuple, std::shared_ptr> parseZoneConfiguration(bool yaml) +{ + auto log = g_slog->withName("config"); + + TXTRecordContent::report(); + OPTRecordContent::report(); + + auto newMap = std::make_shared(); + auto newSet = std::make_shared(); + + processForwardZones(newMap, log); + processForwardZonesFile(newMap, newSet, log); + if (yaml) { + processApiZonesFile(newMap, newSet, log); + } + processExportEtcHosts(newMap, log); + processServeRFC1918(newMap, log); + processAllowNotifyFor(newSet); + processAllowNotifyForFile(newSet, log); return {newMap, newSet}; } diff --git a/pdns/recursordist/settings/.gitignore b/pdns/recursordist/settings/.gitignore new file mode 100644 index 000000000000..c5f95e343306 --- /dev/null +++ b/pdns/recursordist/settings/.gitignore @@ -0,0 +1,4 @@ +/Makefile +/Makefile.in +/cxxsettings-generated.cc +/settings-old-generated.rst diff --git a/pdns/recursordist/settings/Makefile.am b/pdns/recursordist/settings/Makefile.am new file mode 100644 index 000000000000..32b322d405a1 --- /dev/null +++ b/pdns/recursordist/settings/Makefile.am @@ -0,0 +1,19 @@ +EXTRA_DIST = \ + cxxsettings-private.hh \ + cxxsettings.hh \ + docs-old-preamble-in.rst \ + docs-new-preamble-in.rst \ + generate.py \ + rust-bridge-in.rs \ + rust-preamble-in.rs \ + table.py + +all: cxxsettings-generated.cc + +# It's a bit dirty that this target also generated a file inside rust/src (lib.rs) +cxxsettings-generated.cc: table.py generate.py rust-preamble-in.rs rust-bridge-in.rs docs-old-preamble-in.rst docs-new-preamble-in.rst + $(PYTHON) generate.py + +clean-local: + rm -f cxxsettings-generated.cc settings-old-generated.rst + diff --git a/pdns/recursordist/settings/README.md b/pdns/recursordist/settings/README.md new file mode 100644 index 000000000000..9d86c6d8271d --- /dev/null +++ b/pdns/recursordist/settings/README.md @@ -0,0 +1,227 @@ +SETTINGS CODE +============= +This directory contains the code to generate both old-style as new style (YAML) settings code. + +Inside this directory, there is a `rust` subdirectory that contains the Rust code and build files. +The Rust code uses CXX for bridging between C++ and Rust. +At the moment of writing, we only call Rust code from C++ and not vice versa. + +Additionally, the Rust Serde crate (and specifically Serde-YAML) is used to generatec code to handle YAML. + +The entry point for code generation is `generate.py`, which uses `table.py` to produce C++, Rust and .rst files. +See `generate.sh` for some details about the generation process. +This directory also contains a couple of `*-in.*` files which are included into files generated by the generation process. + +From the C++ point of view, several namespaces are defined: + +* `rust`: This namespace contains the classes defined by CXX. +Note that it is sometimes needed to explicitly name it `::rust`, as the `pdns` namespace also has a subnamespace called `rust`. +* `pdns::rust::settings::rec`: The classes and functions generated by CXX, callable from C++. +* `pdns::settings::rec`: The classes and functions of the settings code implemented in C++. This is mainly the code handling the conversion of old-style definitions to new-style (and vice versa). + +Internally, the old-style settings are still used by the recursor code. +Rewriting the existing code to start using the new style settings directly would have made the PR introducing the new-style settings even bigger. +Therefore, we chose to keep the code *using* settings the same. +If a new-style settings YAML file is encountered, it will be parsed, validated and the resulting new-style settings will be used to set the old-style settings to the values found in the YAML file. +In the future, when old-style settings do not need to be supported any longer, the recursor itself can start to use the new style settings directly. + +A `rec_control show-yaml [file]` command has been added to show the conversion of old-style settings to the new-style YAML. + +This directory +-------------- +* `cxxsettings-generated.cc`: generated code that implements the C++ part of the settings code. +* `cxxsettings-private.hh`: private interface used by C++ settings code internally. +* `cxxsettings.hh`: public interface of C++ code to be used by pdns_recursor and rec_control. +* `cxxsupport.cc`: hand written C++ code. +* `docs-new-preamble-in.rst`: non-generated part of new settings docs. +* `docs-old-preamble-in.rst`: non-generated part of old settings docs. +* `generate.py`: the Python script to produce C++, Rust and .rst files based on `table.py`. +* `rust`: the directory containing rust code. +* `rust-bridge-in.rs`: file included in the generated Rust code, placed inside the CXX bridge module. +* `rust-preamble-in.rs`: file included in the generated Rust code as a preamble. +* `table.py`: the definitions of all settings. + +`rust` subdirectory +------------------- +* `Cargo.toml`: The definition of the Rust `settings` crate, including its dependencies. +* `build.rs`: `The custom build file used by CXX, see CXX docs. +* `cxx.h`: The generic types used by CXX generated code. +* `lib.rs.h`: The project specific C++ types generated by CXX. +* `libsettings.a`: The actual static library procuced by this crate. +* `src`: The actual rust code, `lib.rs` is generated, `bridge.rs` and `helpers.rs` are maintained manually. +* `target`: The `cargo` maintained Rust build directory. + +The YAML settings are stored in a struct called (on the C++ side) `pdns::rust::settings::rec::Recursorsettings`. +This struct has a substruct for each section defined. +Each section has multiple typed variables. +Below we will tour some parts of the (generated) code. +An example settings file in YAML format: + +```yaml +dnssec: + log_bogus: true +incoming: + listen: + - 0.0.0.0:5301 + - '[::]:5301' +logging: + common_errors: true + disable_syslog: true + loglevel: 6 +recursor: + daemon: false + extended_resolution_errors: true + socket_dir: /tmp/rec + threads: 4 +webservice: + address: 127.0.0.1 + allow_from: + - 0.0.0.0/0 + api_key: secret + port: 8083 + webserver: true +``` + +The generated code +------------------ +C++, Rust and docmentation generating is done by the `generate.py` Python script using `table.py` as input. +After that, the C++ to Rust bridge code is generated by CXX. +Lets take a look at the `log_bogus` setting. +The source of its definition is in `table.py`: + +```python + { + 'name' : 'log_bogus', + 'section' : 'dnssec', + 'oldname' : 'dnssec-log-bogus', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Log DNSSEC bogus validations', + 'doc' : ''' +Log every DNSSEC validation failure. +**Note**: This is not logged per-query but every time records are validated as Bogus. + ''', + }, +``` + +The old-style documention generated for this can be found in `../docs/settings.rst`: + +``` +.. _setting-dnssec-log-bogus: + +``dnssec-log-bogus`` +~~~~~~~~~~~~~~~~~~~~ + +- Boolean +- Default: no + +- YAML setting: :ref:`setting-yaml-dnssec.log_bogus` + +Log every DNSSEC validation failure. +**Note**: This is not logged per-query but every time records are validated as Bogus. +``` + +The new-style documention generated for this can be found in `../docs/yamlsettings.rst`, its name includes the section and it lists a YAML default: + +``` +.. _setting-yaml-dnssec.log_bogus: + +``dnssec.log_bogus`` +^^^^^^^^^^^^^^^^^^^^ + +- Boolean +- Default: ``false`` + +- Old style setting: :ref:`setting-dnssec-log-bogus` + +Log every DNSSEC validation failure. +**Note**: This is not logged per-query but every time records are validated as Bogus. +``` + +The C++ code generated from this entry can be found in `cxxsettings-generated.cc`. +The code to define the old-style settings, which is called by the recursor very early after startup and is a replacement for the hand-written code that defines all settings in the old recursor code. +Using generated code and generated docs makes sure the docs and the actual implementation are consistent. +Something which was not true for the old code in all cases. + +```cpp +void pdns::settings::rec::defineOldStyleSettings() + ... + ::arg().setSwitch("dnssec-log-bogus", "Log DNSSEC bogus validations") = "no"; + ... +``` + +There is also code generated to assign the current value of old-style `log_bogus` value to the right field in a `Recursorsettings` struct. +This code is used to convert the currently active settings to a YAML file (`pdns_recursor --config=diff`): +```cpp +void pdns::settings::rec::oldStyleSettingsToBridgeStruct(Recursorsettings& settings) + ... + settings.dnssec.log_bogus = arg().mustDo("dnssec-log-bogus"); + ... +``` + +Plus code to set the old-style setting, given a new-style struct: + +```cpp +void pdns::settings::rec::bridgeStructToOldStyleSettings(const Recursorsettings& settings) + ... + ::arg().set("dnssec-log-bogus") = to_arg(settings.dnssec.log_bogus); + ... +``` + +Lastly, there is code to support converting a old-style settings to a new-style struct found in `pdns::settings::rec::oldKVToBridgeStruct()`. +This code is used to convert old style settings files to YAML (used by `rec_control show-yaml`) and to generate a yaml file with all the defaults values (used by `pdns_recursor --config=default`). +The functions implementing that are `pdns::settings::rec::oldStyleSettingsFileToYaml` and `std::string pdns::settings::rec::defaultsToYaml()`, found in `cxxsupport.cc`. + +The Rust code generated by `generate.py` can be found in `rust/src/lib.rs`. +It contains these snippets that define the `log_bogus` field in the section struct `Dnssec` and the `dnssec` field in the `Recursorsettings` struct: + +```rust +pub struct Dnssec { + ... + #[serde(default, skip_serializing_if = "crate::is_default")] + log_bogus: bool, + ... +} +pub struct Recursorsettings { + ... + #[serde(default, skip_serializing_if = "crate::is_default")] + dnssec: Dnssec, + ... +} +``` +The `rust/src/lib.rs` file also contains the generated code to handle Serde defaults. +More details on this can be found in `generate.py`. + +The C++ version of the `Recursorsettings` struct and its substructs can be found in the CXX generated `rust/lib.rs.h` file: + +```cpp +struct Recursorsettings final { + ... + ::pdns::rust::settings::rec::Dnssec dnssec; + ... + }; + ... +struct Dnssec final { + ... + bool log_bogus; + ... +}; +``` + +The Rust functions callable from C++ are listed in `rust-bridge-in.rs` which gets included into `rust/src/lib.rs` by `generate.py` +An example is the function + +```rust + fn parse_yaml_string(str: &String) -> Result; +``` + +Which parses YAML and produces a struct with all the settings. +Settings that are not mentioned in the YAML string wil have their default value. + +`rust/lib.rs.h` contains the corresponding C++ prototype, defined in the `pdns::rust::settings::rec` namespace: + +```cpp +::pdns::rust::settings::rec::Recursorsettings parse_yaml_string(::rust::String const &str); +``` + +The C++ function `pdns::settings::rec::readYamlSettings()` defined in `cxxsupport.cc` and called in `../rec-main.cc` calls the Rust function `pdns::rust::settings::rec::parse_yaml_string()` to do the actual YAML parsing. \ No newline at end of file diff --git a/pdns/recursordist/settings/cxxsettings-private.hh b/pdns/recursordist/settings/cxxsettings-private.hh new file mode 100644 index 000000000000..9c049d01dd0f --- /dev/null +++ b/pdns/recursordist/settings/cxxsettings-private.hh @@ -0,0 +1,97 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +#include +#include +#include +#include + +#include "rust/lib.rs.h" +#include "misc.hh" + +using pdns::rust::settings::rec::AuthZone; +using pdns::rust::settings::rec::ForwardZone; +using pdns::rust::settings::rec::Recursorsettings; + +namespace pdns::settings::rec +{ +::rust::Vec<::rust::String> getStrings(const std::string& name); +::rust::Vec getForwardZones(const std::string& name); +::rust::Vec getAuthZones(const std::string& name); + +inline std::string to_arg(bool arg) +{ + return arg ? "yes" : "no"; +} + +inline std::string to_arg(uint64_t arg) +{ + return std::to_string(arg); +} + +inline std::string to_arg(double arg) +{ + return std::to_string(arg); +} + +inline std::string to_arg(const ::rust::String& str) +{ + return std::string(str); +} + +std::string to_arg(const AuthZone& authzone); +std::string to_arg(const ForwardZone& forwardzone); + +template +std::string to_arg(const ::rust::Vec& vec) +{ + std::ostringstream str; + for (auto iter = vec.begin(); iter != vec.end(); ++iter) { + if (iter != vec.begin()) { + str << ','; + } + str << to_arg(*iter); + } + return str.str(); +} + +inline void to_yaml(bool& field, const std::string& val) +{ + field = val != "no" && val != "off"; +} + +inline void to_yaml(::rust::String& field, const std::string& val) +{ + field = val; +} + +inline void to_yaml(::rust::Vec<::rust::String>& field, const std::string& val) +{ + stringtok(field, val, ", ;"); +} + +void to_yaml(uint64_t& field, const std::string& val); +void to_yaml(double& field, const std::string& val); +void to_yaml(::rust::Vec& field, const std::string& val); +void to_yaml(::rust::Vec& field, const std::string& val, bool recurse = false); +} diff --git a/pdns/recursordist/settings/cxxsettings.hh b/pdns/recursordist/settings/cxxsettings.hh new file mode 100644 index 000000000000..7577e86d320f --- /dev/null +++ b/pdns/recursordist/settings/cxxsettings.hh @@ -0,0 +1,52 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +#include +#include "rust/cxx.h" +#include "rust/lib.rs.h" +#include "logging.hh" + +namespace pdns::settings::rec +{ +enum YamlSettingsStatus : uint8_t +{ + OK, + CannotOpen, + PresentButFailed, +}; + +void defineOldStyleSettings(); +void oldStyleSettingsToBridgeStruct(pdns::rust::settings::rec::Recursorsettings& settings); +void oldStyleForwardsFileToBridgeStruct(const std::string& filename, ::rust::Vec& vec); +void oldStyleAllowFileToBridgeStruct(const std::string& filename, ::rust::Vec<::rust::String>& vec); +bool oldKVToBridgeStruct(string& key, const string& value, ::rust::String& section, ::rust::String& fieldname, ::rust::String& type_name, pdns::rust::settings::rec::Value& rustvalue); +std::string oldStyleSettingsFileToYaml(const string& fname, bool mainFile); +std::string defaultsToYaml(); +YamlSettingsStatus readYamlSettings(const std::string& configname, const std::string& includeDirOnCommandLine, rust::settings::rec::Recursorsettings& settings, std::string& msg, Logr::log_t log); +void bridgeStructToOldStyleSettings(const pdns::rust::settings::rec::Recursorsettings& settings); +void readYamlForwardZonesFile(const std::string& filename, ::rust::Vec& vec, Logr::log_t log); +void readYamlAllowFromFile(const std::string& filename, ::rust::Vec<::rust::String>& vec, Logr::log_t log); +void readYamlAllowNotifyForFile(const std::string& filename, ::rust::Vec<::rust::String>& vec, Logr::log_t log); +void setArgsForZoneRelatedSettings(pdns::rust::settings::rec::Recursorsettings& settings); +void setArgsForACLRelatedSettings(pdns::rust::settings::rec::Recursorsettings& settings); +} diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc new file mode 100644 index 000000000000..84c3f1c455be --- /dev/null +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -0,0 +1,512 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include +#include + +#include "namespaces.hh" +#include "arguments.hh" +#include "misc.hh" +#include "cxxsettings.hh" +#include "cxxsettings-private.hh" +#include "logger.hh" +#include "logging.hh" + +::rust::Vec<::rust::String> pdns::settings::rec::getStrings(const std::string& name) +{ + ::rust::Vec<::rust::String> vec; + to_yaml(vec, arg()[name]); + return vec; +} + +::rust::Vec pdns::settings::rec::getForwardZones(const string& name) +{ + ::rust::Vec vec; + const auto recurse = name == "forward-zones-recurse"; + to_yaml(vec, arg()[name], recurse); + return vec; +} + +::rust::Vec pdns::settings::rec::getAuthZones(const string& name) +{ + ::rust::Vec vec; + to_yaml(vec, arg()[name]); + return vec; +} + +void pdns::settings::rec::oldStyleForwardsFileToBridgeStruct(const std::string& file, ::rust::Vec& vec) +{ + auto filePtr = std::unique_ptr(fopen(file.c_str(), "r"), fclose); + if (!filePtr) { + throw PDNSException("Error opening forward-zones-file '" + file + "': " + stringerror()); + } + + string line; + int linenum = 0; + while (linenum++, stringfgets(filePtr.get(), line)) { + boost::trim(line); + if (line.length() == 0 || line.at(0) == '#') { // Comment line, skip to the next line + continue; + } + auto [domain, instructions] = splitField(line, '='); + instructions = splitField(instructions, '#').first; // Remove EOL comments + boost::trim(domain); + boost::trim(instructions); + if (domain.empty() || instructions.empty()) { + throw PDNSException("Error parsing line " + std::to_string(linenum) + " of " + file); + } + bool allowNotify = false; + bool recurse = false; + for (; !domain.empty(); domain.erase(0, 1)) { + switch (domain[0]) { + case '+': + recurse = true; + continue; + case '^': + allowNotify = true; + continue; + } + break; + } + if (domain.empty()) { + throw PDNSException("Error parsing line " + std::to_string(linenum) + " of " + file); + } + ::rust::Vec<::rust::String> addresses; + stringtok(addresses, instructions, ",; "); + ForwardZone forwardzone{domain, addresses, recurse, allowNotify}; + vec.push_back(std::move(forwardzone)); + } +} + +void pdns::settings::rec::oldStyleAllowFileToBridgeStruct(const std::string& file, ::rust::Vec<::rust::String>& vec) +{ + string line; + ifstream ifs(file); + if (!ifs) { + int err = errno; + throw runtime_error("Could not open '" + file + "': " + stringerror(err)); + } + + while (getline(ifs, line)) { + auto pos = line.find('#'); + if (pos != string::npos) { + line.resize(pos); + } + boost::trim(line); + if (line.empty()) { + continue; + } + vec.emplace_back(line); + } +} + +static void mergeYamlSubFile(const std::string& configname, Recursorsettings& settings, Logr::log_t log) +{ + SLOG(g_log << Logger::Notice << "Processing YAML settings from " << configname << endl, + log->info(Logr::Notice, "Processing YAML settings", "path", Logging::Loggable(configname))); + auto file = ifstream(configname); + if (!file.is_open()) { + throw runtime_error("Cannot open " + configname); + } + auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); + pdns::rust::settings::rec::merge(settings, data); +} + +pdns::settings::rec::YamlSettingsStatus pdns::settings::rec::readYamlSettings(const std::string& configname, const std::string& includeDirOnCommandLine, Recursorsettings& settings, std::string& msg, Logr::log_t log) +{ + auto file = ifstream(configname); + if (!file.is_open()) { + msg = stringerror(errno); + return YamlSettingsStatus::CannotOpen; + } + SLOG(g_log << Logger::Notice << "Processing main YAML settings from " << configname << endl, + log->info(Logr::Notice, "Processing main YAML settings", "path", Logging::Loggable(configname))); + try { + auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); + auto yamlstruct = pdns::rust::settings::rec::parse_yaml_string(data); + std::vector yamlFiles; + ::arg().gatherIncludes(!includeDirOnCommandLine.empty() ? includeDirOnCommandLine : string(yamlstruct.recursor.include_dir), + ".yml", yamlFiles); + for (const auto& yamlfile : yamlFiles) { + mergeYamlSubFile(yamlfile, yamlstruct, log); + } + yamlstruct.validate(); + settings = yamlstruct; + return YamlSettingsStatus::OK; + } + catch (const ::rust::Error& ex) { + msg = ex.what(); + return YamlSettingsStatus::PresentButFailed; + } + catch (const std::exception& ex) { + msg = ex.what(); + return YamlSettingsStatus::PresentButFailed; + } + catch (...) { + msg = "Unexpected exception processing YAML"; + return YamlSettingsStatus::PresentButFailed; + } +} + +void pdns::settings::rec::readYamlAllowFromFile(const std::string& filename, ::rust::Vec<::rust::String>& vec, Logr::log_t log) +{ + SLOG(g_log << Logger::Notice << "Processing allow YAML settings from " << filename << endl, + log->info(Logr::Notice, "Processing allow YAML settings", "path", Logging::Loggable(filename))); + auto file = ifstream(filename); + if (!file.is_open()) { + throw runtime_error(stringerror(errno)); + } + auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); + auto yamlvec = pdns::rust::settings::rec::parse_yaml_string_to_allow_from(data); + pdns::rust::settings::rec::validate_allow_from(filename, yamlvec); + vec = yamlvec; +} + +void pdns::settings::rec::readYamlForwardZonesFile(const std::string& filename, ::rust::Vec& vec, Logr::log_t log) +{ + SLOG(g_log << Logger::Notice << "Processing forwarding YAML settings from " << filename << endl, + log->info(Logr::Notice, "Processing forwarding YAML settings", "path", Logging::Loggable(filename))); + auto file = ifstream(filename); + if (!file.is_open()) { + throw runtime_error(stringerror(errno)); + } + auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); + auto yamlvec = pdns::rust::settings::rec::parse_yaml_string_to_forward_zones(data); + pdns::rust::settings::rec::validate_forward_zones("forward_zones", yamlvec); + vec = yamlvec; +} + +void pdns::settings::rec::readYamlAllowNotifyForFile(const std::string& filename, ::rust::Vec<::rust::String>& vec, Logr::log_t log) +{ + SLOG(g_log << Logger::Notice << "Processing allow-notify-for YAML settings from " << filename << endl, + log->info(Logr::Notice, "Processing allow-notify-for YAML settings", "path", Logging::Loggable(filename))); + auto file = ifstream(filename); + if (!file.is_open()) { + throw runtime_error(stringerror(errno)); + } + auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); + auto yamlvec = pdns::rust::settings::rec::parse_yaml_string_to_allow_notify_for(data); + pdns::rust::settings::rec::validate_allow_notify_for("allow-notify-for", yamlvec); + vec = yamlvec; +} + +std::string pdns::settings::rec::to_arg(const AuthZone& authzone) +{ + std::ostringstream str; + str << to_arg(authzone.zone) << '=' << to_arg(authzone.file); + return str.str(); +} + +std::string pdns::settings::rec::to_arg(const ForwardZone& forwardzone) +{ + std::ostringstream str; + str << to_arg(forwardzone.zone) << '='; + const auto& vec = forwardzone.forwarders; + for (auto iter = vec.begin(); iter != vec.end(); ++iter) { + if (iter != vec.begin()) { + str << ';'; + } + str << to_arg(*iter); + } + return str.str(); +} + +void pdns::settings::rec::setArgsForZoneRelatedSettings(Recursorsettings& settings) +{ + ::arg().set("forward-zones") = to_arg(settings.recursor.forward_zones); + ::arg().set("forward-zones-file") = to_arg(settings.recursor.forward_zones_file); + ::arg().set("forward-zones-recurse") = to_arg(settings.recursor.forward_zones_recurse); + ::arg().set("auth-zones") = to_arg(settings.recursor.auth_zones); + ::arg().set("allow-notify-for") = to_arg(settings.incoming.allow_notify_for); + ::arg().set("allow-notify-for-file") = to_arg(settings.incoming.allow_notify_for_file); + ::arg().set("export-etc-hosts") = to_arg(settings.recursor.export_etc_hosts); + ::arg().set("serve-rfc1918") = to_arg(settings.recursor.serve_rfc1918); +} + +void pdns::settings::rec::setArgsForACLRelatedSettings(Recursorsettings& settings) +{ + ::arg().set("allow-from") = to_arg(settings.incoming.allow_from); + ::arg().set("allow-from-file") = to_arg(settings.incoming.allow_from_file); + ::arg().set("allow-notify-from") = to_arg(settings.incoming.allow_notify_from); + ::arg().set("allow-notify-from-file") = to_arg(settings.incoming.allow_notify_from_file); +} + +void pdns::settings::rec::to_yaml(uint64_t& field, const std::string& val) +{ + if (val.empty()) { + field = 0; + return; + } + + checked_stoi_into(field, val, nullptr, 0); +} + +void pdns::settings::rec::to_yaml(double& field, const std::string& val) +{ + if (val.empty()) { + field = 0.0; + return; + } + + const auto* cptr_orig = val.c_str(); + char* cptr_ret = nullptr; + auto retval = strtod(cptr_orig, &cptr_ret); + + field = retval; +} + +void pdns::settings::rec::to_yaml(::rust::Vec& field, const std::string& val) +{ + vector zones; + stringtok(zones, val, " ,\t\n\r"); + for (const auto& zone : zones) { + auto headers = splitField(zone, '='); + boost::trim(headers.first); + boost::trim(headers.second); + AuthZone authzone{headers.first, headers.second}; + field.push_back(std::move(authzone)); + } +} + +void pdns::settings::rec::to_yaml(::rust::Vec& field, const std::string& val, bool recurse) +{ + vector zones; + stringtok(zones, val, " ,\t\n\r"); + for (const auto& zone : zones) { + auto headers = splitField(zone, '='); + boost::trim(headers.first); + boost::trim(headers.second); + ::rust::Vec<::rust::String> addresses; + stringtok(addresses, headers.second, " ;"); + ForwardZone forwardzone{headers.first, addresses, recurse, false}; + field.push_back(std::move(forwardzone)); + } +} + +using FieldMap = std::map, pdns::rust::settings::rec::OldStyle>; + +static bool simpleRustType(const ::rust::String& rname) +{ + return rname == "bool" || rname == "u64" || rname == "f64" || rname == "String"; +} + +static void processLine(const std::string& arg, FieldMap& map, bool mainFile) +{ + string var; + string val; + string::size_type pos = 0; + bool incremental = false; + + if (arg.find("--") == 0 && (pos = arg.find("+=")) != string::npos) // this is a --port+=25 case + { + var = arg.substr(2, pos - 2); + val = arg.substr(pos + 2); + incremental = true; + } + else if (arg.find("--") == 0 && (pos = arg.find('=')) != string::npos) // this is a --port=25 case + { + var = arg.substr(2, pos - 2); + val = arg.substr(pos + 1); + } + else if (arg.find("--") == 0 && (arg.find('=') == string::npos)) // this is a --daemon case + { + var = arg.substr(2); + val = ""; + } + else if (arg[0] == '-' && arg.length() > 1) { + var = arg.substr(1); + val = ""; + } + boost::trim(var); + if (var.empty()) { + return; + } + pos = val.find_first_not_of(" \t"); // strip leading whitespace + if (pos != 0 && pos != string::npos) { + val = val.substr(pos); + } + + ::rust::String section; + ::rust::String fieldname; + ::rust::String type_name; + pdns::rust::settings::rec::Value rustvalue; + if (pdns::settings::rec::oldKVToBridgeStruct(var, val, section, fieldname, type_name, rustvalue)) { + auto overriding = !mainFile && !incremental && !simpleRustType(type_name); + auto [existing, inserted] = map.emplace(std::pair{std::pair{section, fieldname}, pdns::rust::settings::rec::OldStyle{section, fieldname, var, type_name, rustvalue, overriding}}); + if (!inserted) { + // Simple values overwrite always + existing->second.value.bool_val = rustvalue.bool_val; + existing->second.value.u64_val = rustvalue.u64_val; + existing->second.value.f64_val = rustvalue.f64_val; + existing->second.value.string_val = rustvalue.string_val; + // List values only if = was used + if (!incremental) { + existing->second.value.vec_string_val.clear(); + existing->second.value.vec_forwardzone_val.clear(); + existing->second.value.vec_authzone_val.clear(); + } + for (const auto& add : rustvalue.vec_string_val) { + existing->second.value.vec_string_val.emplace_back(add); + } + for (const auto& add : rustvalue.vec_forwardzone_val) { + existing->second.value.vec_forwardzone_val.emplace_back(add); + } + for (const auto& add : rustvalue.vec_authzone_val) { + existing->second.value.vec_authzone_val.emplace_back(add); + } + } + } +} + +std::string pdns::settings::rec::oldStyleSettingsFileToYaml(const string& fname, bool mainFile) +{ + string line; + string pline; + + std::ifstream configFileStream(fname); + if (!configFileStream) { + int err = errno; + throw runtime_error("Cannot read " + fname + ": " + stringerror(err)); + } + + // Read the old-style config file and produce a map with the data, taking into account the + // difference between = and += + FieldMap map; + while (getline(configFileStream, pline)) { + boost::trim_right(pline); + + if (!pline.empty() && pline[pline.size() - 1] == '\\') { + line += pline.substr(0, pline.length() - 1); + continue; + } + + line += pline; + + // strip everything after a # + string::size_type pos = line.find('#'); + if (pos != string::npos) { + // make sure it's either first char or has whitespace before + // fixes issue #354 + if (pos == 0 || (std::isspace(line[pos - 1]) != 0)) { + line = line.substr(0, pos); + } + } + + // strip trailing spaces + boost::trim_right(line); + + // strip leading spaces + pos = line.find_first_not_of(" \t\r\n"); + if (pos != string::npos) { + line = line.substr(pos); + } + + processLine("--" + line, map, mainFile); + line = ""; + } + + // Convert the map to a vector, as CXX does not have any dictionary like support. + ::rust::Vec vec; + vec.reserve(map.size()); + for (const auto& entry : map) { + vec.emplace_back(entry.second); + } + return std::string(pdns::rust::settings::rec::map_to_yaml_string(vec)); +} + +std::string pdns::settings::rec::defaultsToYaml() +{ + // In this function we make use of the fact that we know a little about the formatting of YAML by + // serde_yaml. ATM there's no way around that, as serde_yaml itself does not have any support for + // comments (other than stripping them while parsing). So produced YAML cannot have any comments. + + // First we construct a map of (section, name) to info about the field (oldname, type, value etc) + FieldMap map; + for (const auto& var : arg().list()) { + if (const auto newname = ArgvMap::isDeprecated(var); !newname.empty()) { + continue; + } + ::rust::String section; + ::rust::String fieldname; + ::rust::String type_name; + pdns::rust::settings::rec::Value rustvalue; + + string name = var; + string val = arg().getDefault(var); + if (pdns::settings::rec::oldKVToBridgeStruct(name, val, section, fieldname, type_name, rustvalue)) { + map.emplace(std::pair{std::pair{section, fieldname}, pdns::rust::settings::rec::OldStyle{section, fieldname, name, type_name, rustvalue, false}}); + } + } + // Convert the map to a vector, as CXX does not have any dictionary like support. + ::rust::Vec vec; + vec.reserve(map.size()); + for (const auto& entry : map) { + vec.emplace_back(entry.second); + } + const auto defs = std::string(pdns::rust::settings::rec::map_to_yaml_string(vec)); + + // We now have a YAML string, with all sections and all default values. Do a litle bit of parsing + // to insert the help text lines. + std::vector lines; + stringtok(lines, defs, "\n"); + std::string res; + + // These two RE's know about the formatting generated by serde_yaml + std::regex sectionRE("^(\\w+):"); + std::regex fieldRE("^ (\\w+):"); + std::string section; + std::string field; + + for (const auto& line : lines) { + bool withHelp = false; + bool sectionChange = false; + std::smatch matches; + std::regex_search(line, matches, sectionRE); + if (!matches.empty()) { + section = matches[1]; + sectionChange = true; + } + std::regex_search(line, matches, fieldRE); + if (!matches.empty()) { + field = matches[1]; + withHelp = true; + } + if (withHelp) { + auto oldname = std::string(map.find(make_pair(section, field))->second.old_name); + res += "##### "; + res += arg().getHelp(oldname); + res += '\n'; + } + if (sectionChange) { + res += "\n######### SECTION "; + res += section; + res += " #########\n"; + res += line; + } + else { + res += "# "; + res += line; + } + res += '\n'; + } + return res; +} diff --git a/pdns/recursordist/settings/docs-new-preamble-in.rst b/pdns/recursordist/settings/docs-new-preamble-in.rst new file mode 100644 index 000000000000..e59cb5d1dba8 --- /dev/null +++ b/pdns/recursordist/settings/docs-new-preamble-in.rst @@ -0,0 +1,185 @@ +PowerDNS Recursor New Style (YAML) Settings +=========================================== + +Each setting can appear on the command line, prefixed by ``--`` and using the old style name, or in configuration files. +Settings on the command line are processed after the file-based settings are processed. + +.. note:: + Starting with version 5.0.0., :program:`Recursor` supports a new YAML syntax for configuration files + as described here. + A configuration using the old style syntax can be converted to a YAML configuration using the instructions in :doc:`appendices/yamlconversion`. + In a future release support for the "old-style" settings will be dropped. + + +YAML settings file +------------------ +Please refer to e.g. ``_ +for a description of YAML syntax. + +A :program:`Recursor` configuration file has several sections. For example, ``incoming`` for +settings related to receiving queries and ``dnssec`` for settings related to DNSSEC processing. + +An example :program:`Recursor` YAML configuration file looks like: + +.. code-block:: yaml + + dnssec: + log_bogus: true + incoming: + listen: + - 0.0.0.0:5301 + - '[::]:5301' + recursor: + extended_resolution_errors: true + forward_zones: + - zone: example.com + forwarders: + - 127.0.0.1:5301 + outgoing: + query_local_address: + - 0.0.0.0 + - '::' + logging: + loglevel: 6 + +Take care when listing IPv6 addresses, as characters used for these are special to YAML. +If in doubt, quote any string containing ``:``, ``[`` or ``]`` and use (online) tools to check your YAML syntax. +Specify an empty sequence using ``[]``. + +The main setting file is called ``recursor.yml`` and will be processed first. +This settings file might refer to other files via the `recursor.include_dir`_ setting. +The next section will describe how settings specified in multiple files are merged. + +Merging multiple setting files +------------------------------ +If `recursor.include_dir`_ is set, all ``.yml`` files in it will be processed in alphabetical order, modifying the settings processed so far. + +For simple values like an boolean or number setting, a value in the processed file will overwrite an existing setting. + +For values of type sequence, the new value will *replace* the existing value if the existing value is equal to the ``default`` or if the new value is marked with the ``!override`` tag. +Otherwise, the existing value will be *extended* with the new value by appending the new sequence to the existing. + +For example, with the above example ``recursor.yml`` and an include directory containing a file ``extra.yml``: + +.. code-block:: yaml + + dnssec: + log_bogus: false + recursor: + forward_zones: + - zone: example.net + forwarders: + - '::1' + outgoing: + query_local_address: !override + - 0.0.0.0 + dont_query: [] + +After merging, ``dnssec.log_bogus`` will be ``false``, the sequence of ``recursor.forward_zones`` will contain 2 zones and the ``outgoing`` addresses used will contain one entry, as the ``extra.yml`` entry has overwritten the existing one. + +``outgoing.dont-query`` has a non-empty sequence as default value. The main ``recursor.yml`` did not set it, so before processing ``extra.yml`` had the default value. +After processing ``extra.yml`` the value will be set to the empty sequence, as existing default values are overwritten by new values. + +.. warning:: + The merging process does not process values deeper than the second level. + For example if the main ``recursor.yml`` specified a forward zone + + .. code-block:: yaml + + forward_zones: + - zone: example.net + forwarders: + - '::1' + + and another settings file contains + + .. code-block:: yaml + + forward_zones: + - zone: example.net + forwarders: + - '::2' + + The result will *not* be a a single forward with two IP addresses, but two entries for ``example.net``. + It depends on the specific setting how the sequence is processed further. + In the future we might add a check for this case. + +Socket Address +^^^^^^^^^^^^^^ +A socket address is either an IP or and IP:port combination +For example: + +.. code-block:: yaml + + some_key: 127.0.0.1 + another_key: '[::1]:8080' + +Subnet +^^^^^^ +A subnet is a single IP address or an IP address followed by a slash and a prefix length. +If no prefix length is specified, ``/32`` or ``/128`` is assumed, indicating a single IP address. +Subnets can also be prefixed with a ``!``, specifying negation. +This can be used to deny addresses from a previously allowed range. + +For example, ``alow-from`` takes a sequence of subnets: + +.. code-block:: yaml + + allow_from: + - '2001:DB8::/32' + - 128.66.0.0/16 + - !128.66.1.2 + +In this case the address ``128.66.1.2`` is excluded from the addresses allowed access. + +Forward Zone +^^^^^^^^^^^^ +A forward zone is defined as: + +.. code-block:: yaml + + zone: zonename + forwarders: + - Socket Address + - ... + recurse: Boolean, default false + allow_notify: Boolean, default false + +An example of a ``forward_zones`` entry, which consists of a sequence of forward zone entries: + +.. code-block:: yaml + + - zone: example1.com + forwarders: + - 127.0.0.1 + - 127.0.0.1:5353 + - '[::1]53' + - zone: example2.com + forwarders: + - '::1' + recurse: true + notify_allowed: true + + +Auth Zone +^^^^^^^^^ +A auth zone is defined as: + +.. code-block:: yaml + + zone: name + file: filename + +An example of a ``auth_zones`` entry, consisting of a sequence of auth zones: + +.. code-block:: yaml + + auth_zones: + - zone: example.com + file: zones/example.com.zone + - zone: example.net + file: zones/example.net.zone + +The YAML settings +----------------- + diff --git a/pdns/recursordist/settings/docs-old-preamble-in.rst b/pdns/recursordist/settings/docs-old-preamble-in.rst new file mode 100644 index 000000000000..19ca61dcb2c9 --- /dev/null +++ b/pdns/recursordist/settings/docs-old-preamble-in.rst @@ -0,0 +1,39 @@ +PowerDNS Recursor Settings +========================== +Each setting can appear on the command line, prefixed by ``--``, or in the configuration file. +The command line overrides the configuration file. + +.. note:: + Starting with version 5.0.0, :program:`Recursor` supports a new YAML syntax for configuration files. + A configuration using the old style syntax can be converted to a YAML configuration using the instructions in :doc:`appendices/yamlconversion`. + In a future release support for the "old-style" settings will be dropped. + +.. note:: + Settings marked as ``Boolean`` can either be set to an empty value, which means **on**, or to ``no`` or ``off`` which means **off**. + Anything else means **on**. + + For example: + + - ``serve-rfc1918`` on its own means: do serve those zones. + - ``serve-rfc1918 = off`` or ``serve-rfc1918 = no`` means: do not serve those zones. + - Anything else means: do serve those zones. + +You can use ``+=`` syntax to set some variables incrementally, but this +requires you to have at least one non-incremental setting for the +variable to act as base setting. This is mostly useful for +:ref:`setting-include-dir` directive. An example:: + + forward-zones = foo.example.com=192.168.100.1; + forward-zones += bar.example.com=[1234::abcde]:5353; + +When a list of **Netmasks** is mentioned, a list of subnets can be specified. +A subnet that is not followed by ``/`` will be interpreted as a ``/32`` or ``/128`` subnet (a single address), depending on address family. +For most settings, it is possible to exclude ranges by prefixing an item with the negation character ``!``. +For example:: + + allow-from = 2001:DB8::/32, 128.66.0.0/16, !128.66.1.2 + +In this case the address ``128.66.1.2`` is excluded from the addresses allowed access. + +The Settings +------------ diff --git a/pdns/recursordist/settings/generate.py b/pdns/recursordist/settings/generate.py new file mode 100644 index 000000000000..b3e3d7df457c --- /dev/null +++ b/pdns/recursordist/settings/generate.py @@ -0,0 +1,743 @@ +"""The Python script that takes table.py and generates C++, Rust ahd .rst code.""" +# +# For C++ it generates cxxsettings-generated.cc containing support for old style +# settings plus conversion from old style to new style. +# +# For Rust it generates rust/src/lib.rs, containing the structs with +# CXX and Serde annotations and associated code. rust-preamble-in.rs is +# included before the generated code and rus-bridge-in.rs inside the +# bridge module in the generated lib.rs. Header files generated by CXX +# (lib.rs.h and cxx.h) are copied from deep inside the generated code +# hierarchy into the rust subdir as well. +# +# Two documentation files are generated: ../docs/settings.rst and +# ../docs/yamlsettings.rst. Each of these files have a preamble as +# well, describing the syntax and giving some examples. +# +# An example table.py entry: +# +# { +# 'name' : "allow_from", +# 'section' : "incoming", +# 'oldname' : "allow-from", +# 'type' : LType.ListSubnets, +# 'default' : "127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, +# 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10", +# 'help' : "If set, only allow these comma separated netmasks to recurse", +# 'doc' : """ +# """ +# } +# +# The fields are: +# +# name: short name within section, also yaml key, must be unique within section and not a C++ or +# Rust keyword +# section: yaml section +# oldname: name in old style settings, must be unique globally +# type : logical type (leave the space before the : as pylint is buggy parsing lines with type +# immediately followed by colon)x +# default: default value, use 'true' and 'false' for Booleans +# help: short help text +# doc: the docs text will be put here +# doc-rst: optional .rst annotations, typically used for ..version_added/changed:: +# doc-new: optional docs text specific to YAML format, e.g. not talking about comma separated +# lists and giving YAML examples. (optional) +# skip-yamL: optional if this key is present, the field wil be skipped in the new style settings. +# Use for deprecated settings, the generated code will use deprecated map from arg() +# to handle old names when converting .conf to .yml +# versionadded: string or list of strings +# +# The above struct will generate in cxxsettings-generated.cc: +# +# ::arg().set("allow-from", "If set, only allow these comma separated netmasks to recurse") = \ +# "127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, ..."; +# +# For Rust, it will generate a field `allow_from' within struct Incoming. +# As CXX places restrictions on the Serde code (which means we cannot +# use Serde extensions) we have to handle the default value and "skip if +# default" functions ourselves. +# +# There are three cases: +# +# 1. Default is the same as the Rust default for the type +# In that case, the field becomes: +# +# #[serde(default, skip_serializing_if = "crate::is_default")] +# nameoffield: bool +# +# 2. Type is primitive and default value is different from the Rust default, e.g.: +# +# #[serde(default = "crate::U64::<2000>::value", +# skip_serializing_if = "crate::U64::<2000>::is_equal")] +# nameoffield: u64 +# +# U64 is implemented in rust/src/helpers.rs +# +# 3. Type is not primitive and has default value different from Rust default, e.g.: +# +# [serde(default = "crate::default_value_incoming_allow_from", +# skip_serializing_if = "crate::default_value_equal_incoming_allow_from")] +# allow_from: Vec +# +# The two functions default_value_incoming_allow_from() and +# default_value_equal_incoming_allow_from() are also generated. +# +from enum import Enum +from enum import auto +import os +import re +import sys + +class LType(Enum): + """The type we handle in table.py""" + Bool = auto() + Command = auto() + Double = auto() + ListAuthZones = auto() + ListSocketAddresses = auto() + ListStrings = auto() + ListSubnets = auto() + ListForwardZones = auto() + String = auto() + Uint64 = auto() + +def get_olddoc_typename(typ): + """Given a type from table.py, return the old-style type name""" + if typ == LType.Bool: + return 'Boolean' + if typ == LType.Uint64: + return 'Integer' + if typ == LType.Double: + return 'Double' + if typ == LType.String: + return 'String' + if typ == LType.ListSocketAddresses: + return 'Comma separated list or IPs of IP:port combinations' + if typ == LType.ListSubnets: + return 'Comma separated list of IP addresses or subnets, negation supported' + if typ == LType.ListStrings: + return 'Comma separated list of strings' + if typ == LType.ListForwardZones: + return 'Comma separated list of \'zonename=IP\' pairs' + if typ == LType.ListAuthZones: + return 'Comma separated list of \'zonename=filename\' pairs' + return 'Unknown' + str(typ) + +def get_newdoc_typename(typ): + """Given a type from table.py, return the new-style type name""" + if typ == LType.Bool: + return 'Boolean' + if typ == LType.Uint64: + return 'Integer' + if typ == LType.Double: + return 'Double' + if typ == LType.String: + return 'String' + if typ == LType.ListSocketAddresses: + return 'Sequence of `Socket Address`_ (IP or IP:port combinations)' + if typ == LType.ListSubnets: + return 'Sequence of `Subnet`_ (IP addresses or subnets, negation supported)' + if typ == LType.ListStrings: + return 'Sequence of strings' + if typ == LType.ListForwardZones: + return 'Sequence of `Forward Zone`_' + if typ == LType.ListAuthZones: + return 'Sequence of `Auth Zone`_' + return 'Unknown' + str(typ) + +def get_default_olddoc_value(typ, val): + """Given a type and a value from table.py return the old doc representation of the value""" + if typ == LType.Bool: + if val == 'false': + return 'no' + return 'yes' + if val == '': + return '(empty)' + return val + +def get_default_newdoc_value(typ, val): + """Given a type and a value from table.py return the new doc representation of the value""" + if typ in (LType.Bool, LType.Uint64, LType.Double): + return '``' + val + '``' + if typ == LType.String and val == '': + return '(empty)' + if typ == LType.String: + return '``' + val + '``' + if val == '': + return '``[]``' + return '``[' + val + ']``' + +def get_rust_type(typ): + """Determine which Rust type is used for a logical type""" + if typ == LType.Bool: + return 'bool' + if typ == LType.Uint64: + return 'u64' + if typ == LType.Double: + return 'f64' + if typ == LType.String: + return 'String' + if typ == LType.ListSocketAddresses: + return 'Vec' + if typ == LType.ListSubnets: + return 'Vec' + if typ == LType.ListStrings: + return 'Vec' + if typ == LType.ListForwardZones: + return 'Vec' + if typ == LType.ListAuthZones: + return 'Vec' + return 'Unknown' + str(typ) + +def quote(arg): + """Return a quoted string""" + return '"' + arg + '"' + +def gen_cxx_defineoldsettings(file, entries): + """Generate C++ code to declare old-style settings""" + file.write('void pdns::settings::rec::defineOldStyleSettings()\n{\n') + for entry in entries: + helptxt = quote(entry['help']) + oldname = quote(entry['oldname']) + if entry['type'] == LType.Bool: + if entry['default'] == "true": + cxxdef = "yes" + else: + cxxdef = "no" + cxxdef = quote(cxxdef) + file.write(f" ::arg().setSwitch({oldname}, {helptxt}) = {cxxdef};\n") + elif entry['type'] == LType.Command: + file.write(f" ::arg().setCmd({oldname}, {helptxt});\n") + else: + file.write(f" ::arg().set({oldname}, {helptxt}) = {quote(entry['default'])};\n") + file.write('}\n\n') + +def gen_cxx_oldstylesettingstobridgestruct(file, entries): + """Generate C++ code the convert old-style settings to new-style struct""" + file.write('void pdns::settings::rec::oldStyleSettingsToBridgeStruct') + file.write('(Recursorsettings& settings)\n{\n') + for entry in entries: + if entry['type'] == LType.Command: + continue + if 'skip-yaml' in entry: + continue + rust_type = get_rust_type(entry['type']) + name = entry['name'] + oldname = entry['oldname'] + section = entry['section'] + file.write(f' settings.{section}.{name} = ') + if rust_type == 'bool': + file.write(f'arg().mustDo("{oldname}")') + elif rust_type == 'u64': + file.write(f'static_cast(arg().asNum("{oldname}"))') + elif rust_type == 'f64': + file.write(f'arg().asDouble("{oldname}")') + elif rust_type == 'String': + file.write(f'arg()["{oldname}"]') + elif rust_type == 'Vec': + file.write(f'getStrings("{oldname}")') + elif rust_type == 'Vec': + file.write(f'getForwardZones("{oldname}")') + elif rust_type == 'Vec': + file.write(f'getAuthZones("{oldname}")') + else: + file.write(f'Unknown type {rust_type}\n') + file.write(';\n') + file.write('}\n\n') + +def gen_cxx_oldkvtobridgestruct(file, entries): + """Generate C++ code for oldKVToBridgeStruct""" + file.write('// Inefficient, but only meant to be used for one-time conversion purposes\n') + file.write('bool pdns::settings::rec::oldKVToBridgeStruct(std::string& key, ') + file.write('const std::string& value, ::rust::String& section, ::rust::String& fieldname, ') + file.write('::rust::String& type_name, pdns::rust::settings::rec::Value& rustvalue)') + file.write('{ // NOLINT(readability-function-cognitive-complexity)\n') + file.write(' if (const auto newname = arg().isDeprecated(key); !newname.empty()) {\n') + file.write(' key = newname;\n') + file.write(' }\n') + for entry in entries: + if entry['type'] == LType.Command: + continue + if 'skip-yaml' in entry: + continue + rust_type = get_rust_type(entry['type']) + extra = '' + if entry['oldname'] == 'forward-zones-recurse': + extra = ', true' + name = entry['name'] + section = entry['section'] + oldname = entry['oldname'] + file.write(f' if (key == "{oldname}") {{\n') + file.write(f' section = "{section}";\n') + file.write(f' fieldname = "{name}";\n') + file.write(f' type_name = "{rust_type}";\n') + if rust_type == 'bool': + file.write(f' to_yaml(rustvalue.bool_val, value{extra});\n') + file.write(' return true;\n }\n') + elif rust_type == 'u64': + file.write(f' to_yaml(rustvalue.u64_val, value{extra});\n') + file.write(' return true;\n }\n') + elif rust_type == 'f64': + file.write(f' to_yaml(rustvalue.f64_val, value{extra});\n') + file.write(' return true;\n }\n') + elif rust_type == 'String': + file.write(f' to_yaml(rustvalue.string_val, value{extra});\n') + file.write(' return true;\n }\n') + elif rust_type == 'Vec': + file.write(f' to_yaml(rustvalue.vec_string_val, value{extra});\n') + file.write(' return true;\n }\n') + elif rust_type == 'Vec': + file.write(f' to_yaml(rustvalue.vec_forwardzone_val, value{extra});\n') + file.write(' return true;\n }\n') + elif rust_type == 'Vec': + file.write(f' to_yaml(rustvalue.vec_authzone_val, value{extra});\n') + file.write(' return true;\n }\n') + else: + file.write(f'Unknown type {rust_type}\n') + file.write(' return false;\n') + file.write('}\n\n') + +def gen_cxx_brigestructtoldstylesettings(file, entries): + """Generate C++ Code for bridgeStructToOldStyleSettings""" + file.write('void pdns::settings::rec::bridgeStructToOldStyleSettings') + file.write('(const Recursorsettings& settings)\n{\n') + for entry in entries: + if entry['type'] == LType.Command: + continue + if 'skip-yaml' in entry: + continue + section = entry['section'].lower() + name = entry['name'] + oldname = entry['oldname'] + file.write(f' ::arg().set("{oldname}") = ') + file.write(f'to_arg(settings.{section}.{name});\n') + file.write('}\n') + +def gen_cxx(entries): + """Generate the C++ code from the defs in table.py""" + with open('cxxsettings-generated.cc', mode='w', encoding="UTF-8") as file: + file.write('// THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir\n\n') + file.write('#include "arguments.hh"\n') + file.write('#include "cxxsettings.hh"\n') + file.write('#include "cxxsettings-private.hh"\n\n') + gen_cxx_defineoldsettings(file, entries) + gen_cxx_oldstylesettingstobridgestruct(file, entries) + gen_cxx_oldkvtobridgestruct(file, entries) + gen_cxx_brigestructtoldstylesettings(file, entries) + +def is_value_rust_default(typ, value): + """Is a value (represented as string) the same as its corresponding Rust default?""" + if typ == 'bool': + return value == 'false' + if typ == 'u64': + return value in ('0', '') + if typ == 'f64': + return value == '0.0' + if typ == 'String': + return value == '' + return False + +def gen_rust_forwardzonevec_default_fucntions(name): + """Generate Rust code for the default handling of a vector for ForwardZones""" + ret = f'// DEFAULT HANDLING for {name}\n' + ret += f'fn default_value_{name}() -> Vec {{\n' + ret += ' Vec::new()\n' + ret += '}\n' + ret += f'fn default_value_equal_{name}(value: &Vec)' + ret += '-> bool {\n' + ret += f' let def = default_value_{name}();\n' + ret += ' &def == value\n' + ret += '}\n\n' + return ret + +def gen_rust_authzonevec_default_functions(name): + """Generate Rust code for the default handling of a vector for AuthZones""" + ret = f'// DEFAULT HANDLING for {name}\n' + ret += f'fn default_value_{name}() -> Vec {{\n' + ret += ' Vec::new()\n' + ret += '}\n' + ret += f'fn default_value_equal_{name}(value: &Vec)' + ret += '-> bool {\n' + ret += f' let def = default_value_{name}();\n' + ret += ' &def == value\n' + ret += '}\n\n' + return ret + +# Example snippet generated +# fn default_value_general_query_local_address() -> Vec { +# vec![String::from("0.0.0.0"), ] +#} +#fn default_value_equal_general_query_local_address(value: &Vec) -> bool { +# let def = default_value_general_query_local_address(); +# &def == value +#} +def gen_rust_stringvec_default_functions(entry, name): + """Generate Rust code for the default handling of a vector for Strings""" + ret = f'// DEFAULT HANDLING for {name}\n' + ret += f'fn default_value_{name}() -> Vec {{\n' + parts = re.split('[ \t,]+', entry['default']) + if len(parts) > 0: + ret += ' vec![\n' + for part in parts: + if part == '': + continue + ret += f' String::from({quote(part)}),\n' + ret += ' ]\n' + else: + ret += ' vec![]\n' + ret += '}\n' + ret += f'fn default_value_equal_{name}(value: &Vec) -> bool {{\n' + ret += f' let def = default_value_{name}();\n' + ret += ' &def == value\n' + ret += '}\n\n' + return ret + +def gen_rust_default_functions(entry, name, rust_type): + """Generate Rust code for the default handling""" + if entry['type'] in (LType.ListSocketAddresses, LType.ListSubnets, LType.ListStrings): + return gen_rust_stringvec_default_functions(entry, name) + if entry['type'] == LType.ListForwardZones: + return gen_rust_forwardzonevec_default_fucntions(name) + if entry['type'] == LType.ListAuthZones: + return gen_rust_authzonevec_default_functions(name) + ret = f'// DEFAULT HANDLING for {name}\n' + ret += f'fn default_value_{name}() -> {rust_type} {{\n' + ret += f" String::from({quote(entry['default'])})\n" + ret += '}\n' + if rust_type == 'String': + rust_type = 'str' + ret += f'fn default_value_equal_{name}(value: &{rust_type})' + ret += '-> bool {\n' + ret += f' value == default_value_{name}()\n' + ret += '}\n\n' + return ret + +def write_rust_field(file, entry, default_funcs): + """Generate Rust code for a field with Serde annotations""" + rust_type = get_rust_type(entry['type']) + the_default = entry['default'] + is_rust_default = is_value_rust_default(rust_type, the_default) + if is_rust_default: + file.write(' #[serde(default, skip_serializing_if = "crate::is_default")]\n') + else: + if entry['type'] == LType.Bool: + file.write(' #[serde(default = "crate::Bool::::value", ') + file.write('skip_serializing_if = "crate::if_true")]\n') + elif entry['type'] == LType.Uint64: + file.write(f' #[serde(default = "crate::U64::<{the_default}>::value", ') + file.write(f'skip_serializing_if = "crate::U64::<{the_default}>::is_equal")]\n') + else: + basename = entry['section'] + '_' + entry['name'] + file.write(f' #[serde(default = "crate::default_value_{basename}", ') + file.write(f'skip_serializing_if = "crate::default_value_equal_{basename}")]\n') + default_funcs.append(gen_rust_default_functions(entry, basename, rust_type)) + file.write(f" {entry['name']}: {rust_type},\n\n") + +def write_rust_section(file, section, entries, default_funcs): + """Generate Rust code for a Section with Serde annotations""" + file.write(f' // SECTION {section.capitalize()}\n') + file.write(' #[derive(Deserialize, Serialize, Debug, PartialEq)]\n') + file.write(' #[serde(deny_unknown_fields)]\n') + file.write(f' pub struct {section.capitalize()} {{\n') + for entry in entries: + if entry['section'] != section: + continue + if entry['type'] == LType.Command: + continue + if 'skip-yaml' in entry: + continue + write_rust_field(file, entry, default_funcs) + file.write(f' }}\n // END SECTION {section.capitalize()}\n\n') + +# +# Each section als has a Default implementation, so that a section with all entries having a default +# value does not get generated into a yaml section. Such a tarit looks like: +# +#impl Default for recsettings::ForwardZone { +# fn default() -> Self { +# let deserialized: recsettings::ForwardZone = serde_yaml::from_str("").unwrap(); +# deserialized +# } +#} + +def write_rust_default_trait_impl(file, section): + """Generate Rust code for the default Trait for a section""" + file.write(f'impl Default for recsettings::{section.capitalize()} {{\n') + file.write(' fn default() -> Self {\n') + file.write(' let deserialized: recsettings::') + file.write(f'{section.capitalize()} = serde_yaml::from_str("").unwrap();\n') + file.write(' deserialized\n') + file.write(' }\n') + file.write('}\n\n') + +def write_validator(file, section, entries): + """Generate Rust code for the Validator Trait for a section""" + file.write(f'impl Validate for recsettings::{section.capitalize()} {{\n') + file.write(' fn validate(&self) -> Result<(), ValidationError> {\n') + for entry in entries: + if entry['section'] != section: + continue + name = entry['name'].lower() + typ = entry['type'] + if typ == LType.ListSubnets: + validator = 'validate_subnet' + elif typ == LType.ListSocketAddresses: + validator = 'validate_socket_address' + elif typ == LType.ListForwardZones: + validator = '|field, element| element.validate(field)' + elif typ == LType.ListAuthZones: + validator = '|field, element| element.validate(field)' + else: + continue + file.write(f' let fieldname = "{section.lower()}.{name}".to_string();\n') + file.write(f' validate_vec(&fieldname, &self.{name}, {validator})?;\n') + file.write(' Ok(())\n') + file.write(' }\n') + file.write('}\n\n') + +def write_rust_merge_trait_impl(file, section, entries): + """Generate Rust code for the Merge Trait for a section""" + file.write(f'impl Merge for recsettings::{section.capitalize()} {{\n') + file.write(' fn merge(&mut self, rhs: &mut Self, map: Option<&serde_yaml::Mapping>) {\n') + file.write(' if let Some(m) = map {\n') + for entry in entries: + if entry['section'] != section: + continue + if 'skip-yaml' in entry: + continue + rtype = get_rust_type(entry['type']) + name = entry['name'] + file.write(f' if m.contains_key("{name}") {{\n') + if rtype in ('bool', 'u64', 'f64', 'String'): + file.write(f' self.{name} = rhs.{name}.to_owned();\n') + else: + file.write(f' if is_overriding(m, "{name}") || ') + file.write(f'self.{name} == DEFAULT_CONFIG.{section}.{name} {{\n') + file.write(f' self.{name}.clear();\n') + file.write(' }\n') + file.write(f' merge_vec(&mut self.{name}, &mut rhs.{name});\n') + file.write(' }\n') + file.write(' }\n') + file.write(' }\n') + file.write('}\n\n') + +def gen_rust(entries): + """Generate Rust code all entries""" + def_functions = [] + sections = {} + with open('rust/src/lib.rs', mode='w', encoding='UTF-8') as file: + file.write('// THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir\n') + file.write('// START INCLUDE rust-preable-in.rs\n') + with open('rust-preamble-in.rs', mode='r', encoding='UTF-8') as pre: + file.write(pre.read()) + file.write('// END INCLUDE rust-preamble-in.rs\n\n') + + file.write('#[cxx::bridge(namespace = "pdns::rust::settings::rec")]\n') + file.write('mod recsettings {\n') + with open('rust-bridge-in.rs', mode='r', encoding='UTF-8') as bridge: + file.write(' // START INCLUDE rust-bridge-in.rs\n') + for line in bridge: + file.write(' ' + line) + + file.write(' // END INCLUDE rust-bridge-in.rs\n\n') + for entry in entries: + if entry['section'] == 'commands': + continue + sections[entry['section']] = entry['section'] + + for section in sections: + write_rust_section(file, section, entries, def_functions) + + file.write(' #[derive(Serialize, Deserialize, Debug)]\n') + file.write(' #[serde(deny_unknown_fields)]\n') + file.write(' pub struct Recursorsettings {\n') + for section in sections: + file.write(' #[serde(default, skip_serializing_if = "crate::is_default")]\n') + file.write(f' {section.lower()}: {section.capitalize()},\n') + file.write('} // End of generated structs\n') + file.write('}\n') + + for section in sections: + write_rust_default_trait_impl(file, section) + write_rust_default_trait_impl(file, 'Recursorsettings') + + for section in sections: + write_validator(file, section, entries) + + file.write('impl crate::recsettings::Recursorsettings {\n') + file.write(' fn validate(&self) -> Result<(), ValidationError> {\n') + for section in sections: + file.write(f' self.{section.lower()}.validate()?;\n') + file.write(' Ok(())\n') + file.write(' }\n') + file.write('}\n\n') + + for section in sections: + write_rust_merge_trait_impl(file, section, entries) + + file.write('impl Merge for crate::recsettings::Recursorsettings {\n') + file.write(' fn merge(&mut self, rhs: &mut Self, map: Option<&serde_yaml::Mapping>) {\n') + file.write(' if let Some(m) = map {\n') + for section in sections: + file.write(f' if let Some(s) = m.get("{section}") {{\n') + file.write(' if s.is_mapping() {\n') + file.write((f' self.{section}.merge(&mut rhs.{section},' + ' s.as_mapping());\n')) + file.write(' }\n') + file.write(' }\n') + file.write(' }\n') + file.write(' }\n') + file.write('}\n\n') + + for entry in def_functions: + file.write(entry) + file.close() + +def gen_docs_meta(file, entry, name, is_tuple): + """Write .. versionadded:: and related entries""" + if name in entry: + val = entry[name] + if not isinstance(val, list): + val = [val] + for vers in val: + if is_tuple: + file.write(f'.. {name}:: {vers[0]}\n\n') + file.write(f' {vers[1].strip()}\n') + else: + file.write(f'.. {name}:: {vers}\n') + +def gen_oldstyle_docs(entries): + """Write old style docs""" + with open('../docs/settings.rst', mode='w', encoding='UTF-8') as file: + file.write('.. THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir\n') + file.write(' START INCLUDE docs-old-preamble-in.rst\n\n') + with open('docs-old-preamble-in.rst', mode='r', encoding='UTF-8') as pre: + file.write(pre.read()) + file.write('.. END INCLUDE docs-old-preamble-in.rst\n\n') + + for entry in entries: + if entry['type'] == LType.Command: + continue + if entry['doc'].strip() == 'SKIP': + continue + oldname = entry['oldname'] + section = entry['section'] + file.write(f'.. _setting-{oldname}:\n\n') + file.write(f'``{oldname}``\n') + dots = '~' * (len(entry['oldname']) + 4) + file.write(f'{dots}\n') + gen_docs_meta(file, entry, 'versionadded', False) + gen_docs_meta(file, entry, 'versionchanged', True) + gen_docs_meta(file, entry, 'deprecated', True) + if 'doc-rst' in entry: + file.write(entry['doc-rst'].strip()) + file.write('\n') + file.write('\n') + typ = get_olddoc_typename(entry['type']) + file.write(f'- {typ}\n') + if 'docdefault' in entry: + file.write(f"- Default: {entry['docdefault']}\n\n") + else: + file.write((f"- Default: " + f"{get_default_olddoc_value(entry['type'], entry['default'])}\n\n")) + if 'skip-yaml' in entry: + file.write('- YAML setting does not exist\n\n') + else: + file.write(f"- YAML setting: :ref:`setting-yaml-{section}.{entry['name']}`\n\n") + file.write(entry['doc'].strip()) + file.write('\n\n') + +def fixxrefs(entries, arg): + """Docs in table refer to old style names, we modify them to ref to new style""" + matches = re.findall(':ref:`setting-(.*?)`', arg) + # We want to replace longest match first, to avoid a short match modifying a long one + matches = sorted(matches, key = lambda x: -len(x)) + for match in matches: + for entry in entries: + if entry['oldname'] == match: + key = ':ref:`setting-' + match + repl = ':ref:`setting-yaml-' + entry['section'] + '.' + entry['name'] + arg = arg.replace(key, repl) + return arg + +def gen_newstyle_docs(argentries): + """Write new style docs""" + entries = sorted(argentries, key = lambda entry: [entry['section'], entry['name']]) + with open('../docs/yamlsettings.rst', 'w', encoding='utf-8') as file: + file.write('.. THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir\n') + file.write(' START INCLUDE docs-new-preamble-in.rst\n\n') + with open('docs-new-preamble-in.rst', mode='r', encoding='utf-8') as pre: + file.write(pre.read()) + file.write('.. END INCLUDE docs-new-preamble-in.rst\n\n') + + for entry in entries: + if entry['type'] == LType.Command: + continue + if entry['doc'].strip() == 'SKIP': + continue + if 'skip-yaml' in entry: + continue + section = entry['section'] + name = entry['name'] + fullname = section + '.' + name + file.write(f'.. _setting-yaml-{fullname}:\n\n') + file.write(f'``{fullname}``\n') + dots = '^' * (len(fullname) + 4) + file.write(f'{dots}\n') + gen_docs_meta(file, entry, 'versionadded', False) + gen_docs_meta(file, entry, 'versionchanged', True) + gen_docs_meta(file, entry, 'deprecated', True) + if 'doc-rst' in entry: + file.write(fixxrefs(entries, entry['doc-rst'].strip())) + file.write('\n') + file.write('\n') + file.write(f"- {get_newdoc_typename(entry['type'])}\n") + if 'docdefault' in entry: + file.write(f"- Default: {entry['docdefault']}\n\n") + else: + file.write((f"- Default: " + f"{get_default_newdoc_value(entry['type'], entry['default'])}\n\n")) + file.write(f"- Old style setting: :ref:`setting-{entry['oldname']}`\n\n") + if 'doc-new' in entry: + file.write(fixxrefs(entries, entry['doc-new'].strip())) + else: + file.write(fixxrefs(entries, entry['doc'].strip())) + file.write('\n\n') + +RUNTIME = '*runtime determined*' + +def generate(): + """Read table, validate and generate C++, Rst and .rst files""" + # read table + with open('table.py', mode='r', encoding="utf-8") as file: + entries = eval(file.read()) + + for entry in entries: + the_oldname = entry['name'].replace('_', '-') + if 'oldname' in entry: + if entry['oldname'] == the_oldname: + sys.stderr.write(f"Redundant old name {entry['oldname']}\n") + else: + entry['oldname'] = the_oldname + + dupcheck1 = {} + dupcheck2 = {} + for entry in entries: + if entry['oldname'] in dupcheck1: + sys.stderr.write(f"duplicate entries with oldname = {entry['oldname']}\n") + sys.exit(1) + if entry['section'] + '.' + entry['name'] in dupcheck2: + sys.stderr.write((f"duplicate entries with section.name = " + f"{entry['section']}.{ entry['name']}\n")) + sys.exit(1) + dupcheck1[entry['oldname']] = True + dupcheck2[entry['section'] + '.' + entry['name']] = True + # And generate C++, Rust and docs code based on table + gen_cxx(entries) + gen_rust(entries) + # Avoid generating doc files in a sdist based build + if os.path.isdir('../docs'): + gen_oldstyle_docs(entries) + gen_newstyle_docs(entries) + +generate() diff --git a/pdns/recursordist/settings/rust-bridge-in.rs b/pdns/recursordist/settings/rust-bridge-in.rs new file mode 100644 index 000000000000..1ee664c173cf --- /dev/null +++ b/pdns/recursordist/settings/rust-bridge-in.rs @@ -0,0 +1,109 @@ +// This file (rust-bridge-in.rs) is included into lib.rs inside the bridge module +/* + * Implement non-generated structs that need to be handled by Serde and CXX + */ + +// A single forward zone +#[derive(Deserialize, Serialize, Debug, PartialEq)] +#[serde(deny_unknown_fields)] +pub struct ForwardZone { + #[serde(default, skip_serializing_if = "crate::is_default")] + zone: String, + #[serde(default, skip_serializing_if = "crate::is_default")] + forwarders: Vec, + #[serde(default, skip_serializing_if = "crate::is_default")] + recurse: bool, + #[serde(default, skip_serializing_if = "crate::is_default")] + notify_allowed: bool, +} + +// A single auth zone +#[derive(Deserialize, Serialize, Debug, PartialEq)] +#[serde(deny_unknown_fields)] +pub struct AuthZone { + #[serde(default, skip_serializing_if = "crate::is_default")] + zone: String, + #[serde(default, skip_serializing_if = "crate::is_default")] + file: String, +} + +// A struct holding bot a vector of forward zones and a vector o auth zones, used by REST API code +#[derive(Deserialize, Serialize, Debug, PartialEq)] +#[serde(deny_unknown_fields)] +struct ApiZones { + #[serde(default, skip_serializing_if = "crate::is_default")] + auth_zones: Vec, + #[serde(default, skip_serializing_if = "crate::is_default")] + forward_zones: Vec, +} + +// Two structs used to generated YAML based on a vector of name to value mappings +// Cannot use Enum as CXX has only very basic Enum support +struct Value { + bool_val: bool, + u64_val: u64, + f64_val: f64, + string_val: String, + vec_string_val: Vec, + vec_forwardzone_val: Vec, + vec_authzone_val: Vec, +} + +struct OldStyle { + section: String, + name: String, + old_name: String, + type_name: String, + value: Value, + overriding: bool, +} + +/* + * Functions callable from C++ + */ +extern "Rust" { + // Parse a string representing YAML text and produce the corresponding data structure known to Serde + // The settings that can be stored in individual files get their own parse function + // Main recursor settings + fn parse_yaml_string(str: &str) -> Result; + // Allow from sequence + fn parse_yaml_string_to_allow_from(str: &str) -> Result>; + // Forward zones sequence + fn parse_yaml_string_to_forward_zones(str: &str) -> Result>; + // Allow notify for sequence + fn parse_yaml_string_to_allow_notify_for(str: &str) -> Result>; + // REST APIU zones + fn parse_yaml_string_to_api_zones(str: &str) -> Result; + + // Prdoduce a YAML formatted sting given a data structure known to Serde + fn to_yaml_string(self: &Recursorsettings) -> Result; + // When doing a conversion of old-style to YAML style we use a vector of OldStyle structs + fn map_to_yaml_string(map: &Vec) -> Result; + fn forward_zones_to_yaml_string(vec: &Vec) -> Result; + fn allow_from_to_yaml_string(vec: &Vec) -> Result; + fn allow_from_to_yaml_string_incoming(key: &String, filekey: &String, vec: &Vec) -> Result; + fn allow_for_to_yaml_string(vec: &Vec) -> Result; + + // Merge a string representing YAML settings into a existing setttings struct + fn merge(lhs: &mut Recursorsettings, rhs: &str) -> Result<()>; + + // Validate the sections inside the main settings struct, sections themselves will valdiate their fields + fn validate(self: &Recursorsettings) -> Result<()>; + // The validate function bewlo are "hand-crafted" as their structs afre mnot generated + fn validate(self: &AuthZone, field: &str) -> Result<()>; + fn validate(self: &ForwardZone, field: &str) -> Result<()>; + fn validate(self: &ApiZones, field: &str) -> Result<()>; + + // Helper functions to call the proper validate function on vectors of various kinds + fn validate_auth_zones(field: &str, vec: &Vec) -> Result<()>; + fn validate_forward_zones(field: &str, vec: &Vec) -> Result<()>; + fn validate_allow_for(field: &str, vec: &Vec) -> Result<()>; + fn validate_allow_notify_for(field: &str, vec: &Vec) -> Result<()>; + fn validate_allow_from(field: &str, vec: &Vec) -> Result<()>; + + // The functions to maintain REST API managed zones + fn api_read_zones(path: &str) -> Result>; + fn api_add_auth_zone(file: &str, authzone: AuthZone) -> Result<()>; + fn api_add_forward_zone(file: &str, forwardzone: ForwardZone) -> Result<()>; + fn api_delete_zone(file: &str, zone: &str) -> Result<()>; +} diff --git a/pdns/recursordist/settings/rust-preamble-in.rs b/pdns/recursordist/settings/rust-preamble-in.rs new file mode 100644 index 000000000000..64fef08e6782 --- /dev/null +++ b/pdns/recursordist/settings/rust-preamble-in.rs @@ -0,0 +1,48 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +// This file (rust-preamble-in.rs) is included at the start of lib.rs + +use serde::{Deserialize, Serialize}; + +mod helpers; +use helpers::*; + +mod bridge; +use bridge::*; + +// Suppresses "Deserialize unused" warning +#[derive(Deserialize, Serialize)] +struct UnusedStruct {} + +trait Validate { + fn validate(&self) -> Result<(), ValidationError>; +} + +#[derive(Debug)] +pub struct ValidationError { + msg: String, +} + +trait Merge { + fn merge(&mut self, rhs: &mut Self, map: Option<&serde_yaml::Mapping>); +} diff --git a/pdns/recursordist/settings/rust/.gitignore b/pdns/recursordist/settings/rust/.gitignore new file mode 100644 index 000000000000..7b8194b04e94 --- /dev/null +++ b/pdns/recursordist/settings/rust/.gitignore @@ -0,0 +1,6 @@ +/target +/Makefile +/Makefile.in +/cxx.h +/lib.rs.h +src/lib.rs diff --git a/pdns/recursordist/settings/rust/Cargo.lock b/pdns/recursordist/settings/rust/Cargo.lock new file mode 100644 index 000000000000..d149f0446937 --- /dev/null +++ b/pdns/recursordist/settings/rust/Cargo.lock @@ -0,0 +1,265 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "cxx" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbe98ba1789d56fb3db3bee5e032774d4f421b685de7ba703643584ba24effbe" +dependencies = [ + "cc", + "cxxbridge-flags", + "cxxbridge-macro", + "link-cplusplus", +] + +[[package]] +name = "cxx-build" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4ce20f6b8433da4841b1dadfb9468709868022d829d5ca1f2ffbda928455ea3" +dependencies = [ + "cc", + "codespan-reporting", + "once_cell", + "proc-macro2", + "quote", + "scratch", + "syn", +] + +[[package]] +name = "cxxbridge-flags" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20888d9e1d2298e2ff473cee30efe7d5036e437857ab68bbfea84c74dba91da2" + +[[package]] +name = "cxxbridge-macro" +version = "1.0.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fa16a70dd58129e4dfffdff535fb1bce66673f7bbeec4a5a1765a504e1ccd84" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "hashbrown" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" + +[[package]] +name = "indexmap" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "ipnet" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6" + +[[package]] +name = "itoa" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af150ab688ff2122fcef229be89cb50dd66af9e01a4ff320cc137eecc9bacc38" + +[[package]] +name = "libc" +version = "0.2.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3" + +[[package]] +name = "link-cplusplus" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d240c6f7e1ba3a28b0249f774e6a9dd0175054b52dfbb61b16eb8505c3785c9" +dependencies = [ + "cc", +] + +[[package]] +name = "once_cell" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" + +[[package]] +name = "proc-macro2" +version = "1.0.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "ryu" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" + +[[package]] +name = "scratch" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3cf7c11c38cb994f3d40e8a8cde3bbd1f72a435e4c49e85d6553d8312306152" + +[[package]] +name = "serde" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9e0fcba69a370eed61bcf2b728575f726b50b55cba78064753d708ddc7549e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.188" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4eca7ac642d82aa35b60049a6eccb4be6be75e599bd2e9adb5f875a737654af2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_yaml" +version = "0.9.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a49e178e4452f45cb61d0cd8cebc1b0fafd3e41929e996cef79aa3aca91f574" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] +name = "settings" +version = "0.1.0" +dependencies = [ + "cxx", + "cxx-build", + "ipnet", + "once_cell", + "serde", + "serde_yaml", +] + +[[package]] +name = "syn" +version = "2.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718fa2415bcb8d8bd775917a1bf12a7931b6dfa890753378538118181e0cb398" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "termcolor" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "unicode-ident" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "unicode-width" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" + +[[package]] +name = "unsafe-libyaml" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28467d3e1d3c6586d8f25fa243f544f5800fec42d97032474e17222c2b75cfa" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/pdns/recursordist/settings/rust/Cargo.toml b/pdns/recursordist/settings/rust/Cargo.toml new file mode 100644 index 000000000000..89cef97885b9 --- /dev/null +++ b/pdns/recursordist/settings/rust/Cargo.toml @@ -0,0 +1,19 @@ +[package] +name = "settings" +version = "0.1.0" +edition = "2021" + +[lib] +name = "settings" +crate-type = ["staticlib"] + +[dependencies] +cxx = "1.0" +serde = { version = "1.0", features = ["derive"] } +serde_yaml = "0.9" +ipnet = "2.8" +once_cell = "1.18.0" + +[build-dependencies] +cxx-build = "1.0" + diff --git a/pdns/recursordist/settings/rust/Makefile.am b/pdns/recursordist/settings/rust/Makefile.am new file mode 100644 index 000000000000..814c21322025 --- /dev/null +++ b/pdns/recursordist/settings/rust/Makefile.am @@ -0,0 +1,20 @@ +CARGO ?= cargo + +all: libsettings.a + +EXTRA_DIST = \ + Cargo.toml \ + Cargo.lock \ + build.rs \ + src/bridge.rs \ + src/helpers.rs + +# should actually end up in a target specific dir... +libsettings.a lib.rs.h: src/bridge.rs src/lib.rs src/helpers.rs Cargo.toml Cargo.lock build.rs + $(CARGO) build --release $(RUST_TARGET) + cp target/$(RUSTC_TARGET_ARCH)/release/libsettings.a libsettings.a + cp target/$(RUSTC_TARGET_ARCH)/cxxbridge/settings/src/lib.rs.h lib.rs.h + cp target/$(RUSTC_TARGET_ARCH)/cxxbridge/rust/cxx.h cxx.h + +clean-local: + rm -rf libsettings.a src/lib.rs lib.rs.h cxx.h target diff --git a/pdns/recursordist/settings/rust/build.rs b/pdns/recursordist/settings/rust/build.rs new file mode 100644 index 000000000000..3bf2cbca45d2 --- /dev/null +++ b/pdns/recursordist/settings/rust/build.rs @@ -0,0 +1,6 @@ +fn main() { + cxx_build::bridge("src/lib.rs") + // .file("src/source.cc") at the moment no C++ code callable from Rust + .flag_if_supported("-std=c++17") + .compile("settings"); +} diff --git a/pdns/recursordist/settings/rust/src/bridge.rs b/pdns/recursordist/settings/rust/src/bridge.rs new file mode 100644 index 000000000000..80d1589e5116 --- /dev/null +++ b/pdns/recursordist/settings/rust/src/bridge.rs @@ -0,0 +1,471 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +use once_cell::sync::Lazy; +use std::fs::File; +use std::io::{BufReader, BufWriter, ErrorKind, Write}; +use std::net::{IpAddr, SocketAddr}; +use std::str::FromStr; +use std::sync::Mutex; + +use crate::helpers::OVERRIDE_TAG; +use crate::recsettings::*; +use crate::{Merge, ValidationError}; + +impl Default for ForwardZone { + fn default() -> Self { + let deserialized: ForwardZone = serde_yaml::from_str("").unwrap(); + deserialized + } +} + +impl Default for AuthZone { + fn default() -> Self { + let deserialized: AuthZone = serde_yaml::from_str("").unwrap(); + deserialized + } +} + +impl Default for ApiZones { + fn default() -> Self { + let deserialized: ApiZones = serde_yaml::from_str("").unwrap(); + deserialized + } +} + +pub fn validate_socket_address(field: &str, val: &String) -> Result<(), ValidationError> { + let sa = SocketAddr::from_str(val); + if sa.is_err() { + let ip = IpAddr::from_str(val); + if ip.is_err() { + let msg = format!( + "{}: value `{}' is not an IP or IP:port combination", + field, val + ); + return Err(ValidationError { msg }); + } + } + Ok(()) +} + +fn validate_name(field: &str, val: &String) -> Result<(), ValidationError> { + if val.is_empty() { + let msg = format!("{}: value may not be empty", field); + return Err(ValidationError { msg }); + } + if val == "." { + return Ok(()); + } + // Strip potential dot at end + let mut testval = val.as_str(); + if testval.ends_with('.') { + testval = &testval[0..testval.len() - 1]; + } + for label in testval.split('.') { + if label.is_empty() { + let msg = format!("{}: `{}' has empty label", field, val); + return Err(ValidationError { msg }); + } + // XXX Too liberal, should check for alnum, - and proper \ddd + if !label.chars().all(|ch| ch.is_ascii()) { + let msg = format!("{}: `{}' contains non-ascii character", field, val); + return Err(ValidationError { msg }); + } + } + Ok(()) +} + +pub fn validate_subnet(field: &str, val: &String) -> Result<(), ValidationError> { + if val.is_empty() { + let msg = format!("{}: value `{}' is not a subnet or IP", field, val); + return Err(ValidationError { msg }); + } + let mut ip = val.as_str(); + if val.starts_with('!') { + ip = &ip[1..]; + } + let subnet = ipnet::IpNet::from_str(ip); + if subnet.is_err() { + let ip = IpAddr::from_str(ip); + if ip.is_err() { + let msg = format!("{}: value `{}' is not a subnet or IP", field, val); + return Err(ValidationError { msg }); + } + } + Ok(()) +} + +pub fn validate_vec(field: &str, vec: &[T], func: F) -> Result<(), ValidationError> +where + F: Fn(&str, &T) -> Result<(), ValidationError>, +{ + vec.iter().try_for_each(|element| func(field, element)) +} + +pub fn parse_yaml_string(str: &str) -> Result { + serde_yaml::from_str(str) +} + +pub fn parse_yaml_string_to_allow_from(str: &str) -> Result, serde_yaml::Error> { + serde_yaml::from_str(str) +} + +pub fn parse_yaml_string_to_forward_zones( + str: &str, +) -> Result, serde_yaml::Error> { + serde_yaml::from_str(str) +} + +pub fn parse_yaml_string_to_api_zones(str: &str) -> Result { + serde_yaml::from_str(str) +} + +pub fn parse_yaml_string_to_allow_notify_for( + str: &str, +) -> Result, serde_yaml::Error> { + serde_yaml::from_str(str) +} + +pub fn forward_zones_to_yaml_string(vec: &Vec) -> Result { + serde_yaml::to_string(vec) +} + +impl ForwardZone { + pub fn validate(&self, field: &str) -> Result<(), ValidationError> { + validate_name(&(field.to_owned() + ".zone"), &self.zone)?; + if self.forwarders.is_empty() { + let msg = format!("{}.forwarders cannot be empty", field); + return Err(ValidationError { msg }); + } + validate_vec( + &(field.to_owned() + ".forwarders"), + &self.forwarders, + validate_socket_address, + ) + } + + fn to_yaml_map(&self) -> serde_yaml::Value { + let mut seq = serde_yaml::Sequence::new(); + for entry in &self.forwarders { + seq.push(serde_yaml::Value::String(entry.to_owned())); + } + + let mut map = serde_yaml::Mapping::new(); + map.insert( + serde_yaml::Value::String("zone".to_owned()), + serde_yaml::Value::String(self.zone.to_owned()), + ); + map.insert( + serde_yaml::Value::String("recurse".to_owned()), + serde_yaml::Value::Bool(self.recurse), + ); + map.insert( + serde_yaml::Value::String("forwarders".to_owned()), + serde_yaml::Value::Sequence(seq), + ); + serde_yaml::Value::Mapping(map) + } +} + +impl AuthZone { + pub fn validate(&self, field: &str) -> Result<(), ValidationError> { + validate_name(&(field.to_owned() + ".zone"), &self.zone)?; + if self.file.is_empty() { + let msg = format!("{}.file cannot be empty", field); + return Err(ValidationError { msg }); + } + Ok(()) + } + + fn to_yaml_map(&self) -> serde_yaml::Value { + let mut map = serde_yaml::Mapping::new(); + map.insert( + serde_yaml::Value::String("zone".to_owned()), + serde_yaml::Value::String(self.zone.to_owned()), + ); + map.insert( + serde_yaml::Value::String("file".to_owned()), + serde_yaml::Value::String(self.file.to_owned()), + ); + serde_yaml::Value::Mapping(map) + } +} + +pub fn validate_auth_zones(field: &str, vec: &Vec) -> Result<(), ValidationError> { + validate_vec(field, vec, |field, element| element.validate(field)) +} + +pub fn validate_forward_zones( + field: &str, + vec: &Vec, +) -> Result<(), ValidationError> { + validate_vec(field, vec, |field, element| element.validate(field)) +} + +pub fn allow_from_to_yaml_string(vec: &Vec) -> Result { + let mut seq = serde_yaml::Sequence::new(); + for entry in vec { + seq.push(serde_yaml::Value::String(entry.to_owned())); + } + let val = serde_yaml::Value::Sequence(seq); + + serde_yaml::to_string(&val) +} + +pub fn allow_from_to_yaml_string_incoming( + key: &String, + filekey: &String, + vec: &Vec, +) -> Result { + // Produce + // incoming: + // allow-from-file: '' + // allow-from: !override + // - ... + let mut seq = serde_yaml::Sequence::new(); + for entry in vec { + seq.push(serde_yaml::Value::String(entry.to_owned())); + } + + let mut innermap = serde_yaml::Mapping::new(); + innermap.insert( + serde_yaml::Value::String(filekey.to_owned()), + serde_yaml::Value::String("".to_owned()), + ); + let af = Box::new(serde_yaml::value::TaggedValue { + tag: serde_yaml::value::Tag::new(OVERRIDE_TAG), + value: serde_yaml::Value::Sequence(seq), + }); + innermap.insert( + serde_yaml::Value::String(key.to_owned()), + serde_yaml::Value::Tagged(af), + ); + + let mut outermap = serde_yaml::Mapping::new(); + outermap.insert( + serde_yaml::Value::String("incoming".to_owned()), + serde_yaml::Value::Mapping(innermap), + ); + let outerval = serde_yaml::Value::Mapping(outermap); + + serde_yaml::to_string(&outerval) +} + +pub fn validate_allow_from(field: &str, vec: &Vec) -> Result<(), ValidationError> { + validate_vec(field, vec, validate_subnet) +} + +pub fn allow_for_to_yaml_string(vec: &Vec) -> Result { + // For purpose of generating yaml allow-for is no different than allow-from as we're handling a + // vector of Strings + allow_from_to_yaml_string(vec) +} + +pub fn validate_allow_for(field: &str, vec: &Vec) -> Result<(), ValidationError> { + validate_vec(field, vec, validate_name) +} + +pub fn validate_allow_notify_for(field: &str, vec: &Vec) -> Result<(), ValidationError> { + validate_vec(field, vec, validate_name) +} + +impl Recursorsettings { + pub fn to_yaml_string(&self) -> Result { + serde_yaml::to_string(self) + } + + // validate() is implemented in the (generated) lib.rs +} + +pub static DEFAULT_CONFIG: Lazy = Lazy::new(Recursorsettings::default); + +pub fn merge_vec(lhs: &mut Vec, rhs: &mut Vec) { + lhs.append(rhs); +} + +// This is used for conversion, where we want to have !override tags in some cases, so we craft a YAML Mapping by hand +pub fn map_to_yaml_string(vec: &Vec) -> Result { + let mut map = serde_yaml::Mapping::new(); + for entry in vec { + let section = entry.section.as_str(); + if !map.contains_key(section) { + let newmap = serde_yaml::Mapping::new(); + map.insert( + serde_yaml::Value::String(section.to_string()), + serde_yaml::Value::Mapping(newmap), + ); + } + if let Some(mapentry) = map.get_mut(section) { + if let Some(mapping) = mapentry.as_mapping_mut() { + let val = match entry.type_name.as_str() { + "bool" => serde_yaml::Value::Bool(entry.value.bool_val), + "u64" => { + serde_yaml::Value::Number(serde_yaml::Number::from(entry.value.u64_val)) + } + "f64" => { + serde_yaml::Value::Number(serde_yaml::Number::from(entry.value.f64_val)) + } + "String" => serde_yaml::Value::String(entry.value.string_val.to_owned()), + "Vec" => { + let mut seq = serde_yaml::Sequence::new(); + for element in &entry.value.vec_string_val { + seq.push(serde_yaml::Value::String(element.to_owned())) + } + serde_yaml::Value::Sequence(seq) + } + "Vec" => { + let mut seq = serde_yaml::Sequence::new(); + for element in &entry.value.vec_forwardzone_val { + seq.push(element.to_yaml_map()); + } + serde_yaml::Value::Sequence(seq) + } + "Vec" => { + let mut seq = serde_yaml::Sequence::new(); + for element in &entry.value.vec_authzone_val { + seq.push(element.to_yaml_map()); + } + serde_yaml::Value::Sequence(seq) + } + other => serde_yaml::Value::String("map_to_yaml_string: Unknown type: ".to_owned() + other), + }; + if entry.overriding { + let tagged_value = Box::new(serde_yaml::value::TaggedValue { + tag: serde_yaml::value::Tag::new(OVERRIDE_TAG), + value: val, + }); + mapping.insert( + serde_yaml::Value::String(entry.name.to_owned()), + serde_yaml::Value::Tagged(tagged_value), + ); + } else { + mapping.insert(serde_yaml::Value::String(entry.name.to_owned()), val); + } + } + } + } + serde_yaml::to_string(&map) +} + +pub fn merge(lhs: &mut Recursorsettings, yaml_str: &str) -> Result<(), serde_yaml::Error> { + // Parse the yaml for the values + let mut rhs: Recursorsettings = serde_yaml::from_str(yaml_str)?; + // Parse again for the map containing the keys present, which is used to only override specific values, + // taking into account !override tags + let map: serde_yaml::Value = serde_yaml::from_str(yaml_str)?; + if map.is_mapping() { + lhs.merge(&mut rhs, map.as_mapping()); + } + + Ok(()) +} + +// API zones maintenance. In contrast to the old settings code, which creates a settings file per +// zone, we maintain a single yaml file with all settings. File locking is no issue, as we are the +// single process managing this dir. So we only use process specific locking. + +impl ApiZones { + pub fn validate(&self, field: &str) -> Result<(), ValidationError> { + validate_auth_zones(&(field.to_owned() + ".auth_zones"), &self.auth_zones)?; + validate_forward_zones(&(field.to_owned() + ".forward_zones"), &self.forward_zones)?; + Ok(()) + } +} + +static LOCK: Mutex = Mutex::new(false); + +// Assume we hold the lock +fn api_read_zones_locked( + path: &str, + create: bool, +) -> Result, std::io::Error> { + let zones = match File::open(path) { + Ok(file) => { + let data: Result = + serde_yaml::from_reader(BufReader::new(file)); + match data { + Err(error) => return Err(std::io::Error::new(ErrorKind::Other, error.to_string())), + Ok(yaml) => yaml, + } + } + Err(error) => match error.kind() { + // If the file does not exist we return an empty struct + ErrorKind::NotFound => { + if create { + ApiZones::default() + } else { + return Err(error); + } + } + // Any other error is fatal + _ => return Err(error), + }, + }; + Ok(cxx::UniquePtr::new(zones)) +} + +// This function is called from C++, it needs to acquire the lock +pub fn api_read_zones(path: &str) -> Result, std::io::Error> { + let _lock = LOCK.lock().unwrap(); + api_read_zones_locked(path, false) +} + +// Assume we hold the lock +fn api_write_zones(path: &str, zones: &ApiZones) -> Result<(), std::io::Error> { + let mut tmpfile = path.to_owned(); + tmpfile.push_str(".tmp"); + + let file = File::create(tmpfile.as_str())?; + let mut buffered_writer = BufWriter::new(&file); + if let Err(error) = serde_yaml::to_writer(&mut buffered_writer, &zones) { + return Err(std::io::Error::new(ErrorKind::Other, error.to_string())); + } + buffered_writer.flush()?; + file.sync_all()?; + drop(buffered_writer); + std::fs::rename(tmpfile.as_str(), path) +} + +// This function is called from C++, it needs to acquire the lock +pub fn api_add_auth_zone(path: &str, authzone: AuthZone) -> Result<(), std::io::Error> { + let _lock = LOCK.lock().unwrap(); + let mut zones = api_read_zones_locked(path, true)?; + zones.auth_zones.push(authzone); + api_write_zones(path, &zones) +} + +// This function is called from C++, it needs to acquire the lock +pub fn api_add_forward_zone(path: &str, forwardzone: ForwardZone) -> Result<(), std::io::Error> { + let _lock = LOCK.lock().unwrap(); + let mut zones = api_read_zones_locked(path, true)?; + zones.forward_zones.push(forwardzone); + api_write_zones(path, &zones) +} +// This function is called from C++, it needs to acquire the lock +pub fn api_delete_zone(path: &str, zone: &str) -> Result<(), std::io::Error> { + let _lock = LOCK.lock().unwrap(); + let mut zones = api_read_zones_locked(path, true)?; + zones.auth_zones.retain(|x| x.zone != zone); + // Zone data file is unlinked in the C++ caller ws-recursor.cc:doDeleteZone() + zones.forward_zones.retain(|x| x.zone != zone); + api_write_zones(path, &zones) +} diff --git a/pdns/recursordist/settings/rust/src/helpers.rs b/pdns/recursordist/settings/rust/src/helpers.rs new file mode 100644 index 000000000000..795d8a585500 --- /dev/null +++ b/pdns/recursordist/settings/rust/src/helpers.rs @@ -0,0 +1,73 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +use std::{error::Error, fmt}; +use crate::ValidationError; + +/* Helper code for validation */ +impl Error for ValidationError {} +impl fmt::Display for ValidationError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.msg) + } +} + +// Generic helpers + +// A helper to define a function returning a constant value and an equal function as a Rust path */ +pub struct U64; +impl U64 { + pub const fn value() -> u64 { + U + } + pub fn is_equal(v: &u64) -> bool { + v == &U + } +} + +// A helper to define constant value as a Rust path */ +pub struct Bool; +impl Bool { + pub const fn value() -> bool { + U + } +} + +// A helper used to decide if a bool value should be skipped +pub fn if_true(v: &bool) -> bool { + *v +} + +/* Helper to decide if a value has a default value, as defined by Default trait */ +pub fn is_default(t: &T) -> bool { + t == &T::default() +} + +pub const OVERRIDE_TAG: &str = "!override"; + +pub fn is_overriding(m: &serde_yaml::Mapping, key: &str) -> bool{ + if let Some(serde_yaml::Value::Tagged(vvv)) = m.get(key) { + return vvv.tag == OVERRIDE_TAG; + } + false +} + diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py new file mode 100644 index 000000000000..56ea6c9ef173 --- /dev/null +++ b/pdns/recursordist/settings/table.py @@ -0,0 +1,2928 @@ +# This file contains the table used to generate old and new-style settings code +# +# Example: +# { +# 'name' : 'allow_from', +# 'section' : 'incoming', +# 'oldname' : 'allow-from' +# 'type' : LType.ListSubnets, +# 'default' : '127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10', +# 'help' : 'If set, only allow these comma separated netmasks to recurse', +# 'doc' : ''' +# ''' +# } +# +# See generate.py for a description of the fields. +# +# Sections +# - incoming +# - outgoing +# - packetcache +# - recursor +# - recordcache +# - dnssec +# - webservice +# - carbon +# - ecs +# - logging +# - nod +# - snmp + +[ + { + 'name' : 'aggressive_nsec_cache_size', + 'section' : 'dnssec', + 'type' : LType.Uint64, + 'default' : '100000', + 'help' : 'The number of records to cache in the aggressive cache. If set to a value greater than 0, and DNSSEC processing or validation is enabled, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in rfc8198', + 'doc' : ''' +The number of records to cache in the aggressive cache. If set to a value greater than 0, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in :rfc:`8198`. +To use this, DNSSEC processing or validation must be enabled by setting :ref:`setting-dnssec` to ``process``, ``log-fail`` or ``validate``. + ''', + 'versionadded': '4.5.0', + }, + { + 'name' : 'aggressive_cache_min_nsec3_hit_ratio', + 'section' : 'dnssec', + 'type' : LType.Uint64, + 'default' : '2000', + 'help' : 'The minimum expected hit ratio to store NSEC3 records into the aggressive cache', + 'doc' : ''' +The limit for which to put NSEC3 records into the aggressive cache. +A value of ``n`` means that an NSEC3 record is only put into the aggressive cache if the estimated probability of a random name hitting the NSEC3 record is higher than ``1/n``. +A higher ``n`` will cause more records to be put into the aggressive cache, e.g. a value of 4000 will cause records to be put in the aggressive cache even if the estimated probability of hitting them is twice as low as would be the case for ``n=2000``. +A value of 0 means no NSEC3 records will be put into the aggressive cache. + +For large zones the effectiveness of the NSEC3 cache is reduced since each NSEC3 record only covers a randomly distributed subset of all possible names. +This setting avoids doing unnecessary work for such large zones. + ''', + 'versionadded' : '4.9.0', + }, + { + 'name' : 'allow_from', + 'section' : 'incoming', + 'type' : LType.ListSubnets, + 'default' : '127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10', + 'help' : 'If set, only allow these comma separated netmasks to recurse', + 'doc' : ''' +Netmasks (both IPv4 and IPv6) that are allowed to use the server. +The default allows access only from :rfc:`1918` private IP addresses. +An empty value means no checking is done, all clients are allowed. +Due to the aggressive nature of the internet these days, it is highly recommended to not open up the recursor for the entire internet. +Questions from IP addresses not listed here are ignored and do not get an answer. + +When the Proxy Protocol is enabled (see :ref:`setting-proxy-protocol-from`), the recursor will check the address of the client IP advertised in the Proxy Protocol header instead of the one of the proxy. + +Note that specifying an IP address without a netmask uses an implicit netmask of /32 or /128. + ''', + }, + { + 'name' : 'allow_from_file', + 'section' : 'incoming', + 'type' : LType.String, + 'default' : '', + 'help' : 'If set, load allowed netmasks from this file', + 'doc' : ''' +Like :ref:`setting-allow-from`, except reading from file. +Overrides the :ref:`setting-allow-from` setting. To use this feature, supply one netmask per line, with optional comments preceded by a '#'. + ''', + 'doc-new' : ''' +Like :ref:`setting-allow-from`, except reading a sequence of `Subnet`_ from file. +Overrides the :ref:`setting-allow-from` setting. Example content of th specified file: + +.. code-block:: yaml + + - 127.0.01 + - ::1 + + ''', + }, + { + 'name' : 'allow_notify_for', + 'section' : 'incoming', + 'type' : LType.ListStrings, + 'default' : '', + 'help' : 'If set, NOTIFY requests for these zones will be allowed', + 'doc' : ''' +Domain names specified in this list are used to permit incoming +NOTIFY operations to wipe any cache entries that match the domain +name. If this list is empty, all NOTIFY operations will be ignored. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'allow_notify_for_file', + 'section' : 'incoming', + 'type' : LType.String, + 'default' : '', + 'help' : 'If set, load NOTIFY-allowed zones from this file', + 'doc' : ''' +Like :ref:`setting-allow-notify-for`, except reading from file. To use this +feature, supply one domain name per line, with optional comments +preceded by a '#'. + +NOTIFY-allowed zones can also be specified using :ref:`setting-forward-zones-file`. + ''', + 'doc-new' : ''' +Like :ref:`setting-allow-notify-for`, except reading a sequence of names from file. Example contents of specified file: + +.. code-block:: yaml + + - example.com + - example.org + + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'allow_notify_from', + 'section' : 'incoming', + 'type' : LType.ListSubnets, + 'default' : '', + 'help' : 'If set, NOTIFY requests from these comma separated netmasks will be allowed', + 'doc' : ''' +Netmasks (both IPv4 and IPv6) that are allowed to issue NOTIFY operations +to the server. NOTIFY operations from IP addresses not listed here are +ignored and do not get an answer. + +When the Proxy Protocol is enabled (see :ref:`setting-proxy-protocol-from`), the +recursor will check the address of the client IP advertised in the +Proxy Protocol header instead of the one of the proxy. + +Note that specifying an IP address without a netmask uses an implicit +netmask of /32 or /128. + +NOTIFY operations received from a client listed in one of these netmasks +will be accepted and used to wipe any cache entries whose zones match +the zone specified in the NOTIFY operation, but only if that zone (or +one of its parents) is included in :ref:`setting-allow-notify-for`, +:ref:`setting-allow-notify-for-file`, or :ref:`setting-forward-zones-file` with a '^' prefix. + ''', + 'doc-new' : ''' +Subnets (both IPv4 and IPv6) that are allowed to issue NOTIFY operations +to the server. NOTIFY operations from IP addresses not listed here are +ignored and do not get an answer. + +When the Proxy Protocol is enabled (see :ref:`setting-proxy-protocol-from`), the +recursor will check the address of the client IP advertised in the +Proxy Protocol header instead of the one of the proxy. + +Note that specifying an IP address without a netmask uses an implicit +netmask of /32 or /128. + +NOTIFY operations received from a client listed in one of these netmasks +will be accepted and used to wipe any cache entries whose zones match +the zone specified in the NOTIFY operation, but only if that zone (or +one of its parents) is included in :ref:`setting-allow-notify-for`, +:ref:`setting-allow-notify-for-file`, or :ref:`setting-forward-zones-file` with a ``allow_notify`` set to ``true``. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'allow_notify_from_file', + 'section' : 'incoming', + 'type' : LType.String, + 'default' : '', + 'help' : 'If set, load NOTIFY-allowed netmasks from this file', + 'doc' : ''' +Like :ref:`setting-allow-notify-from`, except reading from file. To use this +feature, supply one netmask per line, with optional comments preceded +by a '#'. + ''', + 'doc-new' : ''' +Like :ref:`setting-allow-notify-from`, except reading a sequence of `Subnet`_ from file. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'any_to_tcp', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Answer ANY queries with tc=1, shunting to TCP', + 'doc' : ''' +Answer questions for the ANY type on UDP with a truncated packet that refers the remote server to TCP. +Useful for mitigating ANY reflection attacks. + ''', + }, + { + 'name' : 'allow_trust_anchor_query', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Allow queries for trustanchor.server CH TXT and negativetrustanchor.server CH TXT', + 'doc' : ''' +Allow ``trustanchor.server CH TXT`` and ``negativetrustanchor.server CH TXT`` queries to view the configured :doc:`DNSSEC ` (negative) trust anchors. + ''', + 'versionadded': '4.3.0' + }, + { + 'name' : 'api_dir', + 'section' : 'webservice', + 'oldname' : 'api-config-dir', + 'type' : LType.String, + 'default' : '', + 'help' : 'Directory where REST API stores config and zones', + 'doc' : ''' +Directory where the REST API stores its configuration and zones. +For configuration updates to work, :ref:`setting-include-dir` should have the same value. + ''', + 'versionadded': '4.0.0' + }, + { + 'name' : 'api_key', + 'section' : 'webservice', + 'type' : LType.String, + 'default' : '', + 'help' : 'Static pre-shared authentication key for access to the REST API', + 'doc' : ''' +Static pre-shared authentication key for access to the REST API. Since 4.6.0 the key can be hashed and salted using ``rec_control hash-password`` instead of being stored in the configuration in plaintext, but the plaintext version is still supported. + ''', + 'versionadded': '4.0.0', + 'versionchanged': ('4.6.0', 'This setting now accepts a hashed and salted version.') + }, + { + 'name' : 'auth_zones', + 'section' : 'recursor', + 'type' : LType.ListAuthZones, + 'default' : '', + 'help' : 'Zones for which we have authoritative data, comma separated domain=file pairs', + 'doc' : ''' +Zones read from these files (in BIND format) are served authoritatively (but without the AA bit set in responses). +DNSSEC is not supported. Example: + +.. code-block:: none + + auth-zones=example.org=/var/zones/example.org, powerdns.com=/var/zones/powerdns.com + ''', + 'doc-new' : ''' +Zones read from these files (in BIND format) are served authoritatively (but without the AA bit set in responses). +DNSSEC is not supported. Example: + +.. code-block:: yaml + + recursor: + auth-zones: + - zone: example.org + file: /var/zones/example.org + - zone: powerdns.com + file: /var/zones/powerdns.com + ''', + }, + { + 'name' : 'interval', + 'section' : 'carbon', + 'oldname' : 'carbon-interval', + 'type' : LType.Uint64, + 'default' : '30', + 'help' : 'Number of seconds between carbon (graphite) updates', + 'doc' : ''' +If sending carbon updates, this is the interval between them in seconds. +See :doc:`metrics`. + ''', + }, + { + 'name' : 'ns', + 'section' : 'carbon', + 'oldname' : 'carbon-namespace', + 'type' : LType.String, + 'default' : 'pdns', + 'help' : 'If set overwrites the first part of the carbon string', + 'doc' : ''' +Change the namespace or first string of the metric key. The default is pdns. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'ourname', + 'section' : 'carbon', + 'oldname' : 'carbon-ourname', + 'type' : LType.String, + 'default' : '', + 'help' : 'If set, overrides our reported hostname for carbon stats', + 'doc' : ''' +If sending carbon updates, if set, this will override our hostname. +Be careful not to include any dots in this setting, unless you know what you are doing. +See :ref:`metricscarbon`. + ''', + }, + { + 'name' : 'instance', + 'section' : 'carbon', + 'oldname' : 'carbon-instance', + 'type' : LType.String, + 'default' : 'recursor', + 'help' : 'If set overwrites the instance name default', + 'doc' : ''' +Change the instance or third string of the metric key. The default is recursor. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'server', + 'section' : 'carbon', + 'oldname' : 'carbon-server', + 'type' : LType.ListSocketAddresses, + 'default' : '', + 'help' : 'If set, send metrics in carbon (graphite) format to this server IP address', + 'doc' : ''' +If set to an IP or IPv6 address, will send all available metrics to this server via the carbon protocol, which is used by graphite and metronome. Moreover you can specify more than one server using a comma delimited list, ex: carbon-server=10.10.10.10,10.10.10.20. +You may specify an alternate port by appending :port, for example: ``127.0.0.1:2004``. +See :doc:`metrics`. + ''', + 'doc-new' : ''' +Will send all available metrics to these servers via the carbon protocol, which is used by graphite and metronome. +See :doc:`metrics`. + ''', + }, + { + 'name' : 'chroot', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'switch to chroot jail', + 'doc' : ''' +If set, chroot to this directory for more security. +This is not recommended; instead, we recommend containing PowerDNS using operating system features. +We ship systemd unit files with our packages to make this easy. + +Make sure that ``/dev/log`` is available from within the chroot. +Logging will silently fail over time otherwise (on logrotate). + +When using ``chroot``, all other paths (except for :ref:`setting-config-dir`) set in the configuration are relative to the new root. + +When running on a system where systemd manages services, ``chroot`` does not work out of the box, as PowerDNS cannot use the ``NOTIFY_SOCKET``. +Either do not ``chroot`` on these systems or set the 'Type' of this service to 'simple' instead of 'notify' (refer to the systemd documentation on how to modify unit-files). + ''', + }, + { + 'name' : 'tcp_timeout', + 'section' : 'incoming', + 'oldname' : 'client-tcp-timeout', + 'type' : LType.Uint64, + 'default' : '2', + 'help' : 'Timeout in seconds when talking to TCP clients', + 'doc' : ''' +Time to wait for data from TCP clients. + ''', + }, + { + 'name' : 'config', + 'section' : 'commands', + 'type' : LType.Command, + 'default' : 'no', + 'help' : 'Output blank configuration. You can use --config=check to test the config file and command line arguments.', + 'doc' : ''' +EMPTY? ''' + }, + { + 'name' : 'config_dir', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '/etc/powerdns', + 'help' : 'Location of configuration directory (recursor.conf)', + 'doc' : ''' +Location of configuration directory (``recursor.conf``). +Usually ``/etc/powerdns``, but this depends on ``SYSCONFDIR`` during compile-time. + ''', + }, + { + 'name' : 'config_name', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'Name of this virtual configuration - will rename the binary image', + 'doc' : ''' +When running multiple recursors on the same server, read settings from :file:`recursor-{name}.conf`, this will also rename the binary image. + ''', + }, + { + 'name' : 'cpu_map', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'Thread to CPU mapping, space separated thread-id=cpu1,cpu2..cpuN pairs', + 'doc' : ''' +Set CPU affinity for threads, asking the scheduler to run those threads on a single CPU, or a set of CPUs. +This parameter accepts a space separated list of thread-id=cpu-id, or thread-id=cpu-id-1,cpu-id-2,...,cpu-id-N. +For example, to make the worker thread 0 run on CPU id 0 and the worker thread 1 on CPUs 1 and 2:: + + cpu-map=0=0 1=1,2 + +The thread handling the control channel, the webserver and other internal stuff has been assigned id 0, the distributor +threads if any are assigned id 1 and counting, and the worker threads follow behind. +The number of distributor threads is determined by :ref:`setting-distributor-threads`, the number of worker threads is determined by the :ref:`setting-threads` setting. + +This parameter is only available if the OS provides the ``pthread_setaffinity_np()`` function. + +Note that depending on the configuration the Recursor can start more threads. +Typically these threads will sleep most of the time. +These threads cannot be specified in this setting as their thread-ids are left unspecified. + ''', + 'doc' : ''' +Set CPU affinity for threads, asking the scheduler to run those threads on a single CPU, or a set of CPUs. +This parameter accepts a space separated list of thread-id=cpu-id, or thread-id=cpu-id-1,cpu-id-2,...,cpu-id-N. +For example, to make the worker thread 0 run on CPU id 0 and the worker thread 1 on CPUs 1 and 2:: + +.. code-block:: yaml + + recursor: + cpu_map: 0=0 1=1,2 + +The thread handling the control channel, the webserver and other internal stuff has been assigned id 0, the distributor +threads if any are assigned id 1 and counting, and the worker threads follow behind. +The number of distributor threads is determined by :ref:`setting-distributor-threads`, the number of worker threads is determined by the :ref:`setting-threads` setting. + +This parameter is only available if the OS provides the ``pthread_setaffinity_np()`` function. + +Note that depending on the configuration the Recursor can start more threads. +Typically these threads will sleep most of the time. +These threads cannot be specified in this setting as their thread-ids are left unspecified. + ''', + }, + { + 'name' : 'daemon', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Operate as a daemon', + 'doc' : ''' +Operate in the background. + ''', + 'versionchanged': ('4.0.0', 'Default is now ``no``, was ``yes`` before.') + }, + { + 'name' : 'dont_throttle_names', + 'section' : 'outgoing', + 'type' : LType.ListStrings, + 'default' : '', + 'help' : 'Do not throttle nameservers with this name or suffix', + 'doc' : ''' +When an authoritative server does not answer a query or sends a reply the recursor does not like, it is throttled. +Any servers' name suffix-matching the supplied names will never be throttled. + +.. warning:: + Most servers on the internet do not respond for a good reason (overloaded or unreachable), ``dont-throttle-names`` could make this load on the upstream server even higher, resulting in further service degradation. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'dont_throttle_netmasks', + 'section' : 'outgoing', + 'type' : LType.ListSubnets, + 'default' : '', + 'help' : 'Do not throttle nameservers with this IP netmask', + 'doc' : ''' +When an authoritative server does not answer a query or sends a reply the recursor does not like, it is throttled. +Any servers matching the supplied netmasks will never be throttled. + +This can come in handy on lossy networks when forwarding, where the same server is configured multiple times (e.g. with ``forward-zones-recurse=example.com=192.0.2.1;192.0.2.1``). +By default, the PowerDNS Recursor would throttle the 'first' server on a timeout and hence not retry the 'second' one. +In this case, ``dont-throttle-netmasks`` could be set to ``192.0.2.1``. + +.. warning:: + Most servers on the internet do not respond for a good reason (overloaded or unreachable), ``dont-throttle-netmasks`` could make this load on the upstream server even higher, resulting in further service degradation. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'devonly_regression_test_mode', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'internal use only', + 'doc' : 'SKIP', + }, + { + 'name' : 'disable', + 'section' : 'packetcache', + 'oldname' : 'disable-packetcache', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Disable packetcache', + 'doc' : ''' +Turn off the packet cache. Useful when running with Lua scripts that can not be cached, though individual query caching can be controlled from Lua as well. + ''', + }, + { + 'name' : 'disable_syslog', + 'section' : 'logging', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Disable logging to syslog, useful when running inside a supervisor that logs stdout', + 'doc' : ''' +Do not log to syslog, only to stdout. +Use this setting when running inside a supervisor that handles logging (like systemd). +**Note**: do not use this setting in combination with :ref:`setting-daemon` as all logging will disappear. + ''', + }, + { + 'name' : 'distribution_load_factor', + 'section' : 'incoming', + 'type' : LType.Double, + 'default' : '0.0', + 'help' : 'The load factor used when PowerDNS is distributing queries to worker threads', + 'doc' : ''' +If :ref:`setting-pdns-distributes-queries` is set and this setting is set to another value +than 0, the distributor thread will use a bounded load-balancing algorithm while +distributing queries to worker threads, making sure that no thread is assigned +more queries than distribution-load-factor times the average number of queries +currently processed by all the workers. +For example, with a value of 1.25, no server should get more than 125 % of the +average load. This helps making sure that all the workers have roughly the same +share of queries, even if the incoming traffic is very skewed, with a larger +number of requests asking for the same qname. + ''', + 'versionadded': '4.1.12' + }, + { + 'name' : 'distribution_pipe_buffer_size', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread', + 'doc' : ''' +Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread. +Requires support for `F_SETPIPE_SZ` which is present in Linux since 2.6.35. The actual size might be rounded up to +a multiple of a page size. 0 means that the OS default size is used. +A large buffer might allow the recursor to deal with very short-lived load spikes during which a worker thread gets +overloaded, but it will be at the cost of an increased latency. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'distributor_threads', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '0', + 'docdefault' : '1 if :ref:`setting-pdns-distributes-queries` is set, 0 otherwise', + 'help' : 'Launch this number of distributor threads, distributing queries to other threads', + 'doc' : ''' +If :ref:`setting-pdns-distributes-queries` is set, spawn this number of distributor threads on startup. Distributor threads +handle incoming queries and distribute them to other threads based on a hash of the query. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'dot_to_auth_names', + 'section' : 'outgoing', + 'type' : LType.ListStrings, + 'default' : '', + 'help' : 'Use DoT to authoritative servers with these names or suffixes', + 'doc' : ''' +Force DoT to the listed authoritative nameservers. For this to work, DoT support has to be compiled in. +Currently, the certificate is not checked for validity in any way. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'dot_to_port_853', + 'section' : 'outgoing', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Force DoT connection to target port 853 if DoT compiled in', + 'doc' : ''' +Enable DoT to forwarders that specify port 853. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'dns64_prefix', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'DNS64 prefix', + 'doc' : ''' +Enable DNS64 (:rfc:`6147`) support using the supplied /96 IPv6 prefix. This will generate 'fake' ``AAAA`` records for names +with only ``A`` records, as well as 'fake' ``PTR`` records to make sure that reverse lookup of DNS64-generated IPv6 addresses +generate the right name. +See :doc:`dns64` for more flexible but slower alternatives using Lua. + ''', + 'versionadded': '4.4.0' + }, + { + 'name' : 'validation', + 'section' : 'dnssec', + 'oldname' : 'dnssec', + 'type' : LType.String, + 'default' : 'process', + 'help' : 'DNSSEC mode: off/process-no-validate/process (default)/log-fail/validate', + 'doc' : ''' +One of ``off``, ``process-no-validate``, ``process``, ``log-fail``, ``validate`` + +Set the mode for DNSSEC processing, as detailed in :doc:`dnssec`. + +``off`` + No DNSSEC processing whatsoever. + Ignore DO-bits in queries, don't request any DNSSEC information from authoritative servers. + This behaviour is similar to PowerDNS Recursor pre-4.0. +``process-no-validate`` + Respond with DNSSEC records to clients that ask for it, set the DO bit on all outgoing queries. + Don't do any validation. +``process`` + Respond with DNSSEC records to clients that ask for it, set the DO bit on all outgoing queries. + Do validation for clients that request it (by means of the AD- bit or DO-bit in the query). +``log-fail`` + Similar behaviour to ``process``, but validate RRSIGs on responses and log bogus responses. +``validate`` + Full blown DNSSEC validation. Send SERVFAIL to clients on bogus responses. + ''', + 'versionadded': '4.0.0', + 'versionchanged': ('4.5.0', + 'The default changed from ``process-no-validate`` to ``process``') + }, + { + 'name' : 'disabled_algorithms', + 'section' : 'dnssec', + 'oldname' : 'dnssec-disabled-algorithms', + 'type' : LType.ListStrings, + 'default' : '', + 'help' : 'List of DNSSEC algorithm numbers that are considered unsupported', + 'doc' : ''' +A list of DNSSEC algorithm numbers that should be considered disabled. +These algorithms will not be used to validate DNSSEC signatures. +Zones (only) signed with these algorithms will be considered ``Insecure``. + +If this setting is empty (the default), :program:`Recursor` will determine which algorithms to disable automatically. +This is done for specific algorithms only, currently algorithms 5 (``RSASHA1``) and 7 (``RSASHA1NSEC3SHA1``). + +This is important on systems that have a default strict crypto policy, like RHEL9 derived systems. +On such systems not disabling some algorithms (or changing the security policy) will make affected zones to be considered ``Bogus`` as using these algorithms fails. + ''', + 'versionadded': '4.9.0' + }, + { + 'name' : 'log_bogus', + 'section' : 'dnssec', + 'oldname' : 'dnssec-log-bogus', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Log DNSSEC bogus validations', + 'doc' : ''' +Log every DNSSEC validation failure. +**Note**: This is not logged per-query but every time records are validated as Bogus. + ''', + }, + { + 'name' : 'dont_query', + 'section' : 'outgoing', + 'type' : LType.ListSubnets, + 'default' : '127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10, 0.0.0.0/8, 192.0.0.0/24, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::/96, ::ffff:0:0/96, 100::/64, 2001:db8::/32', + 'help' : 'If set, do not query these netmasks for DNS data', + 'doc' : ''' +The DNS is a public database, but sometimes contains delegations to private IP addresses, like for example 127.0.0.1. +This can have odd effects, depending on your network, and may even be a security risk. +Therefore, the PowerDNS Recursor by default does not query private space IP addresses. +This setting can be used to expand or reduce the limitations. + +Queries for names in forward zones and to addresses as configured in any of the settings :ref:`setting-forward-zones`, :ref:`setting-forward-zones-file` or :ref:`setting-forward-zones-recurse` are performed regardless of these limitations. + ''', + }, + { + 'name' : 'add_for', + 'section' : 'ecs', + 'oldname' : 'ecs-add-for', + 'type' : LType.ListSubnets, + 'default' : '0.0.0.0/0, ::/0, !127.0.0.0/8, !10.0.0.0/8, !100.64.0.0/10, !169.254.0.0/16, !192.168.0.0/16, !172.16.0.0/12, !::1/128, !fc00::/7, !fe80::/10', + 'help' : 'List of client netmasks for which EDNS Client Subnet will be added', + 'doc' : ''' +List of requestor netmasks for which the requestor IP Address should be used as the :rfc:`EDNS Client Subnet <7871>` for outgoing queries. Outgoing queries for requestors that do not match this list will use the :ref:`setting-ecs-scope-zero-address` instead. +Valid incoming ECS values from :ref:`setting-use-incoming-edns-subnet` are not replaced. + +Regardless of the value of this setting, ECS values are only sent for outgoing queries matching the conditions in the :ref:`setting-edns-subnet-allow-list` setting. This setting only controls the actual value being sent. + +This defaults to not using the requestor address inside RFC1918 and similar 'private' IP address spaces. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'ipv4_bits', + 'section' : 'ecs', + 'oldname' : 'ecs-ipv4-bits', + 'type' : LType.Uint64, + 'default' : '24', + 'help' : 'Number of bits of IPv4 address to pass for EDNS Client Subnet', + 'doc' : ''' +Number of bits of client IPv4 address to pass when sending EDNS Client Subnet address information. + ''', + 'versionadded': '4.1.0' + }, + { + 'name' : 'ipv4_cache_bits', + 'section' : 'ecs', + 'oldname' : 'ecs-ipv4-cache-bits', + 'type' : LType.Uint64, + 'default' : '24', + 'help' : 'Maximum number of bits of IPv4 mask to cache ECS response', + 'doc' : ''' +Maximum number of bits of client IPv4 address used by the authoritative server (as indicated by the EDNS Client Subnet scope in the answer) for an answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-cache-limit-ttl``. +That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. + ''', + 'versionadded': '4.1.12' + }, + { + 'name' : 'ipv6_bits', + 'section' : 'ecs', + 'oldname' : 'ecs-ipv6-bits', + 'type' : LType.Uint64, + 'default' : '56', + 'help' : 'Number of bits of IPv6 address to pass for EDNS Client Subnet', + 'doc' : ''' +Number of bits of client IPv6 address to pass when sending EDNS Client Subnet address information. + ''', + 'versionadded': '4.1.0' + }, + { + 'name' : 'ipv6_cache_bits', + 'section' : 'ecs', + 'oldname' : 'ecs-ipv6-cache-bits', + 'type' : LType.Uint64, + 'default' : '56', + 'help' : 'Maximum number of bits of IPv6 mask to cache ECS response', + 'doc' : ''' +Maximum number of bits of client IPv6 address used by the authoritative server (as indicated by the EDNS Client Subnet scope in the answer) for an answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-cache-limit-ttl``. +That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. + ''', + 'versionadded': '4.1.12' + }, + { + 'name' : 'ipv4_never_cache', + 'section' : 'ecs', + 'oldname' : 'ecs-ipv4-never-cache', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'If we should never cache IPv4 ECS responses', + 'doc' : ''' +When set, never cache replies carrying EDNS IPv4 Client Subnet scope in the record cache. +In this case the decision made by ```ecs-ipv4-cache-bits`` and ``ecs-cache-limit-ttl`` is no longer relevant. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'ipv6_never_cache', + 'section' : 'ecs', + 'oldname' : 'ecs-ipv6-never-cache', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'If we should never cache IPv6 ECS responses', + 'doc' : ''' +When set, never cache replies carrying EDNS IPv6 Client Subnet scope in the record cache. +In this case the decision made by ```ecs-ipv6-cache-bits`` and ``ecs-cache-limit-ttl`` is no longer relevant. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'minimum_ttl_override', + 'section' : 'ecs', + 'oldname' : 'ecs-minimum-ttl-override', + 'type' : LType.Uint64, + 'default' : '1', + 'help' : 'The minimum TTL for records in ECS-specific answers', + 'doc' : ''' +This setting artificially raises the TTLs of records in the ANSWER section of ECS-specific answers to be at least this long. +Setting this to a value greater than 1 technically is an RFC violation, but might improve performance a lot. +Using a value of 0 impacts performance of TTL 0 records greatly, since it forces the recursor to contact +authoritative servers every time a client requests them. +Can be set at runtime using ``rec_control set-ecs-minimum-ttl 3600``. + ''', + 'versionchanged': ('4.5.0', 'Old versions used default 0.') + }, + { + 'name' : 'cache_limit_ttl', + 'section' : 'ecs', + 'oldname' : 'ecs-cache-limit-ttl', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'Minimum TTL to cache ECS response', + 'doc' : ''' +The minimum TTL for an ECS-specific answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-ipv4-cache-bits`` or ``ecs-ipv6-cache-bits``. +That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. + ''', + 'versionadded': '4.1.12' + }, + { + 'name' : 'scope_zero_address', + 'section' : 'ecs', + 'oldname' : 'ecs-scope-zero-address', + 'type' : LType.String, + 'default' : '', + 'help' : 'Address to send to allow-listed authoritative servers for incoming queries with ECS prefix-length source of 0', + 'doc' : ''' +The IP address sent via EDNS Client Subnet to authoritative servers listed in +:ref:`setting-edns-subnet-allow-list` when :ref:`setting-use-incoming-edns-subnet` is set and the query has +an ECS source prefix-length set to 0. +The default is to look for the first usable (not an ``any`` one) address in +:ref:`setting-query-local-address` (starting with IPv4). If no suitable address is +found, the recursor fallbacks to sending 127.0.0.1. + ''', + 'versionadded': '4.1.0' + }, + { + 'name' : 'edns_bufsize', + 'section' : 'outgoing', + 'oldname' : 'edns-outgoing-bufsize', + 'type' : LType.Uint64, + 'default' : '1232', + 'help' : 'Outgoing EDNS buffer size', + 'doc' : ''' +.. note:: Why 1232? + + 1232 is the largest number of payload bytes that can fit in the smallest IPv6 packet. + IPv6 has a minimum MTU of 1280 bytes (:rfc:`RFC 8200, section 5 <8200#section-5>`), minus 40 bytes for the IPv6 header, minus 8 bytes for the UDP header gives 1232, the maximum payload size for the DNS response. + +This is the value set for the EDNS0 buffer size in outgoing packets. +Lower this if you experience timeouts. + ''', + 'versionchanged': ('4.2.0', 'Before 4.2.0, the default was 1680') + }, + { + 'name' : 'edns_padding_from', + 'section' : 'incoming', + 'type' : LType.String, + 'default' : '', + 'help' : 'List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that \'edns-padding-mode\' applies', + 'doc' : ''' +List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that :ref:`setting-edns-padding-mode` applies. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'edns_padding_mode', + 'section' : 'incoming', + 'type' : LType.String, + 'default' : 'padded-queries-only', + 'help' : 'Whether to add EDNS padding to all responses (\'always\') or only to responses for queries containing the EDNS padding option (\'padded-queries-only\', the default). In both modes, padding will only be added to responses for queries coming from \'setting-edns-padding-from\' sources', + 'doc' : ''' +One of ``always``, ``padded-queries-only``. +Whether to add EDNS padding to all responses (``always``) or only to responses for queries containing the EDNS padding option (``padded-queries-only``, the default). +In both modes, padding will only be added to responses for queries coming from :ref:`setting-edns-padding-from` sources. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'edns_padding', + 'section' : 'outgoing', + 'oldname' : 'edns-padding-out', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Whether to add EDNS padding to outgoing DoT messages', + 'doc' : ''' +Whether to add EDNS padding to outgoing DoT queries. + ''', + 'versionadded': '4.8.0' + }, + { + 'name' : 'edns_padding_tag', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '7830', + 'help' : 'Packetcache tag associated to responses sent with EDNS padding, to prevent sending these to clients for which padding is not enabled.', + 'doc' : ''' +The packetcache tag to use for padded responses, to prevent a client not allowed by the :ref::`setting-edns-padding-from` list to be served a cached answer generated for an allowed one. This +effectively divides the packet cache in two when :ref:`setting-edns-padding-from` is used. Note that this will not override a tag set from one of the ``Lua`` hooks. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'edns_subnet_whitelist', + 'section' : 'outgoing', + 'type' : LType.String, + 'default' : '', + 'help' : 'List of netmasks and domains that we should enable EDNS subnet for (deprecated)', + 'doc' : '', + 'deprecated': ('4.5.0', 'Use :ref:`setting-edns-subnet-allow-list`.'), + 'skip-yaml': True, + }, + { + 'name' : 'edns_subnet_allow_list', + 'section' : 'outgoing', + 'type' : LType.ListStrings, + 'default' : '', + 'help' : 'List of netmasks and domains that we should enable EDNS subnet for', + 'doc' : ''' +List of netmasks and domains that :rfc:`EDNS Client Subnet <7871>` should be enabled for in outgoing queries. + +For example, an EDNS Client Subnet option containing the address of the initial requestor (but see :ref:`setting-ecs-add-for`) will be added to an outgoing query sent to server 192.0.2.1 for domain X if 192.0.2.1 matches one of the supplied netmasks, or if X matches one of the supplied domains. +The initial requestor address will be truncated to 24 bits for IPv4 (see :ref:`setting-ecs-ipv4-bits`) and to 56 bits for IPv6 (see :ref:`setting-ecs-ipv6-bits`), as recommended in the privacy section of RFC 7871. + + +Note that this setting describes the destination of outgoing queries, not the sources of incoming queries, nor the subnets described in the EDNS Client Subnet option. + +By default, this option is empty, meaning no EDNS Client Subnet information is sent. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'entropy_source', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '/dev/urandom', + 'help' : 'If set, read entropy from this file', + 'doc' : ''' +PowerDNS can read entropy from a (hardware) source. +This is used for generating random numbers which are very hard to predict. +Generally on UNIX platforms, this source will be ``/dev/urandom``, which will always supply random numbers, even if entropy is lacking. +Change to ``/dev/random`` if PowerDNS should block waiting for enough entropy to arrive. + ''', + }, + { + 'name' : 'etc_hosts_file', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '/etc/hosts', + 'help' : 'Path to \'hosts\' file', + 'doc' : ''' +The path to the /etc/hosts file, or equivalent. +This file can be used to serve data authoritatively using :ref:`setting-export-etc-hosts`. + ''', + }, + { + 'name' : 'event_trace_enabled', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'If set, event traces are collected and send out via protobuf logging (1), logfile (2) or both(3)', + 'doc' : ''' +Enable the recording and logging of ref:`event traces`. This is an experimental feature and subject to change. +Possible values are 0: (disabled), 1 (add information to protobuf logging messages) and 2 (write to log) and 3 (both). + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'export_etc_hosts', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'If we should serve up contents from /etc/hosts', + 'doc' : ''' +If set, this flag will export the host names and IP addresses mentioned in ``/etc/hosts``. + ''', + }, + { + 'name' : 'export_etc_hosts_search_suffix', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'Also serve up the contents of /etc/hosts with this suffix', + 'doc' : ''' +If set, all hostnames in the :ref:`setting-export-etc-hosts` file are loaded in canonical form, based on this suffix, unless the name contains a '.', in which case the name is unchanged. +So an entry called 'pc' with ``export-etc-hosts-search-suffix='home.com'`` will lead to the generation of 'pc.home.com' within the recursor. +An entry called 'server1.home' will be stored as 'server1.home', regardless of this setting. + ''', + }, + { + 'name' : 'extended_resolution_errors', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'If set, send an EDNS Extended Error extension on resolution failures, like DNSSEC validation errors', + 'doc' : ''' +If set, the recursor will add an EDNS Extended Error (:rfc:`8914`) to responses when resolution failed, like DNSSEC validation errors, explaining the reason it failed. This setting is not needed to allow setting custom error codes from Lua or from a RPZ hit. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'forward_zones', + 'section' : 'recursor', + 'type' : LType.ListForwardZones, + 'default' : '', + 'help' : 'Zones for which we forward queries, comma separated domain=ip pairs', + 'doc' : ''' +Queries for zones listed here will be forwarded to the IP address listed. i.e. + +.. code-block:: none + + forward-zones=example.org=203.0.113.210, powerdns.com=2001:DB8::BEEF:5 + +Multiple IP addresses can be specified and port numbers other than 53 can be configured: + +.. code-block:: none + + forward-zones=example.org=203.0.113.210:5300;127.0.0.1, powerdns.com=127.0.0.1;198.51.100.10:530;[2001:DB8::1:3]:5300 + +Forwarded queries have the ``recursion desired (RD)`` bit set to ``0``, meaning that this setting is intended to forward queries to authoritative servers. +If an ``NS`` record set for a subzone of the forwarded zone is learned, that record set will be used to determine addresses for name servers of the subzone. +This allows e.g. a forward to a local authoritative server holding a copy of the root zone, delegations received from that server will work. + +**IMPORTANT**: When using DNSSEC validation (which is default), forwards to non-delegated (e.g. internal) zones that have a DNSSEC signed parent zone will validate as Bogus. +To prevent this, add a Negative Trust Anchor (NTA) for this zone in the :ref:`setting-lua-config-file` with ``addNTA('your.zone', 'A comment')``. +If this forwarded zone is signed, instead of adding NTA, add the DS record to the :ref:`setting-lua-config-file`. +See the :doc:`dnssec` information. + ''', + 'doc-new' : ''' +Queries for zones listed here will be forwarded to the IP address listed. i.e. + +.. code-block:: yaml + + recursor: + forward-zones: + - zone: example.org + forwarders: + - 203.0.113.210 + - zone: powerdns.com + forwarders: + - 2001:DB8::BEEF:5 + +Multiple IP addresses can be specified and port numbers other than 53 can be configured: + +.. code-block:: yaml + + recursor: + forward-zones: + - zone: example.org + forwarders: + - 203.0.113.210:5300 + - 127.0.0.1 + - zone: powerdns.com + forwarders: + - 127.0.0.1 + - 198.51.100.10:530 + - '[2001:DB8::1:3]:5300' + +Forwarded queries have the ``recursion desired (RD)`` bit set to ``0``, meaning that this setting is intended to forward queries to authoritative servers. +If an ``NS`` record set for a subzone of the forwarded zone is learned, that record set will be used to determine addresses for name servers of the subzone. +This allows e.g. a forward to a local authoritative server holding a copy of the root zone, delegations received from that server will work. + +**IMPORTANT**: When using DNSSEC validation (which is default), forwards to non-delegated (e.g. internal) zones that have a DNSSEC signed parent zone will validate as Bogus. +To prevent this, add a Negative Trust Anchor (NTA) for this zone in the :ref:`setting-lua-config-file` with ``addNTA('your.zone', 'A comment')``. +If this forwarded zone is signed, instead of adding NTA, add the DS record to the :ref:`setting-lua-config-file`. +See the :doc:`dnssec` information. + ''', + }, + { + 'name' : 'forward_zones_file', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'File with (+)domain=ip pairs for forwarding', + 'doc' : ''' +Same as :ref:`setting-forward-zones`, parsed from a file. Only 1 zone is allowed per line, specified as follows: + +.. code-block:: none + + example.org=203.0.113.210, 192.0.2.4:5300 + +Zones prefixed with a ``+`` are treated as with +:ref:`setting-forward-zones-recurse`. Default behaviour without ``+`` is as with +:ref:`setting-forward-zones`. + +The DNSSEC notes from :ref:`setting-forward-zones` apply here as well. + ''', + 'doc-new' : ''' + Same as :ref:`setting-forward-zones`, parsed from a file as a sequence of `ZoneForward`. + +.. code-block:: yaml + + - zone: example1.com + forwarders: + - 127.0.0.1 + - 127.0.0.1:5353 + - '[::1]53' + - zone: example2.com + forwarders: + - ::1 + recurse: true + notify_allowed: true + +The DNSSEC notes from :ref:`setting-forward-zones` apply here as well. + ''', + 'versionchanged': [('4.0.0', '(Old style settings only) Comments are allowed, everything behind ``#`` is ignored.'), + ('4.6.0', '(Old style settings only) Zones prefixed with a ``^`` are added to the :ref:`setting-allow-notify-for` list. Both prefix characters can be used if desired, in any order.')], + }, + { + 'name' : 'forward_zones_recurse', + 'section' : 'recursor', + 'type' : LType.ListForwardZones, + 'default' : '', + 'help' : 'Zones for which we forward queries with recursion bit, comma separated domain=ip pairs', + 'doc' : ''' +Like regular :ref:`setting-forward-zones`, but forwarded queries have the ``recursion desired (RD)`` bit set to ``1``, meaning that this setting is intended to forward queries to other recursive servers. +In contrast to regular forwarding, the rule that delegations of the forwarded subzones are respected is not active. +This is because we rely on the forwarder to resolve the query fully. + +See :ref:`setting-forward-zones` for additional options (such as supplying multiple recursive servers) and an important note about DNSSEC. + ''', + }, + { + 'name' : 'gettag_needs_edns_options', + 'section' : 'incoming', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'If EDNS Options should be extracted before calling the gettag() hook', + 'doc' : ''' +If set, EDNS options in incoming queries are extracted and passed to the :func:`gettag` hook in the ``ednsoptions`` table. + ''', + 'versionadded': '4.1.0' + }, + { + 'name' : 'help', + 'section' : 'commands', + 'type' : LType.Command, + 'default' : 'no', + 'help' : 'Provide a helpful message', + 'doc' : ''' +EMPTY? ''' + }, + { + 'name' : 'hint_file', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'If set, load root hints from this file', + 'doc' : ''' +If set, the root-hints are read from this file. If empty, the default built-in root hints are used. + +In some special cases, processing the root hints is not needed, for example when forwarding all queries to another recursor. +For these special cases, it is possible to disable the processing of root hints by setting the value to ``no`` or ``no-refresh``. +See :ref:`handling-of-root-hints` for more information on root hints handling. + ''', + 'versionchanged': [('4.6.2', 'Introduced the value ``no`` to disable root-hints processing.'), + ('4.9.0', 'Introduced the value ``no-refresh`` to disable both root-hints processing and periodic refresh of the cached root `NS` records.')] + }, + { + 'name' : 'ignore_unknown_settings', + 'section' : 'recursor', + 'type' : LType.ListStrings, + 'default' : '', + 'help' : 'Configuration settings to ignore if they are unknown', + 'doc' : ''' +Names of settings to be ignored while parsing configuration files, if the setting +name is unknown to PowerDNS. + +Useful during upgrade testing. + ''', + }, + { + 'name' : 'include_dir', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'Include *.conf files from this directory', + 'doc' : ''' +Directory to scan for additional config files. All files that end with .conf are loaded in order using ``POSIX`` as locale. + ''', + }, + { + 'name' : 'latency_statistic_size', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '10000', + 'help' : 'Number of latency values to calculate the qa-latency average', + 'doc' : ''' +Indication of how many queries will be averaged to get the average latency reported by the 'qa-latency' metric. + ''', + }, + { + 'name' : 'listen', + 'section' : 'incoming', + 'oldname' : 'local-address', + 'type' : LType.ListSocketAddresses, + 'default' : '127.0.0.1', + 'help' : 'IP addresses to listen on, separated by spaces or commas. Also accepts ports.', + 'doc' : ''' +Local IP addresses to which we bind. Each address specified can +include a port number; if no port is included then the +:ref:`setting-local-port` port will be used for that address. If a +port number is specified, it must be separated from the address with a +':'; for an IPv6 address the address must be enclosed in square +brackets. + +Examples:: + + local-address=127.0.0.1 ::1 + local-address=0.0.0.0:5353 + local-address=[::]:8053 + local-address=127.0.0.1:53, [::1]:5353 + ''', + }, + { + 'name' : 'port', + 'section' : 'incoming', + 'oldname' : 'local-port', + 'type' : LType.Uint64, + 'default' : '53', + 'help' : 'port to listen on', + 'doc' : ''' +Local port to bind to. +If an address in :ref:`setting-local-address` does not have an explicit port, this port is used. + ''', + }, + { + 'name' : 'timestamp', + 'section' : 'logging', + 'oldname' : 'log-timestamp', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Print timestamps in log lines, useful to disable when running with a tool that timestamps stdout already', + 'doc' : ''' + + ''', + }, + { + 'name' : 'non_local_bind', + 'section' : 'incoming', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Enable binding to non-local addresses by using FREEBIND / BINDANY socket options', + 'doc' : ''' +Bind to addresses even if one or more of the :ref:`setting-local-address`'s do not exist on this server. +Setting this option will enable the needed socket options to allow binding to non-local addresses. +This feature is intended to facilitate ip-failover setups, but it may also mask configuration issues and for this reason it is disabled by default. + ''', + }, + { + 'name' : 'loglevel', + 'section' : 'logging', + 'type' : LType.Uint64, + 'default' : '6', + 'help' : 'Amount of logging. Higher is more. Do not set below 3', + 'doc' : ''' +Amount of logging. The higher the number, the more lines logged. +Corresponds to 'syslog' level values (e.g. 0 = emergency, 1 = alert, 2 = critical, 3 = error, 4 = warning, 5 = notice, 6 = info, 7 = debug). +Each level includes itself plus the lower levels before it. +Not recommended to set this below 3. + ''', + }, + { + 'name' : 'common_errors', + 'section' : 'logging', + 'oldname' : 'log-common-errors', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'If we should log rather common errors', + 'doc' : ''' +Some DNS errors occur rather frequently and are no cause for alarm. + ''', + }, + { + 'name' : 'rpz_changes', + 'section' : 'logging', + 'oldname' : 'log-rpz-changes', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Log additions and removals to RPZ zones at Info level', + 'doc' : ''' +Log additions and removals to RPZ zones at Info (6) level instead of Debug (7). + ''', + 'versionadded': '4.1.0' + }, + { + 'name' : 'facility', + 'section' : 'logging', + 'oldname' : 'logging-facility', + 'type' : LType.String, + 'default' : '', + 'help' : 'Facility to log messages as. 0 corresponds to local0', + 'doc' : ''' +If set to a digit, logging is performed under this LOCAL facility. +See :ref:`logging`. +Do not pass names like 'local0'! + ''', + }, + { + 'name' : 'lowercase', + 'section' : 'outgoing', + 'oldname' : 'lowercase-outgoing', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Force outgoing questions to lowercase', + 'doc' : ''' +Set to true to lowercase the outgoing queries. +When set to 'no' (the default) a query from a client using mixed case in the DNS labels (such as a user entering mixed-case names or `draft-vixie-dnsext-dns0x20-00 `_), PowerDNS preserves the case of the query. +Broken authoritative servers might give a wrong or broken answer on this encoding. +Setting ``lowercase-outgoing`` to 'yes' makes the PowerDNS Recursor lowercase all the labels in the query to the authoritative servers, but still return the proper case to the client requesting. + ''', + }, + { + 'name' : 'lua_config_file', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'More powerful configuration options', + 'doc' : ''' +If set, and Lua support is compiled in, this will load an additional configuration file for newer features and more complicated setups. +See :doc:`lua-config/index` for the options that can be set in this file. + ''', + }, + { + 'name' : 'lua_dns_script', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'Filename containing an optional Lua script that will be used to modify dns answers', + 'doc' : ''' +Path to a lua file to manipulate the Recursor's answers. See :doc:`lua-scripting/index` for more information. + ''', + }, + { + 'name' : 'lua_maintenance_interval', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '1', + 'help' : 'Number of seconds between calls to the lua user defined maintenance() function', + 'doc' : ''' +The interval between calls to the Lua user defined `maintenance()` function in seconds. +See :ref:`hooks-maintenance-callback` + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'max_busy_dot_probes', + 'section' : 'outgoing', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'Maximum number of concurrent DoT probes', + 'doc' : ''' +Limit the maximum number of simultaneous DoT probes the Recursor will schedule. +The default value 0 means no DoT probes are scheduled. + +DoT probes are used to check if an authoritative server's IP address supports DoT. +If the probe determines an IP address supports DoT, the Recursor will use DoT to contact it for subsequent queries until a failure occurs. +After a failure, the Recursor will stop using DoT for that specific IP address for a while. +The results of probes are remembered and can be viewed by the ``rec_control dump-dot-probe-map`` command. +If the maximum number of pending probes is reached, no probes will be scheduled, even if no DoT status is known for an address. +If the result of a probe is not yet available, the Recursor will contact the authoritative server in the regular way, unless an authoritative server is configured to be contacted over DoT always using :ref:`setting-dot-to-auth-names`. +In that case no probe will be scheduled. + +.. note:: + DoT probing is an experimental feature. + Please test thoroughly to determine if it is suitable in your specific production environment before enabling. + ''', + 'versionadded': '4.7.0' + }, + { + 'name' : 'max_cache_bogus_ttl', + 'section' : 'recordcache', + 'type' : LType.Uint64, + 'default' : '3600', + 'help' : 'maximum number of seconds to keep a Bogus (positive or negative) cached entry in memory', + 'doc' : ''' +Maximum number of seconds to cache an item in the DNS cache (negative or positive) if its DNSSEC validation failed, no matter what the original TTL specified, to reduce the impact of a broken domain. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'max_entries', + 'section' : 'recordcache', + 'oldname' : 'max-cache-entries', + 'type' : LType.Uint64, + 'default' : '1000000', + 'help' : 'If set, maximum number of entries in the main cache', + 'doc' : ''' +Maximum number of DNS record cache entries, shared by all threads since 4.4.0. +Each entry associates a name and type with a record set. +The size of the negative cache is 10% of this number. + ''', + }, + { + 'name' : 'max_ttl', + 'section' : 'recordcache', + 'oldname' : 'max-cache-ttl', + 'type' : LType.Uint64, + 'default' : '86400', + 'help' : 'maximum number of seconds to keep a cached entry in memory', + 'doc' : ''' +Maximum number of seconds to cache an item in the DNS cache, no matter what the original TTL specified. +This value also controls the refresh period of cached root data. +See :ref:`handling-of-root-hints` for more information on this. + ''', + 'versionchanged': ('4.1.0', 'The minimum value of this setting is 15. i.e. setting this to lower than 15 will make this value 15.') + }, + { + 'name' : 'max_concurrent_requests_per_tcp_connection', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '10', + 'help' : 'Maximum number of requests handled concurrently per TCP connection', + 'doc' : ''' +Maximum number of incoming requests handled concurrently per tcp +connection. This number must be larger than 0 and smaller than 65536 +and also smaller than `max-mthreads`. + ''', + 'versionadded': '4.3.0' + }, + { + 'name' : 'max_include_depth', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '20', + 'help' : 'Maximum nested $INCLUDE depth when loading a zone from a file', + 'doc' : ''' +Maximum number of nested ``$INCLUDE`` directives while processing a zone file. +Zero mean no ``$INCLUDE`` directives will be accepted. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'max_generate_steps', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'Maximum number of $GENERATE steps when loading a zone from a file', + 'doc' : ''' +Maximum number of steps for a '$GENERATE' directive when parsing a +zone file. This is a protection measure to prevent consuming a lot of +CPU and memory when untrusted zones are loaded. Default to 0 which +means unlimited. + ''', + 'versionadded': '4.3.0' + }, + { + 'name' : 'max_mthreads', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '2048', + 'help' : 'Maximum number of simultaneous Mtasker threads', + 'doc' : ''' +Maximum number of simultaneous MTasker threads. + ''', + }, + { + 'name' : 'max_entries', + 'section' : 'packetcache', + 'oldname' : 'max-packetcache-entries', + 'type' : LType.Uint64, + 'default' : '500000', + 'help' : 'maximum number of entries to keep in the packetcache', + 'doc' : ''' +Maximum number of Packet Cache entries. Sharded and shared by all threads since 4.9.0. +''', + }, + { + 'name' : 'max_qperq', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '60', + 'help' : 'Maximum outgoing queries per query', + 'doc' : ''' +The maximum number of outgoing queries that will be sent out during the resolution of a single client query. +This is used to limit endlessly chasing CNAME redirections. +If qname-minimization is enabled, the number will be forced to be 100 +at a minimum to allow for the extra queries qname-minimization generates when the cache is empty. + ''', + }, + { + 'name' : 'max_ns_address_qperq', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '10', + 'help' : 'Maximum outgoing NS address queries per query', + 'doc' : ''' +The maximum number of outgoing queries with empty replies for +resolving nameserver names to addresses we allow during the resolution +of a single client query. If IPv6 is enabled, an A and a AAAA query +for a name counts as 1. If a zone publishes more than this number of +NS records, the limit is further reduced for that zone by lowering +it by the number of NS records found above the +:ref:`setting-max-ns-address-qperq` value. The limit wil not be reduced to a +number lower than 5. + ''', + 'versionadded' : ['4.1.16', '4.2.2', '4.3.1'] + }, + { + 'name' : 'max_ns_per_resolve', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '13', + 'help' : 'Maximum number of NS records to consider to resolve a name, 0 is no limit', + 'doc' : ''' +The maximum number of NS records that will be considered to select a nameserver to contact to resolve a name. +If a zone has more than :ref:`setting-max-ns-per-resolve` NS records, a random sample of this size will be used. +If :ref:`setting-max-ns-per-resolve` is zero, no limit applies. + ''', + 'versionadded': ['4.8.0', '4.7.3', '4.6.4', '4.5.11'] + }, + { + 'name' : 'max_negative_ttl', + 'section' : 'recordcache', + 'type' : LType.Uint64, + 'default' : '3600', + 'help' : 'maximum number of seconds to keep a negative cached entry in memory', + 'doc' : ''' +A query for which there is authoritatively no answer is cached to quickly deny a record's existence later on, without putting a heavy load on the remote server. +In practice, caches can become saturated with hundreds of thousands of hosts which are tried only once. +This setting, which defaults to 3600 seconds, puts a maximum on the amount of time negative entries are cached. + ''', + }, + { + 'name' : 'max_recursion_depth', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '16', + 'help' : 'Maximum number of internal recursion calls per query, 0 for unlimited', + 'doc' : ''' +Total maximum number of internal recursion calls the server may use to answer a single query. +0 means unlimited. +The value of :ref:`setting-stack-size` should be increased together with this one to prevent the stack from overflowing. +If :ref:`setting-qname-minimization` is enabled, the fallback code in case of a failing resolve is allowed an additional `max-recursion-depth/2`. + ''', + 'versionchanged': [('4.1.0', 'Before 4.1.0, this settings was unlimited.'), + ('4.9.0', "Before 4.9.0 this setting's default was 40 and the limit on ``CNAME`` chains (fixed at 16) acted as a bound on he recursion depth.")] + }, + { + 'name' : 'max_tcp_clients', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '128', + 'help' : 'Maximum number of simultaneous TCP clients', + 'doc' : ''' +Maximum number of simultaneous incoming TCP connections allowed. + ''', + }, + { + 'name' : 'max_tcp_per_client', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'If set, maximum number of TCP sessions per client (IP address)', + 'doc' : ''' +Maximum number of simultaneous incoming TCP connections allowed per client (remote IP address). + 0 means unlimited. + ''', + }, + { + 'name' : 'max_tcp_queries_per_connection', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'If set, maximum number of TCP queries in a TCP connection', + 'doc' : ''' +Maximum number of DNS queries in a TCP connection. +0 means unlimited. + ''', + 'versionadded': '4.1.0' + }, + { + 'name' : 'max_total_msec', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '7000', + 'help' : 'Maximum total wall-clock time per query in milliseconds, 0 for unlimited', + 'doc' : ''' +Total maximum number of milliseconds of wallclock time the server may use to answer a single query. +0 means unlimited. + ''', + }, + { + 'name' : 'max_udp_queries_per_round', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '10000', + 'help' : 'Maximum number of UDP queries processed per recvmsg() round, before returning back to normal processing', + 'doc' : ''' +Under heavy load the recursor might be busy processing incoming UDP queries for a long while before there is no more of these, and might therefore +neglect scheduling new ``mthreads``, handling responses from authoritative servers or responding to :doc:`rec_control ` +requests. +This setting caps the maximum number of incoming UDP DNS queries processed in a single round of looping on ``recvmsg()`` after being woken up by the multiplexer, before +returning back to normal processing and handling other events. + ''', + 'versionadded': '4.1.4' + }, + { + 'name' : 'minimum_ttl_override', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '1', + 'help' : 'The minimum TTL', + 'doc' : ''' +This setting artificially raises all TTLs to be at least this long. +Setting this to a value greater than 1 technically is an RFC violation, but might improve performance a lot. +Using a value of 0 impacts performance of TTL 0 records greatly, since it forces the recursor to contact +authoritative servers each time a client requests them. +Can be set at runtime using ``rec_control set-minimum-ttl 3600``. + ''', + 'versionchanged': ('4.5.0', 'Old versions used default 0.') + }, + { + 'name' : 'tracking', + 'section' : 'nod', + 'oldname' : 'new-domain-tracking', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Track newly observed domains (i.e. never seen before).', + 'doc' : ''' +Whether to track newly observed domains, i.e. never seen before. This +is a probabilistic algorithm, using a stable bloom filter to store +records of previously seen domains. When enabled for the first time, +all domains will appear to be newly observed, so the feature is best +left enabled for e.g. a week or longer before using the results. Note +that this feature is optional and must be enabled at compile-time, +thus it may not be available in all pre-built packages. +If protobuf is enabled and configured, then the newly observed domain +status will appear as a flag in Response messages. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'log', + 'section' : 'nod', + 'oldname' : 'new-domain-log', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Log newly observed domains.', + 'doc' : ''' +If a newly observed domain is detected, log that domain in the +recursor log file. The log line looks something like:: + + Jul 18 11:31:25 Newly observed domain nod=sdfoijdfio.com + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'lookup', + 'section' : 'nod', + 'oldname' : 'new-domain-lookup', + 'type' : LType.String, + 'default' : '', + 'help' : 'Perform a DNS lookup newly observed domains as a subdomain of the configured domain', + 'doc' : ''' +If a domain is specified, then each time a newly observed domain is +detected, the recursor will perform an A record lookup of '.'. For example if 'new-domain-lookup' +is configured as 'nod.powerdns.com', and a new domain 'xyz123.tv' is +detected, then an A record lookup will be made for +'xyz123.tv.nod.powerdns.com'. This feature gives a way to share the +newly observed domain with partners, vendors or security teams. The +result of the DNS lookup will be ignored by the recursor. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'db_size', + 'section' : 'nod', + 'oldname' : 'new-domain-db-size', + 'type' : LType.Uint64, + 'default' : '67108864', + 'help' : 'Size of the DB used to track new domains in terms of number of cells. Defaults to 67108864', + 'doc' : ''' +The default size of the stable bloom filter used to store previously +observed domains is 67108864. To change the number of cells, use this +setting. For each cell, the SBF uses 1 bit of memory, and one byte of +disk for the persistent file. +If there are already persistent files saved to disk, this setting will +have no effect unless you remove the existing files. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'history_dir', + 'section' : 'nod', + 'oldname' : 'new-domain-history-dir', + 'type' : LType.String, + 'default' : '/usr/local/var/lib/pdns-recursor/nod', + 'help' : 'Persist new domain tracking data here to persist between restarts', + 'doc' : ''' +This setting controls which directory is used to store the on-disk +cache of previously observed domains. + +The default depends on ``LOCALSTATEDIR`` when building the software. +Usually this comes down to ``/var/lib/pdns-recursor/nod`` or ``/usr/local/var/lib/pdns-recursor/nod``). + +The newly observed domain feature uses a stable bloom filter to store +a history of previously observed domains. The data structure is +synchronized to disk every 10 minutes, and is also initialized from +disk on startup. This ensures that previously observed domains are +preserved across recursor restarts. +If you change the new-domain-db-size setting, you must remove any files +from this directory. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'whitelist', + 'section' : 'nod', + 'oldname' : 'new-domain-whitelist', + 'type' : LType.String, + 'default' : '', + 'help' : 'List of domains (and implicitly all subdomains) which will never be considered a new domain (deprecated)', + 'doc' : '', + 'versionadded': '4.2.0', + 'deprecated': ('4.5.0', 'Use :ref:`setting-new-domain-ignore-list`.'), + 'skip-yaml': True, + }, + { + 'name' : 'ignore_list', + 'section' : 'nod', + 'oldname' : 'new-domain-ignore-list', + 'type' : LType.ListStrings, + 'default' : '', + 'help' : 'List of domains (and implicitly all subdomains) which will never be considered a new domain', + 'doc' : ''' +This setting is a list of all domains (and implicitly all subdomains) +that will never be considered a new domain. For example, if the domain +'xyz123.tv' is in the list, then 'foo.bar.xyz123.tv' will never be +considered a new domain. One use-case for the ignore list is to never +reveal details of internal subdomains via the new-domain-lookup +feature. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'pb_tag', + 'section' : 'nod', + 'oldname' : 'new-domain-pb-tag', + 'type' : LType.String, + 'default' : 'pdns-nod', + 'help' : 'If protobuf is configured, the tag to use for messages containing newly observed domains. Defaults to \'pdns-nod\'', + 'doc' : ''' +If protobuf is configured, then this tag will be added to all protobuf response messages when +a new domain is observed. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'network_timeout', + 'section' : 'outgoing', + 'type' : LType.Uint64, + 'default' : '1500', + 'help' : 'Wait this number of milliseconds for network i/o', + 'doc' : ''' +Number of milliseconds to wait for a remote authoritative server to respond. + ''', + }, + { + 'name' : 'no_shuffle', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Don\'t change', + 'doc' : 'SKIP', + 'skip-yaml': True, + }, + { + 'name' : 'non_resolving_ns_max_fails', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '5', + 'help' : 'Number of failed address resolves of a nameserver to start throttling it, 0 is disabled', + 'doc' : ''' +Number of failed address resolves of a nameserver name to start throttling it, 0 is disabled. +Nameservers matching :ref:`setting-dont-throttle-names` will not be throttled. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'non_resolving_ns_throttle_time', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '60', + 'help' : 'Number of seconds to throttle a nameserver with a name failing to resolve', + 'doc' : ''' +Number of seconds to throttle a nameserver with a name failing to resolve. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'nothing_below_nxdomain', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : 'dnssec', + 'help' : 'When an NXDOMAIN exists in cache for a name with fewer labels than the qname, send NXDOMAIN without doing a lookup (see RFC 8020)', + 'doc' : ''' +- One of ``no``, ``dnssec``, ``yes``. + +The type of :rfc:`8020` handling using cached NXDOMAIN responses. +This RFC specifies that NXDOMAIN means that the DNS tree under the denied name MUST be empty. +When an NXDOMAIN exists in the cache for a shorter name than the qname, no lookup is done and an NXDOMAIN is sent to the client. + +For instance, when ``foo.example.net`` is negatively cached, any query +matching ``*.foo.example.net`` will be answered with NXDOMAIN directly +without consulting authoritative servers. + +``no`` + No :rfc:`8020` processing is done. + +``dnssec`` + :rfc:`8020` processing is only done using cached NXDOMAIN records that are + DNSSEC validated. + +``yes`` + :rfc:`8020` processing is done using any non-Bogus NXDOMAIN record + available in the cache. + ''', + 'versionadded': '4.3.0' + }, + { + 'name' : 'nsec3_max_iterations', + 'section' : 'dnssec', + 'type' : LType.Uint64, + 'default' : '150', + 'help' : 'Maximum number of iterations allowed for an NSEC3 record', + 'doc' : ''' +Maximum number of iterations allowed for an NSEC3 record. +If an answer containing an NSEC3 record with more iterations is received, its DNSSEC validation status is treated as Insecure. + ''', + 'versionadded': '4.1.0', + 'versionchanged': ('4.5.2', 'Default is now 150, was 2500 before.') + }, + { + 'name' : 'ttl', + 'section' : 'packetcache', + 'oldname' : 'packetcache-ttl', + 'type' : LType.Uint64, + 'default' : '86400', + 'help' : 'maximum number of seconds to keep a cached entry in packetcache', + 'doc' : ''' +Maximum number of seconds to cache an item in the packet cache, no matter what the original TTL specified. + ''', + 'versionchanged': ('4.9.0', 'The default was changed from 3600 (1 hour) to 86400 (24 hours).') + }, + { + 'name' : 'negative_ttl', + 'section' : 'packetcache', + 'oldname' : 'packetcache-negative-ttl', + 'type' : LType.Uint64, + 'default' : '60', + 'help' : 'maximum number of seconds to keep a cached NxDomain or NoData entry in packetcache', + 'doc' : ''' +Maximum number of seconds to cache an ``NxDomain`` or ``NoData`` answer in the packetcache. +This setting's maximum is capped to :ref:`setting-packetcache-ttl`. +i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-negative-ttl`` at the default will lower ``packetcache-negative-ttl`` to ``15``. + ''', + 'versionadded': '4.9.0' + }, + { + 'name' : 'servfail_ttl', + 'section' : 'packetcache', + 'oldname' : 'packetcache-servfail-ttl', + 'type' : LType.Uint64, + 'default' : '60', + 'help' : 'maximum number of seconds to keep a cached servfail entry in packetcache', + 'doc' : ''' +Maximum number of seconds to cache an answer indicating a failure to resolve in the packet cache. +Before version 4.6.0 only ``ServFail`` answers were considered as such. Starting with 4.6.0, all responses with a code other than ``NoError`` and ``NXDomain``, or without records in the answer and authority sections, are considered as a failure to resolve. +Since 4.9.0, negative answers are handled separately from resolving failures. + ''', + 'doc-rst' : ''' + 'versionchanged': ('4.0.0', "This setting's maximum is capped to :ref:`setting-packetcache-ttl`. + i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-servfail-ttl`` at the default will lower ``packetcache-servfail-ttl`` to ``15``.") + ''' + }, + { + 'name' : 'shards', + 'section' : 'packetcache', + 'oldname' : 'packetcache-shards', + 'type' : LType.Uint64, + 'default' : '1024', + 'help' : 'Number of shards in the packet cache', + 'doc' : ''' +Sets the number of shards in the packet cache. If you have high contention as reported by ``packetcache-contented/packetcache-acquired``, +you can try to enlarge this value or run with fewer threads. + ''', + 'versionadded': '4.9.0' + }, + { + 'name' : 'pdns_distributes_queries', + 'section' : 'incoming', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'If PowerDNS itself should distribute queries over threads', + 'doc' : ''' +If set, PowerDNS will use distinct threads to listen to client sockets and distribute that work to worker-threads using a hash of the query. +This feature should maximize the cache hit ratio on versions before 4.9.0. +To use more than one thread set :ref:`setting-distributor-threads` in version 4.2.0 or newer. +Enabling should improve performance on systems where :ref:`setting-reuseport` does not have the effect of +balancing the queries evenly over multiple worker threads. + ''', + 'versionchanged': ('4.9.0', 'Default changed to ``no``, previously it was ``yes``.') + }, + { + 'name' : 'processes', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '1', + 'help' : 'Launch this number of processes (EXPERIMENTAL, DO NOT CHANGE)', + 'doc' : '''SKIP''', + 'skip-yaml': True, + }, + { + 'name' : 'protobuf_use_kernel_timestamp', + 'section' : 'logging', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Compute the latency of queries in protobuf messages by using the timestamp set by the kernel when the query was received (when available)', + 'doc' : ''' +Whether to compute the latency of responses in protobuf messages using the timestamp set by the kernel when the query packet was received (when available), instead of computing it based on the moment we start processing the query. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'proxy_protocol_from', + 'section' : 'incoming', + 'type' : LType.String, + 'default' : '', + 'help' : 'A Proxy Protocol header is only allowed from these subnets', + 'doc' : ''' +Ranges that are required to send a Proxy Protocol version 2 header in front of UDP and TCP queries, to pass the original source and destination addresses and ports to the recursor, as well as custom values. +Queries that are not prefixed with such a header will not be accepted from clients in these ranges. Queries prefixed by headers from clients that are not listed in these ranges will be dropped. + +Note that once a Proxy Protocol header has been received, the source address from the proxy header instead of the address of the proxy will be checked against the :ref:`setting-allow-from` ACL. + +The dnsdist docs have `more information about the PROXY protocol `_. + ''', + 'versionadded': '4.4.0' + }, + { + 'name' : 'proxy_protocol_maximum_size', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '512', + 'help' : 'The maximum size of a proxy protocol payload, including the TLV values', + 'doc' : ''' +The maximum size, in bytes, of a Proxy Protocol payload (header, addresses and ports, and TLV values). Queries with a larger payload will be dropped. + ''', + 'versionadded': '4.4.0' + }, + { + 'name' : 'public_suffix_list_file', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'Path to the Public Suffix List file, if any', + 'doc' : ''' +Path to the Public Suffix List file, if any. If set, PowerDNS will try to load the Public Suffix List from this file instead of using the built-in list. The PSL is used to group the queries by relevant domain names when displaying the top queries. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'qname_minimization', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Use Query Name Minimization', + 'doc' : ''' +Enable Query Name Minimization. This implements a relaxed form of Query Name Mimimization as +described in :rfc:`7816`. + ''', + 'versionadded': '4.3.0' + }, + { + 'name' : 'source_address', + 'section' : 'outgoing', + 'oldname' : 'query-local-address', + 'type' : LType.ListSubnets, + 'default' : '0.0.0.0', + 'help' : 'Source IP address for sending queries', + 'doc' : ''' +Send out local queries from this address, or addresses. By adding multiple +addresses, increased spoofing resilience is achieved. When no address of a certain +address family is configured, there are *no* queries sent with that address family. +In the default configuration this means that IPv6 is not used for outgoing queries. + ''', + 'versionchanged': ('4.4.0', 'IPv6 addresses can be set with this option as well.') + }, + { + 'name' : 'quiet', + 'section' : 'logging', + 'type' : LType.Bool, + 'default' : 'yes', + 'help' : 'Suppress logging of questions and answers', + 'doc' : ''' +Don't log queries. + ''', + }, + { + 'name' : 'locked_ttl_perc', + 'section' : 'recordcache', + 'oldname' : 'record-cache-locked-ttl-perc', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'Replace records in record cache only after this % of original TTL has passed', + 'doc' : ''' +Replace record sets in the record cache only after this percentage of the original TTL has passed. +The PowerDNS Recursor already has several mechanisms to protect against spoofing attempts. +This adds an extra layer of protection---as it limits the window of time cache updates are accepted---at the cost of a less efficient record cache. + +The default value of 0 means no extra locking occurs. +When non-zero, record sets received (e.g. in the Additional Section) will not replace existing record sets in the record cache until the given percentage of the original TTL has expired. +A value of 100 means only expired record sets will be replaced. + +There are a few cases where records will be replaced anyway: + +- Record sets that are expired will always be replaced. +- Authoritative record sets will replace unauthoritative record sets unless DNSSEC validation of the new record set failed. +- If the new record set belongs to a DNSSEC-secure zone and successfully passed validation it will replace an existing entry. +- Record sets produced by :ref:`setting-refresh-on-ttl-perc` tasks will also replace existing record sets. + ''', + 'versionadded': '4.8.0' + }, + { + 'name' : 'shards', + 'section' : 'recordcache', + 'oldname' : 'record-cache-shards', + 'type' : LType.Uint64, + 'default' : '1024', + 'help' : 'Number of shards in the record cache', + 'doc' : ''' +Sets the number of shards in the record cache. If you have high +contention as reported by +``record-cache-contented/record-cache-acquired``, you can try to +enlarge this value or run with fewer threads. + ''', + 'versionadded': '4.4.0' + }, + { + 'name' : 'refresh_on_ttl_perc', + 'section' : 'recordcache', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'If a record is requested from the cache and only this % of original TTL remains, refetch', + 'doc' : ''' +Sets the 'refresh almost expired' percentage of the record cache. Whenever a record is fetched from the packet or record cache +and only ``refresh-on-ttl-perc`` percent or less of its original TTL is left, a task is queued to refetch the name/type combination to +update the record cache. In most cases this causes future queries to always see a non-expired record cache entry. +A typical value is 10. If the value is zero, this functionality is disabled. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'reuseport', + 'section' : 'incoming', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Enable SO_REUSEPORT allowing multiple recursors processes to listen to 1 address', + 'doc' : ''' +If ``SO_REUSEPORT`` support is available, allows multiple threads and processes to open listening sockets for the same port. + +Since 4.1.0, when :ref:`setting-pdns-distributes-queries` is disabled and :ref:`setting-reuseport` is enabled, every worker-thread will open a separate listening socket to let the kernel distribute the incoming queries instead of running a distributor thread (which could otherwise be a bottleneck) and avoiding thundering herd issues, thus leading to much higher performance on multi-core boxes. + ''', + 'versionchanged': ('4.9.0', 'The default is changed to ``yes``, previously it was ``no``. If ``SO_REUSEPORT`` support is not available, the setting defaults to ``no``.') + }, + { + 'name' : 'rng', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : 'auto', + 'help' : 'Specify random number generator to use. Valid values are auto,sodium,openssl,getrandom,arc4random,urandom.', + 'doc' : ''' +- String +- Default: auto + +Specify which random number generator to use. Permissible choices are + - auto - choose automatically + - sodium - Use libsodium ``randombytes_uniform`` + - openssl - Use libcrypto ``RAND_bytes`` + - getrandom - Use libc getrandom, falls back to urandom if it does not really work + - arc4random - Use BSD ``arc4random_uniform`` + - urandom - Use ``/dev/urandom`` + - kiss - Use simple settable deterministic RNG. **FOR TESTING PURPOSES ONLY!** + ''', + }, + { + 'name' : 'root_nx_trust', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'If set, believe that an NXDOMAIN from the root means the TLD does not exist', + 'doc' : ''' +If set, an NXDOMAIN from the root-servers will serve as a blanket NXDOMAIN for the entire TLD the query belonged to. +The effect of this is far fewer queries to the root-servers. + ''', + 'versionchanged': ('4.0.0', "Default is ``yes`` now, was ``no`` before 4.0.0") + }, + { + 'name' : 'save_parent_ns_set', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Save parent NS set to be used if child NS set fails', + 'doc' : ''' +If set, a parent (non-authoritative) ``NS`` set is saved if it contains more entries than a newly encountered child (authoritative) ``NS`` set for the same domain. +The saved parent ``NS`` set is tried if resolution using the child ``NS`` set fails. + ''', + 'versionadded': '4.7.0' + }, + { + 'name' : 'security_poll_suffix', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : 'secpoll.powerdns.com.', + 'help' : 'Domain name from which to query security update notifications', + 'doc' : ''' +Domain name from which to query security update notifications. +Setting this to an empty string disables secpoll. + ''', + }, + { + 'name' : 'serve_rfc1918', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'If we should be authoritative for RFC 1918 private IP space', + 'doc' : ''' +This makes the server authoritatively aware of: ``10.in-addr.arpa``, ``168.192.in-addr.arpa``, ``16-31.172.in-addr.arpa``, which saves load on the AS112 servers. +Individual parts of these zones can still be loaded or forwarded. + ''', + }, + { + 'name' : 'serve_stale_extensions', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'Number of times a record\'s ttl is extended by 30s to be served stale', + 'doc' : ''' +Maximum number of times an expired record's TTL is extended by 30s when serving stale. +Extension only occurs if a record cannot be refreshed. +A value of 0 means the ``Serve Stale`` mechanism is not used. +To allow records becoming stale to be served for an hour, use a value of 120. +See :ref:`serve-stale` for a description of the Serve Stale mechanism. + ''', + 'versionadded': '4.8.0' + }, + { + 'name' : 'server_down_max_fails', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '64', + 'help' : 'Maximum number of consecutive timeouts (and unreachables) to mark a server as down ( 0 => disabled )', + 'doc' : ''' +If a server has not responded in any way this many times in a row, no longer send it any queries for :ref:`setting-server-down-throttle-time` seconds. +Afterwards, we will try a new packet, and if that also gets no response at all, we again throttle for :ref:`setting-server-down-throttle-time` seconds. +Even a single response packet will drop the block. + ''', + }, + { + 'name' : 'server_down_throttle_time', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '60', + 'help' : 'Number of seconds to throttle all queries to a server after being marked as down', + 'doc' : ''' +Throttle a server that has failed to respond :ref:`setting-server-down-max-fails` times for this many seconds. + ''', + }, + { + 'name' : 'server_id', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : RUNTIME, + 'help' : 'Returned when queried for \'id.server\' TXT or NSID, defaults to hostname, set custom or \'disabled\'', + 'doc' : ''' +The reply given by The PowerDNS recursor to a query for 'id.server' with its hostname, useful for in clusters. +When a query contains the :rfc:`NSID EDNS0 Option <5001>`, this value is returned in the response as the NSID value. + +This setting can be used to override the answer given to these queries. +Set to 'disabled' to disable NSID and 'id.server' answers. + +Query example (where 192.0.2.14 is your server): + +.. code-block:: sh + + dig @192.0.2.14 CHAOS TXT id.server. + dig @192.0.2.14 example.com IN A +nsid + ''', + }, + { + 'name' : 'setgid', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'If set, change group id to this gid for more security', + 'doc' : ''' +PowerDNS can change its user and group id after binding to its socket. +Can be used for better :doc:`security `. + ''' + }, + { + 'name' : 'setuid', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'If set, change user id to this uid for more security', + 'doc' : ''' +PowerDNS can change its user and group id after binding to its socket. +Can be used for better :doc:`security `. + ''' + }, + { + 'name' : 'signature_inception_skew', + 'section' : 'dnssec', + 'type' : LType.Uint64, + 'default' : '60', + 'help' : 'Allow the signature inception to be off by this number of seconds', + 'doc' : ''' +Allow the signature inception to be off by this number of seconds. Negative values are not allowed. + ''', + 'versionadded': '4.1.5', + 'versionchanged': ('4.2.0', 'Default is now 60, was 0 before.') + }, + { + 'name' : 'single_socket', + 'section' : 'outgoing', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'If set, only use a single socket for outgoing queries', + 'doc' : ''' +Use only a single socket for outgoing queries. + ''', + }, + { + 'name' : 'agent', + 'section' : 'snmp', + 'oldname' : 'snmp-agent', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'If set, register as an SNMP agent', + 'doc' : ''' +If set to true and PowerDNS has been compiled with SNMP support, it will register as an SNMP agent to provide statistics and be able to send traps. + ''', + 'versionadded': '4.1.0' + }, + { + 'name' : 'master_socket', + 'section' : 'snmp', + 'oldname' : 'snmp-master-socket', + 'type' : LType.String, + 'default' : '', + 'help' : 'If set and snmp-agent is set, the socket to use to register to the SNMP daemon (deprecated)', + 'doc' : ''' + ''', + 'versionadded': '4.1.0', + 'deprecated': ('4.5.0', 'Use :ref:`setting-snmp-daemon-socket`.'), + 'skip-yaml': True, + }, + { + 'name' : 'daemon_socket', + 'section' : 'snmp', + 'oldname' : 'snmp-daemon-socket', + 'type' : LType.String, + 'default' : '', + 'help' : 'If set and snmp-agent is set, the socket to use to register to the SNMP daemon', + 'doc' : ''' +If not empty and ``snmp-agent`` is set to true, indicates how PowerDNS should contact the SNMP daemon to register as an SNMP agent. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'soa_minimum_ttl', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'Don\'t change', + 'doc' : '''SKIP''', + 'skip-yaml': True, + }, + { + 'name' : 'socket_dir', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'Where the controlsocket will live, /var/run/pdns-recursor when unset and not chrooted', + 'doc' : ''' +Where to store the control socket and pidfile. +The default depends on ``LOCALSTATEDIR`` or the ``--with-socketdir`` setting when building (usually ``/var/run`` or ``/run``). + +When using :ref:`setting-chroot` the default becomes ``/``. + ''', + }, + { + 'name' : 'socket_group', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'Group of socket', + 'doc' : ''' +Group and mode of the controlsocket. +Owner and group can be specified by name, mode is in octal. +''' + }, + { + 'name' : 'socket_mode', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'Permissions for socket', + 'doc' : ''' +Mode of the controlsocket. +Owner and group can be specified by name, mode is in octal. + ''' + }, + { + 'name' : 'socket_owner', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : '', + 'help' : 'Owner of socket', + 'doc' : ''' +Owner of the controlsocket. +Owner and group can be specified by name, mode is in octal. + ''' + }, + { + 'name' : 'spoof_nearmiss_max', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '1', + 'help' : 'If non-zero, assume spoofing after this many near misses', + 'doc' : ''' +If set to non-zero, PowerDNS will assume it is being spoofed after seeing this many answers with the wrong id. + ''', + 'versionchanged': ('4.5.0', 'Older versions used 20 as the default value.') + }, + { + 'name' : 'stack_cache_size', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '100', + 'help' : 'Size of the stack cache, per mthread', + 'doc' : ''' +Maximum number of mthread stacks that can be cached for later reuse, per thread. Caching these stacks reduces the CPU load at the cost of a slightly higher memory usage, each cached stack consuming `stack-size` bytes of memory. +It makes no sense to cache more stacks than the value of `max-mthreads`, since there will never be more stacks than that in use at a given time. + ''', + 'versionadded': '4.9.0' + }, + { + 'name' : 'stack_size', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '200000', + 'help' : 'stack size per mthread', + 'doc' : ''' +Size in bytes of the stack of each mthread. + ''', + }, + { + 'name' : 'statistics_interval', + 'section' : 'logging', + 'type' : LType.Uint64, + 'default' : '1800', + 'help' : 'Number of seconds between printing of recursor statistics, 0 to disable', + 'doc' : ''' +Interval between logging statistical summary on recursor performance. +Use 0 to disable. + ''', + 'versionadded': '4.1.0' + }, + { + 'name' : 'stats_api_blacklist', + 'section' : 'recursor', + 'type' : LType.ListStrings, + 'default' : 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-1, ecs-v4-response-bits-2, ecs-v4-response-bits-3, ecs-v4-response-bits-4, ecs-v4-response-bits-5, ecs-v4-response-bits-6, ecs-v4-response-bits-7, ecs-v4-response-bits-8, ecs-v4-response-bits-9, ecs-v4-response-bits-10, ecs-v4-response-bits-11, ecs-v4-response-bits-12, ecs-v4-response-bits-13, ecs-v4-response-bits-14, ecs-v4-response-bits-15, ecs-v4-response-bits-16, ecs-v4-response-bits-17, ecs-v4-response-bits-18, ecs-v4-response-bits-19, ecs-v4-response-bits-20, ecs-v4-response-bits-21, ecs-v4-response-bits-22, ecs-v4-response-bits-23, ecs-v4-response-bits-24, ecs-v4-response-bits-25, ecs-v4-response-bits-26, ecs-v4-response-bits-27, ecs-v4-response-bits-28, ecs-v4-response-bits-29, ecs-v4-response-bits-30, ecs-v4-response-bits-31, ecs-v4-response-bits-32, ecs-v6-response-bits-1, ecs-v6-response-bits-2, ecs-v6-response-bits-3, ecs-v6-response-bits-4, ecs-v6-response-bits-5, ecs-v6-response-bits-6, ecs-v6-response-bits-7, ecs-v6-response-bits-8, ecs-v6-response-bits-9, ecs-v6-response-bits-10, ecs-v6-response-bits-11, ecs-v6-response-bits-12, ecs-v6-response-bits-13, ecs-v6-response-bits-14, ecs-v6-response-bits-15, ecs-v6-response-bits-16, ecs-v6-response-bits-17, ecs-v6-response-bits-18, ecs-v6-response-bits-19, ecs-v6-response-bits-20, ecs-v6-response-bits-21, ecs-v6-response-bits-22, ecs-v6-response-bits-23, ecs-v6-response-bits-24, ecs-v6-response-bits-25, ecs-v6-response-bits-26, ecs-v6-response-bits-27, ecs-v6-response-bits-28, ecs-v6-response-bits-29, ecs-v6-response-bits-30, ecs-v6-response-bits-31, ecs-v6-response-bits-32, ecs-v6-response-bits-33, ecs-v6-response-bits-34, ecs-v6-response-bits-35, ecs-v6-response-bits-36, ecs-v6-response-bits-37, ecs-v6-response-bits-38, ecs-v6-response-bits-39, ecs-v6-response-bits-40, ecs-v6-response-bits-41, ecs-v6-response-bits-42, ecs-v6-response-bits-43, ecs-v6-response-bits-44, ecs-v6-response-bits-45, ecs-v6-response-bits-46, ecs-v6-response-bits-47, ecs-v6-response-bits-48, ecs-v6-response-bits-49, ecs-v6-response-bits-50, ecs-v6-response-bits-51, ecs-v6-response-bits-52, ecs-v6-response-bits-53, ecs-v6-response-bits-54, ecs-v6-response-bits-55, ecs-v6-response-bits-56, ecs-v6-response-bits-57, ecs-v6-response-bits-58, ecs-v6-response-bits-59, ecs-v6-response-bits-60, ecs-v6-response-bits-61, ecs-v6-response-bits-62, ecs-v6-response-bits-63, ecs-v6-response-bits-64, ecs-v6-response-bits-65, ecs-v6-response-bits-66, ecs-v6-response-bits-67, ecs-v6-response-bits-68, ecs-v6-response-bits-69, ecs-v6-response-bits-70, ecs-v6-response-bits-71, ecs-v6-response-bits-72, ecs-v6-response-bits-73, ecs-v6-response-bits-74, ecs-v6-response-bits-75, ecs-v6-response-bits-76, ecs-v6-response-bits-77, ecs-v6-response-bits-78, ecs-v6-response-bits-79, ecs-v6-response-bits-80, ecs-v6-response-bits-81, ecs-v6-response-bits-82, ecs-v6-response-bits-83, ecs-v6-response-bits-84, ecs-v6-response-bits-85, ecs-v6-response-bits-86, ecs-v6-response-bits-87, ecs-v6-response-bits-88, ecs-v6-response-bits-89, ecs-v6-response-bits-90, ecs-v6-response-bits-91, ecs-v6-response-bits-92, ecs-v6-response-bits-93, ecs-v6-response-bits-94, ecs-v6-response-bits-95, ecs-v6-response-bits-96, ecs-v6-response-bits-97, ecs-v6-response-bits-98, ecs-v6-response-bits-99, ecs-v6-response-bits-100, ecs-v6-response-bits-101, ecs-v6-response-bits-102, ecs-v6-response-bits-103, ecs-v6-response-bits-104, ecs-v6-response-bits-105, ecs-v6-response-bits-106, ecs-v6-response-bits-107, ecs-v6-response-bits-108, ecs-v6-response-bits-109, ecs-v6-response-bits-110, ecs-v6-response-bits-111, ecs-v6-response-bits-112, ecs-v6-response-bits-113, ecs-v6-response-bits-114, ecs-v6-response-bits-115, ecs-v6-response-bits-116, ecs-v6-response-bits-117, ecs-v6-response-bits-118, ecs-v6-response-bits-119, ecs-v6-response-bits-120, ecs-v6-response-bits-121, ecs-v6-response-bits-122, ecs-v6-response-bits-123, ecs-v6-response-bits-124, ecs-v6-response-bits-125, ecs-v6-response-bits-126, ecs-v6-response-bits-127, ecs-v6-response-bits-128', + 'help' : 'List of statistics that are disabled when retrieving the complete list of statistics via the API (deprecated)', + 'docdefault': '', + 'doc' : '', + 'versionadded': '4.2.0', + 'deprecated': ('4.5.0', 'Use :ref:`setting-stats-api-disabled-list`.'), + 'skip-yaml': True, + }, + { + 'name' : 'stats_api_disabled_list', + 'section' : 'recursor', + 'type' : LType.ListStrings, + 'default' : 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-1, ecs-v4-response-bits-2, ecs-v4-response-bits-3, ecs-v4-response-bits-4, ecs-v4-response-bits-5, ecs-v4-response-bits-6, ecs-v4-response-bits-7, ecs-v4-response-bits-8, ecs-v4-response-bits-9, ecs-v4-response-bits-10, ecs-v4-response-bits-11, ecs-v4-response-bits-12, ecs-v4-response-bits-13, ecs-v4-response-bits-14, ecs-v4-response-bits-15, ecs-v4-response-bits-16, ecs-v4-response-bits-17, ecs-v4-response-bits-18, ecs-v4-response-bits-19, ecs-v4-response-bits-20, ecs-v4-response-bits-21, ecs-v4-response-bits-22, ecs-v4-response-bits-23, ecs-v4-response-bits-24, ecs-v4-response-bits-25, ecs-v4-response-bits-26, ecs-v4-response-bits-27, ecs-v4-response-bits-28, ecs-v4-response-bits-29, ecs-v4-response-bits-30, ecs-v4-response-bits-31, ecs-v4-response-bits-32, ecs-v6-response-bits-1, ecs-v6-response-bits-2, ecs-v6-response-bits-3, ecs-v6-response-bits-4, ecs-v6-response-bits-5, ecs-v6-response-bits-6, ecs-v6-response-bits-7, ecs-v6-response-bits-8, ecs-v6-response-bits-9, ecs-v6-response-bits-10, ecs-v6-response-bits-11, ecs-v6-response-bits-12, ecs-v6-response-bits-13, ecs-v6-response-bits-14, ecs-v6-response-bits-15, ecs-v6-response-bits-16, ecs-v6-response-bits-17, ecs-v6-response-bits-18, ecs-v6-response-bits-19, ecs-v6-response-bits-20, ecs-v6-response-bits-21, ecs-v6-response-bits-22, ecs-v6-response-bits-23, ecs-v6-response-bits-24, ecs-v6-response-bits-25, ecs-v6-response-bits-26, ecs-v6-response-bits-27, ecs-v6-response-bits-28, ecs-v6-response-bits-29, ecs-v6-response-bits-30, ecs-v6-response-bits-31, ecs-v6-response-bits-32, ecs-v6-response-bits-33, ecs-v6-response-bits-34, ecs-v6-response-bits-35, ecs-v6-response-bits-36, ecs-v6-response-bits-37, ecs-v6-response-bits-38, ecs-v6-response-bits-39, ecs-v6-response-bits-40, ecs-v6-response-bits-41, ecs-v6-response-bits-42, ecs-v6-response-bits-43, ecs-v6-response-bits-44, ecs-v6-response-bits-45, ecs-v6-response-bits-46, ecs-v6-response-bits-47, ecs-v6-response-bits-48, ecs-v6-response-bits-49, ecs-v6-response-bits-50, ecs-v6-response-bits-51, ecs-v6-response-bits-52, ecs-v6-response-bits-53, ecs-v6-response-bits-54, ecs-v6-response-bits-55, ecs-v6-response-bits-56, ecs-v6-response-bits-57, ecs-v6-response-bits-58, ecs-v6-response-bits-59, ecs-v6-response-bits-60, ecs-v6-response-bits-61, ecs-v6-response-bits-62, ecs-v6-response-bits-63, ecs-v6-response-bits-64, ecs-v6-response-bits-65, ecs-v6-response-bits-66, ecs-v6-response-bits-67, ecs-v6-response-bits-68, ecs-v6-response-bits-69, ecs-v6-response-bits-70, ecs-v6-response-bits-71, ecs-v6-response-bits-72, ecs-v6-response-bits-73, ecs-v6-response-bits-74, ecs-v6-response-bits-75, ecs-v6-response-bits-76, ecs-v6-response-bits-77, ecs-v6-response-bits-78, ecs-v6-response-bits-79, ecs-v6-response-bits-80, ecs-v6-response-bits-81, ecs-v6-response-bits-82, ecs-v6-response-bits-83, ecs-v6-response-bits-84, ecs-v6-response-bits-85, ecs-v6-response-bits-86, ecs-v6-response-bits-87, ecs-v6-response-bits-88, ecs-v6-response-bits-89, ecs-v6-response-bits-90, ecs-v6-response-bits-91, ecs-v6-response-bits-92, ecs-v6-response-bits-93, ecs-v6-response-bits-94, ecs-v6-response-bits-95, ecs-v6-response-bits-96, ecs-v6-response-bits-97, ecs-v6-response-bits-98, ecs-v6-response-bits-99, ecs-v6-response-bits-100, ecs-v6-response-bits-101, ecs-v6-response-bits-102, ecs-v6-response-bits-103, ecs-v6-response-bits-104, ecs-v6-response-bits-105, ecs-v6-response-bits-106, ecs-v6-response-bits-107, ecs-v6-response-bits-108, ecs-v6-response-bits-109, ecs-v6-response-bits-110, ecs-v6-response-bits-111, ecs-v6-response-bits-112, ecs-v6-response-bits-113, ecs-v6-response-bits-114, ecs-v6-response-bits-115, ecs-v6-response-bits-116, ecs-v6-response-bits-117, ecs-v6-response-bits-118, ecs-v6-response-bits-119, ecs-v6-response-bits-120, ecs-v6-response-bits-121, ecs-v6-response-bits-122, ecs-v6-response-bits-123, ecs-v6-response-bits-124, ecs-v6-response-bits-125, ecs-v6-response-bits-126, ecs-v6-response-bits-127, ecs-v6-response-bits-128', + 'docdefault': 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*', + 'help' : 'List of statistics that are disabled when retrieving the complete list of statistics via the API', + 'doc' : ''' +A list of comma-separated statistic names, that are disabled when retrieving the complete list of statistics via the API for performance reasons. +These statistics can still be retrieved individually by specifically asking for it. + ''', + 'doc-new' : ''' +A sequence of statistic names, that are disabled when retrieving the complete list of statistics via the API for performance reasons. +These statistics can still be retrieved individually by specifically asking for it. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'stats_carbon_blacklist', + 'section' : 'recursor', + 'type' : LType.ListStrings, + 'default' : 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-1, ecs-v4-response-bits-2, ecs-v4-response-bits-3, ecs-v4-response-bits-4, ecs-v4-response-bits-5, ecs-v4-response-bits-6, ecs-v4-response-bits-7, ecs-v4-response-bits-8, ecs-v4-response-bits-9, ecs-v4-response-bits-10, ecs-v4-response-bits-11, ecs-v4-response-bits-12, ecs-v4-response-bits-13, ecs-v4-response-bits-14, ecs-v4-response-bits-15, ecs-v4-response-bits-16, ecs-v4-response-bits-17, ecs-v4-response-bits-18, ecs-v4-response-bits-19, ecs-v4-response-bits-20, ecs-v4-response-bits-21, ecs-v4-response-bits-22, ecs-v4-response-bits-23, ecs-v4-response-bits-24, ecs-v4-response-bits-25, ecs-v4-response-bits-26, ecs-v4-response-bits-27, ecs-v4-response-bits-28, ecs-v4-response-bits-29, ecs-v4-response-bits-30, ecs-v4-response-bits-31, ecs-v4-response-bits-32, ecs-v6-response-bits-1, ecs-v6-response-bits-2, ecs-v6-response-bits-3, ecs-v6-response-bits-4, ecs-v6-response-bits-5, ecs-v6-response-bits-6, ecs-v6-response-bits-7, ecs-v6-response-bits-8, ecs-v6-response-bits-9, ecs-v6-response-bits-10, ecs-v6-response-bits-11, ecs-v6-response-bits-12, ecs-v6-response-bits-13, ecs-v6-response-bits-14, ecs-v6-response-bits-15, ecs-v6-response-bits-16, ecs-v6-response-bits-17, ecs-v6-response-bits-18, ecs-v6-response-bits-19, ecs-v6-response-bits-20, ecs-v6-response-bits-21, ecs-v6-response-bits-22, ecs-v6-response-bits-23, ecs-v6-response-bits-24, ecs-v6-response-bits-25, ecs-v6-response-bits-26, ecs-v6-response-bits-27, ecs-v6-response-bits-28, ecs-v6-response-bits-29, ecs-v6-response-bits-30, ecs-v6-response-bits-31, ecs-v6-response-bits-32, ecs-v6-response-bits-33, ecs-v6-response-bits-34, ecs-v6-response-bits-35, ecs-v6-response-bits-36, ecs-v6-response-bits-37, ecs-v6-response-bits-38, ecs-v6-response-bits-39, ecs-v6-response-bits-40, ecs-v6-response-bits-41, ecs-v6-response-bits-42, ecs-v6-response-bits-43, ecs-v6-response-bits-44, ecs-v6-response-bits-45, ecs-v6-response-bits-46, ecs-v6-response-bits-47, ecs-v6-response-bits-48, ecs-v6-response-bits-49, ecs-v6-response-bits-50, ecs-v6-response-bits-51, ecs-v6-response-bits-52, ecs-v6-response-bits-53, ecs-v6-response-bits-54, ecs-v6-response-bits-55, ecs-v6-response-bits-56, ecs-v6-response-bits-57, ecs-v6-response-bits-58, ecs-v6-response-bits-59, ecs-v6-response-bits-60, ecs-v6-response-bits-61, ecs-v6-response-bits-62, ecs-v6-response-bits-63, ecs-v6-response-bits-64, ecs-v6-response-bits-65, ecs-v6-response-bits-66, ecs-v6-response-bits-67, ecs-v6-response-bits-68, ecs-v6-response-bits-69, ecs-v6-response-bits-70, ecs-v6-response-bits-71, ecs-v6-response-bits-72, ecs-v6-response-bits-73, ecs-v6-response-bits-74, ecs-v6-response-bits-75, ecs-v6-response-bits-76, ecs-v6-response-bits-77, ecs-v6-response-bits-78, ecs-v6-response-bits-79, ecs-v6-response-bits-80, ecs-v6-response-bits-81, ecs-v6-response-bits-82, ecs-v6-response-bits-83, ecs-v6-response-bits-84, ecs-v6-response-bits-85, ecs-v6-response-bits-86, ecs-v6-response-bits-87, ecs-v6-response-bits-88, ecs-v6-response-bits-89, ecs-v6-response-bits-90, ecs-v6-response-bits-91, ecs-v6-response-bits-92, ecs-v6-response-bits-93, ecs-v6-response-bits-94, ecs-v6-response-bits-95, ecs-v6-response-bits-96, ecs-v6-response-bits-97, ecs-v6-response-bits-98, ecs-v6-response-bits-99, ecs-v6-response-bits-100, ecs-v6-response-bits-101, ecs-v6-response-bits-102, ecs-v6-response-bits-103, ecs-v6-response-bits-104, ecs-v6-response-bits-105, ecs-v6-response-bits-106, ecs-v6-response-bits-107, ecs-v6-response-bits-108, ecs-v6-response-bits-109, ecs-v6-response-bits-110, ecs-v6-response-bits-111, ecs-v6-response-bits-112, ecs-v6-response-bits-113, ecs-v6-response-bits-114, ecs-v6-response-bits-115, ecs-v6-response-bits-116, ecs-v6-response-bits-117, ecs-v6-response-bits-118, ecs-v6-response-bits-119, ecs-v6-response-bits-120, ecs-v6-response-bits-121, ecs-v6-response-bits-122, ecs-v6-response-bits-123, ecs-v6-response-bits-124, ecs-v6-response-bits-125, ecs-v6-response-bits-126, ecs-v6-response-bits-127, ecs-v6-response-bits-128, cumul-clientanswers, cumul-authanswers, policy-hits, proxy-mapping-total, remote-logger-count', + 'docdefault': '', + 'help' : 'List of statistics that are prevented from being exported via Carbon (deprecated)', + 'doc' : '', + 'versionadded': '4.2.0', + 'deprecated': ('4.5.0', 'Use :ref:`setting-stats-carbon-disabled-list`.'), + 'skip-yaml': True, + }, + { + 'name' : 'stats_carbon_disabled_list', + 'section' : 'recursor', + 'type' : LType.ListStrings, + 'default' : 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-1, ecs-v4-response-bits-2, ecs-v4-response-bits-3, ecs-v4-response-bits-4, ecs-v4-response-bits-5, ecs-v4-response-bits-6, ecs-v4-response-bits-7, ecs-v4-response-bits-8, ecs-v4-response-bits-9, ecs-v4-response-bits-10, ecs-v4-response-bits-11, ecs-v4-response-bits-12, ecs-v4-response-bits-13, ecs-v4-response-bits-14, ecs-v4-response-bits-15, ecs-v4-response-bits-16, ecs-v4-response-bits-17, ecs-v4-response-bits-18, ecs-v4-response-bits-19, ecs-v4-response-bits-20, ecs-v4-response-bits-21, ecs-v4-response-bits-22, ecs-v4-response-bits-23, ecs-v4-response-bits-24, ecs-v4-response-bits-25, ecs-v4-response-bits-26, ecs-v4-response-bits-27, ecs-v4-response-bits-28, ecs-v4-response-bits-29, ecs-v4-response-bits-30, ecs-v4-response-bits-31, ecs-v4-response-bits-32, ecs-v6-response-bits-1, ecs-v6-response-bits-2, ecs-v6-response-bits-3, ecs-v6-response-bits-4, ecs-v6-response-bits-5, ecs-v6-response-bits-6, ecs-v6-response-bits-7, ecs-v6-response-bits-8, ecs-v6-response-bits-9, ecs-v6-response-bits-10, ecs-v6-response-bits-11, ecs-v6-response-bits-12, ecs-v6-response-bits-13, ecs-v6-response-bits-14, ecs-v6-response-bits-15, ecs-v6-response-bits-16, ecs-v6-response-bits-17, ecs-v6-response-bits-18, ecs-v6-response-bits-19, ecs-v6-response-bits-20, ecs-v6-response-bits-21, ecs-v6-response-bits-22, ecs-v6-response-bits-23, ecs-v6-response-bits-24, ecs-v6-response-bits-25, ecs-v6-response-bits-26, ecs-v6-response-bits-27, ecs-v6-response-bits-28, ecs-v6-response-bits-29, ecs-v6-response-bits-30, ecs-v6-response-bits-31, ecs-v6-response-bits-32, ecs-v6-response-bits-33, ecs-v6-response-bits-34, ecs-v6-response-bits-35, ecs-v6-response-bits-36, ecs-v6-response-bits-37, ecs-v6-response-bits-38, ecs-v6-response-bits-39, ecs-v6-response-bits-40, ecs-v6-response-bits-41, ecs-v6-response-bits-42, ecs-v6-response-bits-43, ecs-v6-response-bits-44, ecs-v6-response-bits-45, ecs-v6-response-bits-46, ecs-v6-response-bits-47, ecs-v6-response-bits-48, ecs-v6-response-bits-49, ecs-v6-response-bits-50, ecs-v6-response-bits-51, ecs-v6-response-bits-52, ecs-v6-response-bits-53, ecs-v6-response-bits-54, ecs-v6-response-bits-55, ecs-v6-response-bits-56, ecs-v6-response-bits-57, ecs-v6-response-bits-58, ecs-v6-response-bits-59, ecs-v6-response-bits-60, ecs-v6-response-bits-61, ecs-v6-response-bits-62, ecs-v6-response-bits-63, ecs-v6-response-bits-64, ecs-v6-response-bits-65, ecs-v6-response-bits-66, ecs-v6-response-bits-67, ecs-v6-response-bits-68, ecs-v6-response-bits-69, ecs-v6-response-bits-70, ecs-v6-response-bits-71, ecs-v6-response-bits-72, ecs-v6-response-bits-73, ecs-v6-response-bits-74, ecs-v6-response-bits-75, ecs-v6-response-bits-76, ecs-v6-response-bits-77, ecs-v6-response-bits-78, ecs-v6-response-bits-79, ecs-v6-response-bits-80, ecs-v6-response-bits-81, ecs-v6-response-bits-82, ecs-v6-response-bits-83, ecs-v6-response-bits-84, ecs-v6-response-bits-85, ecs-v6-response-bits-86, ecs-v6-response-bits-87, ecs-v6-response-bits-88, ecs-v6-response-bits-89, ecs-v6-response-bits-90, ecs-v6-response-bits-91, ecs-v6-response-bits-92, ecs-v6-response-bits-93, ecs-v6-response-bits-94, ecs-v6-response-bits-95, ecs-v6-response-bits-96, ecs-v6-response-bits-97, ecs-v6-response-bits-98, ecs-v6-response-bits-99, ecs-v6-response-bits-100, ecs-v6-response-bits-101, ecs-v6-response-bits-102, ecs-v6-response-bits-103, ecs-v6-response-bits-104, ecs-v6-response-bits-105, ecs-v6-response-bits-106, ecs-v6-response-bits-107, ecs-v6-response-bits-108, ecs-v6-response-bits-109, ecs-v6-response-bits-110, ecs-v6-response-bits-111, ecs-v6-response-bits-112, ecs-v6-response-bits-113, ecs-v6-response-bits-114, ecs-v6-response-bits-115, ecs-v6-response-bits-116, ecs-v6-response-bits-117, ecs-v6-response-bits-118, ecs-v6-response-bits-119, ecs-v6-response-bits-120, ecs-v6-response-bits-121, ecs-v6-response-bits-122, ecs-v6-response-bits-123, ecs-v6-response-bits-124, ecs-v6-response-bits-125, ecs-v6-response-bits-126, ecs-v6-response-bits-127, ecs-v6-response-bits-128, cumul-clientanswers, cumul-authanswers, policy-hits, proxy-mapping-total, remote-logger-count', + 'docdefault': 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\*', + 'help' : 'List of statistics that are prevented from being exported via Carbon', + 'doc' : ''' +A list of comma-separated statistic names, that are prevented from being exported via carbon for performance reasons. + ''', + 'doc-new' : ''' +A sequence of statistic names, that are prevented from being exported via carbon for performance reasons. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'stats_rec_control_blacklist', + 'section' : 'recursor', + 'type' : LType.ListStrings, + 'default' : 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-1, ecs-v4-response-bits-2, ecs-v4-response-bits-3, ecs-v4-response-bits-4, ecs-v4-response-bits-5, ecs-v4-response-bits-6, ecs-v4-response-bits-7, ecs-v4-response-bits-8, ecs-v4-response-bits-9, ecs-v4-response-bits-10, ecs-v4-response-bits-11, ecs-v4-response-bits-12, ecs-v4-response-bits-13, ecs-v4-response-bits-14, ecs-v4-response-bits-15, ecs-v4-response-bits-16, ecs-v4-response-bits-17, ecs-v4-response-bits-18, ecs-v4-response-bits-19, ecs-v4-response-bits-20, ecs-v4-response-bits-21, ecs-v4-response-bits-22, ecs-v4-response-bits-23, ecs-v4-response-bits-24, ecs-v4-response-bits-25, ecs-v4-response-bits-26, ecs-v4-response-bits-27, ecs-v4-response-bits-28, ecs-v4-response-bits-29, ecs-v4-response-bits-30, ecs-v4-response-bits-31, ecs-v4-response-bits-32, ecs-v6-response-bits-1, ecs-v6-response-bits-2, ecs-v6-response-bits-3, ecs-v6-response-bits-4, ecs-v6-response-bits-5, ecs-v6-response-bits-6, ecs-v6-response-bits-7, ecs-v6-response-bits-8, ecs-v6-response-bits-9, ecs-v6-response-bits-10, ecs-v6-response-bits-11, ecs-v6-response-bits-12, ecs-v6-response-bits-13, ecs-v6-response-bits-14, ecs-v6-response-bits-15, ecs-v6-response-bits-16, ecs-v6-response-bits-17, ecs-v6-response-bits-18, ecs-v6-response-bits-19, ecs-v6-response-bits-20, ecs-v6-response-bits-21, ecs-v6-response-bits-22, ecs-v6-response-bits-23, ecs-v6-response-bits-24, ecs-v6-response-bits-25, ecs-v6-response-bits-26, ecs-v6-response-bits-27, ecs-v6-response-bits-28, ecs-v6-response-bits-29, ecs-v6-response-bits-30, ecs-v6-response-bits-31, ecs-v6-response-bits-32, ecs-v6-response-bits-33, ecs-v6-response-bits-34, ecs-v6-response-bits-35, ecs-v6-response-bits-36, ecs-v6-response-bits-37, ecs-v6-response-bits-38, ecs-v6-response-bits-39, ecs-v6-response-bits-40, ecs-v6-response-bits-41, ecs-v6-response-bits-42, ecs-v6-response-bits-43, ecs-v6-response-bits-44, ecs-v6-response-bits-45, ecs-v6-response-bits-46, ecs-v6-response-bits-47, ecs-v6-response-bits-48, ecs-v6-response-bits-49, ecs-v6-response-bits-50, ecs-v6-response-bits-51, ecs-v6-response-bits-52, ecs-v6-response-bits-53, ecs-v6-response-bits-54, ecs-v6-response-bits-55, ecs-v6-response-bits-56, ecs-v6-response-bits-57, ecs-v6-response-bits-58, ecs-v6-response-bits-59, ecs-v6-response-bits-60, ecs-v6-response-bits-61, ecs-v6-response-bits-62, ecs-v6-response-bits-63, ecs-v6-response-bits-64, ecs-v6-response-bits-65, ecs-v6-response-bits-66, ecs-v6-response-bits-67, ecs-v6-response-bits-68, ecs-v6-response-bits-69, ecs-v6-response-bits-70, ecs-v6-response-bits-71, ecs-v6-response-bits-72, ecs-v6-response-bits-73, ecs-v6-response-bits-74, ecs-v6-response-bits-75, ecs-v6-response-bits-76, ecs-v6-response-bits-77, ecs-v6-response-bits-78, ecs-v6-response-bits-79, ecs-v6-response-bits-80, ecs-v6-response-bits-81, ecs-v6-response-bits-82, ecs-v6-response-bits-83, ecs-v6-response-bits-84, ecs-v6-response-bits-85, ecs-v6-response-bits-86, ecs-v6-response-bits-87, ecs-v6-response-bits-88, ecs-v6-response-bits-89, ecs-v6-response-bits-90, ecs-v6-response-bits-91, ecs-v6-response-bits-92, ecs-v6-response-bits-93, ecs-v6-response-bits-94, ecs-v6-response-bits-95, ecs-v6-response-bits-96, ecs-v6-response-bits-97, ecs-v6-response-bits-98, ecs-v6-response-bits-99, ecs-v6-response-bits-100, ecs-v6-response-bits-101, ecs-v6-response-bits-102, ecs-v6-response-bits-103, ecs-v6-response-bits-104, ecs-v6-response-bits-105, ecs-v6-response-bits-106, ecs-v6-response-bits-107, ecs-v6-response-bits-108, ecs-v6-response-bits-109, ecs-v6-response-bits-110, ecs-v6-response-bits-111, ecs-v6-response-bits-112, ecs-v6-response-bits-113, ecs-v6-response-bits-114, ecs-v6-response-bits-115, ecs-v6-response-bits-116, ecs-v6-response-bits-117, ecs-v6-response-bits-118, ecs-v6-response-bits-119, ecs-v6-response-bits-120, ecs-v6-response-bits-121, ecs-v6-response-bits-122, ecs-v6-response-bits-123, ecs-v6-response-bits-124, ecs-v6-response-bits-125, ecs-v6-response-bits-126, ecs-v6-response-bits-127, ecs-v6-response-bits-128, cumul-clientanswers, cumul-authanswers, policy-hits, proxy-mapping-total, remote-logger-count', + 'docdefault': '', + 'help' : 'List of statistics that are prevented from being exported via rec_control get-all (deprecated)', + 'doc' : '', + 'versionadded': '4.2.0', + 'deprecated': ('4.5.0', 'Use :ref:`setting-stats-rec-control-disabled-list`.'), + 'skip-yaml': True, + }, + { + 'name' : 'stats_rec_control_disabled_list', + 'section' : 'recursor', + 'type' : LType.ListStrings, + 'default' : 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-1, ecs-v4-response-bits-2, ecs-v4-response-bits-3, ecs-v4-response-bits-4, ecs-v4-response-bits-5, ecs-v4-response-bits-6, ecs-v4-response-bits-7, ecs-v4-response-bits-8, ecs-v4-response-bits-9, ecs-v4-response-bits-10, ecs-v4-response-bits-11, ecs-v4-response-bits-12, ecs-v4-response-bits-13, ecs-v4-response-bits-14, ecs-v4-response-bits-15, ecs-v4-response-bits-16, ecs-v4-response-bits-17, ecs-v4-response-bits-18, ecs-v4-response-bits-19, ecs-v4-response-bits-20, ecs-v4-response-bits-21, ecs-v4-response-bits-22, ecs-v4-response-bits-23, ecs-v4-response-bits-24, ecs-v4-response-bits-25, ecs-v4-response-bits-26, ecs-v4-response-bits-27, ecs-v4-response-bits-28, ecs-v4-response-bits-29, ecs-v4-response-bits-30, ecs-v4-response-bits-31, ecs-v4-response-bits-32, ecs-v6-response-bits-1, ecs-v6-response-bits-2, ecs-v6-response-bits-3, ecs-v6-response-bits-4, ecs-v6-response-bits-5, ecs-v6-response-bits-6, ecs-v6-response-bits-7, ecs-v6-response-bits-8, ecs-v6-response-bits-9, ecs-v6-response-bits-10, ecs-v6-response-bits-11, ecs-v6-response-bits-12, ecs-v6-response-bits-13, ecs-v6-response-bits-14, ecs-v6-response-bits-15, ecs-v6-response-bits-16, ecs-v6-response-bits-17, ecs-v6-response-bits-18, ecs-v6-response-bits-19, ecs-v6-response-bits-20, ecs-v6-response-bits-21, ecs-v6-response-bits-22, ecs-v6-response-bits-23, ecs-v6-response-bits-24, ecs-v6-response-bits-25, ecs-v6-response-bits-26, ecs-v6-response-bits-27, ecs-v6-response-bits-28, ecs-v6-response-bits-29, ecs-v6-response-bits-30, ecs-v6-response-bits-31, ecs-v6-response-bits-32, ecs-v6-response-bits-33, ecs-v6-response-bits-34, ecs-v6-response-bits-35, ecs-v6-response-bits-36, ecs-v6-response-bits-37, ecs-v6-response-bits-38, ecs-v6-response-bits-39, ecs-v6-response-bits-40, ecs-v6-response-bits-41, ecs-v6-response-bits-42, ecs-v6-response-bits-43, ecs-v6-response-bits-44, ecs-v6-response-bits-45, ecs-v6-response-bits-46, ecs-v6-response-bits-47, ecs-v6-response-bits-48, ecs-v6-response-bits-49, ecs-v6-response-bits-50, ecs-v6-response-bits-51, ecs-v6-response-bits-52, ecs-v6-response-bits-53, ecs-v6-response-bits-54, ecs-v6-response-bits-55, ecs-v6-response-bits-56, ecs-v6-response-bits-57, ecs-v6-response-bits-58, ecs-v6-response-bits-59, ecs-v6-response-bits-60, ecs-v6-response-bits-61, ecs-v6-response-bits-62, ecs-v6-response-bits-63, ecs-v6-response-bits-64, ecs-v6-response-bits-65, ecs-v6-response-bits-66, ecs-v6-response-bits-67, ecs-v6-response-bits-68, ecs-v6-response-bits-69, ecs-v6-response-bits-70, ecs-v6-response-bits-71, ecs-v6-response-bits-72, ecs-v6-response-bits-73, ecs-v6-response-bits-74, ecs-v6-response-bits-75, ecs-v6-response-bits-76, ecs-v6-response-bits-77, ecs-v6-response-bits-78, ecs-v6-response-bits-79, ecs-v6-response-bits-80, ecs-v6-response-bits-81, ecs-v6-response-bits-82, ecs-v6-response-bits-83, ecs-v6-response-bits-84, ecs-v6-response-bits-85, ecs-v6-response-bits-86, ecs-v6-response-bits-87, ecs-v6-response-bits-88, ecs-v6-response-bits-89, ecs-v6-response-bits-90, ecs-v6-response-bits-91, ecs-v6-response-bits-92, ecs-v6-response-bits-93, ecs-v6-response-bits-94, ecs-v6-response-bits-95, ecs-v6-response-bits-96, ecs-v6-response-bits-97, ecs-v6-response-bits-98, ecs-v6-response-bits-99, ecs-v6-response-bits-100, ecs-v6-response-bits-101, ecs-v6-response-bits-102, ecs-v6-response-bits-103, ecs-v6-response-bits-104, ecs-v6-response-bits-105, ecs-v6-response-bits-106, ecs-v6-response-bits-107, ecs-v6-response-bits-108, ecs-v6-response-bits-109, ecs-v6-response-bits-110, ecs-v6-response-bits-111, ecs-v6-response-bits-112, ecs-v6-response-bits-113, ecs-v6-response-bits-114, ecs-v6-response-bits-115, ecs-v6-response-bits-116, ecs-v6-response-bits-117, ecs-v6-response-bits-118, ecs-v6-response-bits-119, ecs-v6-response-bits-120, ecs-v6-response-bits-121, ecs-v6-response-bits-122, ecs-v6-response-bits-123, ecs-v6-response-bits-124, ecs-v6-response-bits-125, ecs-v6-response-bits-126, ecs-v6-response-bits-127, ecs-v6-response-bits-128, cumul-clientanswers, cumul-authanswers, policy-hits, proxy-mapping-total, remote-logger-count', + 'docdefault': 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\*', + 'help' : 'List of statistics that are prevented from being exported via rec_control get-all', + 'doc' : ''' +A list of comma-separated statistic names, that are disabled when retrieving the complete list of statistics via `rec_control get-all`, for performance reasons. +These statistics can still be retrieved individually. + ''', + 'doc-new' : ''' +A sequence of statistic names, that are disabled when retrieving the complete list of statistics via `rec_control get-all`, for performance reasons. +These statistics can still be retrieved individually. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'stats_ringbuffer_entries', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '10000', + 'help' : 'maximum number of packets to store statistics for', + 'doc' : ''' +Number of entries in the remotes ringbuffer, which keeps statistics on who is querying your server. +Can be read out using ``rec_control top-remotes``. + ''', + }, + { + 'name' : 'stats_snmp_blacklist', + 'section' : 'recursor', + 'type' : LType.ListStrings, + 'default' : 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-1, ecs-v4-response-bits-2, ecs-v4-response-bits-3, ecs-v4-response-bits-4, ecs-v4-response-bits-5, ecs-v4-response-bits-6, ecs-v4-response-bits-7, ecs-v4-response-bits-8, ecs-v4-response-bits-9, ecs-v4-response-bits-10, ecs-v4-response-bits-11, ecs-v4-response-bits-12, ecs-v4-response-bits-13, ecs-v4-response-bits-14, ecs-v4-response-bits-15, ecs-v4-response-bits-16, ecs-v4-response-bits-17, ecs-v4-response-bits-18, ecs-v4-response-bits-19, ecs-v4-response-bits-20, ecs-v4-response-bits-21, ecs-v4-response-bits-22, ecs-v4-response-bits-23, ecs-v4-response-bits-24, ecs-v4-response-bits-25, ecs-v4-response-bits-26, ecs-v4-response-bits-27, ecs-v4-response-bits-28, ecs-v4-response-bits-29, ecs-v4-response-bits-30, ecs-v4-response-bits-31, ecs-v4-response-bits-32, ecs-v6-response-bits-1, ecs-v6-response-bits-2, ecs-v6-response-bits-3, ecs-v6-response-bits-4, ecs-v6-response-bits-5, ecs-v6-response-bits-6, ecs-v6-response-bits-7, ecs-v6-response-bits-8, ecs-v6-response-bits-9, ecs-v6-response-bits-10, ecs-v6-response-bits-11, ecs-v6-response-bits-12, ecs-v6-response-bits-13, ecs-v6-response-bits-14, ecs-v6-response-bits-15, ecs-v6-response-bits-16, ecs-v6-response-bits-17, ecs-v6-response-bits-18, ecs-v6-response-bits-19, ecs-v6-response-bits-20, ecs-v6-response-bits-21, ecs-v6-response-bits-22, ecs-v6-response-bits-23, ecs-v6-response-bits-24, ecs-v6-response-bits-25, ecs-v6-response-bits-26, ecs-v6-response-bits-27, ecs-v6-response-bits-28, ecs-v6-response-bits-29, ecs-v6-response-bits-30, ecs-v6-response-bits-31, ecs-v6-response-bits-32, ecs-v6-response-bits-33, ecs-v6-response-bits-34, ecs-v6-response-bits-35, ecs-v6-response-bits-36, ecs-v6-response-bits-37, ecs-v6-response-bits-38, ecs-v6-response-bits-39, ecs-v6-response-bits-40, ecs-v6-response-bits-41, ecs-v6-response-bits-42, ecs-v6-response-bits-43, ecs-v6-response-bits-44, ecs-v6-response-bits-45, ecs-v6-response-bits-46, ecs-v6-response-bits-47, ecs-v6-response-bits-48, ecs-v6-response-bits-49, ecs-v6-response-bits-50, ecs-v6-response-bits-51, ecs-v6-response-bits-52, ecs-v6-response-bits-53, ecs-v6-response-bits-54, ecs-v6-response-bits-55, ecs-v6-response-bits-56, ecs-v6-response-bits-57, ecs-v6-response-bits-58, ecs-v6-response-bits-59, ecs-v6-response-bits-60, ecs-v6-response-bits-61, ecs-v6-response-bits-62, ecs-v6-response-bits-63, ecs-v6-response-bits-64, ecs-v6-response-bits-65, ecs-v6-response-bits-66, ecs-v6-response-bits-67, ecs-v6-response-bits-68, ecs-v6-response-bits-69, ecs-v6-response-bits-70, ecs-v6-response-bits-71, ecs-v6-response-bits-72, ecs-v6-response-bits-73, ecs-v6-response-bits-74, ecs-v6-response-bits-75, ecs-v6-response-bits-76, ecs-v6-response-bits-77, ecs-v6-response-bits-78, ecs-v6-response-bits-79, ecs-v6-response-bits-80, ecs-v6-response-bits-81, ecs-v6-response-bits-82, ecs-v6-response-bits-83, ecs-v6-response-bits-84, ecs-v6-response-bits-85, ecs-v6-response-bits-86, ecs-v6-response-bits-87, ecs-v6-response-bits-88, ecs-v6-response-bits-89, ecs-v6-response-bits-90, ecs-v6-response-bits-91, ecs-v6-response-bits-92, ecs-v6-response-bits-93, ecs-v6-response-bits-94, ecs-v6-response-bits-95, ecs-v6-response-bits-96, ecs-v6-response-bits-97, ecs-v6-response-bits-98, ecs-v6-response-bits-99, ecs-v6-response-bits-100, ecs-v6-response-bits-101, ecs-v6-response-bits-102, ecs-v6-response-bits-103, ecs-v6-response-bits-104, ecs-v6-response-bits-105, ecs-v6-response-bits-106, ecs-v6-response-bits-107, ecs-v6-response-bits-108, ecs-v6-response-bits-109, ecs-v6-response-bits-110, ecs-v6-response-bits-111, ecs-v6-response-bits-112, ecs-v6-response-bits-113, ecs-v6-response-bits-114, ecs-v6-response-bits-115, ecs-v6-response-bits-116, ecs-v6-response-bits-117, ecs-v6-response-bits-118, ecs-v6-response-bits-119, ecs-v6-response-bits-120, ecs-v6-response-bits-121, ecs-v6-response-bits-122, ecs-v6-response-bits-123, ecs-v6-response-bits-124, ecs-v6-response-bits-125, ecs-v6-response-bits-126, ecs-v6-response-bits-127, ecs-v6-response-bits-128, cumul-clientanswers, cumul-authanswers, policy-hits, proxy-mapping-total, remote-logger-count', + 'docdefault': '', + 'help' : 'List of statistics that are prevented from being exported via SNMP (deprecated)', + 'doc' : '', + 'versionadded': '4.2.0', + 'deprecated': ('4.5.0', 'Use :ref:`setting-stats-snmp-disabled-list`.'), + 'skip-yaml': True, + }, + { + 'name' : 'stats_snmp_disabled_list', + 'section' : 'recursor', + 'type' : LType.ListStrings, + 'default' : 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-1, ecs-v4-response-bits-2, ecs-v4-response-bits-3, ecs-v4-response-bits-4, ecs-v4-response-bits-5, ecs-v4-response-bits-6, ecs-v4-response-bits-7, ecs-v4-response-bits-8, ecs-v4-response-bits-9, ecs-v4-response-bits-10, ecs-v4-response-bits-11, ecs-v4-response-bits-12, ecs-v4-response-bits-13, ecs-v4-response-bits-14, ecs-v4-response-bits-15, ecs-v4-response-bits-16, ecs-v4-response-bits-17, ecs-v4-response-bits-18, ecs-v4-response-bits-19, ecs-v4-response-bits-20, ecs-v4-response-bits-21, ecs-v4-response-bits-22, ecs-v4-response-bits-23, ecs-v4-response-bits-24, ecs-v4-response-bits-25, ecs-v4-response-bits-26, ecs-v4-response-bits-27, ecs-v4-response-bits-28, ecs-v4-response-bits-29, ecs-v4-response-bits-30, ecs-v4-response-bits-31, ecs-v4-response-bits-32, ecs-v6-response-bits-1, ecs-v6-response-bits-2, ecs-v6-response-bits-3, ecs-v6-response-bits-4, ecs-v6-response-bits-5, ecs-v6-response-bits-6, ecs-v6-response-bits-7, ecs-v6-response-bits-8, ecs-v6-response-bits-9, ecs-v6-response-bits-10, ecs-v6-response-bits-11, ecs-v6-response-bits-12, ecs-v6-response-bits-13, ecs-v6-response-bits-14, ecs-v6-response-bits-15, ecs-v6-response-bits-16, ecs-v6-response-bits-17, ecs-v6-response-bits-18, ecs-v6-response-bits-19, ecs-v6-response-bits-20, ecs-v6-response-bits-21, ecs-v6-response-bits-22, ecs-v6-response-bits-23, ecs-v6-response-bits-24, ecs-v6-response-bits-25, ecs-v6-response-bits-26, ecs-v6-response-bits-27, ecs-v6-response-bits-28, ecs-v6-response-bits-29, ecs-v6-response-bits-30, ecs-v6-response-bits-31, ecs-v6-response-bits-32, ecs-v6-response-bits-33, ecs-v6-response-bits-34, ecs-v6-response-bits-35, ecs-v6-response-bits-36, ecs-v6-response-bits-37, ecs-v6-response-bits-38, ecs-v6-response-bits-39, ecs-v6-response-bits-40, ecs-v6-response-bits-41, ecs-v6-response-bits-42, ecs-v6-response-bits-43, ecs-v6-response-bits-44, ecs-v6-response-bits-45, ecs-v6-response-bits-46, ecs-v6-response-bits-47, ecs-v6-response-bits-48, ecs-v6-response-bits-49, ecs-v6-response-bits-50, ecs-v6-response-bits-51, ecs-v6-response-bits-52, ecs-v6-response-bits-53, ecs-v6-response-bits-54, ecs-v6-response-bits-55, ecs-v6-response-bits-56, ecs-v6-response-bits-57, ecs-v6-response-bits-58, ecs-v6-response-bits-59, ecs-v6-response-bits-60, ecs-v6-response-bits-61, ecs-v6-response-bits-62, ecs-v6-response-bits-63, ecs-v6-response-bits-64, ecs-v6-response-bits-65, ecs-v6-response-bits-66, ecs-v6-response-bits-67, ecs-v6-response-bits-68, ecs-v6-response-bits-69, ecs-v6-response-bits-70, ecs-v6-response-bits-71, ecs-v6-response-bits-72, ecs-v6-response-bits-73, ecs-v6-response-bits-74, ecs-v6-response-bits-75, ecs-v6-response-bits-76, ecs-v6-response-bits-77, ecs-v6-response-bits-78, ecs-v6-response-bits-79, ecs-v6-response-bits-80, ecs-v6-response-bits-81, ecs-v6-response-bits-82, ecs-v6-response-bits-83, ecs-v6-response-bits-84, ecs-v6-response-bits-85, ecs-v6-response-bits-86, ecs-v6-response-bits-87, ecs-v6-response-bits-88, ecs-v6-response-bits-89, ecs-v6-response-bits-90, ecs-v6-response-bits-91, ecs-v6-response-bits-92, ecs-v6-response-bits-93, ecs-v6-response-bits-94, ecs-v6-response-bits-95, ecs-v6-response-bits-96, ecs-v6-response-bits-97, ecs-v6-response-bits-98, ecs-v6-response-bits-99, ecs-v6-response-bits-100, ecs-v6-response-bits-101, ecs-v6-response-bits-102, ecs-v6-response-bits-103, ecs-v6-response-bits-104, ecs-v6-response-bits-105, ecs-v6-response-bits-106, ecs-v6-response-bits-107, ecs-v6-response-bits-108, ecs-v6-response-bits-109, ecs-v6-response-bits-110, ecs-v6-response-bits-111, ecs-v6-response-bits-112, ecs-v6-response-bits-113, ecs-v6-response-bits-114, ecs-v6-response-bits-115, ecs-v6-response-bits-116, ecs-v6-response-bits-117, ecs-v6-response-bits-118, ecs-v6-response-bits-119, ecs-v6-response-bits-120, ecs-v6-response-bits-121, ecs-v6-response-bits-122, ecs-v6-response-bits-123, ecs-v6-response-bits-124, ecs-v6-response-bits-125, ecs-v6-response-bits-126, ecs-v6-response-bits-127, ecs-v6-response-bits-128, cumul-clientanswers, cumul-authanswers, policy-hits, proxy-mapping-total, remote-logger-count', + 'docdefault': 'cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*', + 'help' : 'List of statistics that are prevented from being exported via SNMP', + 'doc' : ''' +A list of comma-separated statistic names, that are prevented from being exported via SNMP, for performance reasons. + ''', + 'doc-new' : ''' +A sequence of statistic names, that are prevented from being exported via SNMP, for performance reasons. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'structured_logging', + 'section' : 'logging', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Prefer structured logging', + 'doc' : ''' +Prefer structured logging when both an old style and a structured log messages is available. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'structured_logging_backend', + 'section' : 'logging', + 'type' : LType.String, + 'default' : 'default', + 'help' : 'Structured logging backend', + 'doc' : ''' +The backend used for structured logging output. +This setting must be set on the command line (``--structured-logging-backend=...``) to be effective. +Available backends are: + +- ``default``: use the traditional logging system to output structured logging information. +- ``systemd-journal``: use systemd-journal. + When using this backend, provide ``-o verbose`` or simular output option to ``journalctl`` to view the full information. + ''', + 'versionadded': '4.8.0' + }, + { + 'name' : 'tcp_fast_open', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'Enable TCP Fast Open support on the listening sockets, using the supplied numerical value as the queue size', + 'doc' : ''' +Enable TCP Fast Open support, if available, on the listening sockets. +The numerical value supplied is used as the queue size, 0 meaning disabled. See :ref:`tcp-fast-open-support`. + ''', + 'versionadded': '4.1.0' + }, + { + 'name' : 'tcp_fast_open_connect', + 'section' : 'outgoing', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Enable TCP Fast Open support on outgoing sockets', + 'doc' : ''' +Enable TCP Fast Open Connect support, if available, on the outgoing connections to authoritative servers. See :ref:`tcp-fast-open-support`. + ''', + 'versionadded': '4.5.0' + }, + { + 'name' : 'tcp_max_idle_ms', + 'section' : 'outgoing', + 'oldname' : 'tcp-out-max-idle-ms', + 'type' : LType.Uint64, + 'default' : '10000', + 'help' : 'Time TCP/DoT connections are left idle in milliseconds or 0 if no limit', + 'doc' : ''' +Time outgoing TCP/DoT connections are left idle in milliseconds or 0 if no limit. After having been idle for this time, the connection is eligible for closing. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'tcp_max_idle_per_auth', + 'section' : 'outgoing', + 'oldname' : 'tcp-out-max-idle-per-auth', + 'type' : LType.Uint64, + 'default' : '10', + 'help' : 'Maximum number of idle TCP/DoT connections to a specific IP per thread, 0 means do not keep idle connections open', + 'doc' : ''' +Maximum number of idle outgoing TCP/DoT connections to a specific IP per thread, 0 means do not keep idle connections open. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'tcp_max_queries', + 'section' : 'outgoing', + 'oldname' : 'tcp-out-max-queries', + 'type' : LType.Uint64, + 'default' : '0', + 'help' : 'Maximum total number of queries per TCP/DoT connection, 0 means no limit', + 'doc' : ''' +Maximum total number of queries per outgoing TCP/DoT connection, 0 means no limit. After this number of queries, the connection is +closed and a new one will be created if needed. + ''', + }, + { + 'name' : 'tcp_max_idle_per_thread', + 'section' : 'outgoing', + 'oldname' : 'tcp-out-max-idle-per-thread', + 'type' : LType.Uint64, + 'default' : '100', + 'help' : 'Maximum number of idle TCP/DoT connections per thread', + 'doc' : ''' +Maximum number of idle outgoing TCP/DoT connections per thread, 0 means do not keep idle connections open. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'threads', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '2', + 'help' : 'Launch this number of threads', + 'doc' : ''' +Spawn this number of threads on startup. + ''', + }, + { + 'name' : 'trace', + 'section' : 'logging', + 'type' : LType.String, + 'default' : 'no', + 'help' : 'if we should output heaps of logging. set to \'fail\' to only log failing domains', + 'doc' : ''' +One of ``no``, ``yes`` or ``fail``. +If turned on, output impressive heaps of logging. +May destroy performance under load. +To log only queries resulting in a ``ServFail`` answer from the resolving process, this value can be set to ``fail``, but note that the performance impact is still large. +Also note that queries that do produce a result but with a failing DNSSEC validation are not written to the log + ''', + }, + { + 'name' : 'udp_source_port_min', + 'section' : 'outgoing', + 'type' : LType.Uint64, + 'default' : '1024', + 'help' : 'Minimum UDP port to bind on', + 'doc' : ''' +This option sets the low limit of UDP port number to bind on. + +In combination with :ref:`setting-udp-source-port-max` it configures the UDP +port range to use. Port numbers are randomized within this range on +initialization, and exceptions can be configured with :ref:`setting-udp-source-port-avoid` + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'udp_source_port_max', + 'section' : 'outgoing', + 'type' : LType.Uint64, + 'default' : '65535', + 'help' : 'Maximum UDP port to bind on', + 'doc' : ''' +This option sets the maximum limit of UDP port number to bind on. + +See :ref:`setting-udp-source-port-min`. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'udp_source_port_avoid', + 'section' : 'outgoing', + 'type' : LType.ListStrings, + 'default' : '11211', + 'help' : 'List of comma separated UDP port number to avoid', + 'doc' : ''' +A list of comma-separated UDP port numbers to avoid when binding. +Ex: `5300,11211` + +See :ref:`setting-udp-source-port-min`. + ''', + 'doc-new' : ''' +A sequence of UDP port numbers to avoid when binding. For example: + +.. code-block:: yaml + + outgoing: + udp_source_port_avoid: + - 5300 + - 11211 + +See :ref:`setting-udp-source-port-min`. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'udp_truncation_threshold', + 'section' : 'incoming', + 'type' : LType.Uint64, + 'default' : '1232', + 'help' : 'Maximum UDP response size before we truncate', + 'doc' : ''' +EDNS0 allows for large UDP response datagrams, which can potentially raise performance. +Large responses however also have downsides in terms of reflection attacks. +This setting limits the accepted size. +Maximum value is 65535, but values above 4096 should probably not be attempted. + +To know why 1232, see the note at :ref:`setting-edns-outgoing-bufsize`. + ''', + 'versionchanged': ('4.2.0', 'Before 4.2.0, the default was 1680.') + }, + { + 'name' : 'unique_response_tracking', + 'section' : 'nod', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Track unique responses (tuple of query name, type and RR).', + 'doc' : ''' +Whether to track unique DNS responses, i.e. never seen before combinations +of the triplet (query name, query type, RR[rrname, rrtype, rrdata]). +This can be useful for tracking potentially suspicious domains and +behaviour, e.g. DNS fast-flux. +If protobuf is enabled and configured, then the Protobuf Response message +will contain a flag with udr set to true for each RR that is considered +unique, i.e. never seen before. +This feature uses a probabilistic data structure (stable bloom filter) to +track unique responses, which can have false positives as well as false +negatives, thus it is a best-effort feature. Increasing the number of cells +in the SBF using the unique-response-db-size setting can reduce FPs and FNs. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'unique_response_log', + 'section' : 'nod', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Log unique responses', + 'doc' : ''' +Whether to log when a unique response is detected. The log line +looks something like: + +Oct 24 12:11:27 Unique response observed: qname=foo.com qtype=A rrtype=AAAA rrname=foo.com rrcontent=1.2.3.4 + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'unique_response_db_size', + 'section' : 'nod', + 'type' : LType.Uint64, + 'default' : '67108864', + 'help' : 'Size of the DB used to track unique responses in terms of number of cells. Defaults to 67108864', + 'doc' : ''' +The default size of the stable bloom filter used to store previously +observed responses is 67108864. To change the number of cells, use this +setting. For each cell, the SBF uses 1 bit of memory, and one byte of +disk for the persistent file. +If there are already persistent files saved to disk, this setting will +have no effect unless you remove the existing files. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'unique_response_history_dir', + 'section' : 'nod', + 'type' : LType.String, + 'default' : '/usr/local/var/lib/pdns-recursor/udr', + 'help' : 'Persist unique response tracking data here to persist between restarts', + 'doc' : ''' +This setting controls which directory is used to store the on-disk +cache of previously observed responses. + +The default depends on ``LOCALSTATEDIR`` when building the software. +Usually this comes down to ``/var/lib/pdns-recursor/udr`` or ``/usr/local/var/lib/pdns-recursor/udr``). + +The newly observed domain feature uses a stable bloom filter to store +a history of previously observed responses. The data structure is +synchronized to disk every 10 minutes, and is also initialized from +disk on startup. This ensures that previously observed responses are +preserved across recursor restarts. If you change the +unique-response-db-size, you must remove any files from this directory. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'unique_response_pb_tag', + 'section' : 'nod', + 'type' : LType.String, + 'default' : 'pdns-udr', + 'help' : 'If protobuf is configured, the tag to use for messages containing unique DNS responses. Defaults to \'pdns-udr\'', + 'doc' : ''' +If protobuf is configured, then this tag will be added to all protobuf response messages when +a unique DNS response is observed. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'use_incoming_edns_subnet', + 'section' : 'incoming', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Pass along received EDNS Client Subnet information', + 'doc' : ''' +Whether to process and pass along a received EDNS Client Subnet to authoritative servers. +The ECS information will only be sent for netmasks and domains listed in :ref:`setting-edns-subnet-allow-list` and will be truncated if the received scope exceeds :ref:`setting-ecs-ipv4-bits` for IPv4 or :ref:`setting-ecs-ipv6-bits` for IPv6. + ''', + }, + { + 'name' : 'version', + 'section' : 'commands', + 'type' : LType.Command, + 'default' : 'no', + 'help' : 'Print version string', + 'doc' : ''' +Print version of this binary. Useful for checking which version of the PowerDNS recursor is installed on a system. + ''', + }, + { + 'name' : 'version_string', + 'section' : 'recursor', + 'type' : LType.String, + 'default' : RUNTIME, + 'help' : 'string reported on version.pdns or version.bind', + 'doc' : ''' +By default, PowerDNS replies to the 'version.bind' query with its version number. +Security conscious users may wish to override the reply PowerDNS issues. + ''', + }, + { + 'name' : 'webserver', + 'section' : 'webservice', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Start a webserver (for REST API)', + 'doc' : ''' +Start the webserver (for REST API). + ''', + }, + { + 'name' : 'address', + 'section' : 'webservice', + 'oldname' : 'webserver-address', + 'type' : LType.String, + 'default' : '127.0.0.1', + 'help' : 'IP Address of webserver to listen on', + 'doc' : ''' +IP address for the webserver to listen on. + ''', + }, + { + 'name' : 'allow_from', + 'section' : 'webservice', + 'oldname' : 'webserver-allow-from', + 'type' : LType.ListSubnets, + 'default' : '127.0.0.1, ::1', + 'help' : 'Webserver access is only allowed from these subnets', + 'doc' : ''' +These IPs and subnets are allowed to access the webserver. Note that +specifying an IP address without a netmask uses an implicit netmask +of /32 or /128. + ''', + 'versionchanged': ('4.1.0', 'Default is now 127.0.0.1,::1, was 0.0.0.0/0,::/0 before.') + }, + { + 'name' : 'hash_plaintext_credentials', + 'section' : 'webservice', + 'oldname': 'webserver-hash-plaintext-credentials', + 'type' : LType.Bool, + 'default' : 'false', + 'help' : 'Whether to hash passwords and api keys supplied in plaintext, to prevent keeping the plaintext version in memory at runtime', + 'doc' : ''' +Whether passwords and API keys supplied in the configuration as plaintext should be hashed during startup, to prevent the plaintext versions from staying in memory. Doing so increases significantly the cost of verifying credentials and is thus disabled by default. +Note that this option only applies to credentials stored in the configuration as plaintext, but hashed credentials are supported without enabling this option. + ''', + 'versionadded': '4.6.0' + }, + { + 'name' : 'loglevel', + 'section' : 'webservice', + 'oldname' : 'webserver-loglevel', + 'type' : LType.String, + 'default' : 'normal', + 'help' : 'Amount of logging in the webserver (none, normal, detailed)', + 'doc' : ''' +One of ``one``, ``normal``, ``detailed``. +The amount of logging the webserver must do. 'none' means no useful webserver information will be logged. +When set to 'normal', the webserver will log a line per request that should be familiar:: + + [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 'GET /api/v1/servers/localhost/bla HTTP/1.1' 404 196 + +When set to 'detailed', all information about the request and response are logged:: + + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Request Details: + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Headers: + [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept-encoding: gzip, deflate + [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept-language: en-US,en;q=0.5 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e connection: keep-alive + [webserver] e235780e-a5cf-415e-9326-9d33383e739e dnt: 1 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e host: 127.0.0.1:8081 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e upgrade-insecure-requests: 1 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e No body + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Response details: + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Headers: + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Connection: close + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Content-Length: 49 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Content-Type: text/html; charset=utf-8 + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Server: PowerDNS/0.0.15896.0.gaba8bab3ab + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Full body: + [webserver] e235780e-a5cf-415e-9326-9d33383e739e Not Found

        Not Found

        + [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 'GET /api/v1/servers/localhost/bla HTTP/1.1' 404 196 + +The value between the hooks is a UUID that is generated for each request. This can be used to find all lines related to a single request. + +.. note:: + The webserver logs these line on the NOTICE level. The :ref:`setting-loglevel` seting must be 5 or higher for these lines to end up in the log. + ''', + 'versionadded': '4.2.0' + }, + { + 'name' : 'password', + 'section' : 'webservice', + 'oldname' : 'webserver-password', + 'type' : LType.String, + 'default' : '', + 'help' : 'Password required for accessing the webserver', + 'doc' : ''' +Password required to access the webserver. Since 4.6.0 the password can be hashed and salted using ``rec_control hash-password`` instead of being present in the configuration in plaintext, but the plaintext version is still supported. + ''', + 'versionchanged': ('4.6.0', 'This setting now accepts a hashed and salted version.') + }, + { + 'name' : 'port', + 'section' : 'webservice', + 'type' : LType.Uint64, + 'oldname': 'webserver-port', + 'default' : '8082', + 'help' : 'Port of webserver to listen on', + 'doc' : ''' +TCP port where the webserver should listen on. + ''', + }, + { + 'name' : 'write_pid', + 'section' : 'recursor', + 'type' : LType.Bool, + 'default' : 'true', + 'help' : 'Write a PID file', + 'doc' : ''' +If a PID file should be written to :ref:`setting-socket-dir` + ''', + }, + { + 'name' : 'x_dnssec_names', + 'section' : 'dnssec', + 'type' : LType.ListStrings, + 'default' : '', + 'help' : 'Collect DNSSEC statistics for names or suffixes in this list in separate x-dnssec counters', + 'doc' : ''' +List of names whose DNSSEC validation metrics will be counted in a separate set of metrics that start +with ``x-dnssec-result-``. +The names are suffix-matched. +This can be used to not count known failing (test) name validations in the ordinary DNSSEC metrics. + ''', + 'versionadded': '4.5.0' + }, +] diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 9e8b622e20b1..9d40aa52fb75 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -904,7 +904,7 @@ extern uint16_t g_outgoingEDNSBufsize; extern std::atomic g_maxCacheEntries, g_maxPacketCacheEntries; extern bool g_lowercaseOutgoing; -std::string reloadZoneConfiguration(); +std::string reloadZoneConfiguration(bool yaml); typedef std::function pipefunc_t; void broadcastFunction(const pipefunc_t& func); void distributeAsyncFunction(const std::string& packet, const pipefunc_t& func); @@ -919,7 +919,7 @@ template T broadcastAccFunction(const std::function& func); typedef std::unordered_set notifyset_t; -std::tuple, std::shared_ptr> parseZoneConfiguration(); +std::tuple, std::shared_ptr> parseZoneConfiguration(bool yaml); void* pleaseSupplantAllowNotifyFor(std::shared_ptr allowNotifyFor); uint64_t* pleaseGetNsSpeedsSize(); diff --git a/pdns/recursordist/test-settings.cc b/pdns/recursordist/test-settings.cc new file mode 100644 index 000000000000..779684e4d256 --- /dev/null +++ b/pdns/recursordist/test-settings.cc @@ -0,0 +1,422 @@ +#define BOOST_TEST_DYN_LINK +#include + +#include +#include +#include + +#include "settings/cxxsettings.hh" + +BOOST_AUTO_TEST_SUITE(test_settings) + +BOOST_AUTO_TEST_CASE(test_rust_empty) +{ + const std::string yaml = "{}\n"; + auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml); + + // Check an attribute to see if it has the right default value + BOOST_CHECK_EQUAL(settings.dnssec.aggressive_nsec_cache_size, 100000U); + + // Generate yaml, should be empty as all values are default + auto back = settings.to_yaml_string(); + // rust::String does not play nice with BOOST_CHECK_EQUAL, it lacks a << + BOOST_CHECK_EQUAL(yaml, std::string(back)); +} + +BOOST_AUTO_TEST_CASE(test_rust_syntaxerror) +{ + const std::string yaml = "{incoming: port: \n"; + BOOST_CHECK_THROW(pdns::rust::settings::rec::parse_yaml_string(yaml), rust::Error); +} + +BOOST_AUTO_TEST_CASE(test_rust_unknown_section) +{ + const std::string yaml = "{adskldsaj: port: \n"; + BOOST_CHECK_THROW(pdns::rust::settings::rec::parse_yaml_string(yaml), rust::Error); +} + +BOOST_AUTO_TEST_CASE(test_rust_unknown_field) +{ + const std::string yaml = "{incoming: akajkj0: \n"; + BOOST_CHECK_THROW(pdns::rust::settings::rec::parse_yaml_string(yaml), rust::Error); +} + +BOOST_AUTO_TEST_CASE(test_rust_parse) +{ + const std::string yaml = R"EOT(dnssec: + aggressive_nsec_cache_size: 10 +incoming: + allow_from: + - '!123.123.123.123' + - ::1 +recursor: + auth_zones: + - zone: example.com + file: a/file/name + - zone: example.net + file: another/file/name + forward_zones: + - zone: . + forwarders: + - 9.9.9.9 + forward_zones_recurse: + - zone: . + forwarders: + - 9.9.9.9 + - 1.2.3.4 + - ::99 + recurse: true +webservice: + api_key: otto +packetcache: + disable: true +)EOT"; + + auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml); + BOOST_CHECK_EQUAL(settings.dnssec.aggressive_nsec_cache_size, 10U); + BOOST_CHECK_EQUAL(settings.incoming.allow_from.size(), 2U); + BOOST_REQUIRE_EQUAL(settings.recursor.auth_zones.size(), 2U); + BOOST_REQUIRE_EQUAL(settings.recursor.forward_zones.size(), 1U); + BOOST_REQUIRE_EQUAL(settings.recursor.forward_zones[0].forwarders.size(), 1U); + BOOST_REQUIRE_EQUAL(settings.recursor.forward_zones_recurse.size(), 1U); + BOOST_REQUIRE_EQUAL(settings.recursor.forward_zones_recurse[0].forwarders.size(), 3U); + BOOST_CHECK(settings.recursor.forward_zones_recurse[0].recurse); + auto back = settings.to_yaml_string(); + // rust::String does not play nice with BOOST_CHECK_EQUAL, it lacks a << + BOOST_CHECK_EQUAL(yaml, std::string(back)); +} + +BOOST_AUTO_TEST_CASE(test_rust_validation_with_error1) +{ + const std::string yaml = R"EOT( +incoming: + allow_from: ["1.2.3.8999"] +)EOT"; + + BOOST_CHECK_THROW({ + auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml); + auto back = settings.to_yaml_string(); + settings.validate(); + }, + rust::Error); +} + +BOOST_AUTO_TEST_CASE(test_rust_validation_with_error2) +{ + const std::string yaml = R"EOT( +recursor: + forward_zones: + - zone: "example.com" + forwarders: + - 1.2.3.4 + - a.b +)EOT"; + + auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml); + auto back = settings.to_yaml_string(); + BOOST_CHECK_THROW({ + settings.validate(); + }, + rust::Error); +} + +BOOST_AUTO_TEST_CASE(test_rust_validation_with_error3) +{ + const std::string yaml = R"EOT( +recursor: + forward_zones: + - zone: + forwarders: + - 1.2.3.4 +)EOT"; + + BOOST_CHECK_THROW({ + auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml); + auto back = settings.to_yaml_string(); + settings.validate(); + }, + rust::Error); +} + +BOOST_AUTO_TEST_CASE(test_rust_validation_with_error4) +{ + const std::string yaml = R"EOT( +recursor: + forward_zones: + - zone: ok +)EOT"; + + BOOST_CHECK_THROW({ + auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml); + auto back = settings.to_yaml_string(); + settings.validate(); + }, + rust::Error); +} + +BOOST_AUTO_TEST_CASE(test_rust_validation_with_error5) +{ + const std::string yaml = R"EOT( +recursor: + auth_zones: + - zone: %1% + file: filename +)EOT"; + + const vector oktests = { + ".", + "one", + "one.", + "two.label" + "two.label.", + }; + for (const auto& ok : oktests) { + auto yamltest = boost::format(yaml) % ok; + BOOST_CHECK_NO_THROW({ + auto settings = pdns::rust::settings::rec::parse_yaml_string(yamltest.str()); + settings.validate(); + }); + } + const vector noktests = { + "", + "..", + "two..label", + ".two.label", + "three€.a.label", + "three.a.label..", + }; + for (const auto& nok : noktests) { + auto yamltest = boost::format(yaml) % nok; + BOOST_CHECK_THROW({ + auto settings = pdns::rust::settings::rec::parse_yaml_string(yamltest.str()); + auto back = settings.to_yaml_string(); + settings.validate(); + }, + rust::Error); + } +} + +BOOST_AUTO_TEST_CASE(test_rust_validation_no_error) +{ + // All defaults + const std::string yaml = "{}\n"; + + BOOST_CHECK_NO_THROW({ + auto settings = pdns::rust::settings::rec::parse_yaml_string(yaml); + settings.validate(); + }); +} + +BOOST_AUTO_TEST_CASE(test_rust_forwardzones_to_yaml) +{ + using pdns::rust::settings::rec::ForwardZone; + rust::Vec vec; + vec.emplace_back(ForwardZone{"zone1", {"1.2.3.4"}, false, false}); + vec.emplace_back(ForwardZone{"zone2", {"1.2.3.4", "::1"}, true, true}); + + auto yaml = pdns::rust::settings::rec::forward_zones_to_yaml_string(vec); + + const std::string expected = R"EOT(- zone: zone1 + forwarders: + - 1.2.3.4 +- zone: zone2 + forwarders: + - 1.2.3.4 + - ::1 + recurse: true + notify_allowed: true +)EOT"; + + BOOST_CHECK_EQUAL(std::string(yaml), expected); +} + +BOOST_AUTO_TEST_CASE(test_rust_parse_forwardzones_to_yaml) +{ + std::string fileContent = R"EOT( +# aap +example1.com= 1.2.3.4, 5.6.7.8; 8.9.0.1 +^+example2.com = ::1 +)EOT"; + + const std::string expected = R"EOT(- zone: example1.com + forwarders: + - 1.2.3.4 + - 5.6.7.8 + - 8.9.0.1 +- zone: example2.com + forwarders: + - ::1 + recurse: true + notify_allowed: true +)EOT"; + + std::string temp("/tmp/test-settingsXXXXXXXXXX"); + int fileDesc = mkstemp(temp.data()); + BOOST_REQUIRE(fileDesc > 0); + auto filePtr = std::unique_ptr(fdopen(fileDesc, "w"), fclose); + BOOST_REQUIRE(filePtr != nullptr); + size_t written = fwrite(fileContent.data(), 1, fileContent.length(), filePtr.get()); + BOOST_REQUIRE(written == fileContent.length()); + filePtr = nullptr; + + rust::Vec forwards; + pdns::settings::rec::oldStyleForwardsFileToBridgeStruct(temp, forwards); + unlink(temp.data()); + + auto yaml = pdns::rust::settings::rec::forward_zones_to_yaml_string(forwards); + BOOST_CHECK_EQUAL(std::string(yaml), expected); +} + +BOOST_AUTO_TEST_CASE(test_rust_merge_defaults) +{ + const std::string yaml = "{}\n"; + auto lhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + + pdns::rust::settings::rec::merge(lhs, yaml); + auto back = lhs.to_yaml_string(); + BOOST_CHECK_EQUAL(yaml, std::string(back)); +} + +BOOST_AUTO_TEST_CASE(test_rust_merge_lhs_default) +{ + const std::string yaml = "{}\n"; + auto lhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + auto rhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + + const std::string yaml2 = R"EOT( +recursor: + forward_zones: + - zone: zone + forwarders: + - 1.2.3.4 +dnssec: + validation: validate +)EOT"; + + pdns::rust::settings::rec::merge(lhs, yaml2); + + BOOST_CHECK_EQUAL(std::string(lhs.dnssec.validation), "validate"); + BOOST_CHECK_EQUAL(lhs.recursor.forward_zones.size(), 1U); +} + +BOOST_AUTO_TEST_CASE(test_rust_merge_lhs_nondefault) +{ + const std::string yaml = "{}\n"; + auto lhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + auto rhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + + lhs.dnssec.validation = "no"; + lhs.recursor.forward_zones.emplace_back(pdns::rust::settings::rec::ForwardZone{"zone1", {"1.2.3.4"}, false, false}); + + rhs.dnssec.validation = "validate"; + rhs.recursor.forward_zones.emplace_back(pdns::rust::settings::rec::ForwardZone{"zone2", {"1.2.3.4"}, false, false}); + + const auto yaml2 = rhs.to_yaml_string(); + pdns::rust::settings::rec::merge(lhs, yaml2); + + BOOST_CHECK_EQUAL(std::string(lhs.dnssec.validation), "validate"); + BOOST_CHECK_EQUAL(lhs.recursor.forward_zones.size(), 2U); +} + +BOOST_AUTO_TEST_CASE(test_rust_merge_rhs_mixed) +{ + const std::string yaml = "{}\n"; + auto lhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + auto rhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + + lhs.dnssec.validation = "no"; + lhs.recursor.forward_zones.emplace_back(pdns::rust::settings::rec::ForwardZone{"zone1", {"1.2.3.4"}, false, false}); + rhs.recursor.forward_zones.emplace_back(pdns::rust::settings::rec::ForwardZone{"zone2", {"1.2.3.4"}, false, false}); + + const auto yaml2 = rhs.to_yaml_string(); + pdns::rust::settings::rec::merge(lhs, yaml); + + pdns::rust::settings::rec::merge(lhs, yaml2); + + BOOST_CHECK_EQUAL(std::string(lhs.dnssec.validation), "no"); + BOOST_CHECK_EQUAL(lhs.recursor.forward_zones.size(), 2U); +} + +BOOST_AUTO_TEST_CASE(test_rust_merge_list_nonempty_default1) +{ + const std::string yaml = "{}\n"; + auto lhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + auto rhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + + // Note that dont_query is a non-empty list by default + // lhs default, rhs is not (empty ), rhs overwrites lhs + rhs.outgoing.dont_query = {}; + const auto yaml2 = rhs.to_yaml_string(); + pdns::rust::settings::rec::merge(lhs, yaml2); + + BOOST_CHECK_EQUAL(lhs.outgoing.dont_query.size(), 0U); +} + +BOOST_AUTO_TEST_CASE(test_rust_merge_list_nonempty_default2) +{ + const std::string yaml = "{}\n"; + auto lhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + auto rhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + + rhs.outgoing.dont_query = {"1.2.3.4"}; + // lhs default, rhs overwrites lhs + const auto yaml2 = rhs.to_yaml_string(); + pdns::rust::settings::rec::merge(lhs, yaml2); + + BOOST_CHECK_EQUAL(lhs.outgoing.dont_query.size(), 1U); + + rhs = pdns::rust::settings::rec::parse_yaml_string(yaml); + rhs.outgoing.dont_query = {"4.5.6.7"}; + // lhs not default, rhs gets merged + const auto yaml3 = rhs.to_yaml_string(); + pdns::rust::settings::rec::merge(lhs, yaml2); + + BOOST_CHECK_EQUAL(lhs.outgoing.dont_query.size(), 2U); +} + +BOOST_AUTO_TEST_CASE(test_rust_merge_nondefault_and_default) +{ + const std::string yaml1 = "{}\n"; + auto lhs = pdns::rust::settings::rec::parse_yaml_string(yaml1); + lhs.recordcache.max_entries = 99; + lhs.dnssec.validation = "no"; + const std::string yaml2 = R"EOT( + dnssec: + validation: process + incoming: + allow_from: + - 4.5.6.7/1 +)EOT"; + pdns::rust::settings::rec::merge(lhs, yaml2); + + BOOST_CHECK_EQUAL(lhs.dnssec.validation, "process"); + BOOST_CHECK_EQUAL(lhs.incoming.allow_from.size(), 1U); + BOOST_CHECK_EQUAL(lhs.recordcache.max_entries, 99U); +} + +BOOST_AUTO_TEST_CASE(test_rust_merge_override) +{ + const std::string yaml1 = R"EOT( + incoming: + allow_from: + - 4.5.6.7/1 +)EOT"; + auto lhs = pdns::rust::settings::rec::parse_yaml_string(yaml1); + lhs.recordcache.max_entries = 99; + lhs.dnssec.validation = "no"; + const std::string yaml2 = R"EOT( + dnssec: + validation: process + incoming: + allow_from: !override + - 1.2.3.4/1 +)EOT"; + pdns::rust::settings::rec::merge(lhs, yaml2); + + BOOST_CHECK_EQUAL(lhs.dnssec.validation, "process"); + BOOST_REQUIRE_EQUAL(lhs.incoming.allow_from.size(), 1U); + BOOST_CHECK_EQUAL(lhs.incoming.allow_from.at(0), "1.2.3.4/1"); + BOOST_CHECK_EQUAL(lhs.recordcache.max_entries, 99U); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index 98e420bb2716..2737f78ec02d 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -45,6 +45,7 @@ #include "uuid-utils.hh" #include "tcpiohandler.hh" #include "rec-main.hh" +#include "settings/cxxsettings.hh" using json11::Json; @@ -69,8 +70,14 @@ static void apiWriteConfigFile(const string& filebasename, const string& content throw ApiException("Config Option \"api-config-dir\" must be set"); } - string filename = ::arg()["api-config-dir"] + "/" + filebasename + ".conf"; - ofstream ofconf(filename.c_str()); + string filename = ::arg()["api-config-dir"] + "/" + filebasename; + if (g_yamlSettings) { + filename += ".yml"; + } + else { + filename += ".conf"; + } + ofstream ofconf(filename); if (!ofconf) { throw ApiException("Could not open config fragment file '" + filename + "' for writing: " + stringerror()); } @@ -89,26 +96,49 @@ static void apiServerConfigACL(const std::string& aclType, HttpRequest* req, Htt throw ApiException("'value' must be an array"); } - NetmaskGroup nmg; - for (const auto& value : jlist.array_items()) { + if (g_yamlSettings) { + ::rust::Vec<::rust::String> vec; + for (const auto& value : jlist.array_items()) { + vec.emplace_back(value.string_value()); + } + try { - nmg.addMask(value.string_value()); + ::pdns::rust::settings::rec::validate_allow_from(aclType, vec); } - catch (const NetmaskException& e) { - throw ApiException(e.reason); + catch (const ::rust::Error& e) { + throw ApiException(string("Unable to convert: ") + e.what()); } + ::rust::String yaml; + if (aclType == "allow-from") { + yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_from", "allow_from_file", vec); + } + else { + yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_notify_from", "allow_notify_from_file", vec); + } + apiWriteConfigFile(aclType, string(yaml)); } + else { + NetmaskGroup nmg; + for (const auto& value : jlist.array_items()) { + try { + nmg.addMask(value.string_value()); + } + catch (const NetmaskException& e) { + throw ApiException(e.reason); + } + } - ostringstream strStream; + ostringstream strStream; - // Clear -from-file if set, so our changes take effect - strStream << aclType << "-file=" << endl; + // Clear -from-file if set, so our changes take effect + strStream << aclType << "-file=" << endl; - // Clear ACL setting, and provide a "parent" value - strStream << aclType << "=" << endl; - strStream << aclType << "+=" << nmg.toString() << endl; + // Clear ACL setting, and provide a "parent" value + strStream << aclType << "=" << endl; + strStream << aclType << "+=" << nmg.toString() << endl; - apiWriteConfigFile(aclType, strStream.str()); + apiWriteConfigFile(aclType, strStream.str()); + } parseACLs(); @@ -195,6 +225,8 @@ static void doCreateZone(const Json& document) bool rdFlag = boolFromJson(document, "recursion_desired"); string confbasename = "zone-" + apiZoneNameToId(zone); + const string yamlAPiZonesFile = ::arg()["api-config-dir"] + "/apizones"; + if (kind == "NATIVE") { if (rdFlag) { throw ApiException("kind=Native and recursion_desired are mutually exclusive"); @@ -224,35 +256,55 @@ static void doCreateZone(const Json& document) } ofzone.close(); - apiWriteConfigFile(confbasename, "auth-zones+=" + zonename + "=" + zonefilename); + if (g_yamlSettings) { + pdns::rust::settings::rec::AuthZone authzone; + authzone.zone = zonename; + authzone.file = zonefilename; + pdns::rust::settings::rec::api_add_auth_zone(yamlAPiZonesFile, authzone); + } + else { + apiWriteConfigFile(confbasename, "auth-zones+=" + zonename + "=" + zonefilename); + } } else if (kind == "FORWARDED") { - string serverlist; - for (const auto& value : document["servers"].array_items()) { - const string& server = value.string_value(); - if (server.empty()) { - throw ApiException("Forwarded-to server must not be an empty string"); + if (g_yamlSettings) { + pdns::rust::settings::rec::ForwardZone forward; + forward.zone = zonename; + forward.recurse = rdFlag; + forward.notify_allowed = false; + for (const auto& value : document["servers"].array_items()) { + forward.forwarders.emplace_back(value.string_value()); } - try { - ComboAddress address = parseIPAndPort(server, 53); - if (!serverlist.empty()) { - serverlist += ";"; + pdns::rust::settings::rec::api_add_forward_zone(yamlAPiZonesFile, forward); + } + else { + string serverlist; + for (const auto& value : document["servers"].array_items()) { + const string& server = value.string_value(); + if (server.empty()) { + throw ApiException("Forwarded-to server must not be an empty string"); + } + try { + ComboAddress address = parseIPAndPort(server, 53); + if (!serverlist.empty()) { + serverlist += ";"; + } + serverlist += address.toStringWithPort(); + } + catch (const PDNSException& e) { + throw ApiException(e.reason); } - serverlist += address.toStringWithPort(); } - catch (const PDNSException& e) { - throw ApiException(e.reason); + if (serverlist.empty()) { + throw ApiException("Need at least one upstream server when forwarding"); } - } - if (serverlist.empty()) { - throw ApiException("Need at least one upstream server when forwarding"); - } - if (rdFlag) { - apiWriteConfigFile(confbasename, "forward-zones-recurse+=" + zonename + "=" + serverlist); - } - else { - apiWriteConfigFile(confbasename, "forward-zones+=" + zonename + "=" + serverlist); + if (rdFlag) { + apiWriteConfigFile(confbasename, "forward-zones-recurse+=" + zonename + "=" + serverlist); + } + else { + apiWriteConfigFile(confbasename, "forward-zones+=" + zonename + "=" + serverlist); + } } } else { @@ -267,13 +319,17 @@ static bool doDeleteZone(const DNSName& zonename) } string filename; - - // this one must exist - filename = ::arg()["api-config-dir"] + "/zone-" + apiZoneNameToId(zonename) + ".conf"; - if (unlink(filename.c_str()) != 0) { - return false; + if (g_yamlSettings) { + const string yamlAPiZonesFile = ::arg()["api-config-dir"] + "/apizones"; + pdns::rust::settings::rec::api_delete_zone(yamlAPiZonesFile, zonename.toString()); + } + else { + // this one must exist + filename = ::arg()["api-config-dir"] + "/zone-" + apiZoneNameToId(zonename) + ".conf"; + if (unlink(filename.c_str()) != 0) { + return false; + } } - // .zone file is optional filename = ::arg()["api-config-dir"] + "/zone-" + apiZoneNameToId(zonename) + ".zone"; unlink(filename.c_str()); @@ -298,7 +354,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp) } doCreateZone(document); - reloadZoneConfiguration(); + reloadZoneConfiguration(g_yamlSettings); fillZone(zonename, resp); resp->status = 201; return; @@ -342,7 +398,7 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) doDeleteZone(zonename); doCreateZone(document); - reloadZoneConfiguration(); + reloadZoneConfiguration(g_yamlSettings); resp->body = ""; resp->status = 204; // No Content, but indicate success } @@ -351,7 +407,7 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp) throw ApiException("Deleting domain failed"); } - reloadZoneConfiguration(); + reloadZoneConfiguration(g_yamlSettings); // empty body on success resp->body = ""; resp->status = 204; // No Content: declare that the zone is gone now diff --git a/regression-tests.api/.gitignore b/regression-tests.api/.gitignore index d443eca5d1aa..fcd61ea7b4ed 100644 --- a/regression-tests.api/.gitignore +++ b/regression-tests.api/.gitignore @@ -12,3 +12,7 @@ /recursor.conf /rec-conf.d /bindbackend.conf +/acl-notify.list +/acl-notify.list.yml +/acl.list.yml +/recursor.yml diff --git a/regression-tests.api/runtests.py b/regression-tests.api/runtests.py index 515439d7bb57..50065051d1ac 100755 --- a/regression-tests.api/runtests.py +++ b/regression-tests.api/runtests.py @@ -84,32 +84,35 @@ ACL_LIST_TPL = """ # Generated by runtests.py # local host -127.0.0.1 -::1 +- 127.0.0.1 +- ::1 """ ACL_NOTIFY_LIST_TPL = """ # Generated by runtests.py # local host -127.0.0.1 -::1 +- 127.0.0.1 +- ::1 """ REC_EXAMPLE_COM_CONF_TPL = """ # Generated by runtests.py -auth-zones+=example.com=../regression-tests/zones/example.com.rec +recursor: + auth_zones: + - zone: example.com + file: ../regression-tests/zones/example.com.rec """ REC_CONF_TPL = """ # Generated by runtests.py -auth-zones= -forward-zones= -forward-zones-recurse= -allow-from-file=acl.list -allow-notify-from-file=acl-notify.list -api-config-dir=%(conf_dir)s -include-dir=%(conf_dir)s -devonly-regression-test-mode +incoming: + allow_from_file: acl.list.yml + allow_notify_from_file: acl-notify.list.yml +webservice: + api_dir: %(conf_dir)s +recursor: + include_dir: %(conf_dir)s + devonly_regression_test_mode: true """ @@ -222,13 +225,13 @@ def run_check_call(cmd, *args, **kwargs): else: conf_dir = 'rec-conf.d' ensure_empty_dir(conf_dir) - with open('acl.list', 'w') as acl_list: + with open('acl.list.yml', 'w') as acl_list: acl_list.write(ACL_LIST_TPL) - with open('acl-notify.list', 'w') as acl_notify_list: + with open('acl-notify.list.yml', 'w') as acl_notify_list: acl_notify_list.write(ACL_NOTIFY_LIST_TPL) - with open('recursor.conf', 'w') as recursor_conf: + with open('recursor.yml', 'w') as recursor_conf: recursor_conf.write(REC_CONF_TPL % locals()) - with open(conf_dir+'/example.com..conf', 'w') as conf_file: + with open(conf_dir+'/example.com.yml', 'w') as conf_file: conf_file.write(REC_EXAMPLE_COM_CONF_TPL) servercmd = [pdns_recursor] + common_args diff --git a/regression-tests.recursor-dnssec/recursortests.py b/regression-tests.recursor-dnssec/recursortests.py index cf883fb4ee1d..c19426965e0b 100644 --- a/regression-tests.recursor-dnssec/recursortests.py +++ b/regression-tests.recursor-dnssec/recursortests.py @@ -58,6 +58,28 @@ class RecursorTest(AssertEqualDNSMessageMixin, unittest.TestCase): disable-syslog=yes log-common-errors=yes statistics-interval=0 +""" + _config_template_yaml_default = """ +recursor: + daemon: false + threads: 2 + include_dir: %s +recordcache: + max_ttl: 15 +incoming: + listen: + - 127.0.0.1 +packetcache: + ttl: 15 + servfail_ttl: 15 +outgoing: + dont_query: [] +logging: + trace: true + disable_syslog: true + common_errors: true + loglevel: 9 + statistics_interval: 0 """ _config_template = """ """ @@ -620,6 +642,44 @@ def generateRecursorConfig(cls, confdir): roothints.write(cls._roothints) conf.write("hint-file=%s\n" % roothintspath) + @classmethod + def generateRecursorYamlConfig(cls, confdir): + params = tuple([getattr(cls, param) for param in cls._config_params]) + if len(params): + print(params) + + recursorconf = os.path.join(confdir, 'recursor.yml') + + with open(recursorconf, 'w') as conf: + conf.write("# Autogenerated by recursortests.py\n") + conf.write(cls._config_template_yaml_default % confdir) + recursorconf = os.path.join(confdir, 'recursor01.yml') + with open(recursorconf, 'w') as conf: + conf.write(cls._config_template % params) + conf.write("\n") + recursorconf = os.path.join(confdir, 'recursor02.yml') + with open(recursorconf, 'w') as conf: + conf.write("recursor:\n") + conf.write(" socket_dir: %s\n" % confdir) + if cls._lua_config_file or cls._root_DS: + luaconfpath = os.path.join(confdir, 'conffile.lua') + with open(luaconfpath, 'w') as luaconf: + if cls._root_DS: + luaconf.write("addTA('.', '%s')\n" % cls._root_DS) + if cls._lua_config_file: + luaconf.write(cls._lua_config_file) + conf.write(" lua_config_file: %s\n" % luaconfpath) + if cls._lua_dns_script_file: + luascriptpath = os.path.join(confdir, 'dnsscript.lua') + with open(luascriptpath, 'w') as luascript: + luascript.write(cls._lua_dns_script_file) + conf.write(" lua_dns_script: %s\n" % luascriptpath) + if cls._roothints: + roothintspath = os.path.join(confdir, 'root.hints') + with open(roothintspath, 'w') as roothints: + roothints.write(cls._roothints) + conf.write(" hint_file: %s\n" % roothintspath) + @classmethod def startResponders(cls): pass diff --git a/regression-tests.recursor-dnssec/test_SimpleYAML.py b/regression-tests.recursor-dnssec/test_SimpleYAML.py new file mode 100644 index 000000000000..22775ea2ec0f --- /dev/null +++ b/regression-tests.recursor-dnssec/test_SimpleYAML.py @@ -0,0 +1,112 @@ +import dns +import os +from recursortests import RecursorTest + +class testSimple(RecursorTest): + _confdir = 'Simple' + + _config_template = """ +recursor: + auth_zones: + - zone: authzone.example + file: configs/%s/authzone.zone +dnssec: + validation: validate""" % _confdir + + @classmethod + def generateRecursorConfig(cls, confdir): + authzonepath = os.path.join(confdir, 'authzone.zone') + with open(authzonepath, 'w') as authzone: + authzone.write("""$ORIGIN authzone.example. +@ 3600 IN SOA {soa} +@ 3600 IN A 192.0.2.88 +""".format(soa=cls._SOA)) + super(testSimple, cls).generateRecursorYamlConfig(confdir) + + def testSOAs(self): + for zone in ['.', 'example.', 'secure.example.']: + expected = dns.rrset.from_text(zone, 0, dns.rdataclass.IN, 'SOA', self._SOA) + query = dns.message.make_query(zone, 'SOA', want_dnssec=True) + query.flags |= dns.flags.AD + + res = self.sendUDPQuery(query) + + self.assertMessageIsAuthenticated(res) + self.assertRRsetInAnswer(res, expected) + self.assertMatchingRRSIGInAnswer(res, expected) + + def testA(self): + expected = dns.rrset.from_text('ns.secure.example.', 0, dns.rdataclass.IN, 'A', '{prefix}.9'.format(prefix=self._PREFIX)) + query = dns.message.make_query('ns.secure.example', 'A', want_dnssec=True) + query.flags |= dns.flags.AD + + res = self.sendUDPQuery(query) + + self.assertMessageIsAuthenticated(res) + self.assertRRsetInAnswer(res, expected) + self.assertMatchingRRSIGInAnswer(res, expected) + + def testDelegation(self): + query = dns.message.make_query('example', 'NS', want_dnssec=True) + query.flags |= dns.flags.AD + + expectedNS = dns.rrset.from_text('example.', 0, 'IN', 'NS', 'ns1.example.', 'ns2.example.') + + res = self.sendUDPQuery(query) + + self.assertMessageIsAuthenticated(res) + self.assertRRsetInAnswer(res, expectedNS) + + def testBogus(self): + query = dns.message.make_query('ted.bogus.example', 'A', want_dnssec=True) + + res = self.sendUDPQuery(query) + + self.assertRcodeEqual(res, dns.rcode.SERVFAIL) + + def testAuthZone(self): + query = dns.message.make_query('authzone.example', 'A', want_dnssec=True) + + expectedA = dns.rrset.from_text('authzone.example.', 0, 'IN', 'A', '192.0.2.88') + + res = self.sendUDPQuery(query) + + self.assertRcodeEqual(res, dns.rcode.NOERROR) + self.assertRRsetInAnswer(res, expectedA) + + def testLocalhost(self): + queryA = dns.message.make_query('localhost', 'A', want_dnssec=True) + expectedA = dns.rrset.from_text('localhost.', 0, 'IN', 'A', '127.0.0.1') + + queryPTR = dns.message.make_query('1.0.0.127.in-addr.arpa', 'PTR', want_dnssec=True) + expectedPTR = dns.rrset.from_text('1.0.0.127.in-addr.arpa.', 0, 'IN', 'PTR', 'localhost.') + + resA = self.sendUDPQuery(queryA) + resPTR = self.sendUDPQuery(queryPTR) + + self.assertRcodeEqual(resA, dns.rcode.NOERROR) + self.assertRRsetInAnswer(resA, expectedA) + + self.assertRcodeEqual(resPTR, dns.rcode.NOERROR) + self.assertRRsetInAnswer(resPTR, expectedPTR) + + def testLocalhostSubdomain(self): + queryA = dns.message.make_query('foo.localhost', 'A', want_dnssec=True) + expectedA = dns.rrset.from_text('foo.localhost.', 0, 'IN', 'A', '127.0.0.1') + + resA = self.sendUDPQuery(queryA) + + self.assertRcodeEqual(resA, dns.rcode.NOERROR) + self.assertRRsetInAnswer(resA, expectedA) + + def testIslandOfSecurity(self): + query = dns.message.make_query('cname-to-islandofsecurity.secure.example.', 'A', want_dnssec=True) + + expectedCNAME = dns.rrset.from_text('cname-to-islandofsecurity.secure.example.', 0, 'IN', 'CNAME', 'node1.islandofsecurity.example.') + expectedA = dns.rrset.from_text('node1.islandofsecurity.example.', 0, 'IN', 'A', '192.0.2.20') + + res = self.sendUDPQuery(query) + + self.assertRcodeEqual(res, dns.rcode.NOERROR) + self.assertRRsetInAnswer(res, expectedA) + diff --git a/tasks.py b/tasks.py index 6115bd4ed5b7..e84fc968defb 100644 --- a/tasks.py +++ b/tasks.py @@ -8,6 +8,7 @@ auth_backend_ip_addr = os.getenv('AUTH_BACKEND_IP_ADDR', '127.0.0.1') clang_version = os.getenv('CLANG_VERSION', '13') +rust_version = 'rust-1.72.0-x86_64-unknown-linux-gnu' all_build_deps = [ 'ccache', @@ -170,6 +171,10 @@ def install_clang_runtime(c): # this gives us the symbolizer, for symbols in asan/ubsan traces c.sudo(f'apt-get -y --no-install-recommends install clang-{clang_version}') +@task +def ci_install_rust(c, repo): + c.sudo(f'{repo}/builder-support/helpers/install_rust.sh {rust_version}') + def install_libdecaf(c, product): c.run('git clone https://git.code.sf.net/p/ed448goldilocks/code /tmp/libdecaf') with c.cd('/tmp/libdecaf'): From e917c86bb2f6bb9b31586dd66d1fdbf3e022d47c Mon Sep 17 00:00:00 2001 From: Alexis Romero Date: Thu, 3 Aug 2023 13:53:27 +0200 Subject: [PATCH 671/909] adding make distdir step to build-and-test-all --- .github/workflows/build-and-test-all.yml | 56 +++++++++++++++++------- tasks.py | 6 ++- 2 files changed, 46 insertions(+), 16 deletions(-) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 7d2a75fd49e2..6ec3c7916215 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -14,6 +14,7 @@ env: CLANG_VERSION: '13' # github.workspace variable points to the Runner home folder. Container home folder defined below. REPO_HOME: '/__w/pdns/pdns' + BUILDER_VERSION: '0.0.0-git1' jobs: build-auth: @@ -29,6 +30,9 @@ jobs: UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" UNIT_TESTS: yes options: --sysctl net.ipv6.conf.all.disable_ipv6=0 + defaults: + run: + working-directory: ./pdns-${{ env.BUILDER_VERSION }} outputs: clang-tidy-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: @@ -41,7 +45,9 @@ jobs: run: | echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" shell: bash + working-directory: . - run: mkdir -p ~/.ccache + working-directory: . - name: let GitHub cache our ccache data uses: actions/cache@v3 with: @@ -49,14 +55,19 @@ jobs: key: auth-ccache-${{ steps.get-stamp.outputs.stamp }} restore-keys: auth-ccache- - run: inv ci-autoconf + working-directory: . - run: inv ci-auth-configure - - run: inv ci-auth-make-bear # This runs under pdns/ - - run: ln -s .clang-tidy.full .clang-tidy + working-directory: . + - run: inv ci-make-distdir + working-directory: . + - run: inv ci-auth-configure + - run: inv ci-auth-make-bear # This runs under pdns-$BUILDER_VERSION/pdns/ + - run: ln -s ../clang-tidy.full .clang-tidy - name: Run clang-tidy - working-directory: pdns - run: git diff -U0 HEAD^..HEAD | python3 ../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p2 -export-fixes clang-tidy-auth.yml + working-directory: ./pdns-${{ env.BUILDER_VERSION }}/pdns + run: git diff -U0 HEAD^..HEAD | python3 ../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p2 -export-fixes clang-tidy-auth.yml - name: Print clang-tidy fixes YAML - working-directory: pdns + working-directory: ./pdns-${{ env.BUILDER_VERSION }}/pdns shell: bash run: | if [ -f clang-tidy-auth.yml ]; then @@ -65,11 +76,11 @@ jobs: - name: Result annotations id: clang-tidy-annotations shell: bash - working-directory: pdns + working-directory: ./pdns-${{ env.BUILDER_VERSION }}/pdns run: | if [ -f clang-tidy-auth.yml ]; then set +e - python3 ../.github/scripts/clang-tidy.py --fixes-file clang-tidy-auth.yml + python3 ../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-auth.yml echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-auth-install-remotebackend-test-deps @@ -100,7 +111,7 @@ jobs: options: --sysctl net.ipv6.conf.all.disable_ipv6=0 defaults: run: - working-directory: ./pdns/recursordist/ + working-directory: ./pdns/recursordist/pdns-recursor-${{ env.BUILDER_VERSION }} outputs: clang-tidy-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: @@ -113,7 +124,9 @@ jobs: run: | echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" shell: bash + working-directory: . - run: mkdir -p ~/.ccache + working-directory: . - name: let GitHub cache our ccache data uses: actions/cache@v3 with: @@ -121,11 +134,16 @@ jobs: key: recursor-${{ matrix.sanitizers }}-ccache-${{ steps.get-stamp.outputs.stamp }} restore-keys: recursor-${{ matrix.sanitizers }}-ccache- - run: inv ci-autoconf + working-directory: ./pdns/recursordist/ + - run: inv ci-rec-configure + working-directory: ./pdns/recursordist/ + - run: inv ci-make-distdir + working-directory: ./pdns/recursordist/ - run: inv ci-rec-configure - run: inv ci-rec-make-bear - - run: ln -s ../../.clang-tidy.full .clang-tidy + - run: ln -s ../../../.clang-tidy.full .clang-tidy - name: Run clang-tidy - run: git diff -U0 HEAD^..HEAD | python3 ../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-rec.yml + run: git diff -U0 HEAD^..HEAD | python3 ../../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-rec.yml - name: Print clang-tidy fixes YAML shell: bash run: | @@ -138,7 +156,7 @@ jobs: run: | if [ -f clang-tidy-rec.yml ]; then set +e - python ../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-rec.yml + python ../../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-rec.yml echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-rec-run-unit-tests @@ -169,10 +187,11 @@ jobs: SANITIZERS: ${{ matrix.sanitizers }} UBSAN_OPTIONS: "print_stacktrace=1:halt_on_error=1:suppressions=${{ env.REPO_HOME }}/build-scripts/UBSan.supp" UNIT_TESTS: yes + FUZZING_TARGETS: yes options: --sysctl net.ipv6.conf.all.disable_ipv6=0 defaults: run: - working-directory: ./pdns/dnsdistdist/ + working-directory: ./pdns/dnsdistdist/dnsdist-${{ env.BUILDER_VERSION }} outputs: clang-tidy-failed: ${{ steps.clang-tidy-annotations.outputs.failed }} steps: @@ -185,7 +204,9 @@ jobs: run: | echo "stamp=$(/bin/date +%s)" >> "$GITHUB_OUTPUT" shell: bash + working-directory: . - run: mkdir -p ~/.ccache + working-directory: . - name: let GitHub cache our ccache data uses: actions/cache@v3 with: @@ -193,11 +214,16 @@ jobs: key: dnsdist-${{ matrix.features }}-${{ matrix.sanitizers }}-ccache-${{ steps.get-stamp.outputs.stamp }} restore-keys: dnsdist-${{ matrix.features }}-${{ matrix.sanitizers }}-ccache- - run: inv ci-autoconf + working-directory: ./pdns/dnsdistdist/ + - run: inv ci-dnsdist-configure ${{ matrix.features }} + working-directory: ./pdns/dnsdistdist/ + - run: inv ci-make-distdir + working-directory: ./pdns/dnsdistdist/ - run: inv ci-dnsdist-configure ${{ matrix.features }} - run: inv ci-dnsdist-make-bear - - run: ln -s ../../.clang-tidy.full .clang-tidy + - run: ln -s ../../../.clang-tidy.full .clang-tidy - name: Run clang-tidy - run: git diff -U0 HEAD^..HEAD | python3 ../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-dnsdist.yml + run: git diff -U0 HEAD^..HEAD | python3 ../../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-dnsdist.yml - name: Print clang-tidy fixes YAML shell: bash run: | @@ -210,7 +236,7 @@ jobs: run: | if [ -f clang-tidy-dnsdist.yml ]; then set +e - python ../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-dnsdist.yml + python ../../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-dnsdist.yml echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-dnsdist-run-unit-tests diff --git a/tasks.py b/tasks.py index 096aa5d0902b..a3964e9cfd95 100644 --- a/tasks.py +++ b/tasks.py @@ -299,7 +299,7 @@ def install_dnsdist_build_deps(c): @task def ci_autoconf(c): - c.run('BUILDER_VERSION=0.0.0-git1 autoreconf -vfi') + c.run('autoreconf -vfi') @task def ci_docs_build(c): @@ -589,6 +589,10 @@ def ci_dnsdist_run_unit_tests(c): c.run('cat test-suite.log') raise UnexpectedExit(res) +@task +def ci_make_distdir(c): + res = c.run('make distdir') + @task def ci_make_install(c): res = c.run('make install') # FIXME: this builds auth docs - again From e4f652fda30788eeac9a7fcb9f6910bef0ab5aba Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 12 Sep 2023 09:59:21 +0200 Subject: [PATCH 672/909] Fix typo in function name (both def and caller) --- pdns/recursordist/settings/generate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/settings/generate.py b/pdns/recursordist/settings/generate.py index b3e3d7df457c..84051fb6cd59 100644 --- a/pdns/recursordist/settings/generate.py +++ b/pdns/recursordist/settings/generate.py @@ -337,7 +337,7 @@ def is_value_rust_default(typ, value): return value == '' return False -def gen_rust_forwardzonevec_default_fucntions(name): +def gen_rust_forwardzonevec_default_functions(name): """Generate Rust code for the default handling of a vector for ForwardZones""" ret = f'// DEFAULT HANDLING for {name}\n' ret += f'fn default_value_{name}() -> Vec {{\n' @@ -397,7 +397,7 @@ def gen_rust_default_functions(entry, name, rust_type): if entry['type'] in (LType.ListSocketAddresses, LType.ListSubnets, LType.ListStrings): return gen_rust_stringvec_default_functions(entry, name) if entry['type'] == LType.ListForwardZones: - return gen_rust_forwardzonevec_default_fucntions(name) + return gen_rust_forwardzonevec_default_functions(name) if entry['type'] == LType.ListAuthZones: return gen_rust_authzonevec_default_functions(name) ret = f'// DEFAULT HANDLING for {name}\n' From 6311767375aaeff2f9f06142348ede3c7fc53246 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 12 Sep 2023 11:14:16 +0200 Subject: [PATCH 673/909] Introduce randomness in test order to catch hidden dependencies between unit-tests Also be a bit more lenient in a recently introduced test that checks timing of some aggressive cache manipulations. --- pdns/Makefile.am | 2 +- pdns/dnsdistdist/Makefile.am | 2 +- pdns/recursordist/Makefile.am | 2 +- pdns/recursordist/test-aggressive_nsec_cc.cc | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pdns/Makefile.am b/pdns/Makefile.am index cb9e538f7fe8..b5eef7a5444a 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -1514,7 +1514,7 @@ noinst_PROGRAMS = speedtest if UNIT_TESTS noinst_PROGRAMS += testrunner if HAVE_BOOST_GE_148 -TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message SRCDIR='$(srcdir)' +TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message BOOST_TEST_RANDOM=1 SRCDIR='$(srcdir)' TESTS=testrunner else check-local: diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index c39015d50f93..ee14af84b804 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -119,7 +119,7 @@ bin_PROGRAMS = dnsdist if UNIT_TESTS noinst_PROGRAMS = testrunner -TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message SRCDIR='$(srcdir)' +TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message BOOST_TEST_RANDOM=1 SRCDIR='$(srcdir)' TESTS=testrunner else check-local: diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index fc330b3c6d2a..6045315575c7 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -91,7 +91,7 @@ TESTS=test_libcrypto if UNIT_TESTS noinst_PROGRAMS = testrunner -TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message SRCDIR='$(srcdir)' +TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message BOOST_TEST_RANDOM=1 SRCDIR='$(srcdir)' TESTS += testrunner else check-local: diff --git a/pdns/recursordist/test-aggressive_nsec_cc.cc b/pdns/recursordist/test-aggressive_nsec_cc.cc index 1809deea2371..d62b146b9e6d 100644 --- a/pdns/recursordist/test-aggressive_nsec_cc.cc +++ b/pdns/recursordist/test-aggressive_nsec_cc.cc @@ -1121,7 +1121,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_replace) auto diff2 = time.udiff(true); // Check that replace is about equally fast as insert - BOOST_CHECK(diff1 < diff2 * 1.2 && diff2 < diff1 * 1.2); + BOOST_CHECK(diff1 < diff2 * 1.3 && diff2 < diff1 * 1.3); } BOOST_AUTO_TEST_CASE(test_aggressive_nsec_wiping) From 10d5c4df7596858b751507f4e4fb3c8dfe309fc7 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 12 Sep 2023 12:11:29 +0200 Subject: [PATCH 674/909] Be even more lenient in allowing timing differences --- pdns/recursordist/test-aggressive_nsec_cc.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/test-aggressive_nsec_cc.cc b/pdns/recursordist/test-aggressive_nsec_cc.cc index d62b146b9e6d..249e9b561f74 100644 --- a/pdns/recursordist/test-aggressive_nsec_cc.cc +++ b/pdns/recursordist/test-aggressive_nsec_cc.cc @@ -1121,7 +1121,7 @@ BOOST_AUTO_TEST_CASE(test_aggressive_nsec_replace) auto diff2 = time.udiff(true); // Check that replace is about equally fast as insert - BOOST_CHECK(diff1 < diff2 * 1.3 && diff2 < diff1 * 1.3); + BOOST_CHECK(diff1 < diff2 * 2 && diff2 < diff1 * 2); } BOOST_AUTO_TEST_CASE(test_aggressive_nsec_wiping) From 47e383787a01079279170982afc9872e88d7b51c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 12 Sep 2023 12:41:35 +0200 Subject: [PATCH 675/909] With #13101 the cwd of the build changed, adapt call to rust install --- .github/workflows/build-and-test-all.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 216f81b289d2..bd7d62b248ec 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -134,6 +134,7 @@ jobs: key: recursor-${{ matrix.sanitizers }}-ccache-${{ steps.get-stamp.outputs.stamp }} restore-keys: recursor-${{ matrix.sanitizers }}-ccache- - run: inv ci-install-rust ${{ env.REPO_HOME }} + working-directory: ./pdns/recursordist/ - run: inv ci-autoconf working-directory: ./pdns/recursordist/ - run: inv ci-rec-configure From 1c9d6d73465ac6afb7a368ef419196da5e0cb99b Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 12 Sep 2023 14:45:55 +0200 Subject: [PATCH 676/909] Rec: Settings Rust bridge ignore Emacs' .dir-locals.el --- pdns/recursordist/settings/rust/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/recursordist/settings/rust/.gitignore b/pdns/recursordist/settings/rust/.gitignore index 7b8194b04e94..eacb110ccd06 100644 --- a/pdns/recursordist/settings/rust/.gitignore +++ b/pdns/recursordist/settings/rust/.gitignore @@ -4,3 +4,4 @@ /cxx.h /lib.rs.h src/lib.rs +.dir-locals.el From 617ced6d11b2243456228f578bad6a2e9b8577b4 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 12 Sep 2023 14:51:07 +0200 Subject: [PATCH 677/909] Rec's unit tests (in combination with asan+ubsan) are not ready yet for randomization --- pdns/recursordist/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index 8856b2eee04c..9dfe5fd5646f 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -93,7 +93,7 @@ TESTS=test_libcrypto if UNIT_TESTS noinst_PROGRAMS = testrunner -TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message BOOST_TEST_RANDOM=1 SRCDIR='$(srcdir)' +TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message BOOST_TEST_RANDOM=0 SRCDIR='$(srcdir)' TESTS += testrunner else check-local: From ea0681a158aa8bc60fdbc8fe39b41d60ae800629 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 12 Sep 2023 14:46:18 +0200 Subject: [PATCH 678/909] Rec: Settings Rust bridge prefer slices over Vec references --- pdns/recursordist/rec_control.cc | 6 +++--- pdns/recursordist/settings/cxxsupport.cc | 6 +++--- pdns/recursordist/settings/rust-bridge-in.rs | 10 +++++----- pdns/recursordist/settings/rust/src/bridge.rs | 10 +++++----- pdns/recursordist/ws-recursor.cc | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pdns/recursordist/rec_control.cc b/pdns/recursordist/rec_control.cc index 6264ae51220a..79315a3e6352 100644 --- a/pdns/recursordist/rec_control.cc +++ b/pdns/recursordist/rec_control.cc @@ -153,7 +153,7 @@ static std::string showForwardFileYAML(const ::rust::string& rfilename) msg += std::string(yaml); msg += "# Validation result: "; try { - pdns::rust::settings::rec::validate_forward_zones("forward_zones", forwards); + pdns::rust::settings::rec::validate_forward_zones("forward_zones", {forwards.data(), forwards.size()}); msg += "OK"; } catch (const rust::Error& err) { @@ -163,7 +163,7 @@ static std::string showForwardFileYAML(const ::rust::string& rfilename) return msg; } -static std::string showAllowYAML(const ::rust::String& rfilename, const string& section, const string& key, const std::function&)>& func) +static std::string showAllowYAML(const ::rust::String& rfilename, const string& section, const string& key, const std::function)>& func) { std::string msg; if (rfilename.empty() || boost::ends_with(rfilename, ".yml")) { @@ -178,7 +178,7 @@ static std::string showAllowYAML(const ::rust::String& rfilename, const string& msg += std::string(yaml); msg += "# Validation result: "; try { - func(key, allows); + func(key, {allows.data(), allows.size()}); msg += "OK"; } catch (const rust::Error& err) { diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index 84c3f1c455be..46ba962f0afa 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -177,7 +177,7 @@ void pdns::settings::rec::readYamlAllowFromFile(const std::string& filename, ::r } auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); auto yamlvec = pdns::rust::settings::rec::parse_yaml_string_to_allow_from(data); - pdns::rust::settings::rec::validate_allow_from(filename, yamlvec); + pdns::rust::settings::rec::validate_allow_from(filename, {yamlvec.data(), yamlvec.size()}); vec = yamlvec; } @@ -191,7 +191,7 @@ void pdns::settings::rec::readYamlForwardZonesFile(const std::string& filename, } auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); auto yamlvec = pdns::rust::settings::rec::parse_yaml_string_to_forward_zones(data); - pdns::rust::settings::rec::validate_forward_zones("forward_zones", yamlvec); + pdns::rust::settings::rec::validate_forward_zones("forward_zones", {yamlvec.data(), yamlvec.size()}); vec = yamlvec; } @@ -205,7 +205,7 @@ void pdns::settings::rec::readYamlAllowNotifyForFile(const std::string& filename } auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); auto yamlvec = pdns::rust::settings::rec::parse_yaml_string_to_allow_notify_for(data); - pdns::rust::settings::rec::validate_allow_notify_for("allow-notify-for", yamlvec); + pdns::rust::settings::rec::validate_allow_notify_for("allow-notify-for", {yamlvec.data(), yamlvec.size()}); vec = yamlvec; } diff --git a/pdns/recursordist/settings/rust-bridge-in.rs b/pdns/recursordist/settings/rust-bridge-in.rs index 1ee664c173cf..ff82a1c585df 100644 --- a/pdns/recursordist/settings/rust-bridge-in.rs +++ b/pdns/recursordist/settings/rust-bridge-in.rs @@ -95,11 +95,11 @@ extern "Rust" { fn validate(self: &ApiZones, field: &str) -> Result<()>; // Helper functions to call the proper validate function on vectors of various kinds - fn validate_auth_zones(field: &str, vec: &Vec) -> Result<()>; - fn validate_forward_zones(field: &str, vec: &Vec) -> Result<()>; - fn validate_allow_for(field: &str, vec: &Vec) -> Result<()>; - fn validate_allow_notify_for(field: &str, vec: &Vec) -> Result<()>; - fn validate_allow_from(field: &str, vec: &Vec) -> Result<()>; + fn validate_auth_zones(field: &str, vec: &[AuthZone]) -> Result<()>; + fn validate_forward_zones(field: &str, vec: &[ForwardZone]) -> Result<()>; + fn validate_allow_for(field: &str, vec: &[String]) -> Result<()>; + fn validate_allow_notify_for(field: &str, vec: &[String]) -> Result<()>; + fn validate_allow_from(field: &str, vec: &[String]) -> Result<()>; // The functions to maintain REST API managed zones fn api_read_zones(path: &str) -> Result>; diff --git a/pdns/recursordist/settings/rust/src/bridge.rs b/pdns/recursordist/settings/rust/src/bridge.rs index 80d1589e5116..b08b9ed01921 100644 --- a/pdns/recursordist/settings/rust/src/bridge.rs +++ b/pdns/recursordist/settings/rust/src/bridge.rs @@ -210,13 +210,13 @@ impl AuthZone { } } -pub fn validate_auth_zones(field: &str, vec: &Vec) -> Result<(), ValidationError> { +pub fn validate_auth_zones(field: &str, vec: &[AuthZone]) -> Result<(), ValidationError> { validate_vec(field, vec, |field, element| element.validate(field)) } pub fn validate_forward_zones( field: &str, - vec: &Vec, + vec: &[ForwardZone], ) -> Result<(), ValidationError> { validate_vec(field, vec, |field, element| element.validate(field)) } @@ -270,7 +270,7 @@ pub fn allow_from_to_yaml_string_incoming( serde_yaml::to_string(&outerval) } -pub fn validate_allow_from(field: &str, vec: &Vec) -> Result<(), ValidationError> { +pub fn validate_allow_from(field: &str, vec: &[String]) -> Result<(), ValidationError> { validate_vec(field, vec, validate_subnet) } @@ -280,11 +280,11 @@ pub fn allow_for_to_yaml_string(vec: &Vec) -> Result) -> Result<(), ValidationError> { +pub fn validate_allow_for(field: &str, vec: &[String]) -> Result<(), ValidationError> { validate_vec(field, vec, validate_name) } -pub fn validate_allow_notify_for(field: &str, vec: &Vec) -> Result<(), ValidationError> { +pub fn validate_allow_notify_for(field: &str, vec: &[String]) -> Result<(), ValidationError> { validate_vec(field, vec, validate_name) } diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index 2737f78ec02d..5ec0c01c5715 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -103,7 +103,7 @@ static void apiServerConfigACL(const std::string& aclType, HttpRequest* req, Htt } try { - ::pdns::rust::settings::rec::validate_allow_from(aclType, vec); + ::pdns::rust::settings::rec::validate_allow_from(aclType, {vec.data(), vec.size()}); } catch (const ::rust::Error& e) { throw ApiException(string("Unable to convert: ") + e.what()); From 680bf548a94ba676e0e14c94bbcefc976b0f842c Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 12 Sep 2023 14:53:02 +0200 Subject: [PATCH 679/909] Rec: Typos --- pdns/recursordist/Makefile.am | 2 +- pdns/recursordist/lazy_allocator.hh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index e231ea2b0203..8339ebae8884 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -46,7 +46,7 @@ CLEANFILES = htmlfiles.h \ htmlfiles.h: incfiles html/* html/js/* ./incfiles > $@ -# We explicilt build settings in two steps, as settings modifies files in the settings/rust subdir +# We explicitly build settings in two steps, as settings modifies files in the settings/rust subdir SUBDIRS=ext settings settings/rust if LUA diff --git a/pdns/recursordist/lazy_allocator.hh b/pdns/recursordist/lazy_allocator.hh index 39665b6ad266..ead82293af9d 100644 --- a/pdns/recursordist/lazy_allocator.hh +++ b/pdns/recursordist/lazy_allocator.hh @@ -85,7 +85,7 @@ struct lazy_allocator #ifdef __OpenBSD__ // OpenBSD does not like mmap MAP_STACK regions that have // PROT_NONE, so allocate r/w and mprotect the guard pages - // explictly. + // explicitly. const int protection = PROT_READ | PROT_WRITE; #else const int protection = PROT_NONE; From c92878f1eebd42db5d0668f6e379282031797565 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 12 Sep 2023 16:46:24 +0200 Subject: [PATCH 680/909] dnsdist: Fix the test order dependency in the Dynamic Blocks unit tests --- pdns/dnsdistdist/test-dnsdistdynblocks_hh.cc | 58 ++++++++------------ 1 file changed, 24 insertions(+), 34 deletions(-) diff --git a/pdns/dnsdistdist/test-dnsdistdynblocks_hh.cc b/pdns/dnsdistdist/test-dnsdistdynblocks_hh.cc index dda6ff8d4cc4..46f9916b715b 100644 --- a/pdns/dnsdistdist/test-dnsdistdynblocks_hh.cc +++ b/pdns/dnsdistdist/test-dnsdistdynblocks_hh.cc @@ -15,7 +15,20 @@ shared_ptr g_defaultBPFFilter{nullptr}; BOOST_AUTO_TEST_SUITE(dnsdistdynblocks_hh) -BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate) { +struct TestFixture +{ + TestFixture() + { + g_rings.reset(); + g_rings.init(); + } + ~TestFixture() + { + g_rings.reset(); + } +}; + +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesGroup_QueryRate, TestFixture) { dnsheader dh; memset(&dh, 0, sizeof(dh)); DNSName qname("rings.powerdns.com."); @@ -36,9 +49,6 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate) { const auto action = DNSAction::Action::Drop; const std::string reason = "Exceeded query rate"; - g_rings.reset(); - g_rings.init(); - DynBlockRulesGroup dbrg; dbrg.setQuiet(true); @@ -154,7 +164,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate) { } } -BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate_RangeV6) { +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesGroup_QueryRate_RangeV6, TestFixture) { /* Check that we correctly group IPv6 addresses from the same /64 subnet into the same dynamic block entry, if instructed to do so */ dnsheader dh; @@ -180,9 +190,6 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate_RangeV6) { dbrg.setQuiet(true); dbrg.setMasks(32, 64, 0); - g_rings.reset(); - g_rings.init(); - /* block above 50 qps for numberOfSeconds seconds, no warning */ dbrg.setQueryRate(50, 0, numberOfSeconds, reason, blockDuration, action); @@ -257,7 +264,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate_RangeV6) { } } -BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate_V4Ports) { +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesGroup_QueryRate_V4Ports, TestFixture) { /* Check that we correctly split IPv4 addresses based on port ranges, when instructed to do so */ dnsheader dh; memset(&dh, 0, sizeof(dh)); @@ -283,9 +290,6 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate_V4Ports) { /* split v4 by ports using a /2 (0 - 16383, 16384 - 32767, 32768 - 49151, 49152 - 65535) */ dbrg.setMasks(32, 128, 2); - g_rings.reset(); - g_rings.init(); - /* block above 50 qps for numberOfSeconds seconds, no warning */ dbrg.setQueryRate(50, 0, numberOfSeconds, reason, blockDuration, action); @@ -391,7 +395,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate_V4Ports) { } } -BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate_responses) { +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesGroup_QueryRate_responses, TestFixture) { /* check that the responses are not accounted as queries when a rcode rate rule is defined (sounds very specific but actually happened) */ dnsheader dh; @@ -453,7 +457,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QueryRate_responses) { } } -BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QTypeRate) { +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesGroup_QTypeRate, TestFixture) { dnsheader dh; memset(&dh, 0, sizeof(dh)); DNSName qname("rings.powerdns.com."); @@ -473,8 +477,6 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QTypeRate) { DynBlockRulesGroup dbrg; dbrg.setQuiet(true); - g_rings.reset(); - g_rings.init(); /* block above 50 qps for numberOfSeconds seconds, no warning */ dbrg.setQTypeRate(QType::AAAA, 50, 0, numberOfSeconds, reason, blockDuration, action); @@ -543,7 +545,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_QTypeRate) { } -BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRate) { +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesGroup_RCodeRate, TestFixture) { dnsheader dh; memset(&dh, 0, sizeof(dh)); DNSName qname("rings.powerdns.com."); @@ -636,7 +638,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRate) { } -BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRatio) { +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesGroup_RCodeRatio, TestFixture) { dnsheader dh; memset(&dh, 0, sizeof(dh)); DNSName qname("rings.powerdns.com."); @@ -660,9 +662,6 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRatio) { DynBlockRulesGroup dbrg; dbrg.setQuiet(true); - g_rings.reset(); - g_rings.init(); - /* block above 0.2 ServFail/Total ratio over numberOfSeconds seconds, no warning, minimum number of queries should be at least 51 */ dbrg.setRCodeRatio(rcode, 0.2, 0, numberOfSeconds, reason, blockDuration, action, 51); @@ -758,7 +757,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_RCodeRatio) { } } -BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_ResponseByteRate) { +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesGroup_ResponseByteRate, TestFixture) { dnsheader dh; memset(&dh, 0, sizeof(dh)); DNSName qname("rings.powerdns.com."); @@ -782,9 +781,6 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_ResponseByteRate) { DynBlockRulesGroup dbrg; dbrg.setQuiet(true); - g_rings.reset(); - g_rings.init(); - /* block above 10kB/s for numberOfSeconds seconds, no warning */ dbrg.setResponseByteRate(10000, 0, numberOfSeconds, reason, blockDuration, action); @@ -835,7 +831,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_ResponseByteRate) { } -BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Warning) { +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesGroup_Warning, TestFixture) { dnsheader dh; memset(&dh, 0, sizeof(dh)); DNSName qname("rings.powerdns.com."); @@ -856,9 +852,6 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Warning) { DynBlockRulesGroup dbrg; dbrg.setQuiet(true); - g_rings.reset(); - g_rings.init(); - /* warn above 20 qps for numberOfSeconds seconds, block above 50 qps */ dbrg.setQueryRate(50, 20, numberOfSeconds, reason, blockDuration, action); @@ -998,7 +991,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Warning) { } } -BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Ranges) { +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesGroup_Ranges, TestFixture) { dnsheader dh; memset(&dh, 0, sizeof(dh)); DNSName qname("rings.powerdns.com."); @@ -1026,9 +1019,6 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Ranges) { /* block above 50 qps for numberOfSeconds seconds, no warning */ dbrg.setQueryRate(50, 0, numberOfSeconds, reason, blockDuration, action); - g_rings.reset(); - g_rings.init(); - { /* insert just above 50 qps from the two clients in the last 10s this should trigger the rule for the first one but not the second one */ @@ -1058,7 +1048,7 @@ BOOST_AUTO_TEST_CASE(test_DynBlockRulesGroup_Ranges) { } -BOOST_AUTO_TEST_CASE(test_DynBlockRulesMetricsCache_GetTopN) { +BOOST_FIXTURE_TEST_CASE(test_DynBlockRulesMetricsCache_GetTopN, TestFixture) { dnsheader dh; memset(&dh, 0, sizeof(dh)); DNSName qname("rings.powerdns.com."); From f1cbc20b72ab95531f0a84bab40ac6ea1610241f Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 12 Sep 2023 17:09:57 +0200 Subject: [PATCH 681/909] smysql: stop explicity setting MYSQL_OPT_RECONNECT to 0 Setting this option, even to 0, causes spurious warnings to the console with recent libmysqlclient versions. The upstream bug ( https://bugs.mysql.com/bug.php?id=112089 ) has now been open for a month, so we're implementing a workaround. 0 was the default since at least MySQL 5.7, perhaps longer. closes #13242 --- modules/gmysqlbackend/smysql.cc | 5 ----- 1 file changed, 5 deletions(-) diff --git a/modules/gmysqlbackend/smysql.cc b/modules/gmysqlbackend/smysql.cc index 04518bb5ce34..c8a3d880b537 100644 --- a/modules/gmysqlbackend/smysql.cc +++ b/modules/gmysqlbackend/smysql.cc @@ -489,11 +489,6 @@ void SMySQL::connect() do { -#if MYSQL_VERSION_ID >= 50013 - my_bool set_reconnect = 0; - mysql_options(&d_db, MYSQL_OPT_RECONNECT, &set_reconnect); -#endif - #if MYSQL_VERSION_ID >= 50100 if (d_timeout) { mysql_options(&d_db, MYSQL_OPT_READ_TIMEOUT, &d_timeout); From 5a2a8db2bd905d02f0ec2aa0befa9c697e8a39d5 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 12 Sep 2023 23:24:12 +0200 Subject: [PATCH 682/909] Revert "Rec: Settings Rust bridge prefer slices over Vec references" This reverts commit ea0681a158aa8bc60fdbc8fe39b41d60ae800629. --- pdns/recursordist/rec_control.cc | 6 +++--- pdns/recursordist/settings/cxxsupport.cc | 6 +++--- pdns/recursordist/settings/rust-bridge-in.rs | 10 +++++----- pdns/recursordist/settings/rust/src/bridge.rs | 10 +++++----- pdns/recursordist/ws-recursor.cc | 2 +- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/pdns/recursordist/rec_control.cc b/pdns/recursordist/rec_control.cc index 79315a3e6352..6264ae51220a 100644 --- a/pdns/recursordist/rec_control.cc +++ b/pdns/recursordist/rec_control.cc @@ -153,7 +153,7 @@ static std::string showForwardFileYAML(const ::rust::string& rfilename) msg += std::string(yaml); msg += "# Validation result: "; try { - pdns::rust::settings::rec::validate_forward_zones("forward_zones", {forwards.data(), forwards.size()}); + pdns::rust::settings::rec::validate_forward_zones("forward_zones", forwards); msg += "OK"; } catch (const rust::Error& err) { @@ -163,7 +163,7 @@ static std::string showForwardFileYAML(const ::rust::string& rfilename) return msg; } -static std::string showAllowYAML(const ::rust::String& rfilename, const string& section, const string& key, const std::function)>& func) +static std::string showAllowYAML(const ::rust::String& rfilename, const string& section, const string& key, const std::function&)>& func) { std::string msg; if (rfilename.empty() || boost::ends_with(rfilename, ".yml")) { @@ -178,7 +178,7 @@ static std::string showAllowYAML(const ::rust::String& rfilename, const string& msg += std::string(yaml); msg += "# Validation result: "; try { - func(key, {allows.data(), allows.size()}); + func(key, allows); msg += "OK"; } catch (const rust::Error& err) { diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index 46ba962f0afa..84c3f1c455be 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -177,7 +177,7 @@ void pdns::settings::rec::readYamlAllowFromFile(const std::string& filename, ::r } auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); auto yamlvec = pdns::rust::settings::rec::parse_yaml_string_to_allow_from(data); - pdns::rust::settings::rec::validate_allow_from(filename, {yamlvec.data(), yamlvec.size()}); + pdns::rust::settings::rec::validate_allow_from(filename, yamlvec); vec = yamlvec; } @@ -191,7 +191,7 @@ void pdns::settings::rec::readYamlForwardZonesFile(const std::string& filename, } auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); auto yamlvec = pdns::rust::settings::rec::parse_yaml_string_to_forward_zones(data); - pdns::rust::settings::rec::validate_forward_zones("forward_zones", {yamlvec.data(), yamlvec.size()}); + pdns::rust::settings::rec::validate_forward_zones("forward_zones", yamlvec); vec = yamlvec; } @@ -205,7 +205,7 @@ void pdns::settings::rec::readYamlAllowNotifyForFile(const std::string& filename } auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); auto yamlvec = pdns::rust::settings::rec::parse_yaml_string_to_allow_notify_for(data); - pdns::rust::settings::rec::validate_allow_notify_for("allow-notify-for", {yamlvec.data(), yamlvec.size()}); + pdns::rust::settings::rec::validate_allow_notify_for("allow-notify-for", yamlvec); vec = yamlvec; } diff --git a/pdns/recursordist/settings/rust-bridge-in.rs b/pdns/recursordist/settings/rust-bridge-in.rs index ff82a1c585df..1ee664c173cf 100644 --- a/pdns/recursordist/settings/rust-bridge-in.rs +++ b/pdns/recursordist/settings/rust-bridge-in.rs @@ -95,11 +95,11 @@ extern "Rust" { fn validate(self: &ApiZones, field: &str) -> Result<()>; // Helper functions to call the proper validate function on vectors of various kinds - fn validate_auth_zones(field: &str, vec: &[AuthZone]) -> Result<()>; - fn validate_forward_zones(field: &str, vec: &[ForwardZone]) -> Result<()>; - fn validate_allow_for(field: &str, vec: &[String]) -> Result<()>; - fn validate_allow_notify_for(field: &str, vec: &[String]) -> Result<()>; - fn validate_allow_from(field: &str, vec: &[String]) -> Result<()>; + fn validate_auth_zones(field: &str, vec: &Vec) -> Result<()>; + fn validate_forward_zones(field: &str, vec: &Vec) -> Result<()>; + fn validate_allow_for(field: &str, vec: &Vec) -> Result<()>; + fn validate_allow_notify_for(field: &str, vec: &Vec) -> Result<()>; + fn validate_allow_from(field: &str, vec: &Vec) -> Result<()>; // The functions to maintain REST API managed zones fn api_read_zones(path: &str) -> Result>; diff --git a/pdns/recursordist/settings/rust/src/bridge.rs b/pdns/recursordist/settings/rust/src/bridge.rs index b08b9ed01921..80d1589e5116 100644 --- a/pdns/recursordist/settings/rust/src/bridge.rs +++ b/pdns/recursordist/settings/rust/src/bridge.rs @@ -210,13 +210,13 @@ impl AuthZone { } } -pub fn validate_auth_zones(field: &str, vec: &[AuthZone]) -> Result<(), ValidationError> { +pub fn validate_auth_zones(field: &str, vec: &Vec) -> Result<(), ValidationError> { validate_vec(field, vec, |field, element| element.validate(field)) } pub fn validate_forward_zones( field: &str, - vec: &[ForwardZone], + vec: &Vec, ) -> Result<(), ValidationError> { validate_vec(field, vec, |field, element| element.validate(field)) } @@ -270,7 +270,7 @@ pub fn allow_from_to_yaml_string_incoming( serde_yaml::to_string(&outerval) } -pub fn validate_allow_from(field: &str, vec: &[String]) -> Result<(), ValidationError> { +pub fn validate_allow_from(field: &str, vec: &Vec) -> Result<(), ValidationError> { validate_vec(field, vec, validate_subnet) } @@ -280,11 +280,11 @@ pub fn allow_for_to_yaml_string(vec: &Vec) -> Result Result<(), ValidationError> { +pub fn validate_allow_for(field: &str, vec: &Vec) -> Result<(), ValidationError> { validate_vec(field, vec, validate_name) } -pub fn validate_allow_notify_for(field: &str, vec: &[String]) -> Result<(), ValidationError> { +pub fn validate_allow_notify_for(field: &str, vec: &Vec) -> Result<(), ValidationError> { validate_vec(field, vec, validate_name) } diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index 5ec0c01c5715..2737f78ec02d 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -103,7 +103,7 @@ static void apiServerConfigACL(const std::string& aclType, HttpRequest* req, Htt } try { - ::pdns::rust::settings::rec::validate_allow_from(aclType, {vec.data(), vec.size()}); + ::pdns::rust::settings::rec::validate_allow_from(aclType, vec); } catch (const ::rust::Error& e) { throw ApiException(string("Unable to convert: ") + e.what()); From a7aad94e66761ef46668e9818d2d79c1c3d45205 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 12 Sep 2023 23:47:02 +0200 Subject: [PATCH 683/909] Rec: Settings Rust bridge allow passing references to owned Vecs --- pdns/recursordist/settings/rust/src/bridge.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pdns/recursordist/settings/rust/src/bridge.rs b/pdns/recursordist/settings/rust/src/bridge.rs index 80d1589e5116..370a881074f8 100644 --- a/pdns/recursordist/settings/rust/src/bridge.rs +++ b/pdns/recursordist/settings/rust/src/bridge.rs @@ -210,10 +210,12 @@ impl AuthZone { } } +#[allow(clippy::ptr_arg)] //# Avoids creating a rust::Slice object on the C++ side. pub fn validate_auth_zones(field: &str, vec: &Vec) -> Result<(), ValidationError> { validate_vec(field, vec, |field, element| element.validate(field)) } +#[allow(clippy::ptr_arg)] //# Avoids creating a rust::Slice object on the C++ side. pub fn validate_forward_zones( field: &str, vec: &Vec, @@ -270,6 +272,7 @@ pub fn allow_from_to_yaml_string_incoming( serde_yaml::to_string(&outerval) } +#[allow(clippy::ptr_arg)] //# Avoids creating a rust::Slice object on the C++ side. pub fn validate_allow_from(field: &str, vec: &Vec) -> Result<(), ValidationError> { validate_vec(field, vec, validate_subnet) } @@ -280,10 +283,12 @@ pub fn allow_for_to_yaml_string(vec: &Vec) -> Result) -> Result<(), ValidationError> { validate_vec(field, vec, validate_name) } +#[allow(clippy::ptr_arg)] //# Avoids creating a rust::Slice object on the C++ side. pub fn validate_allow_notify_for(field: &str, vec: &Vec) -> Result<(), ValidationError> { validate_vec(field, vec, validate_name) } From f28017017f4a976bd541d92da7eef38ad1193fad Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 13 Sep 2023 08:07:30 +0200 Subject: [PATCH 684/909] Fix wrongly converted default for "quiet" --- pdns/recursordist/settings/table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index 56ea6c9ef173..e57ea13940b1 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -1975,7 +1975,7 @@ 'name' : 'quiet', 'section' : 'logging', 'type' : LType.Bool, - 'default' : 'yes', + 'default' : 'true', 'help' : 'Suppress logging of questions and answers', 'doc' : ''' Don't log queries. From 48403e5dea7b9d55d25950b2a22f52369c601fe2 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 13 Sep 2023 08:54:18 +0200 Subject: [PATCH 685/909] rec: fix docker build; it does `make install` without first building the default target --- pdns/recursordist/settings/Makefile.am | 2 ++ pdns/recursordist/settings/rust/Makefile.am | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/settings/Makefile.am b/pdns/recursordist/settings/Makefile.am index 32b322d405a1..6e5952c9581a 100644 --- a/pdns/recursordist/settings/Makefile.am +++ b/pdns/recursordist/settings/Makefile.am @@ -10,6 +10,8 @@ EXTRA_DIST = \ all: cxxsettings-generated.cc +BUILT_SOURCES=cxxsettings-generated.cc + # It's a bit dirty that this target also generated a file inside rust/src (lib.rs) cxxsettings-generated.cc: table.py generate.py rust-preamble-in.rs rust-bridge-in.rs docs-old-preamble-in.rst docs-new-preamble-in.rst $(PYTHON) generate.py diff --git a/pdns/recursordist/settings/rust/Makefile.am b/pdns/recursordist/settings/rust/Makefile.am index 814c21322025..ac1a27e330ff 100644 --- a/pdns/recursordist/settings/rust/Makefile.am +++ b/pdns/recursordist/settings/rust/Makefile.am @@ -1,6 +1,6 @@ CARGO ?= cargo -all: libsettings.a +all install: libsettings.a EXTRA_DIST = \ Cargo.toml \ From 30ef2a39eccb7f3474fee6d04cbc13e2312edd61 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 13 Sep 2023 09:15:20 +0200 Subject: [PATCH 686/909] Install Rust in docker build env --- Dockerfile-recursor | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Dockerfile-recursor b/Dockerfile-recursor index 724da16fc43f..9b118cd866fc 100644 --- a/Dockerfile-recursor +++ b/Dockerfile-recursor @@ -28,6 +28,9 @@ COPY ext /source/ext COPY .git /source/.git COPY builder/helpers/set-configure-ac-version.sh /usr/local/bin +COPY builder-support/helpers/install_rust.sh /source/install_rust.sh +RUN /source/install_rust.sh + # build and install (TODO: before we hit this line, rearrange /source structure if we are coming from a tarball) WORKDIR /source/pdns/recursordist From 4e259dad6e868e3528cb02a59957638c5735b2b1 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 13 Sep 2023 12:07:08 +0200 Subject: [PATCH 687/909] rec: Fix Coverityy 1519054: Using invalid iterator --- pdns/recursordist/settings/cxxsupport.cc | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index 84c3f1c455be..bde1a244a3ae 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -491,7 +491,10 @@ std::string pdns::settings::rec::defaultsToYaml() withHelp = true; } if (withHelp) { - auto oldname = std::string(map.find(make_pair(section, field))->second.old_name); + std::string oldname; + if (auto iter = map.find(make_pair(section, field)); iter != map.end()) { + oldname = std::string(iter->second.old_name); + } res += "##### "; res += arg().getHelp(oldname); res += '\n'; From b3d6c94912e55d12f648b9e3b48f4a561f7bf242 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 12 Sep 2023 09:26:45 +0200 Subject: [PATCH 688/909] Prep for rec-5.0.0-alpha1 --- .github/actions/spell-check/expect.txt | 5 + docs/secpoll.zone | 3 +- pdns/recursordist/docs/changelog/5.0.rst | 190 +++++++++++++++++++++ pdns/recursordist/docs/changelog/index.rst | 1 + pdns/recursordist/docs/upgrade.rst | 22 ++- pdns/recursordist/docs/yamlsettings.rst | 2 +- 6 files changed, 219 insertions(+), 4 deletions(-) create mode 100644 pdns/recursordist/docs/changelog/5.0.rst diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 1381e213df42..b5892c7e8bc0 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -82,6 +82,7 @@ axfrfilter Baan backgrounding backported +backticks BADALG BADCOOKIE badips @@ -119,6 +120,7 @@ binddn BINDTODEVICE Binero binlog +bitfield bitmaps bla blackhole @@ -241,6 +243,7 @@ cryptopp cryptoshop csum csync +Cunha custommetrics cve cvename @@ -834,6 +837,7 @@ mrtg msdcs MSDNS msphinx +msrv mtasker mthread Mulholland @@ -1197,6 +1201,7 @@ rsasha Rueckert rulesets runtimedir +rustup Ruthensteiner Rvd rwlock diff --git a/docs/secpoll.zone b/docs/secpoll.zone index e3e021ea3120..49b741c2ea17 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023090801 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023091300 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -358,6 +358,7 @@ recursor-4.9.0-beta1.security-status 60 IN TXT "2 Unsupported recursor-4.9.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release" recursor-4.9.0.security-status 60 IN TXT "1 OK" recursor-4.9.1.security-status 60 IN TXT "1 OK" +recursor-5.0.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release" ; Recursor Debian recursor-3.6.2-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/" diff --git a/pdns/recursordist/docs/changelog/5.0.rst b/pdns/recursordist/docs/changelog/5.0.rst new file mode 100644 index 000000000000..3532e8b63161 --- /dev/null +++ b/pdns/recursordist/docs/changelog/5.0.rst @@ -0,0 +1,190 @@ +Changelogs for 5.0.X +==================== +.. changelog:: + :version: 5.0.0-alpha1 + :released: 13th of September 2023 + + .. change:: + :tags: Improvements + :pullreq: 13008 + + Rewrite settings code, introducing YAML settings file, using Rust and generated code to implement YAML processing + + .. change:: + :tags: Improvements + :pullreq: 13209 + + Make aggressive cache pruning more effective and more fair. + + .. change:: + :tags: Bug Fixes + :pullreq: 13210 + + Remove Before=nss-lookup.target line from unit file. + + .. change:: + :tags: Improvements + :pullreq: 13208 + + Remove make_tuple and make_pair (Rosen Penev). + + .. change:: + :tags: Improvements + :pullreq: 13190 + + Rec: fix a few unused argument warnings (depending on features enabled). + + .. change:: + :tags: Bug Fixes + :pullreq: 13167 + + TCPIOHandler: Fix a race when creating the first TLS connections. + + .. change:: + :tags: Bug Fixes + :pullreq: 13174 + + Rec: Include cstdint in mtasker_ucontext.cc, noted by @zeha. + + .. change:: + :tags: Improvements + :pullreq: 13168 + + Change the default for building with net-snmp from `auto` to `no`. + + .. change:: + :tags: Improvements + :pullreq: 13155 + :tickets: 13147 + + Channel: Make the blocking parameters of the object queue explicit. + + .. change:: + :tags: Improvements + :pullreq: 13102 + + Do not assume the records are in a particular order when determining if an answer is NODATA. + + .. change:: + :tags: Improvements + :pullreq: 13111 + + Document default for `webserver-loglevel` (Frank Louwers). + + .. change:: + :tags: Improvements + :pullreq: 13087 + + Remove unused sysv init files. + + .. change:: + :tags: Improvements + :pullreq: 13092 + + Fixes a few performance issues reported by Coverity. + + .. change:: + :tags: Improvements + :pullreq: 13074 + + Highlight why regression tests failed with github annotation (Josh Soref) + + .. change:: + :tags: Improvements + :pullreq: 13073 + + Switch from deprecated ::set-output (Josh Soref). + + .. change:: + :tags: Improvements + :pullreq: 13067 + + Use backticks in rec_control(1) (Josh Soref). + + .. change:: + :tags: Improvements + :pullreq: 13068 + + Clarify why bulktest is failing (Josh Soref). + + .. change:: + :tags: Improvements + :pullreq: 13043 + :tickets: 13011 + + Set TTL in getFakePTRRecords. + + .. change:: + :tags: Improvements + :pullreq: 13032 + + Update settings.rst -- clarify edns-subnet-allow-list (Seth Arnold). + + .. change:: + :tags: Improvements + :pullreq: 13026 + + Dnsheader: Switch from bitfield to uint16_t whenever possible. + + .. change:: + :tags: Improvements + :pullreq: 12805 + + Clarify log message for NODATA/NXDOMAIN without AA (Håkan Lindqvist). + + .. change:: + :tags: Improvements + :pullreq: 12913,12931,12999,13001,13022,13175,15197 + + Use arc4random only for random values. + + .. change:: + :tags: Improvements + :pullreq: 12851 + + Update base Debian version in Docker docs (Italo Cunha). + + .. change:: + :tags: Improvements + :pullreq: 12917 + + Delint pdns recursor.cc. + + .. change:: + :tags: Improvements + :pullreq: 12957 + + Include qname when logging skip of step 4 of qname minimization (Doug Freed). + + .. change:: + :tags: Improvements + :pullreq: 12952 + + Fix a set of move optimizations, as suggested by Coverity. + + .. change:: + :tags: Improvements + :pullreq: 12934 + + Silence Coverity 1462719 Unchecked return value from library. + + .. change:: + :tags: Improvements + :pullreq: 12930 + + Fix compile warnings. + + .. change:: + :tags: Improvements + :pullreq: 12913 + + Dns random: add method to get full 32-bits of randomness. + + .. change:: + :tags: Improvements + :pullreq: 12808 + + Reformat and delint arguments.cc and arguments.hh. + + + diff --git a/pdns/recursordist/docs/changelog/index.rst b/pdns/recursordist/docs/changelog/index.rst index 56b0bd0e9975..8e2e384b6047 100644 --- a/pdns/recursordist/docs/changelog/index.rst +++ b/pdns/recursordist/docs/changelog/index.rst @@ -6,6 +6,7 @@ The changelogs for the recursor are split between release trains. .. toctree:: :maxdepth: 2 + 5.0 4.9 4.8 4.7 diff --git a/pdns/recursordist/docs/upgrade.rst b/pdns/recursordist/docs/upgrade.rst index f1c43ed50f6a..a786699a99cb 100644 --- a/pdns/recursordist/docs/upgrade.rst +++ b/pdns/recursordist/docs/upgrade.rst @@ -4,8 +4,26 @@ Upgrade Guide Before upgrading, it is advised to read the :doc:`changelog/index`. When upgrading several versions, please read **all** notes applying to the upgrade. -4.8.0 to 4.9.0 and master -------------------------- +4.9.0 to 5.0.0 and master +-------------------------- + +YAML setings +------------ +Starting with version 5.0.0-alpha1 the settings file(s) can be specified using YAML syntax. +The old-style settings files are still accepted but will be unsupported in a future release. +When a ``recursor.yml`` settings file is encountered it will be processed instead of a ``recursor.conf`` file. +Refer to :doc:`yamlsettings` for details and the :doc:`appendices/yamlconversion` guide for how to convert old-style settings to the new YAML format. + +Rust +---- +Some parts of the Recursor code are now written in Rust. +This has impact if you do local builds or are third-package maintainer. +According to `cargo msrv` the minimum version to compile the Rust code and its dependencies is 1.64. +Some distributions ship with an older Rust compiler, see `Rustup `__ for a way to install a more recent one. +For our package builds, we install a Rust compiler from the ``Standalone`` section of `Other Rust Installation Methods `__. + +4.8.0 to 4.9.0 +-------------- Metrics ^^^^^^^ diff --git a/pdns/recursordist/docs/yamlsettings.rst b/pdns/recursordist/docs/yamlsettings.rst index c81f1dc87837..ccaa639cc3dc 100644 --- a/pdns/recursordist/docs/yamlsettings.rst +++ b/pdns/recursordist/docs/yamlsettings.rst @@ -1095,7 +1095,7 @@ Whether to compute the latency of responses in protobuf messages using the times ^^^^^^^^^^^^^^^^^ - Boolean -- Default: ``yes`` +- Default: ``true`` - Old style setting: :ref:`setting-quiet` From 027330ebea75279547ca6db37811dfa3397386c7 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 12 Sep 2023 17:09:15 +0200 Subject: [PATCH 689/909] When an exception is thrown from an mthread register stack switch in the ASAN case --- pdns/mtasker.cc | 9 ++++++++- pdns/recursordist/test-mtasker.cc | 15 --------------- pdns/recursordist/test-rec-zonetocache.cc | 2 ++ 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/pdns/mtasker.cc b/pdns/mtasker.cc index 82d1bbe87547..dd7ccc50bd11 100644 --- a/pdns/mtasker.cc +++ b/pdns/mtasker.cc @@ -325,7 +325,14 @@ templatebool MTasker::schedule(con d_threads[d_tid].dt.start(); #endif notifyStackSwitch(d_threads[d_tid].startOfStack, d_stacksize); - pdns_swapcontext(d_kernel, *d_threads[d_tid].context); + try { + pdns_swapcontext(d_kernel, *d_threads[d_tid].context); + } + catch (...) { + notifyStackSwitchDone(); + // It is not clear if the d_runQueue.pop() should be done in this case + throw; + } notifyStackSwitchDone(); d_runQueue.pop(); diff --git a/pdns/recursordist/test-mtasker.cc b/pdns/recursordist/test-mtasker.cc index dd716cae0e5c..18a9620c7df9 100644 --- a/pdns/recursordist/test-mtasker.cc +++ b/pdns/recursordist/test-mtasker.cc @@ -78,19 +78,6 @@ BOOST_AUTO_TEST_CASE(test_AlmostStackOverflow) BOOST_CHECK_EQUAL(g_result, o); } -#if defined(HAVE_FIBER_SANITIZER) && defined(__APPLE__) && defined(__arm64__) - -// This test is buggy on MacOS when compiled with asan. It also causes subsequents tests to report spurious issues. -// So switch it off for now -// See https://github.com/PowerDNS/pdns/issues/12151 - -BOOST_AUTO_TEST_CASE(test_MtaskerException) -{ - cerr << "test_MtaskerException test disabled on this platform with asan enabled, please fix" << endl; -} - -#else - static void willThrow(void* /* p */) { throw std::runtime_error("Help!"); @@ -111,6 +98,4 @@ BOOST_AUTO_TEST_CASE(test_MtaskerException) std::exception); } -#endif // defined(HAVE_FIBER_SANITIZER) && defined(__APPLE__) && defined(__arm64__) - BOOST_AUTO_TEST_SUITE_END() diff --git a/pdns/recursordist/test-rec-zonetocache.cc b/pdns/recursordist/test-rec-zonetocache.cc index 6f95abced8a5..12c0a6dc9aa6 100644 --- a/pdns/recursordist/test-rec-zonetocache.cc +++ b/pdns/recursordist/test-rec-zonetocache.cc @@ -169,6 +169,8 @@ static void zonemdGenericTest(const std::string& lines, pdns::ZoneMD::Config mod BOOST_AUTO_TEST_CASE(test_zonetocachegeneric) { + g_log.setLoglevel(Logger::Critical); + g_log.toConsole(Logger::Critical); zonemdGenericTest(genericTest, pdns::ZoneMD::Config::Require, pdns::ZoneMD::Config::Ignore, 4U); zonemdGenericTest(genericBadTest, pdns::ZoneMD::Config::Require, pdns::ZoneMD::Config::Ignore, 0U); } From cc79ff2bccb952558e190c2d76b5fd639963d9a1 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 29 Aug 2023 13:58:31 +0200 Subject: [PATCH 690/909] Refactor actual processing of query out of handleRunningTCPQuestion --- pdns/recursordist/rec-tcp.cc | 481 ++++++++++++++++++----------------- 1 file changed, 242 insertions(+), 239 deletions(-) diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 4b43326e05a4..7d8905f388b4 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -216,6 +216,245 @@ class RunningTCPQuestionGuard int d_fd{-1}; }; + +static void doProcessTCPQuestion(std::unique_ptr& comboWriter, shared_ptr& conn, RunningTCPQuestionGuard& tcpGuard, int fileDesc) +{ + struct timeval start{}; + Utility::gettimeofday(&start, nullptr); + + DNSName qname; + uint16_t qtype = 0; + uint16_t qclass = 0; + bool needECS = false; + string requestorId; + string deviceId; + string deviceName; + bool logQuery = false; + bool qnameParsed = false; + + comboWriter->d_eventTrace.setEnabled(SyncRes::s_event_trace_enabled != 0); + comboWriter->d_eventTrace.add(RecEventTrace::ReqRecv); + auto luaconfsLocal = g_luaconfs.getLocal(); + if (checkProtobufExport(luaconfsLocal)) { + needECS = true; + } + logQuery = t_protobufServers.servers && luaconfsLocal->protobufExportConfig.logQueries; + comboWriter->d_logResponse = t_protobufServers.servers && luaconfsLocal->protobufExportConfig.logResponses; + + if (needECS || (t_pdl && (t_pdl->d_gettag_ffi || t_pdl->d_gettag)) || comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { + + try { + EDNSOptionViewMap ednsOptions; + comboWriter->d_ecsParsed = true; + comboWriter->d_ecsFound = false; + getQNameAndSubnet(conn->data, &qname, &qtype, &qclass, + comboWriter->d_ecsFound, &comboWriter->d_ednssubnet, g_gettagNeedsEDNSOptions ? &ednsOptions : nullptr); + qnameParsed = true; + + if (t_pdl) { + try { + if (t_pdl->d_gettag_ffi) { + RecursorLua4::FFIParams params(qname, qtype, comboWriter->d_destination, comboWriter->d_source, comboWriter->d_ednssubnet.source, comboWriter->d_data, comboWriter->d_policyTags, comboWriter->d_records, ednsOptions, comboWriter->d_proxyProtocolValues, requestorId, deviceId, deviceName, comboWriter->d_routingTag, comboWriter->d_rcode, comboWriter->d_ttlCap, comboWriter->d_variable, true, logQuery, comboWriter->d_logResponse, comboWriter->d_followCNAMERecords, comboWriter->d_extendedErrorCode, comboWriter->d_extendedErrorExtra, comboWriter->d_responsePaddingDisabled, comboWriter->d_meta); + comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTagFFI); + comboWriter->d_tag = t_pdl->gettag_ffi(params); + comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTagFFI, comboWriter->d_tag, false); + } + else if (t_pdl->d_gettag) { + comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTag); + comboWriter->d_tag = t_pdl->gettag(comboWriter->d_source, comboWriter->d_ednssubnet.source, comboWriter->d_destination, qname, qtype, &comboWriter->d_policyTags, comboWriter->d_data, ednsOptions, true, requestorId, deviceId, deviceName, comboWriter->d_routingTag, comboWriter->d_proxyProtocolValues); + comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTag, comboWriter->d_tag, false); + } + } + catch (const std::exception& e) { + if (g_logCommonErrors) { + SLOG(g_log << Logger::Warning << "Error parsing a query packet qname='" << qname << "' for tag determination, setting tag=0: " << e.what() << endl, + g_slogtcpin->info(Logr::Warning, "Error parsing a query packet for tag determination, setting tag=0", "remote", Logging::Loggable(conn->d_remote), "qname", Logging::Loggable(qname))); + } + } + } + } + catch (const std::exception& e) { + if (g_logCommonErrors) { + SLOG(g_log << Logger::Warning << "Error parsing a query packet for tag determination, setting tag=0: " << e.what() << endl, + g_slogtcpin->error(Logr::Warning, e.what(), "Error parsing a query packet for tag determination, setting tag=0", "exception", Logging::Loggable("std::exception"), "remote", Logging::Loggable(conn->d_remote))); + } + } + } + + if (comboWriter->d_tag == 0 && !comboWriter->d_responsePaddingDisabled && g_paddingFrom.match(comboWriter->d_remote)) { + comboWriter->d_tag = g_paddingTag; + } + + const dnsheader_aligned headerdata(conn->data.data()); + const struct dnsheader* dnsheader = headerdata.get(); + + if (t_protobufServers.servers || t_outgoingProtobufServers.servers) { + comboWriter->d_requestorId = requestorId; + comboWriter->d_deviceId = deviceId; + comboWriter->d_deviceName = deviceName; + comboWriter->d_uuid = getUniqueID(); + } + + if (t_protobufServers.servers) { + try { + + if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && comboWriter->d_policyTags.empty())) { + protobufLogQuery(luaconfsLocal, comboWriter->d_uuid, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet.source, true, dnsheader->id, conn->qlen, qname, qtype, qclass, comboWriter->d_policyTags, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta); + } + } + catch (const std::exception& e) { + if (g_logCommonErrors) { + SLOG(g_log << Logger::Warning << "Error parsing a TCP query packet for edns subnet: " << e.what() << endl, + g_slogtcpin->error(Logr::Warning, e.what(), "Error parsing a TCP query packet for edns subnet", "exception", Logging::Loggable("std::exception"), "remote", Logging::Loggable(conn->d_remote))); + } + } + } + + if (t_pdl) { + bool ipf = t_pdl->ipfilter(comboWriter->d_source, comboWriter->d_destination, *dnsheader, comboWriter->d_eventTrace); + if (ipf) { + if (!g_quiet) { + SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " [" << g_multiTasker->getTid() << "/" << g_multiTasker->numProcesses() << "] DROPPED TCP question from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << " based on policy" << endl, + g_slogtcpin->info(Logr::Info, "Dropped TCP question based on policy", "remote", Logging::Loggable(conn->d_remote), "source", Logging::Loggable(comboWriter->d_source))); + } + t_Counters.at(rec::Counter::policyDrops)++; + return; + } + } + + if (comboWriter->d_mdp.d_header.qr) { + t_Counters.at(rec::Counter::ignoredCount)++; + if (g_logCommonErrors) { + SLOG(g_log << Logger::Error << "Ignoring answer from TCP client " << comboWriter->getRemote() << " on server socket!" << endl, + g_slogtcpin->info(Logr::Error, "Ignoring answer from TCP client on server socket", "remote", Logging::Loggable(comboWriter->getRemote()))); + } + return; + } + if (comboWriter->d_mdp.d_header.opcode != static_cast(Opcode::Query) && comboWriter->d_mdp.d_header.opcode != static_cast(Opcode::Notify)) { + t_Counters.at(rec::Counter::ignoredCount)++; + if (g_logCommonErrors) { + SLOG(g_log << Logger::Error << "Ignoring unsupported opcode " << Opcode::to_s(comboWriter->d_mdp.d_header.opcode) << " from TCP client " << comboWriter->getRemote() << " on server socket!" << endl, + g_slogtcpin->info(Logr::Error, "Ignoring unsupported opcode from TCP client", "remote", Logging::Loggable(comboWriter->getRemote()), "opcode", Logging::Loggable(Opcode::to_s(comboWriter->d_mdp.d_header.opcode)))); + } + sendErrorOverTCP(comboWriter, RCode::NotImp); + tcpGuard.keep(); + return; + } + if (dnsheader->qdcount == 0U) { + t_Counters.at(rec::Counter::emptyQueriesCount)++; + if (g_logCommonErrors) { + SLOG(g_log << Logger::Error << "Ignoring empty (qdcount == 0) query from " << comboWriter->getRemote() << " on server socket!" << endl, + g_slogtcpin->info(Logr::Error, "Ignoring empty (qdcount == 0) query on server socket", "remote", Logging::Loggable(comboWriter->getRemote()))); + } + sendErrorOverTCP(comboWriter, RCode::NotImp); + tcpGuard.keep(); + return; + } + { + // We have read a proper query + //++t_Counters.at(rec::Counter::qcounter); + ++t_Counters.at(rec::Counter::qcounter); + ++t_Counters.at(rec::Counter::tcpqcounter); + + if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { + if (!t_allowNotifyFrom || !t_allowNotifyFrom->match(comboWriter->d_mappedSource)) { + if (!g_quiet) { + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", address not matched by allow-notify-from" << endl, + g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, address not matched by allow-notify-from", "source", Logging::Loggable(comboWriter->d_mappedSource))); + } + + t_Counters.at(rec::Counter::sourceDisallowedNotify)++; + return; + } + + if (!isAllowNotifyForZone(qname)) { + if (!g_quiet) { + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", for " << qname.toLogString() << ", zone not matched by allow-notify-for" << endl, + g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, zone not matched by allow-notify-for", "source", Logging::Loggable(comboWriter->d_mappedSource), "zone", Logging::Loggable(qname))); + } + + t_Counters.at(rec::Counter::zoneDisallowedNotify)++; + return; + } + } + + string response; + RecursorPacketCache::OptPBData pbData{boost::none}; + + if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Query)) { + /* It might seem like a good idea to skip the packet cache lookup if we know that the answer is not cacheable, + but it means that the hash would not be computed. If some script decides at a later time to mark back the answer + as cacheable we would cache it with a wrong tag, so better safe than sorry. */ + comboWriter->d_eventTrace.add(RecEventTrace::PCacheCheck); + bool cacheHit = checkForCacheHit(qnameParsed, comboWriter->d_tag, conn->data, qname, qtype, qclass, g_now, response, comboWriter->d_qhash, pbData, true, comboWriter->d_source, comboWriter->d_mappedSource); + comboWriter->d_eventTrace.add(RecEventTrace::PCacheCheck, cacheHit, false); + + if (cacheHit) { + if (!g_quiet) { + SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " TCP question answered from packet cache tag=" << comboWriter->d_tag << " from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << endl, + g_slogtcpin->info(Logr::Notice, "TCP question answered from packet cache", "tag", Logging::Loggable(comboWriter->d_tag), + "qname", Logging::Loggable(qname), "qtype", Logging::Loggable(QType(qtype)), + "source", Logging::Loggable(comboWriter->d_source), "remote", Logging::Loggable(comboWriter->d_remote))); + } + + bool hadError = sendResponseOverTCP(comboWriter, response); + finishTCPReply(comboWriter, hadError, false); + struct timeval now + { + }; + Utility::gettimeofday(&now, nullptr); + uint64_t spentUsec = uSec(now - start); + t_Counters.at(rec::Histogram::cumulativeAnswers)(spentUsec); + comboWriter->d_eventTrace.add(RecEventTrace::AnswerSent); + + if (t_protobufServers.servers && comboWriter->d_logResponse && (!luaconfsLocal->protobufExportConfig.taggedOnly || !pbData || pbData->d_tagged)) { + struct timeval tval + { + 0, 0 + }; + protobufLogResponse(dnsheader, luaconfsLocal, pbData, tval, true, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet, comboWriter->d_uuid, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta, comboWriter->d_eventTrace, comboWriter->d_policyTags); + } + + if (comboWriter->d_eventTrace.enabled() && (SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_log) != 0) { + SLOG(g_log << Logger::Info << comboWriter->d_eventTrace.toString() << endl, + g_slogtcpin->info(Logr::Info, comboWriter->d_eventTrace.toString())); // More fancy? + } + tcpGuard.keep(); + t_Counters.updateSnap(g_regressionTestMode); + return; + } // cache hit + } // query opcode + + if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { + if (!g_quiet) { + SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " got NOTIFY for " << qname.toLogString() << " from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << endl, + g_slogtcpin->info(Logr::Notice, "Got NOTIFY", "qname", Logging::Loggable(qname), "source", Logging::Loggable(comboWriter->d_source), "remote", Logging::Loggable(comboWriter->d_remote))); + } + + requestWipeCaches(qname); + + // the operation will now be treated as a Query, generating + // a normal response, as the rest of the code does not + // check dh->opcode, but we need to ensure that the response + // to this request does not get put into the packet cache + comboWriter->d_variable = true; + } + + // setup for startDoResolve() in an mthread + ++conn->d_requestsInFlight; + if (conn->d_requestsInFlight >= TCPConnection::s_maxInFlight) { + t_fdm->removeReadFD(fileDesc); // should no longer awake ourselves when there is data to read + } + else { + Utility::gettimeofday(&g_now, nullptr); // needed? + struct timeval ttd = g_now; + t_fdm->setReadTTD(fileDesc, ttd, g_tcpTimeout); + } + tcpGuard.keep(); + g_multiTasker->makeThread(startDoResolve, comboWriter.release()); // deletes dc + } // good query +} + static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& var) // NOLINT(readability-function-cognitive-complexity) https://github.com/PowerDNS/pdns/issues/12791 { auto conn = boost::any_cast>(var); @@ -382,245 +621,9 @@ static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& v all queries sent over this connection */ comboWriter->d_proxyProtocolValues = conn->proxyProtocolValues; - struct timeval start - { - }; - Utility::gettimeofday(&start, nullptr); - - DNSName qname; - uint16_t qtype = 0; - uint16_t qclass = 0; - bool needECS = false; - string requestorId; - string deviceId; - string deviceName; - bool logQuery = false; - bool qnameParsed = false; - - comboWriter->d_eventTrace.setEnabled(SyncRes::s_event_trace_enabled != 0); - comboWriter->d_eventTrace.add(RecEventTrace::ReqRecv); - auto luaconfsLocal = g_luaconfs.getLocal(); - if (checkProtobufExport(luaconfsLocal)) { - needECS = true; - } - logQuery = t_protobufServers.servers && luaconfsLocal->protobufExportConfig.logQueries; - comboWriter->d_logResponse = t_protobufServers.servers && luaconfsLocal->protobufExportConfig.logResponses; - - if (needECS || (t_pdl && (t_pdl->d_gettag_ffi || t_pdl->d_gettag)) || comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { - - try { - EDNSOptionViewMap ednsOptions; - comboWriter->d_ecsParsed = true; - comboWriter->d_ecsFound = false; - getQNameAndSubnet(conn->data, &qname, &qtype, &qclass, - comboWriter->d_ecsFound, &comboWriter->d_ednssubnet, g_gettagNeedsEDNSOptions ? &ednsOptions : nullptr); - qnameParsed = true; - - if (t_pdl) { - try { - if (t_pdl->d_gettag_ffi) { - RecursorLua4::FFIParams params(qname, qtype, comboWriter->d_destination, comboWriter->d_source, comboWriter->d_ednssubnet.source, comboWriter->d_data, comboWriter->d_policyTags, comboWriter->d_records, ednsOptions, comboWriter->d_proxyProtocolValues, requestorId, deviceId, deviceName, comboWriter->d_routingTag, comboWriter->d_rcode, comboWriter->d_ttlCap, comboWriter->d_variable, true, logQuery, comboWriter->d_logResponse, comboWriter->d_followCNAMERecords, comboWriter->d_extendedErrorCode, comboWriter->d_extendedErrorExtra, comboWriter->d_responsePaddingDisabled, comboWriter->d_meta); - comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTagFFI); - comboWriter->d_tag = t_pdl->gettag_ffi(params); - comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTagFFI, comboWriter->d_tag, false); - } - else if (t_pdl->d_gettag) { - comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTag); - comboWriter->d_tag = t_pdl->gettag(comboWriter->d_source, comboWriter->d_ednssubnet.source, comboWriter->d_destination, qname, qtype, &comboWriter->d_policyTags, comboWriter->d_data, ednsOptions, true, requestorId, deviceId, deviceName, comboWriter->d_routingTag, comboWriter->d_proxyProtocolValues); - comboWriter->d_eventTrace.add(RecEventTrace::LuaGetTag, comboWriter->d_tag, false); - } - } - catch (const std::exception& e) { - if (g_logCommonErrors) { - SLOG(g_log << Logger::Warning << "Error parsing a query packet qname='" << qname << "' for tag determination, setting tag=0: " << e.what() << endl, - g_slogtcpin->info(Logr::Warning, "Error parsing a query packet for tag determination, setting tag=0", "remote", Logging::Loggable(conn->d_remote), "qname", Logging::Loggable(qname))); - } - } - } - } - catch (const std::exception& e) { - if (g_logCommonErrors) { - SLOG(g_log << Logger::Warning << "Error parsing a query packet for tag determination, setting tag=0: " << e.what() << endl, - g_slogtcpin->error(Logr::Warning, e.what(), "Error parsing a query packet for tag determination, setting tag=0", "exception", Logging::Loggable("std::exception"), "remote", Logging::Loggable(conn->d_remote))); - } - } - } - - if (comboWriter->d_tag == 0 && !comboWriter->d_responsePaddingDisabled && g_paddingFrom.match(comboWriter->d_remote)) { - comboWriter->d_tag = g_paddingTag; - } - - const dnsheader_aligned headerdata(conn->data.data()); - const struct dnsheader* dnsheader = headerdata.get(); - - if (t_protobufServers.servers || t_outgoingProtobufServers.servers) { - comboWriter->d_requestorId = requestorId; - comboWriter->d_deviceId = deviceId; - comboWriter->d_deviceName = deviceName; - comboWriter->d_uuid = getUniqueID(); - } - - if (t_protobufServers.servers) { - try { - - if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && comboWriter->d_policyTags.empty())) { - protobufLogQuery(luaconfsLocal, comboWriter->d_uuid, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet.source, true, dnsheader->id, conn->qlen, qname, qtype, qclass, comboWriter->d_policyTags, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta); - } - } - catch (const std::exception& e) { - if (g_logCommonErrors) { - SLOG(g_log << Logger::Warning << "Error parsing a TCP query packet for edns subnet: " << e.what() << endl, - g_slogtcpin->error(Logr::Warning, e.what(), "Error parsing a TCP query packet for edns subnet", "exception", Logging::Loggable("std::exception"), "remote", Logging::Loggable(conn->d_remote))); - } - } - } - - if (t_pdl) { - bool ipf = t_pdl->ipfilter(comboWriter->d_source, comboWriter->d_destination, *dnsheader, comboWriter->d_eventTrace); - if (ipf) { - if (!g_quiet) { - SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " [" << g_multiTasker->getTid() << "/" << g_multiTasker->numProcesses() << "] DROPPED TCP question from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << " based on policy" << endl, - g_slogtcpin->info(Logr::Info, "Dropped TCP question based on policy", "remote", Logging::Loggable(conn->d_remote), "source", Logging::Loggable(comboWriter->d_source))); - } - t_Counters.at(rec::Counter::policyDrops)++; - return; - } - } - - if (comboWriter->d_mdp.d_header.qr) { - t_Counters.at(rec::Counter::ignoredCount)++; - if (g_logCommonErrors) { - SLOG(g_log << Logger::Error << "Ignoring answer from TCP client " << comboWriter->getRemote() << " on server socket!" << endl, - g_slogtcpin->info(Logr::Error, "Ignoring answer from TCP client on server socket", "remote", Logging::Loggable(comboWriter->getRemote()))); - } - return; - } - if (comboWriter->d_mdp.d_header.opcode != static_cast(Opcode::Query) && comboWriter->d_mdp.d_header.opcode != static_cast(Opcode::Notify)) { - t_Counters.at(rec::Counter::ignoredCount)++; - if (g_logCommonErrors) { - SLOG(g_log << Logger::Error << "Ignoring unsupported opcode " << Opcode::to_s(comboWriter->d_mdp.d_header.opcode) << " from TCP client " << comboWriter->getRemote() << " on server socket!" << endl, - g_slogtcpin->info(Logr::Error, "Ignoring unsupported opcode from TCP client", "remote", Logging::Loggable(comboWriter->getRemote()), "opcode", Logging::Loggable(Opcode::to_s(comboWriter->d_mdp.d_header.opcode)))); - } - sendErrorOverTCP(comboWriter, RCode::NotImp); - tcpGuard.keep(); - return; - } - if (dnsheader->qdcount == 0U) { - t_Counters.at(rec::Counter::emptyQueriesCount)++; - if (g_logCommonErrors) { - SLOG(g_log << Logger::Error << "Ignoring empty (qdcount == 0) query from " << comboWriter->getRemote() << " on server socket!" << endl, - g_slogtcpin->info(Logr::Error, "Ignoring empty (qdcount == 0) query on server socket", "remote", Logging::Loggable(comboWriter->getRemote()))); - } - sendErrorOverTCP(comboWriter, RCode::NotImp); - tcpGuard.keep(); - return; - } - { - // We have read a proper query - //++t_Counters.at(rec::Counter::qcounter); - ++t_Counters.at(rec::Counter::qcounter); - ++t_Counters.at(rec::Counter::tcpqcounter); - - if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { - if (!t_allowNotifyFrom || !t_allowNotifyFrom->match(comboWriter->d_mappedSource)) { - if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", address not matched by allow-notify-from" << endl, - g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, address not matched by allow-notify-from", "source", Logging::Loggable(comboWriter->d_mappedSource))); - } - - t_Counters.at(rec::Counter::sourceDisallowedNotify)++; - return; - } - - if (!isAllowNotifyForZone(qname)) { - if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", for " << qname.toLogString() << ", zone not matched by allow-notify-for" << endl, - g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, zone not matched by allow-notify-for", "source", Logging::Loggable(comboWriter->d_mappedSource), "zone", Logging::Loggable(qname))); - } - - t_Counters.at(rec::Counter::zoneDisallowedNotify)++; - return; - } - } - - string response; - RecursorPacketCache::OptPBData pbData{boost::none}; - - if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Query)) { - /* It might seem like a good idea to skip the packet cache lookup if we know that the answer is not cacheable, - but it means that the hash would not be computed. If some script decides at a later time to mark back the answer - as cacheable we would cache it with a wrong tag, so better safe than sorry. */ - comboWriter->d_eventTrace.add(RecEventTrace::PCacheCheck); - bool cacheHit = checkForCacheHit(qnameParsed, comboWriter->d_tag, conn->data, qname, qtype, qclass, g_now, response, comboWriter->d_qhash, pbData, true, comboWriter->d_source, comboWriter->d_mappedSource); - comboWriter->d_eventTrace.add(RecEventTrace::PCacheCheck, cacheHit, false); - - if (cacheHit) { - if (!g_quiet) { - SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " TCP question answered from packet cache tag=" << comboWriter->d_tag << " from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << endl, - g_slogtcpin->info(Logr::Notice, "TCP question answered from packet cache", "tag", Logging::Loggable(comboWriter->d_tag), - "qname", Logging::Loggable(qname), "qtype", Logging::Loggable(QType(qtype)), - "source", Logging::Loggable(comboWriter->d_source), "remote", Logging::Loggable(comboWriter->d_remote))); - } - - bool hadError = sendResponseOverTCP(comboWriter, response); - finishTCPReply(comboWriter, hadError, false); - struct timeval now - { - }; - Utility::gettimeofday(&now, nullptr); - uint64_t spentUsec = uSec(now - start); - t_Counters.at(rec::Histogram::cumulativeAnswers)(spentUsec); - comboWriter->d_eventTrace.add(RecEventTrace::AnswerSent); - - if (t_protobufServers.servers && comboWriter->d_logResponse && (!luaconfsLocal->protobufExportConfig.taggedOnly || !pbData || pbData->d_tagged)) { - struct timeval tval - { - 0, 0 - }; - protobufLogResponse(dnsheader, luaconfsLocal, pbData, tval, true, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet, comboWriter->d_uuid, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta, comboWriter->d_eventTrace, comboWriter->d_policyTags); - } - - if (comboWriter->d_eventTrace.enabled() && (SyncRes::s_event_trace_enabled & SyncRes::event_trace_to_log) != 0) { - SLOG(g_log << Logger::Info << comboWriter->d_eventTrace.toString() << endl, - g_slogtcpin->info(Logr::Info, comboWriter->d_eventTrace.toString())); // More fancy? - } - tcpGuard.keep(); - t_Counters.updateSnap(g_regressionTestMode); - return; - } // cache hit - } // query opcode - - if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { - if (!g_quiet) { - SLOG(g_log << Logger::Notice << RecThreadInfo::id() << " got NOTIFY for " << qname.toLogString() << " from " << comboWriter->d_source.toStringWithPort() << (comboWriter->d_source != comboWriter->d_remote ? " (via " + comboWriter->d_remote.toStringWithPort() + ")" : "") << endl, - g_slogtcpin->info(Logr::Notice, "Got NOTIFY", "qname", Logging::Loggable(qname), "source", Logging::Loggable(comboWriter->d_source), "remote", Logging::Loggable(comboWriter->d_remote))); - } - - requestWipeCaches(qname); - - // the operation will now be treated as a Query, generating - // a normal response, as the rest of the code does not - // check dh->opcode, but we need to ensure that the response - // to this request does not get put into the packet cache - comboWriter->d_variable = true; - } - - // setup for startDoResolve() in an mthread - ++conn->d_requestsInFlight; - if (conn->d_requestsInFlight >= TCPConnection::s_maxInFlight) { - t_fdm->removeReadFD(fileDesc); // should no longer awake ourselves when there is data to read - } - else { - Utility::gettimeofday(&g_now, nullptr); // needed? - struct timeval ttd = g_now; - t_fdm->setReadTTD(fileDesc, ttd, g_tcpTimeout); - } - tcpGuard.keep(); - g_multiTasker->makeThread(startDoResolve, comboWriter.release()); // deletes dc - } // good query - } // read full query - } // reading query - + doProcessTCPQuestion(comboWriter, conn, tcpGuard, fileDesc); + } // reading query + } // more to come tcpGuard.keep(); } From f30f6502950b4786824b94f76d8cc1ad29ab1a08 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 29 Aug 2023 15:54:36 +0200 Subject: [PATCH 691/909] Some more refactoring to get complexity down plus comments on the way tcp-in works --- pdns/recursordist/rec-tcp.cc | 113 +++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 39 deletions(-) diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 7d8905f388b4..313a062bab66 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -27,6 +27,32 @@ #include "mplexer.hh" #include "uuid-utils.hh" +// When pdns_distributes query is false with reuseport true (the default since 4.9.0), TCP queries +// are read and handled by worker threads. If the kernel balancing is OK for TCP sockets (observed +// to be good on Debian bullseye, but not good on e.g. MacOS), the TCP handling is no extra burden. +// In the case of MacOS all incoming TCP queries are handled by a single worker, while incoming UDP +// queries do get distributed round-robin over the worker threads. Do note the TCP queries might +// need to wait until the g_maxUDPQueriesPerRound is reached. +// +// In the case of pdns-distributes-queries true and reuseport false the queries are read and +// initially processed by the distributor thread(s). +// +// Initial processing consist of parsing, calling gettag and checking if we have a packet cache +// hit. If that does not produce a hit, the query is passed to an mthread in the same way as with +// UDP queries, but do note that the mthread processing is serviced by the distributor thread. The +// final answer will be sent by the same distributor thread that originally picked up the query. +// +// Changing this, and having incoming TCP queries handled by worker threads is somewhat more complex +// than UDP, as the socket must remain avaiable in the distributor thread (for reading more +// queries), but the TCP socket must also be passed to a worker thread so it can write its +// answer. The in-flight bookkeeping also has to be aware of how a query is handled to do the +// accounting properly. I am not sure if changing the current setup is worth all this trouble, +// especilly since the default is now to not use pdns-distributes-queries, which works well in many +// cases. +// +// The drawback mentioned in https://github.com/PowerDNS/pdns/issues/8394 are not longer true, so an +// alternative approach would be to introduce dedicated TCP worker thread(s). + size_t g_tcpMaxQueriesPerConn; unsigned int g_maxTCPPerClient; int g_tcpTimeout; @@ -216,10 +242,49 @@ class RunningTCPQuestionGuard int d_fd{-1}; }; +static void handleNotify(std::unique_ptr& comboWriter, const DNSName& qname) +{ + if (!t_allowNotifyFrom || !t_allowNotifyFrom->match(comboWriter->d_mappedSource)) { + if (!g_quiet) { + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", address not matched by allow-notify-from" << endl, + g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, address not matched by allow-notify-from", "source", Logging::Loggable(comboWriter->d_mappedSource))); + } + + t_Counters.at(rec::Counter::sourceDisallowedNotify)++; + return; + } + + if (!isAllowNotifyForZone(qname)) { + if (!g_quiet) { + SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", for " << qname.toLogString() << ", zone not matched by allow-notify-for" << endl, + g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, zone not matched by allow-notify-for", "source", Logging::Loggable(comboWriter->d_mappedSource), "zone", Logging::Loggable(qname))); + } + + t_Counters.at(rec::Counter::zoneDisallowedNotify)++; + return; + } +} + +static void doProtobufLogQuery(bool logQuery, LocalStateHolder& luaconfsLocal, const std::unique_ptr& comboWriter, const DNSName& qname, QType qtype, QClass qclass, const dnsheader* dnsheader, const shared_ptr& conn) +{ + try { + if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && comboWriter->d_policyTags.empty())) { + protobufLogQuery(luaconfsLocal, comboWriter->d_uuid, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet.source, true, dnsheader->id, conn->qlen, qname, qtype, qclass, comboWriter->d_policyTags, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta); + } + } + catch (const std::exception& e) { + if (g_logCommonErrors) { + SLOG(g_log << Logger::Warning << "Error parsing a TCP query packet for edns subnet: " << e.what() << endl, + g_slogtcpin->error(Logr::Warning, e.what(), "Error parsing a TCP query packet for edns subnet", "exception", Logging::Loggable("std::exception"), "remote", Logging::Loggable(conn->d_remote))); + } + } +} static void doProcessTCPQuestion(std::unique_ptr& comboWriter, shared_ptr& conn, RunningTCPQuestionGuard& tcpGuard, int fileDesc) { - struct timeval start{}; + struct timeval start + { + }; Utility::gettimeofday(&start, nullptr); DNSName qname; @@ -296,18 +361,7 @@ static void doProcessTCPQuestion(std::unique_ptr& comboWriter, s } if (t_protobufServers.servers) { - try { - - if (logQuery && !(luaconfsLocal->protobufExportConfig.taggedOnly && comboWriter->d_policyTags.empty())) { - protobufLogQuery(luaconfsLocal, comboWriter->d_uuid, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet.source, true, dnsheader->id, conn->qlen, qname, qtype, qclass, comboWriter->d_policyTags, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta); - } - } - catch (const std::exception& e) { - if (g_logCommonErrors) { - SLOG(g_log << Logger::Warning << "Error parsing a TCP query packet for edns subnet: " << e.what() << endl, - g_slogtcpin->error(Logr::Warning, e.what(), "Error parsing a TCP query packet for edns subnet", "exception", Logging::Loggable("std::exception"), "remote", Logging::Loggable(conn->d_remote))); - } - } + doProtobufLogQuery(logQuery, luaconfsLocal, comboWriter, qname, qtype, qclass, dnsheader, conn); } if (t_pdl) { @@ -352,30 +406,11 @@ static void doProcessTCPQuestion(std::unique_ptr& comboWriter, s } { // We have read a proper query - //++t_Counters.at(rec::Counter::qcounter); ++t_Counters.at(rec::Counter::qcounter); ++t_Counters.at(rec::Counter::tcpqcounter); if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { - if (!t_allowNotifyFrom || !t_allowNotifyFrom->match(comboWriter->d_mappedSource)) { - if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", address not matched by allow-notify-from" << endl, - g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, address not matched by allow-notify-from", "source", Logging::Loggable(comboWriter->d_mappedSource))); - } - - t_Counters.at(rec::Counter::sourceDisallowedNotify)++; - return; - } - - if (!isAllowNotifyForZone(qname)) { - if (!g_quiet) { - SLOG(g_log << Logger::Error << "[" << g_multiTasker->getTid() << "] dropping TCP NOTIFY from " << comboWriter->d_mappedSource.toString() << ", for " << qname.toLogString() << ", zone not matched by allow-notify-for" << endl, - g_slogtcpin->info(Logr::Error, "Dropping TCP NOTIFY, zone not matched by allow-notify-for", "source", Logging::Loggable(comboWriter->d_mappedSource), "zone", Logging::Loggable(qname))); - } - - t_Counters.at(rec::Counter::zoneDisallowedNotify)++; - return; - } + handleNotify(comboWriter, qname); } string response; @@ -400,8 +435,8 @@ static void doProcessTCPQuestion(std::unique_ptr& comboWriter, s bool hadError = sendResponseOverTCP(comboWriter, response); finishTCPReply(comboWriter, hadError, false); struct timeval now - { - }; + { + }; Utility::gettimeofday(&now, nullptr); uint64_t spentUsec = uSec(now - start); t_Counters.at(rec::Histogram::cumulativeAnswers)(spentUsec); @@ -409,9 +444,9 @@ static void doProcessTCPQuestion(std::unique_ptr& comboWriter, s if (t_protobufServers.servers && comboWriter->d_logResponse && (!luaconfsLocal->protobufExportConfig.taggedOnly || !pbData || pbData->d_tagged)) { struct timeval tval - { - 0, 0 - }; + { + 0, 0 + }; protobufLogResponse(dnsheader, luaconfsLocal, pbData, tval, true, comboWriter->d_source, comboWriter->d_destination, comboWriter->d_mappedSource, comboWriter->d_ednssubnet, comboWriter->d_uuid, comboWriter->d_requestorId, comboWriter->d_deviceId, comboWriter->d_deviceName, comboWriter->d_meta, comboWriter->d_eventTrace, comboWriter->d_policyTags); } @@ -455,7 +490,7 @@ static void doProcessTCPQuestion(std::unique_ptr& comboWriter, s } // good query } -static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& var) // NOLINT(readability-function-cognitive-complexity) https://github.com/PowerDNS/pdns/issues/12791 +static void handleRunningTCPQuestion(int fileDesc, FDMultiplexer::funcparam_t& var) { auto conn = boost::any_cast>(var); From 7819971141a048d482e97db29a70107d2c56b109 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 30 Aug 2023 12:34:34 +0200 Subject: [PATCH 692/909] Run seperate TCP threads. These threads listen and process incoming TCP queries TODO: test, validate reuseport behaviour, settings, docs --- pdns/recursordist/pdns_recursor.cc | 8 +- pdns/recursordist/rec-main.cc | 188 +++++++++++++++++------------ pdns/recursordist/rec-main.hh | 93 +++++++++++--- 3 files changed, 192 insertions(+), 97 deletions(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index e6ef3bae63c2..d8da4bd7a41b 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -2064,7 +2064,7 @@ void requestWipeCaches(const DNSName& canon) ThreadMSG* tmsg = new ThreadMSG(); // NOLINT: pointer owner tmsg->func = [=] { return pleaseWipeCaches(canon, true, 0xffff); }; tmsg->wantAnswer = false; - if (write(RecThreadInfo::info(0).pipes.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // NOLINT: correct sizeof + if (write(RecThreadInfo::info(0).getPipes().writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // NOLINT: correct sizeof delete tmsg; // NOLINT: pointer owner unixDie("write to thread pipe returned wrong size or error"); @@ -2084,7 +2084,7 @@ bool expectProxyProtocol(const ComboAddress& from) // mappedSource: the address we assume the query is coming from. Differs from source if table based mapping has been applied static string* doProcessUDPQuestion(const std::string& question, const ComboAddress& fromaddr, const ComboAddress& destaddr, ComboAddress source, ComboAddress destination, const ComboAddress& mappedSource, struct timeval tval, int fileDesc, std::vector& proxyProtocolValues, RecEventTrace& eventTrace) // NOLINT(readability-function-cognitive-complexity): https://github.com/PowerDNS/pdns/issues/12791 { - ++(RecThreadInfo::self().numberOfDistributedQueries); + RecThreadInfo::self().incNumberOfDistributedQueries(); gettimeofday(&g_now, nullptr); if (tval.tv_sec != 0) { struct timeval diff = g_now - tval; @@ -2691,7 +2691,7 @@ static bool trySendingQueryToWorker(unsigned int target, ThreadMSG* tmsg) _exit(1); } - const auto& tps = targetInfo.pipes; + const auto& tps = targetInfo.getPipes(); ssize_t written = write(tps.writeQueriesToThread, &tmsg, sizeof(tmsg)); // NOLINT: correct sizeof if (written > 0) { @@ -2714,7 +2714,7 @@ static bool trySendingQueryToWorker(unsigned int target, ThreadMSG* tmsg) static unsigned int getWorkerLoad(size_t workerIdx) { - const auto* multiThreader = RecThreadInfo::info(RecThreadInfo::numHandlers() + RecThreadInfo::numDistributors() + workerIdx).mt; + const auto* multiThreader = RecThreadInfo::info(RecThreadInfo::numHandlers() + RecThreadInfo::numDistributors() + workerIdx).getMT(); if (multiThreader != nullptr) { return multiThreader->numProcesses(); } diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 10469fb44508..5a060f57e94e 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -106,7 +106,8 @@ std::shared_ptr g_slogudpin; std::shared_ptr g_slogudpout; /* without reuseport, all listeners share the same sockets */ -deferredAdd_t g_deferredAdds; +static deferredAdd_t g_deferredAdds; +static deferredAdd_t g_deferredTCPAdds; /* first we have the handler thread, t_id == 0 (some other helper threads like SNMP might have t_id == 0 as well) @@ -120,6 +121,7 @@ thread_local std::unique_ptr t_proxyMapping; bool RecThreadInfo::s_weDistributeQueries; // if true, 1 or more threads listen on the incoming query sockets and distribute them to workers unsigned int RecThreadInfo::s_numDistributorThreads; unsigned int RecThreadInfo::s_numWorkerThreads; +unsigned int RecThreadInfo::s_numTCPWorkerThreads; thread_local unsigned int RecThreadInfo::t_id; static std::map> parseCPUMap(Logr::log_t log) @@ -218,7 +220,6 @@ void RecThreadInfo::start(unsigned int tid, const string& tname, const std::map< int RecThreadInfo::runThreads(Logr::log_t log) { int ret = EXIT_SUCCESS; - unsigned int currentThreadId = 1; const auto cpusMap = parseCPUMap(log); if (RecThreadInfo::numDistributors() + RecThreadInfo::numWorkers() == 1) { @@ -226,72 +227,106 @@ int RecThreadInfo::runThreads(Logr::log_t log) log->info(Logr::Notice, "Operating with single distributor/worker thread")); /* This thread handles the web server, carbon, statistics and the control channel */ - auto& handlerInfo = RecThreadInfo::info(0); + unsigned int currentThreadId = 0; + auto& handlerInfo = RecThreadInfo::info(currentThreadId); handlerInfo.setHandler(); - handlerInfo.start(0, "web+stat", cpusMap, log); - auto& taskInfo = RecThreadInfo::info(2); - taskInfo.setTaskThread(); - taskInfo.start(2, "task", cpusMap, log); + handlerInfo.start(currentThreadId, "web+stat", cpusMap, log); + // We skip the single UDP worker thread 1, it's handled after the loop and taskthreads + currentThreadId = 2; + for (unsigned int thread = 0; thread < RecThreadInfo::numTCPWorkers(); thread++, currentThreadId++) { + auto& info = RecThreadInfo::info(currentThreadId); + info.setListener(); + info.setTCPListener(); + info.setWorker(); + info.start(currentThreadId, "tcpworker", cpusMap, log); + } + + for (unsigned int thread = 0; thread < RecThreadInfo::numTaskThreads(); thread++, currentThreadId++) { + auto& taskInfo = RecThreadInfo::info(currentThreadId); + taskInfo.setTaskThread(); + taskInfo.start(currentThreadId, "task", cpusMap, log); + } + + currentThreadId = 1; auto& info = RecThreadInfo::info(currentThreadId); info.setListener(); + info.setTCPListener(); info.setWorker(); - RecThreadInfo::setThreadId(currentThreadId++); + RecThreadInfo::setThreadId(currentThreadId); recursorThread(); - handlerInfo.thread.join(); - if (handlerInfo.exitCode != 0) { - ret = handlerInfo.exitCode; - } - taskInfo.thread.join(); - if (taskInfo.exitCode != 0) { - ret = taskInfo.exitCode; + for (unsigned int thread = 0; thread < RecThreadInfo::numRecursorThreads(); thread++) { + if (thread == 1) { + continue; + } + auto& tInfo = RecThreadInfo::info(thread); + tInfo.thread.join(); + if (tInfo.exitCode != 0) { + ret = tInfo.exitCode; + } } } else { // Setup RecThreadInfo objects - unsigned int tmp = currentThreadId; + unsigned int currentThreadId = 1; if (RecThreadInfo::weDistributeQueries()) { - for (unsigned int thread = 0; thread < RecThreadInfo::numDistributors(); ++thread) { - RecThreadInfo::info(tmp++).setListener(); + for (unsigned int thread = 0; thread < RecThreadInfo::numDistributors(); thread++, currentThreadId++) { + RecThreadInfo::info(currentThreadId).setListener(); } } - for (unsigned int thread = 0; thread < RecThreadInfo::numWorkers(); ++thread) { - auto& info = RecThreadInfo::info(tmp++); + for (unsigned int thread = 0; thread < RecThreadInfo::numWorkers(); thread++, currentThreadId++) { + auto& info = RecThreadInfo::info(currentThreadId); info.setListener(!RecThreadInfo::weDistributeQueries()); info.setWorker(); } - for (unsigned int thread = 0; thread < RecThreadInfo::numTaskThreads(); ++thread) { - auto& info = RecThreadInfo::info(tmp++); + for (unsigned int thread = 0; thread < RecThreadInfo::numTCPWorkers(); thread++, currentThreadId++) { + auto& info = RecThreadInfo::info(currentThreadId); + info.setListener(); + info.setTCPListener(); + info.setWorker(); + } + for (unsigned int thread = 0; thread < RecThreadInfo::numTaskThreads(); thread++, currentThreadId++) { + auto& info = RecThreadInfo::info(currentThreadId); info.setTaskThread(); } // And now start the actual threads + currentThreadId = 1; if (RecThreadInfo::weDistributeQueries()) { SLOG(g_log << Logger::Warning << "Launching " << RecThreadInfo::numDistributors() << " distributor threads" << endl, log->info(Logr::Notice, "Launching distributor threads", "count", Logging::Loggable(RecThreadInfo::numDistributors()))); - for (unsigned int thread = 0; thread < RecThreadInfo::numDistributors(); ++thread) { + for (unsigned int thread = 0; thread < RecThreadInfo::numDistributors(); thread++, currentThreadId++) { auto& info = RecThreadInfo::info(currentThreadId); - info.start(currentThreadId++, "distr", cpusMap, log); + info.start(currentThreadId, "distr", cpusMap, log); } } SLOG(g_log << Logger::Warning << "Launching " << RecThreadInfo::numWorkers() << " worker threads" << endl, log->info(Logr::Notice, "Launching worker threads", "count", Logging::Loggable(RecThreadInfo::numWorkers()))); - for (unsigned int thread = 0; thread < RecThreadInfo::numWorkers(); ++thread) { + for (unsigned int thread = 0; thread < RecThreadInfo::numWorkers(); thread++, currentThreadId++) { + auto& info = RecThreadInfo::info(currentThreadId); + info.start(currentThreadId, "worker", cpusMap, log); + } + + SLOG(g_log << Logger::Warning << "Launching " << RecThreadInfo::numTCPWorkers() << " tcpworker threads" << endl, + log->info(Logr::Notice, "Launching tcpworker threads", "count", Logging::Loggable(RecThreadInfo::numTCPWorkers()))); + + for (unsigned int thread = 0; thread < RecThreadInfo::numTCPWorkers(); thread++, currentThreadId++) { auto& info = RecThreadInfo::info(currentThreadId); - info.start(currentThreadId++, "worker", cpusMap, log); + info.start(currentThreadId, "tcpworker", cpusMap, log); } - for (unsigned int thread = 0; thread < RecThreadInfo::numTaskThreads(); ++thread) { + for (unsigned int thread = 0; thread < RecThreadInfo::numTaskThreads(); thread++, currentThreadId++) { auto& info = RecThreadInfo::info(currentThreadId); - info.start(currentThreadId++, "task", cpusMap, log); + info.start(currentThreadId, "task", cpusMap, log); } /* This thread handles the web server, carbon, statistics and the control channel */ - auto& info = RecThreadInfo::info(0); + currentThreadId = 0; + auto& info = RecThreadInfo::info(currentThreadId); info.setHandler(); - info.start(0, "web+stat", cpusMap, log); + info.start(currentThreadId, "web+stat", cpusMap, log); for (auto& tInfo : RecThreadInfo::infos()) { tInfo.thread.join(); @@ -1123,8 +1158,8 @@ static void doStats() size_t idx = 0; for (const auto& threadInfo : RecThreadInfo::infos()) { if (threadInfo.isWorker()) { - SLOG(g_log << Logger::Notice << "stats: thread " << idx << " has been distributed " << threadInfo.numberOfDistributedQueries << " queries" << endl, - log->info(Logr::Info, "Queries handled by thread", "thread", Logging::Loggable(idx), "count", Logging::Loggable(threadInfo.numberOfDistributedQueries))); + SLOG(g_log << Logger::Notice << "stats: thread " << idx << " has been distributed " << threadInfo.getNumberOfDistributedQueries() << " queries" << endl, + log->info(Logr::Info, "Queries handled by thread", "thread", Logging::Loggable(idx), "count", Logging::Loggable(threadInfo.getNumberOfDistributedQueries()))); ++idx; } } @@ -1341,7 +1376,7 @@ void broadcastFunction(const pipefunc_t& func) } unsigned int thread = 0; - for (const auto& threadInfo : RecThreadInfo::infos()) { + for (auto& threadInfo : RecThreadInfo::infos()) { if (thread++ == RecThreadInfo::id()) { func(); // don't write to ourselves! continue; @@ -1350,14 +1385,14 @@ void broadcastFunction(const pipefunc_t& func) ThreadMSG* tmsg = new ThreadMSG(); // NOLINT: manual ownership handling tmsg->func = func; tmsg->wantAnswer = true; - if (write(threadInfo.pipes.writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // NOLINT: sizeof correct + if (write(threadInfo.getPipes().writeToThread, &tmsg, sizeof(tmsg)) != sizeof(tmsg)) { // NOLINT: sizeof correct delete tmsg; // NOLINT: manual ownership handling unixDie("write to thread pipe returned wrong size or error"); } string* resp = nullptr; - if (read(threadInfo.pipes.readFromThread, &resp, sizeof(resp)) != sizeof(resp)) { // NOLINT: sizeof correct + if (read(threadInfo.getPipes().readFromThread, &resp, sizeof(resp)) != sizeof(resp)) { // NOLINT: sizeof correct unixDie("read from thread pipe returned wrong size or error"); } @@ -1420,12 +1455,12 @@ T broadcastAccFunction(const std::function& func) unsigned int thread = 0; T ret = T(); - for (const auto& threadInfo : RecThreadInfo::infos()) { + for (auto& threadInfo : RecThreadInfo::infos()) { if (thread++ == RecThreadInfo::id()) { continue; } - const auto& tps = threadInfo.pipes; + const auto& tps = threadInfo.getPipes(); ThreadMSG* tmsg = new ThreadMSG(); // NOLINT: manual ownership handling tmsg->func = [func] { return voider(func); }; tmsg->wantAnswer = true; @@ -1720,50 +1755,45 @@ static void initDistribution(Logr::log_t log) g_reusePort = ::arg().mustDo("reuseport"); #endif - RecThreadInfo::infos().resize(RecThreadInfo::numHandlers() + RecThreadInfo::numDistributors() + RecThreadInfo::numWorkers() + RecThreadInfo::numTaskThreads()); + RecThreadInfo::infos().resize(RecThreadInfo::numRecursorThreads()); if (g_reusePort) { + unsigned int threadNum = 1; if (RecThreadInfo::weDistributeQueries()) { /* first thread is the handler, then distributors */ - for (unsigned int threadId = 1; threadId <= RecThreadInfo::numDistributors(); threadId++) { - auto& info = RecThreadInfo::info(threadId); - auto& deferredAdds = info.deferredAdds; - auto& tcpSockets = info.tcpSockets; + for (unsigned int i = 0; i < RecThreadInfo::numDistributors(); i++, threadNum++) { + auto& info = RecThreadInfo::info(threadNum); + auto& deferredAdds = info.getDeferredAdds(); makeUDPServerSockets(deferredAdds, log); - makeTCPServerSockets(deferredAdds, tcpSockets, log); } } else { /* first thread is the handler, there is no distributor here and workers are accepting queries */ - for (unsigned int threadId = 1; threadId <= RecThreadInfo::numWorkers(); threadId++) { - auto& info = RecThreadInfo::info(threadId); - auto& deferredAdds = info.deferredAdds; - auto& tcpSockets = info.tcpSockets; + for (unsigned int i = 0; i < RecThreadInfo::numWorkers(); i++, threadNum++) { + auto& info = RecThreadInfo::info(threadNum); + auto& deferredAdds = info.getDeferredAdds(); makeUDPServerSockets(deferredAdds, log); - makeTCPServerSockets(deferredAdds, tcpSockets, log); } } + threadNum = 1 + RecThreadInfo::numDistributors() + RecThreadInfo::numWorkers(); + for (unsigned int i = 0; i < RecThreadInfo::numTCPWorkers(); i++, threadNum++) { + auto& info = RecThreadInfo::info(threadNum); + auto& deferredAdds = info.getDeferredAdds(); + auto& tcpSockets = info.getTCPSockets(); + makeTCPServerSockets(deferredAdds, tcpSockets, log); + } } else { std::set tcpSockets; /* we don't have reuseport so we can only open one socket per listening addr:port and everyone will listen on it */ makeUDPServerSockets(g_deferredAdds, log); - makeTCPServerSockets(g_deferredAdds, tcpSockets, log); + makeTCPServerSockets(g_deferredTCPAdds, tcpSockets, log); - /* every listener (so distributor if g_weDistributeQueries, workers otherwise) - needs to listen to the shared sockets */ - if (RecThreadInfo::weDistributeQueries()) { - /* first thread is the handler, then distributors */ - for (unsigned int threadId = 1; threadId <= RecThreadInfo::numDistributors(); threadId++) { - RecThreadInfo::info(threadId).tcpSockets = tcpSockets; - } - } - else { - /* first thread is the handler, there is no distributor here and workers are accepting queries */ - for (unsigned int threadId = 1; threadId <= RecThreadInfo::numWorkers(); threadId++) { - RecThreadInfo::info(threadId).tcpSockets = tcpSockets; - } + // TCP queries are handled by TCP workers + for (unsigned int i = 0; i < RecThreadInfo::numTCPWorkers(); i++) { + auto& info = RecThreadInfo::info(i + 1 + RecThreadInfo::numDistributors() + RecThreadInfo::numWorkers()); + info.setTCPSockets(tcpSockets); } } } @@ -1938,7 +1968,7 @@ static void initSuffixMatchNodes([[maybe_unused]] Logr::log_t log) vector parts; stringtok(parts, ::arg()["dot-to-auth-names"], " ,"); #ifndef HAVE_DNS_OVER_TLS - if (parts.size()) { + if (!parts.empty()) { SLOG(g_log << Logger::Error << "dot-to-auth-names setting contains names, but Recursor was built without DNS over TLS support. Setting will be ignored." << endl, log->info(Logr::Error, "dot-to-auth-names setting contains names, but Recursor was built without DNS over TLS support. Setting will be ignored")); } @@ -2102,6 +2132,12 @@ static int serviceMain(Logr::log_t log) log->info(Logr::Warning, "Asked to run with 0 threads, raising to 1 instead")); RecThreadInfo::setNumWorkerThreads(1); } + RecThreadInfo::setNumTCPWorkerThreads(1); // XXX + if (RecThreadInfo::numTCPWorkers() < 1) { + SLOG(g_log << Logger::Warning << "Asked to run with 0 tcpthreads, raising to 1 instead" << endl, + log->info(Logr::Warning, "Asked to run with 0 tcpthreads, raising to 1 instead")); + RecThreadInfo::setNumTCPWorkerThreads(1); + } g_maxMThreads = ::arg().asNum("max-mthreads"); @@ -2241,7 +2277,7 @@ static void handlePipeRequest(int fileDesc, FDMultiplexer::funcparam_t& /* var * } } if (tmsg->wantAnswer) { - if (write(RecThreadInfo::self().pipes.writeFromThread, &resp, sizeof(resp)) != sizeof(resp)) { + if (write(RecThreadInfo::self().getPipes().writeFromThread, &resp, sizeof(resp)) != sizeof(resp)) { delete tmsg; // NOLINT: manual ownership handling unixDie("write to thread pipe returned wrong size or error"); } @@ -2262,9 +2298,8 @@ static void handleRCC(int fileDesc, FDMultiplexer::funcparam_t& /* var */) SLOG(g_log << Logger::Info << "Received rec_control command '" << msg << "' via controlsocket" << endl, log->info(Logr::Info, "Received rec_control command via control socket", "command", Logging::Loggable(msg))); - RecursorControlParser rcp; RecursorControlParser::func_t* command = nullptr; - auto answer = rcp.getAnswer(clientfd, msg, &command); + auto answer = RecursorControlParser::getAnswer(clientfd, msg, &command); g_rcc.send(clientfd, answer); command(); @@ -2293,7 +2328,6 @@ class PeriodicTask void runIfDue(struct timeval& now, const std::function& function) { if (last_run < now - period) { - // cerr << RecThreadInfo::id() << ' ' << name << ' ' << now.tv_sec << '.' << now.tv_usec << " running" << endl; function(); Utility::gettimeofday(&last_run); now = last_run; @@ -2567,10 +2601,10 @@ static void runLuaMaintenance(RecThreadInfo& threadInfo, time_t& last_lua_mainte static void runTCPMaintenance(RecThreadInfo& threadInfo, bool& listenOnTCP, unsigned int maxTcpClients) { - if (threadInfo.isListener()) { + if (threadInfo.isTCPListener()) { if (listenOnTCP) { if (TCPConnection::getCurrentConnections() > maxTcpClients) { // shutdown, too many connections - for (const auto fileDesc : threadInfo.tcpSockets) { + for (const auto fileDesc : threadInfo.getTCPSockets()) { t_fdm->removeReadFD(fileDesc); } listenOnTCP = false; @@ -2578,7 +2612,7 @@ static void runTCPMaintenance(RecThreadInfo& threadInfo, bool& listenOnTCP, unsi } else { if (TCPConnection::getCurrentConnections() <= maxTcpClients) { // reenable - for (const auto fileDesc : threadInfo.tcpSockets) { + for (const auto fileDesc : threadInfo.getTCPSockets()) { t_fdm->addReadFD(fileDesc, handleNewTCPQuestion); } listenOnTCP = true; @@ -2741,7 +2775,7 @@ static void recursorThread() t_bogusqueryring->set_capacity(ringsize); } g_multiTasker = std::make_unique(::arg().asNum("stack-size"), ::arg().asNum("stack-cache-size")); - threadInfo.mt = g_multiTasker.get(); + threadInfo.setMT(g_multiTasker.get()); /* start protobuf export threads if needed */ auto luaconfsLocal = g_luaconfs.getLocal(); @@ -2756,7 +2790,7 @@ static void recursorThread() std::unique_ptr rws; - t_fdm->addReadFD(threadInfo.pipes.readToThread, handlePipeRequest); + t_fdm->addReadFD(threadInfo.getPipes().readToThread, handlePipeRequest); if (threadInfo.isHandler()) { if (::arg().mustDo("webserver")) { @@ -2775,18 +2809,18 @@ static void recursorThread() log->info(Logr::Info, "Enabled multiplexer", "name", Logging::Loggable(t_fdm->getName()))); } else { - t_fdm->addReadFD(threadInfo.pipes.readQueriesToThread, handlePipeRequest); + t_fdm->addReadFD(threadInfo.getPipes().readQueriesToThread, handlePipeRequest); if (threadInfo.isListener()) { if (g_reusePort) { /* then every listener has its own FDs */ - for (const auto& deferred : threadInfo.deferredAdds) { + for (const auto& deferred : threadInfo.getDeferredAdds()) { t_fdm->addReadFD(deferred.first, deferred.second); } } else { /* otherwise all listeners are listening on the same ones */ - for (const auto& deferred : g_deferredAdds) { + for (const auto& deferred : threadInfo.isTCPListener() ? g_deferredTCPAdds : g_deferredAdds) { t_fdm->addReadFD(deferred.first, deferred.second); } } @@ -3494,10 +3528,10 @@ static string* pleaseUseNewTraceRegex(const std::string& newRegex, int file) } t_traceRegex = std::make_shared(newRegex); t_tracefd = file; - return new string("ok\n"); + return new string("ok\n"); // NOLINT(cppcoreguidelines-owning-memory): it's the API } catch (const PDNSException& ae) { - return new string(ae.reason + "\n"); + return new string(ae.reason + "\n"); // NOLINT(cppcoreguidelines-owning-memory): it's the API } } diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index b048da71a7ff..d254274b33a9 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -279,7 +279,6 @@ extern std::set g_avoidUdpSourcePorts; /* without reuseport, all listeners share the same sockets */ typedef vector>> deferredAdd_t; -extern deferredAdd_t g_deferredAdds; typedef map tcpClientCounts_t; extern thread_local std::unique_ptr t_tcpClientCounts; @@ -346,9 +345,9 @@ public: return s_threadInfos.at(t_id); } - static RecThreadInfo& info(unsigned int i) + static RecThreadInfo& info(unsigned int index) { - return s_threadInfos.at(i); + return s_threadInfos.at(index); } static vector& infos() @@ -356,7 +355,7 @@ public: return s_threadInfos; } - bool isDistributor() const + [[nodiscard]] bool isDistributor() const { if (t_id == 0) { return false; @@ -364,7 +363,7 @@ public: return s_weDistributeQueries && listener; } - bool isHandler() const + [[nodiscard]] bool isHandler() const { if (t_id == 0) { return true; @@ -372,17 +371,21 @@ public: return handler; } - bool isWorker() const + [[nodiscard]] bool isWorker() const { return worker; } - bool isListener() const + [[nodiscard]] bool isListener() const { return listener; } + [[nodiscard]] bool isTCPListener() const + { + return tcplistener; + } - bool isTaskThread() const + [[nodiscard]] bool isTaskThread() const { return taskThread; } @@ -402,6 +405,11 @@ public: listener = flag; } + void setTCPListener(bool flag = true) + { + tcplistener = flag; + } + void setTaskThread() { taskThread = true; @@ -412,12 +420,12 @@ public: return t_id; } - static void setThreadId(unsigned int id) + static void setThreadId(unsigned int arg) { - t_id = id; + t_id = arg; } - std::string getName() const + [[nodiscard]] std::string getName() const { return name; } @@ -437,6 +445,11 @@ public: return s_numWorkerThreads; } + static unsigned int numTCPWorkers() + { + return s_numTCPWorkerThreads; + } + static unsigned int numDistributors() { return s_numDistributorThreads; @@ -457,6 +470,11 @@ public: s_numWorkerThreads = n; } + static void setNumTCPWorkerThreads(unsigned int n) + { + s_numTCPWorkerThreads = n; + } + static void setNumDistributorThreads(unsigned int n) { s_numDistributorThreads = n; @@ -464,17 +482,58 @@ public: static unsigned int numRecursorThreads() { - return numHandlers() + numDistributors() + numWorkers() + numTaskThreads(); + return numHandlers() + numDistributors() + numWorkers() + numTCPWorkers() + numTaskThreads(); } static int runThreads(Logr::log_t); static void makeThreadPipes(Logr::log_t); - void setExitCode(int e) + void setExitCode(int n) { - exitCode = e; + exitCode = n; } + std::set& getTCPSockets() + { + return tcpSockets; + } + + void setTCPSockets(std::set& socks) + { + tcpSockets = socks; + } + + deferredAdd_t& getDeferredAdds() + { + return deferredAdds; + } + + ThreadPipeSet& getPipes() + { + return pipes; + } + + [[nodiscard]] uint64_t getNumberOfDistributedQueries() const + { + return numberOfDistributedQueries; + } + + void incNumberOfDistributedQueries() + { + numberOfDistributedQueries++; + } + + MT_t* getMT() + { + return mt; + } + + void setMT(MT_t* theMT) + { + mt = theMT; + } + +private: // FD corresponding to TCP sockets this thread is listening on. // These FDs are also in deferredAdds when we have one socket per // listener, and in g_deferredAdds instead. @@ -488,8 +547,7 @@ public: MT_t* mt{nullptr}; uint64_t numberOfDistributedQueries{0}; -private: - void start(unsigned int id, const string& name, const std::map>& cpusMap, Logr::log_t); + void start(unsigned int theId, const string& name, const std::map>& cpusMap, Logr::log_t); std::string name; std::thread thread; @@ -499,6 +557,8 @@ private: bool handler{false}; // accept incoming queries (and distributes them to the workers if pdns-distributes-queries is set) bool listener{false}; + // accept incoming TCP queries (and distributes them to the workers if pdns-distributes-queries is set) + bool tcplistener{false}; // process queries bool worker{false}; // run async tasks: from TaskQueue and ZoneToCache @@ -509,6 +569,7 @@ private: static bool s_weDistributeQueries; // if true, 1 or more threads listen on the incoming query sockets and distribute them to workers static unsigned int s_numDistributorThreads; static unsigned int s_numWorkerThreads; + static unsigned int s_numTCPWorkerThreads; }; struct ThreadMSG From 6e7acc51d7abedfc9d406ea79e0e2bbf8db24766 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 30 Aug 2023 14:10:56 +0200 Subject: [PATCH 693/909] In the singkle thread case, TCP is still handled by a separate thread --- pdns/recursordist/rec-main.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 5a060f57e94e..2b0a6eb4a79d 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -251,7 +251,6 @@ int RecThreadInfo::runThreads(Logr::log_t log) currentThreadId = 1; auto& info = RecThreadInfo::info(currentThreadId); info.setListener(); - info.setTCPListener(); info.setWorker(); RecThreadInfo::setThreadId(currentThreadId); recursorThread(); From 9bed6715d5d0b7281c06767898857e7775b98741 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 30 Aug 2023 15:07:44 +0200 Subject: [PATCH 694/909] Also count TCP "distributed" queries and show them in the periodic stats Do note that the rules to increment various counters are a bit divergent if you compare TCP and UDP --- pdns/recursordist/rec-main.cc | 2 +- pdns/recursordist/rec-tcp.cc | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 2b0a6eb4a79d..533a23ddcd70 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1158,7 +1158,7 @@ static void doStats() for (const auto& threadInfo : RecThreadInfo::infos()) { if (threadInfo.isWorker()) { SLOG(g_log << Logger::Notice << "stats: thread " << idx << " has been distributed " << threadInfo.getNumberOfDistributedQueries() << " queries" << endl, - log->info(Logr::Info, "Queries handled by thread", "thread", Logging::Loggable(idx), "count", Logging::Loggable(threadInfo.getNumberOfDistributedQueries()))); + log->info(Logr::Info, "Queries handled by thread", "thread", Logging::Loggable(idx), "tname", Logging::Loggable(threadInfo.getName()), "count", Logging::Loggable(threadInfo.getNumberOfDistributedQueries()))); ++idx; } } diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 313a062bab66..19ea2327f72d 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -282,6 +282,7 @@ static void doProtobufLogQuery(bool logQuery, LocalStateHolder& static void doProcessTCPQuestion(std::unique_ptr& comboWriter, shared_ptr& conn, RunningTCPQuestionGuard& tcpGuard, int fileDesc) { + RecThreadInfo::self().incNumberOfDistributedQueries(); struct timeval start { }; @@ -408,6 +409,9 @@ static void doProcessTCPQuestion(std::unique_ptr& comboWriter, s // We have read a proper query ++t_Counters.at(rec::Counter::qcounter); ++t_Counters.at(rec::Counter::tcpqcounter); + if (comboWriter->d_source.sin4.sin_family == AF_INET6) { + ++t_Counters.at(rec::Counter::ipv6qcounter); + } if (comboWriter->d_mdp.d_header.opcode == static_cast(Opcode::Notify)) { handleNotify(comboWriter, qname); From 6be3251cafac6e963500435f56c57c31dbb85644 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 30 Aug 2023 15:15:30 +0200 Subject: [PATCH 695/909] Include all rec threads for CPU usage stats --- pdns/recursordist/rec_channel_rec.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index b69a96e081cf..2373e5f80269 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -1189,9 +1189,9 @@ static StatsMap toCPUStatsMap(const string& name) { const string pbasename = getPrometheusName(name); StatsMap entries; - // Only distr and worker threads, I think we should revisit this as we now not only have the handler thread but also - // taskThread(s). - for (unsigned int n = 0; n < RecThreadInfo::numDistributors() + RecThreadInfo::numWorkers(); ++n) { + + // Handler is not reported + for (unsigned int n = 0; n < RecThreadInfo::numRecursorThreads() - 1; ++n) { uint64_t tm = doGetThreadCPUMsec(n); std::string pname = pbasename + "{thread=\"" + std::to_string(n) + "\"}"; entries.emplace(name + "-thread-" + std::to_string(n), StatsMapEntry{std::move(pname), std::to_string(tm)}); From 48ec0d7e405224ad0c35a56547b8c052dcc7bf87 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 30 Aug 2023 16:32:55 +0200 Subject: [PATCH 696/909] Tweaks and some docs --- pdns/recursordist/docs/performance.rst | 14 ++++++++++++-- pdns/recursordist/rec-main.cc | 6 +++--- pdns/recursordist/rec-tcp.cc | 4 ++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pdns/recursordist/docs/performance.rst b/pdns/recursordist/docs/performance.rst index 4f5f6e76d15e..2176d7d960fb 100644 --- a/pdns/recursordist/docs/performance.rst +++ b/pdns/recursordist/docs/performance.rst @@ -80,10 +80,14 @@ MTasker and MThreads PowerDNS Recursor uses a cooperative multitasking in userspace called ``MTasker``, based either on ``boost::context`` if available, or on ``System V ucontexts`` otherwise. For maximum performance, please make sure that your system supports ``boost::context``, as the alternative has been known to be quite slower. The maximum number of simultaneous MTasker threads, called ``MThreads``, can be tuned via :ref:`setting-max-mthreads`, as the default value of 2048 might not be enough for large-scale installations. +This number limits the number of mthreads *per physical (Posix) thread*. +The threads that create mthreads are the distributor and worker threads. When a ``MThread`` is started, a new stack is dynamically allocated for it on the heap. The size of that stack can be configured via the :ref:`setting-stack-size` parameter, whose default value is 200 kB which should be enough in most cases. -To reduce the cost of allocating a new stack for every query, the recursor can cache a small amount of stacks to make sure that the allocation stays cheap. This can be configured via the :ref:`setting-stack-cache-size` setting. The only trade-off of enabling this cache is a slightly increased memory consumption, at worst equals to the number of stacks specified by :ref:`setting-stack-cache-size` multiplied by the size of one stack, itself specified via :ref:`setting-stack-size`. +To reduce the cost of allocating a new stack for every query, the recursor can cache a small amount of stacks to make sure that the allocation stays cheap. This can be configured via the :ref:`setting-stack-cache-size` setting. +This limit is per physcial (Posix) thread. +The only trade-off of enabling this cache is a slightly increased memory consumption, at worst equals to the number of stacks specified by :ref:`setting-stack-cache-size` multiplied by the size of one stack, itself specified via :ref:`setting-stack-size`. Performance tips ---------------- @@ -177,8 +181,13 @@ Each of the queries processed will consume an mthread until processing is done. A response to a query is sent immediately when it becomes available; the response can be sent before other responses to queries that were received earlier by the Recursor. This is the Out-of-Order feature which greatly enhances performance, as a single slow query does not prevent other queries to be processed. +Before version 5.0.0, TCP queries are processed by either the distributer thread(s) if :ref:`setting-pdns-distributes-queries` is true, or by worker threads if :ref:`setting-pdns-distributes-queries` is false. +Starting with version 5.0.0, :program:`Recursor` has dedicated thread(s) processing TCP queries. + The maximum number of mthreads consumed by TCP queries is :ref:`setting-max-tcp-clients` times :ref:`setting-max-concurrent-requests-per-tcp-connection`. -This number should be (much) lower than :ref:`setting-max-mthreads`, to also allow UDP queries to be handled as these also consume mthreads. +If :ref:`setting-pdns-distributes-queries` is true, this number should be (much) lower than :ref:`setting-max-mthreads`, to also allow UDP queries to be handled as these also consume mthrea ds. +Note that :ref:`setting-max-mthreads` is a per Posix thread setting. +This means that the global maximum number of mthreads is (#distributor threads + #worker threads) * max-mthreads. If you expect few clients, you can increase :ref:`setting-max-concurrent-requests-per-tcp-connection`, to allow more concurrency per TCP connection. If you expect many clients and you have increased :ref:`setting-max-tcp-clients`, reduce :ref:`setting-max-concurrent-requests-per-tcp-connection` number to prevent mthread starvation or increase the maximum number of mthreads. @@ -188,6 +197,7 @@ To see the current number of mthreads in use consult the :ref:`stat-concurrent-q If a query could not be handled due to mthread shortage, the :ref:`stat-over-capacity-drops` metric is increased. As an example, if you have typically 200 TCP clients, and the default maximum number of mthreads of 2048, a good number of concurrent requests per TCP connection would be 5. Assuming a worst case packet cache hit ratio, if all 200 TCP clients fill their connections with queries, about half (5 * 200) of the mthreads would be used by incoming TCP queries, leaving the other half for incoming UDP queries. +Note that starting with versino 5.0.0, TCP queries are processed by dedicated TCP thread(s), so the sharing of mthreads between UDP and TCP queries no longer applies. The total number of incoming TCP connections is limited by :ref:`setting-max-tcp-clients`. There is also a per client address limit: :ref:`setting-max-tcp-per-client` to limit the impact of a single client. diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 533a23ddcd70..59ab27e7ed67 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -910,8 +910,8 @@ static void checkLinuxIPv6Limits([[maybe_unused]] Logr::log_t log) static void checkOrFixFDS(Logr::log_t log) { unsigned int availFDs = getFilenumLimit(); - unsigned int wantFDs = g_maxMThreads * RecThreadInfo::numWorkers() + 25; // even healthier margin then before - wantFDs += RecThreadInfo::numWorkers() * TCPOutConnectionManager::s_maxIdlePerThread; + unsigned int wantFDs = g_maxMThreads * (RecThreadInfo::numWorkers() + RecThreadInfo::numTCPWorkers()) + 25; // even healthier margin than before + wantFDs += (RecThreadInfo::numWorkers() + RecThreadInfo::numTCPWorkers()) * TCPOutConnectionManager::s_maxIdlePerThread; if (wantFDs > availFDs) { unsigned int hardlimit = getFilenumLimit(true); @@ -921,7 +921,7 @@ static void checkOrFixFDS(Logr::log_t log) log->info(Logr::Warning, "Raised soft limit on number of filedescriptors to match max-mthreads and threads settings", "limit", Logging::Loggable(wantFDs))); } else { - auto newval = (hardlimit - 25 - TCPOutConnectionManager::s_maxIdlePerThread) / RecThreadInfo::numWorkers(); + auto newval = (hardlimit - 25 - TCPOutConnectionManager::s_maxIdlePerThread) / (RecThreadInfo::numWorkers() + RecThreadInfo::numTCPWorkers()); SLOG(g_log << Logger::Warning << "Insufficient number of filedescriptors available for max-mthreads*threads setting! (" << hardlimit << " < " << wantFDs << "), reducing max-mthreads to " << newval << endl, log->info(Logr::Warning, "Insufficient number of filedescriptors available for max-mthreads*threads setting! Reducing max-mthreads", "hardlimit", Logging::Loggable(hardlimit), "want", Logging::Loggable(wantFDs), "max-mthreads", Logging::Loggable(newval))); g_maxMThreads = newval; diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 19ea2327f72d..3e0cb05a263a 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -52,6 +52,10 @@ // // The drawback mentioned in https://github.com/PowerDNS/pdns/issues/8394 are not longer true, so an // alternative approach would be to introduce dedicated TCP worker thread(s). +// +// And this approach was implemented in https://github.com/PowerDNS/pdns/pull/13195. The distributor +// and worker thread(s) now no longe process TCP queries. + size_t g_tcpMaxQueriesPerConn; unsigned int g_maxTCPPerClient; From 84b183ca172a139b68abd570f4590654f7e06c7b Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 31 Aug 2023 20:26:21 +0200 Subject: [PATCH 697/909] Apply spelling fixes Co-authored-by: Remi Gacogne --- pdns/recursordist/docs/performance.rst | 8 ++++---- pdns/recursordist/rec-tcp.cc | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/pdns/recursordist/docs/performance.rst b/pdns/recursordist/docs/performance.rst index 2176d7d960fb..9acb87fe65ec 100644 --- a/pdns/recursordist/docs/performance.rst +++ b/pdns/recursordist/docs/performance.rst @@ -80,13 +80,13 @@ MTasker and MThreads PowerDNS Recursor uses a cooperative multitasking in userspace called ``MTasker``, based either on ``boost::context`` if available, or on ``System V ucontexts`` otherwise. For maximum performance, please make sure that your system supports ``boost::context``, as the alternative has been known to be quite slower. The maximum number of simultaneous MTasker threads, called ``MThreads``, can be tuned via :ref:`setting-max-mthreads`, as the default value of 2048 might not be enough for large-scale installations. -This number limits the number of mthreads *per physical (Posix) thread*. +This setting limits the number of mthreads *per physical (Posix) thread*. The threads that create mthreads are the distributor and worker threads. When a ``MThread`` is started, a new stack is dynamically allocated for it on the heap. The size of that stack can be configured via the :ref:`setting-stack-size` parameter, whose default value is 200 kB which should be enough in most cases. To reduce the cost of allocating a new stack for every query, the recursor can cache a small amount of stacks to make sure that the allocation stays cheap. This can be configured via the :ref:`setting-stack-cache-size` setting. -This limit is per physcial (Posix) thread. +This limit is per physical (Posix) thread. The only trade-off of enabling this cache is a slightly increased memory consumption, at worst equals to the number of stacks specified by :ref:`setting-stack-cache-size` multiplied by the size of one stack, itself specified via :ref:`setting-stack-size`. Performance tips @@ -185,7 +185,7 @@ Before version 5.0.0, TCP queries are processed by either the distributer thread Starting with version 5.0.0, :program:`Recursor` has dedicated thread(s) processing TCP queries. The maximum number of mthreads consumed by TCP queries is :ref:`setting-max-tcp-clients` times :ref:`setting-max-concurrent-requests-per-tcp-connection`. -If :ref:`setting-pdns-distributes-queries` is true, this number should be (much) lower than :ref:`setting-max-mthreads`, to also allow UDP queries to be handled as these also consume mthrea ds. +If :ref:`setting-pdns-distributes-queries` is true, this number should be (much) lower than :ref:`setting-max-mthreads`, to also allow UDP queries to be handled as these also consume mthreads. Note that :ref:`setting-max-mthreads` is a per Posix thread setting. This means that the global maximum number of mthreads is (#distributor threads + #worker threads) * max-mthreads. @@ -197,7 +197,7 @@ To see the current number of mthreads in use consult the :ref:`stat-concurrent-q If a query could not be handled due to mthread shortage, the :ref:`stat-over-capacity-drops` metric is increased. As an example, if you have typically 200 TCP clients, and the default maximum number of mthreads of 2048, a good number of concurrent requests per TCP connection would be 5. Assuming a worst case packet cache hit ratio, if all 200 TCP clients fill their connections with queries, about half (5 * 200) of the mthreads would be used by incoming TCP queries, leaving the other half for incoming UDP queries. -Note that starting with versino 5.0.0, TCP queries are processed by dedicated TCP thread(s), so the sharing of mthreads between UDP and TCP queries no longer applies. +Note that starting with version 5.0.0, TCP queries are processed by dedicated TCP thread(s), so the sharing of mthreads between UDP and TCP queries no longer applies. The total number of incoming TCP connections is limited by :ref:`setting-max-tcp-clients`. There is also a per client address limit: :ref:`setting-max-tcp-per-client` to limit the impact of a single client. diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index 3e0cb05a263a..e8b9da98c379 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -27,7 +27,7 @@ #include "mplexer.hh" #include "uuid-utils.hh" -// When pdns_distributes query is false with reuseport true (the default since 4.9.0), TCP queries +// When pdns-distributes-queries is false with reuseport true (the default since 4.9.0), TCP queries // are read and handled by worker threads. If the kernel balancing is OK for TCP sockets (observed // to be good on Debian bullseye, but not good on e.g. MacOS), the TCP handling is no extra burden. // In the case of MacOS all incoming TCP queries are handled by a single worker, while incoming UDP @@ -47,7 +47,7 @@ // queries), but the TCP socket must also be passed to a worker thread so it can write its // answer. The in-flight bookkeeping also has to be aware of how a query is handled to do the // accounting properly. I am not sure if changing the current setup is worth all this trouble, -// especilly since the default is now to not use pdns-distributes-queries, which works well in many +// especially since the default is now to not use pdns-distributes-queries, which works well in many // cases. // // The drawback mentioned in https://github.com/PowerDNS/pdns/issues/8394 are not longer true, so an From a808ca6966fbb1ff028409dbe451769118056b9b Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 1 Sep 2023 09:03:40 +0200 Subject: [PATCH 698/909] Adopt code change suggestions from @rgacogne's review --- pdns/recursordist/pdns_recursor.cc | 16 +++++----- pdns/recursordist/rec-main.cc | 48 ++++++++++++++---------------- pdns/recursordist/rec-main.hh | 20 ++++++++----- pdns/recursordist/rec-tcp.cc | 1 - 4 files changed, 43 insertions(+), 42 deletions(-) diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index d8da4bd7a41b..3eafd3f69c2d 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -2723,27 +2723,27 @@ static unsigned int getWorkerLoad(size_t workerIdx) static unsigned int selectWorker(unsigned int hash) { - assert(RecThreadInfo::numWorkers() != 0); // NOLINT: assert implementation + assert(RecThreadInfo::numUDPWorkers() != 0); // NOLINT: assert implementation if (g_balancingFactor == 0) { - return RecThreadInfo::numHandlers() + RecThreadInfo::numDistributors() + (hash % RecThreadInfo::numWorkers()); + return RecThreadInfo::numHandlers() + RecThreadInfo::numDistributors() + (hash % RecThreadInfo::numUDPWorkers()); } /* we start with one, representing the query we are currently handling */ double currentLoad = 1; - std::vector load(RecThreadInfo::numWorkers()); - for (size_t idx = 0; idx < RecThreadInfo::numWorkers(); idx++) { + std::vector load(RecThreadInfo::numUDPWorkers()); + for (size_t idx = 0; idx < RecThreadInfo::numUDPWorkers(); idx++) { load[idx] = getWorkerLoad(idx); currentLoad += load[idx]; } - double targetLoad = (currentLoad / RecThreadInfo::numWorkers()) * g_balancingFactor; + double targetLoad = (currentLoad / RecThreadInfo::numUDPWorkers()) * g_balancingFactor; - unsigned int worker = hash % RecThreadInfo::numWorkers(); + unsigned int worker = hash % RecThreadInfo::numUDPWorkers(); /* at least one server has to be at or below the average load */ if (load[worker] > targetLoad) { ++t_Counters.at(rec::Counter::rebalancedQueries); do { - worker = (worker + 1) % RecThreadInfo::numWorkers(); + worker = (worker + 1) % RecThreadInfo::numUDPWorkers(); } while (load[worker] > targetLoad); } @@ -2777,7 +2777,7 @@ void distributeAsyncFunction(const string& packet, const pipefunc_t& func) was full, let's try another one */ unsigned int newTarget = 0; do { - newTarget = RecThreadInfo::numHandlers() + RecThreadInfo::numDistributors() + dns_random(RecThreadInfo::numWorkers()); + newTarget = RecThreadInfo::numHandlers() + RecThreadInfo::numDistributors() + dns_random(RecThreadInfo::numUDPWorkers()); } while (newTarget == target); if (!trySendingQueryToWorker(newTarget, tmsg)) { diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 59ab27e7ed67..997882f9cb80 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -106,8 +106,8 @@ std::shared_ptr g_slogudpin; std::shared_ptr g_slogudpout; /* without reuseport, all listeners share the same sockets */ -static deferredAdd_t g_deferredAdds; -static deferredAdd_t g_deferredTCPAdds; +static deferredAdd_t s_deferredUDPadds; +static deferredAdd_t s_deferredTCPadds; /* first we have the handler thread, t_id == 0 (some other helper threads like SNMP might have t_id == 0 as well) @@ -120,7 +120,7 @@ thread_local std::unique_ptr t_proxyMapping; bool RecThreadInfo::s_weDistributeQueries; // if true, 1 or more threads listen on the incoming query sockets and distribute them to workers unsigned int RecThreadInfo::s_numDistributorThreads; -unsigned int RecThreadInfo::s_numWorkerThreads; +unsigned int RecThreadInfo::s_numUDPWorkerThreads; unsigned int RecThreadInfo::s_numTCPWorkerThreads; thread_local unsigned int RecThreadInfo::t_id; @@ -222,7 +222,7 @@ int RecThreadInfo::runThreads(Logr::log_t log) int ret = EXIT_SUCCESS; const auto cpusMap = parseCPUMap(log); - if (RecThreadInfo::numDistributors() + RecThreadInfo::numWorkers() == 1) { + if (RecThreadInfo::numDistributors() + RecThreadInfo::numUDPWorkers() == 1) { SLOG(g_log << Logger::Warning << "Operating with single distributor/worker thread" << endl, log->info(Logr::Notice, "Operating with single distributor/worker thread")); @@ -236,7 +236,6 @@ int RecThreadInfo::runThreads(Logr::log_t log) currentThreadId = 2; for (unsigned int thread = 0; thread < RecThreadInfo::numTCPWorkers(); thread++, currentThreadId++) { auto& info = RecThreadInfo::info(currentThreadId); - info.setListener(); info.setTCPListener(); info.setWorker(); info.start(currentThreadId, "tcpworker", cpusMap, log); @@ -274,14 +273,13 @@ int RecThreadInfo::runThreads(Logr::log_t log) RecThreadInfo::info(currentThreadId).setListener(); } } - for (unsigned int thread = 0; thread < RecThreadInfo::numWorkers(); thread++, currentThreadId++) { + for (unsigned int thread = 0; thread < RecThreadInfo::numUDPWorkers(); thread++, currentThreadId++) { auto& info = RecThreadInfo::info(currentThreadId); info.setListener(!RecThreadInfo::weDistributeQueries()); info.setWorker(); } for (unsigned int thread = 0; thread < RecThreadInfo::numTCPWorkers(); thread++, currentThreadId++) { auto& info = RecThreadInfo::info(currentThreadId); - info.setListener(); info.setTCPListener(); info.setWorker(); } @@ -300,10 +298,10 @@ int RecThreadInfo::runThreads(Logr::log_t log) info.start(currentThreadId, "distr", cpusMap, log); } } - SLOG(g_log << Logger::Warning << "Launching " << RecThreadInfo::numWorkers() << " worker threads" << endl, - log->info(Logr::Notice, "Launching worker threads", "count", Logging::Loggable(RecThreadInfo::numWorkers()))); + SLOG(g_log << Logger::Warning << "Launching " << RecThreadInfo::numUDPWorkers() << " worker threads" << endl, + log->info(Logr::Notice, "Launching worker threads", "count", Logging::Loggable(RecThreadInfo::numUDPWorkers()))); - for (unsigned int thread = 0; thread < RecThreadInfo::numWorkers(); thread++, currentThreadId++) { + for (unsigned int thread = 0; thread < RecThreadInfo::numUDPWorkers(); thread++, currentThreadId++) { auto& info = RecThreadInfo::info(currentThreadId); info.start(currentThreadId, "worker", cpusMap, log); } @@ -910,8 +908,8 @@ static void checkLinuxIPv6Limits([[maybe_unused]] Logr::log_t log) static void checkOrFixFDS(Logr::log_t log) { unsigned int availFDs = getFilenumLimit(); - unsigned int wantFDs = g_maxMThreads * (RecThreadInfo::numWorkers() + RecThreadInfo::numTCPWorkers()) + 25; // even healthier margin than before - wantFDs += (RecThreadInfo::numWorkers() + RecThreadInfo::numTCPWorkers()) * TCPOutConnectionManager::s_maxIdlePerThread; + unsigned int wantFDs = g_maxMThreads * (RecThreadInfo::numUDPWorkers() + RecThreadInfo::numTCPWorkers()) + 25; // even healthier margin than before + wantFDs += (RecThreadInfo::numUDPWorkers() + RecThreadInfo::numTCPWorkers()) * TCPOutConnectionManager::s_maxIdlePerThread; if (wantFDs > availFDs) { unsigned int hardlimit = getFilenumLimit(true); @@ -921,7 +919,7 @@ static void checkOrFixFDS(Logr::log_t log) log->info(Logr::Warning, "Raised soft limit on number of filedescriptors to match max-mthreads and threads settings", "limit", Logging::Loggable(wantFDs))); } else { - auto newval = (hardlimit - 25 - TCPOutConnectionManager::s_maxIdlePerThread) / (RecThreadInfo::numWorkers() + RecThreadInfo::numTCPWorkers()); + auto newval = (hardlimit - 25 - TCPOutConnectionManager::s_maxIdlePerThread) / (RecThreadInfo::numUDPWorkers() + RecThreadInfo::numTCPWorkers()); SLOG(g_log << Logger::Warning << "Insufficient number of filedescriptors available for max-mthreads*threads setting! (" << hardlimit << " < " << wantFDs << "), reducing max-mthreads to " << newval << endl, log->info(Logr::Warning, "Insufficient number of filedescriptors available for max-mthreads*threads setting! Reducing max-mthreads", "hardlimit", Logging::Loggable(hardlimit), "want", Logging::Loggable(wantFDs), "max-mthreads", Logging::Loggable(newval))); g_maxMThreads = newval; @@ -1375,7 +1373,7 @@ void broadcastFunction(const pipefunc_t& func) } unsigned int thread = 0; - for (auto& threadInfo : RecThreadInfo::infos()) { + for (const auto& threadInfo : RecThreadInfo::infos()) { if (thread++ == RecThreadInfo::id()) { func(); // don't write to ourselves! continue; @@ -1454,7 +1452,7 @@ T broadcastAccFunction(const std::function& func) unsigned int thread = 0; T ret = T(); - for (auto& threadInfo : RecThreadInfo::infos()) { + for (const auto& threadInfo : RecThreadInfo::infos()) { if (thread++ == RecThreadInfo::id()) { continue; } @@ -1768,13 +1766,13 @@ static void initDistribution(Logr::log_t log) } else { /* first thread is the handler, there is no distributor here and workers are accepting queries */ - for (unsigned int i = 0; i < RecThreadInfo::numWorkers(); i++, threadNum++) { + for (unsigned int i = 0; i < RecThreadInfo::numUDPWorkers(); i++, threadNum++) { auto& info = RecThreadInfo::info(threadNum); auto& deferredAdds = info.getDeferredAdds(); makeUDPServerSockets(deferredAdds, log); } } - threadNum = 1 + RecThreadInfo::numDistributors() + RecThreadInfo::numWorkers(); + threadNum = 1 + RecThreadInfo::numDistributors() + RecThreadInfo::numUDPWorkers(); for (unsigned int i = 0; i < RecThreadInfo::numTCPWorkers(); i++, threadNum++) { auto& info = RecThreadInfo::info(threadNum); auto& deferredAdds = info.getDeferredAdds(); @@ -1786,12 +1784,12 @@ static void initDistribution(Logr::log_t log) std::set tcpSockets; /* we don't have reuseport so we can only open one socket per listening addr:port and everyone will listen on it */ - makeUDPServerSockets(g_deferredAdds, log); - makeTCPServerSockets(g_deferredTCPAdds, tcpSockets, log); + makeUDPServerSockets(s_deferredUDPadds, log); + makeTCPServerSockets(s_deferredTCPadds, tcpSockets, log); // TCP queries are handled by TCP workers for (unsigned int i = 0; i < RecThreadInfo::numTCPWorkers(); i++) { - auto& info = RecThreadInfo::info(i + 1 + RecThreadInfo::numDistributors() + RecThreadInfo::numWorkers()); + auto& info = RecThreadInfo::info(i + 1 + RecThreadInfo::numDistributors() + RecThreadInfo::numUDPWorkers()); info.setTCPSockets(tcpSockets); } } @@ -2125,11 +2123,11 @@ static int serviceMain(Logr::log_t log) g_paddingOutgoing = ::arg().mustDo("edns-padding-out"); RecThreadInfo::setNumDistributorThreads(::arg().asNum("distributor-threads")); - RecThreadInfo::setNumWorkerThreads(::arg().asNum("threads")); - if (RecThreadInfo::numWorkers() < 1) { + RecThreadInfo::setNumUDPWorkerThreads(::arg().asNum("threads")); + if (RecThreadInfo::numUDPWorkers() < 1) { SLOG(g_log << Logger::Warning << "Asked to run with 0 threads, raising to 1 instead" << endl, log->info(Logr::Warning, "Asked to run with 0 threads, raising to 1 instead")); - RecThreadInfo::setNumWorkerThreads(1); + RecThreadInfo::setNumUDPWorkerThreads(1); } RecThreadInfo::setNumTCPWorkerThreads(1); // XXX if (RecThreadInfo::numTCPWorkers() < 1) { @@ -2748,7 +2746,7 @@ static void recursorThread() } } - unsigned int ringsize = ::arg().asNum("stats-ringbuffer-entries") / RecThreadInfo::numWorkers(); + unsigned int ringsize = ::arg().asNum("stats-ringbuffer-entries") / RecThreadInfo::numUDPWorkers(); if (ringsize != 0) { t_remotes = std::make_unique(); if (RecThreadInfo::weDistributeQueries()) { @@ -2819,7 +2817,7 @@ static void recursorThread() } else { /* otherwise all listeners are listening on the same ones */ - for (const auto& deferred : threadInfo.isTCPListener() ? g_deferredTCPAdds : g_deferredAdds) { + for (const auto& deferred : threadInfo.isTCPListener() ? s_deferredTCPadds : s_deferredUDPadds) { t_fdm->addReadFD(deferred.first, deferred.second); } } diff --git a/pdns/recursordist/rec-main.hh b/pdns/recursordist/rec-main.hh index d254274b33a9..daeb0dc77f4d 100644 --- a/pdns/recursordist/rec-main.hh +++ b/pdns/recursordist/rec-main.hh @@ -376,10 +376,13 @@ public: return worker; } + // UDP or TCP listener? [[nodiscard]] bool isListener() const { return listener; } + + // A TCP-only listener? [[nodiscard]] bool isTCPListener() const { return tcplistener; @@ -407,6 +410,7 @@ public: void setTCPListener(bool flag = true) { + setListener(flag); tcplistener = flag; } @@ -440,9 +444,9 @@ public: return 1; } - static unsigned int numWorkers() + static unsigned int numUDPWorkers() { - return s_numWorkerThreads; + return s_numUDPWorkerThreads; } static unsigned int numTCPWorkers() @@ -465,9 +469,9 @@ public: s_weDistributeQueries = flag; } - static void setNumWorkerThreads(unsigned int n) + static void setNumUDPWorkerThreads(unsigned int n) { - s_numWorkerThreads = n; + s_numUDPWorkerThreads = n; } static void setNumTCPWorkerThreads(unsigned int n) @@ -482,7 +486,7 @@ public: static unsigned int numRecursorThreads() { - return numHandlers() + numDistributors() + numWorkers() + numTCPWorkers() + numTaskThreads(); + return numHandlers() + numDistributors() + numUDPWorkers() + numTCPWorkers() + numTaskThreads(); } static int runThreads(Logr::log_t); @@ -508,7 +512,7 @@ public: return deferredAdds; } - ThreadPipeSet& getPipes() + const ThreadPipeSet& getPipes() const { return pipes; } @@ -547,7 +551,7 @@ private: MT_t* mt{nullptr}; uint64_t numberOfDistributedQueries{0}; - void start(unsigned int theId, const string& name, const std::map>& cpusMap, Logr::log_t); + void start(unsigned int tid, const string& tname, const std::map>& cpusMap, Logr::log_t); std::string name; std::thread thread; @@ -568,7 +572,7 @@ private: static std::vector s_threadInfos; static bool s_weDistributeQueries; // if true, 1 or more threads listen on the incoming query sockets and distribute them to workers static unsigned int s_numDistributorThreads; - static unsigned int s_numWorkerThreads; + static unsigned int s_numUDPWorkerThreads; static unsigned int s_numTCPWorkerThreads; }; diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index e8b9da98c379..a5a921cd49a3 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -56,7 +56,6 @@ // And this approach was implemented in https://github.com/PowerDNS/pdns/pull/13195. The distributor // and worker thread(s) now no longe process TCP queries. - size_t g_tcpMaxQueriesPerConn; unsigned int g_maxTCPPerClient; int g_tcpTimeout; From 49edd025edc7ff3ac2db7caa37f48d66e4166940 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 1 Sep 2023 09:06:13 +0200 Subject: [PATCH 699/909] Only init Lua for workers (both UDP and TCP) Now that distributor threads do no longer process (TCP) queries, no need to have Lua inited for those --- pdns/recursordist/rec-main.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 997882f9cb80..0d863ff354d7 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2575,8 +2575,7 @@ static void runLuaMaintenance(RecThreadInfo& threadInfo, time_t& last_lua_mainte { if (t_pdl != nullptr) { // lua-dns-script directive is present, call the maintenance callback if needed - /* remember that the listener threads handle TCP queries */ - if (threadInfo.isWorker() || threadInfo.isListener()) { + if (threadInfo.isWorker()) { // either UDP of TCP worker // Only on threads processing queries if (g_now.tv_sec - last_lua_maintenance >= luaMaintenanceInterval) { struct timeval start From 77fbf36dc972850ae2775943b336e7099bff1259 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 1 Sep 2023 09:12:47 +0200 Subject: [PATCH 700/909] Before this PR, if pdns-distributes-queries is *false* worker threads process both UDP and TCP queries --- pdns/recursordist/docs/performance.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/docs/performance.rst b/pdns/recursordist/docs/performance.rst index 9acb87fe65ec..b5163b6645f4 100644 --- a/pdns/recursordist/docs/performance.rst +++ b/pdns/recursordist/docs/performance.rst @@ -185,7 +185,7 @@ Before version 5.0.0, TCP queries are processed by either the distributer thread Starting with version 5.0.0, :program:`Recursor` has dedicated thread(s) processing TCP queries. The maximum number of mthreads consumed by TCP queries is :ref:`setting-max-tcp-clients` times :ref:`setting-max-concurrent-requests-per-tcp-connection`. -If :ref:`setting-pdns-distributes-queries` is true, this number should be (much) lower than :ref:`setting-max-mthreads`, to also allow UDP queries to be handled as these also consume mthreads. +Before version 5.0.0, if :ref:`setting-pdns-distributes-queries` is false, this number should be (much) lower than :ref:`setting-max-mthreads`, to also allow UDP queries to be handled as these also consume mthreads. Note that :ref:`setting-max-mthreads` is a per Posix thread setting. This means that the global maximum number of mthreads is (#distributor threads + #worker threads) * max-mthreads. From d11a5834732bec009da07daf0f6bcef33db12c15 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 13 Sep 2023 13:47:40 +0200 Subject: [PATCH 701/909] Introduce setting recursor.tcp_threads. While working on this, I noticed that after changing table.py the new lib.rs is generated, but the Serde derives to not seem to get triggered until afert I do a make clean. To be investigated. --- pdns/recursordist/docs/settings.rst | 12 ++++++++++++ pdns/recursordist/docs/yamlsettings.rst | 12 ++++++++++++ pdns/recursordist/rec-main.cc | 6 +++--- pdns/recursordist/settings/table.py | 10 ++++++++++ 4 files changed, 37 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 23682e1a01f8..a6cda8236aba 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -2744,6 +2744,18 @@ Maximum number of idle outgoing TCP/DoT connections per thread, 0 means do not k Spawn this number of threads on startup. +.. _setting-tcp-threads: + +``tcp-threads`` +~~~~~~~~~~~~~~~ + +- Integer +- Default: 1 + +- YAML setting: :ref:`setting-yaml-recursor.tcp_threads` + +Spawn this number of TCP processing threads on startup. + .. _setting-trace: ``trace`` diff --git a/pdns/recursordist/docs/yamlsettings.rst b/pdns/recursordist/docs/yamlsettings.rst index ccaa639cc3dc..895dbf0040a4 100644 --- a/pdns/recursordist/docs/yamlsettings.rst +++ b/pdns/recursordist/docs/yamlsettings.rst @@ -2955,6 +2955,18 @@ Can be read out using ``rec_control top-remotes``. A sequence of statistic names, that are prevented from being exported via SNMP, for performance reasons. +.. _setting-yaml-recursor.tcp_threads: + +``recursor.tcp_threads`` +^^^^^^^^^^^^^^^^^^^^^^^^ + +- Integer +- Default: ``1`` + +- Old style setting: :ref:`setting-tcp-threads` + +Spawn this number of TCP processing threads on startup. + .. _setting-yaml-recursor.threads: ``recursor.threads`` diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 0d863ff354d7..dc192506f5e7 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2129,10 +2129,10 @@ static int serviceMain(Logr::log_t log) log->info(Logr::Warning, "Asked to run with 0 threads, raising to 1 instead")); RecThreadInfo::setNumUDPWorkerThreads(1); } - RecThreadInfo::setNumTCPWorkerThreads(1); // XXX + RecThreadInfo::setNumTCPWorkerThreads(::arg().asNum("tcp-threads")); if (RecThreadInfo::numTCPWorkers() < 1) { - SLOG(g_log << Logger::Warning << "Asked to run with 0 tcpthreads, raising to 1 instead" << endl, - log->info(Logr::Warning, "Asked to run with 0 tcpthreads, raising to 1 instead")); + SLOG(g_log << Logger::Warning << "Asked to run with 0 TCP threads, raising to 1 instead" << endl, + log->info(Logr::Warning, "Asked to run with 0 TCP threads, raising to 1 instead")); RecThreadInfo::setNumTCPWorkerThreads(1); } diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index e57ea13940b1..d2b8a903aaaa 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -2583,6 +2583,16 @@ 'help' : 'Launch this number of threads', 'doc' : ''' Spawn this number of threads on startup. + ''', + }, + { + 'name' : 'tcp_threads', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '1', + 'help' : 'Launch this number of threads listening for and processing TCP queries', + 'doc' : ''' +Spawn this number of TCP processing threads on startup. ''', }, { From 0117d33345a668e940e4510c32fbe36f1197d942 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 13 Sep 2023 13:53:08 +0200 Subject: [PATCH 702/909] Add 'versionadded' --- pdns/recursordist/docs/settings.rst | 1 + pdns/recursordist/docs/yamlsettings.rst | 1 + pdns/recursordist/settings/table.py | 1 + 3 files changed, 3 insertions(+) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index a6cda8236aba..c8be1e6aa1c2 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -2748,6 +2748,7 @@ Spawn this number of threads on startup. ``tcp-threads`` ~~~~~~~~~~~~~~~ +.. versionadded:: 5.0.0 - Integer - Default: 1 diff --git a/pdns/recursordist/docs/yamlsettings.rst b/pdns/recursordist/docs/yamlsettings.rst index 895dbf0040a4..a2ef41882081 100644 --- a/pdns/recursordist/docs/yamlsettings.rst +++ b/pdns/recursordist/docs/yamlsettings.rst @@ -2959,6 +2959,7 @@ A sequence of statistic names, that are prevented from being exported via SNMP, ``recursor.tcp_threads`` ^^^^^^^^^^^^^^^^^^^^^^^^ +.. versionadded:: 5.0.0 - Integer - Default: ``1`` diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index d2b8a903aaaa..9fedfa37a389 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -2594,6 +2594,7 @@ 'doc' : ''' Spawn this number of TCP processing threads on startup. ''', + 'versionadded': '5.0.0' }, { 'name' : 'trace', From dd922c2168062b54c43de97f8889551d7fa6b3d9 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 13 Sep 2023 14:20:15 +0200 Subject: [PATCH 703/909] Also catch/throw in sendEvent() case --- pdns/mtasker.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pdns/mtasker.cc b/pdns/mtasker.cc index dd7ccc50bd11..a02f6bcc9ef2 100644 --- a/pdns/mtasker.cc +++ b/pdns/mtasker.cc @@ -252,7 +252,13 @@ templateint MTaskercontext); d_waiters.erase(waiter); // removes the waitpoint notifyStackSwitch(d_threads[d_tid].startOfStack, d_stacksize); - pdns_swapcontext(d_kernel,*userspace); // swaps back to the above point 'A' + try { + pdns_swapcontext(d_kernel,*userspace); // swaps back to the above point 'A' + } + catch (...) { + notifyStackSwitchDone(); + throw; + } notifyStackSwitchDone(); return 1; } From c3b9a89e369047691ac60eaf72cd71bac0bfbf2a Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 13 Sep 2023 15:22:36 +0200 Subject: [PATCH 704/909] And another case for catch/throw --- pdns/mtasker.cc | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/pdns/mtasker.cc b/pdns/mtasker.cc index a02f6bcc9ef2..157953471872 100644 --- a/pdns/mtasker.cc +++ b/pdns/mtasker.cc @@ -380,7 +380,13 @@ templatebool MTasker::schedule(con ttdindex.erase(i++); // removes the waitpoint notifyStackSwitch(d_threads[d_tid].startOfStack, d_stacksize); - pdns_swapcontext(d_kernel, *uc); // swaps back to the above point 'A' + try { + pdns_swapcontext(d_kernel, *uc); // swaps back to the above point 'A' + } + catch (...) { + notifyStackSwitchDone(); + throw; + } notifyStackSwitchDone(); } else if(i->ttd.tv_sec) From dfbcaf8482a7355743e9421b5c59f7266e01d8d6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 13 Sep 2023 15:47:50 +0200 Subject: [PATCH 705/909] Add make -C rust clean when generate.py is run. See comment for motivation. While working on the settings project, I had this line, but I thouhgt it was no longer needed so I removed it. It turns out it *is* needed. Found out when adding the recursor.tcp_threads field. --- pdns/recursordist/settings/Makefile.am | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/settings/Makefile.am b/pdns/recursordist/settings/Makefile.am index 6e5952c9581a..536dc712e706 100644 --- a/pdns/recursordist/settings/Makefile.am +++ b/pdns/recursordist/settings/Makefile.am @@ -12,8 +12,12 @@ all: cxxsettings-generated.cc BUILT_SOURCES=cxxsettings-generated.cc -# It's a bit dirty that this target also generated a file inside rust/src (lib.rs) +# It's a bit dirty that this target also generates a file inside rust/src (lib.rs). Also, we need to +# clean in the Rust dir, as in some cases the Serde/CXX derive/generate code does not get re-run by +# cargo after rust/src/lib.rs changed because of a generate.py run. In that case we end up with an +# rust/src/lib.rs.h that does not contain e.g. field name or field type changes. cxxsettings-generated.cc: table.py generate.py rust-preamble-in.rs rust-bridge-in.rs docs-old-preamble-in.rst docs-new-preamble-in.rst + $(MAKE) -C rust clean $(PYTHON) generate.py clean-local: From 58ae5410e204c3775831b501be3cc92fd4595ea2 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 13 Sep 2023 16:27:51 +0200 Subject: [PATCH 706/909] dnsdist: Fix a race in TLS certificate generation in the tests The OCSP and TLS tests are generating new TLS certificate and key, so there was a time window for a certificate/key mismatch if a test is starting right at the moment the OCSP and TLS tests are generating new material. This commit fixes it by using different file names for these tests. --- regression-tests.dnsdist/.gitignore | 12 +++++++- regression-tests.dnsdist/dnsdisttests.py | 13 ++++---- regression-tests.dnsdist/test_OCSP.py | 38 ++++++++++++++---------- regression-tests.dnsdist/test_TLS.py | 33 ++++++++++++++++---- 4 files changed, 68 insertions(+), 28 deletions(-) diff --git a/regression-tests.dnsdist/.gitignore b/regression-tests.dnsdist/.gitignore index bde839b04413..78d7bc1ccb7a 100644 --- a/regression-tests.dnsdist/.gitignore +++ b/regression-tests.dnsdist/.gitignore @@ -14,8 +14,18 @@ /server.csr /server.key /server.pem -/server.ocsp /server.p12 +/server-ocsp.chain +/server-ocsp.csr +/server-ocsp.key +/server-ocsp.pem +/server-ocsp.p12 +/server-tls.chain +/server-tls.csr +/server-tls.key +/server-tls.pem +/server-tls.p12 +/server.ocsp /configs /dnsdist.log /dnsdist_test.conf diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index c82f2b9ac9dd..75f12e620221 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -905,16 +905,17 @@ def checkQueryNoEDNS(self, expected, received): def checkResponseNoEDNS(self, expected, received): self.checkMessageNoEDNS(expected, received) - def generateNewCertificateAndKey(self): + @staticmethod + def generateNewCertificateAndKey(filePrefix): # generate and sign a new cert - cmd = ['openssl', 'req', '-new', '-newkey', 'rsa:2048', '-nodes', '-keyout', 'server.key', '-out', 'server.csr', '-config', 'configServer.conf'] + cmd = ['openssl', 'req', '-new', '-newkey', 'rsa:2048', '-nodes', '-keyout', filePrefix + '.key', '-out', filePrefix + '.csr', '-config', 'configServer.conf'] output = None try: process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) output = process.communicate(input='') except subprocess.CalledProcessError as exc: raise AssertionError('openssl req failed (%d): %s' % (exc.returncode, exc.output)) - cmd = ['openssl', 'x509', '-req', '-days', '1', '-CA', 'ca.pem', '-CAkey', 'ca.key', '-CAcreateserial', '-in', 'server.csr', '-out', 'server.pem', '-extfile', 'configServer.conf', '-extensions', 'v3_req'] + cmd = ['openssl', 'x509', '-req', '-days', '1', '-CA', 'ca.pem', '-CAkey', 'ca.key', '-CAcreateserial', '-in', filePrefix + '.csr', '-out', filePrefix + '.pem', '-extfile', 'configServer.conf', '-extensions', 'v3_req'] output = None try: process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) @@ -922,12 +923,12 @@ def generateNewCertificateAndKey(self): except subprocess.CalledProcessError as exc: raise AssertionError('openssl x509 failed (%d): %s' % (exc.returncode, exc.output)) - with open('server.chain', 'w') as outFile: - for inFileName in ['server.pem', 'ca.pem']: + with open(filePrefix + '.chain', 'w') as outFile: + for inFileName in [filePrefix + '.pem', 'ca.pem']: with open(inFileName) as inFile: outFile.write(inFile.read()) - cmd = ['openssl', 'pkcs12', '-export', '-passout', 'pass:passw0rd', '-clcerts', '-in', 'server.pem', '-CAfile', 'ca.pem', '-inkey', 'server.key', '-out', 'server.p12'] + cmd = ['openssl', 'pkcs12', '-export', '-passout', 'pass:passw0rd', '-clcerts', '-in', filePrefix + '.pem', '-CAfile', 'ca.pem', '-inkey', filePrefix + '.key', '-out', filePrefix + '.p12'] output = None try: process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT, close_fds=True) diff --git a/regression-tests.dnsdist/test_OCSP.py b/regression-tests.dnsdist/test_OCSP.py index de520dcdaf50..695863151c2f 100644 --- a/regression-tests.dnsdist/test_OCSP.py +++ b/regression-tests.dnsdist/test_OCSP.py @@ -35,13 +35,20 @@ def getOCSPSerial(cls, output): def getTLSProvider(self): return self.sendConsoleCommand("getBind(0):getEffectiveTLSProvider()").rstrip() + @classmethod + def setUpClass(cls): + cls.generateNewCertificateAndKey('server-ocsp') + cls.startResponders() + cls.startDNSDist() + cls.setUpSockets() + @unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled') class TestOCSPStaplingDOH(DNSDistOCSPStaplingTest): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _serverKey = 'server.key' - _serverCert = 'server.chain' + _serverKey = 'server-ocsp.key' + _serverCert = 'server-ocsp.chain' _serverName = 'tls.tests.dnsdist.org' _ocspFile = 'server.ocsp' _caCert = 'ca.pem' @@ -67,6 +74,7 @@ def setUpClass(cls): if 'SKIP_DOH_TESTS' in os.environ: raise unittest.SkipTest('DNS over HTTPS tests are disabled') + cls.generateNewCertificateAndKey('server-ocsp') cls.startResponders() cls.startDNSDist() cls.setUpSockets() @@ -84,7 +92,7 @@ def testOCSPStapling(self): serialNumber = self.getOCSPSerial(output) self.assertTrue(serialNumber) - self.generateNewCertificateAndKey() + self.generateNewCertificateAndKey('server-ocsp') self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile)) self.sendConsoleCommand("reloadAllCertificates()") @@ -98,8 +106,8 @@ class TestBrokenOCSPStaplingDoH(DNSDistOCSPStaplingTest): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _serverKey = 'server.key' - _serverCert = 'server.chain' + _serverKey = 'server-ocsp.key' + _serverCert = 'server-ocsp.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' # invalid OCSP file! @@ -129,8 +137,8 @@ class TestOCSPStaplingTLSGnuTLS(DNSDistOCSPStaplingTest): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _serverKey = 'server.key' - _serverCert = 'server.chain' + _serverKey = 'server-ocsp.key' + _serverCert = 'server-ocsp.chain' _serverName = 'tls.tests.dnsdist.org' _ocspFile = 'server.ocsp' _caCert = 'ca.pem' @@ -158,7 +166,7 @@ def testOCSPStapling(self): serialNumber = self.getOCSPSerial(output) self.assertTrue(serialNumber) - self.generateNewCertificateAndKey() + self.generateNewCertificateAndKey('server-ocsp') self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile)) self.sendConsoleCommand("reloadAllCertificates()") @@ -172,8 +180,8 @@ class TestBrokenOCSPStaplingTLSGnuTLS(DNSDistOCSPStaplingTest): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _serverKey = 'server.key' - _serverCert = 'server.chain' + _serverKey = 'server-ocsp.key' + _serverCert = 'server-ocsp.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' # invalid OCSP file! @@ -200,8 +208,8 @@ class TestOCSPStaplingTLSOpenSSL(DNSDistOCSPStaplingTest): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _serverKey = 'server.key' - _serverCert = 'server.chain' + _serverKey = 'server-ocsp.key' + _serverCert = 'server-ocsp.chain' _serverName = 'tls.tests.dnsdist.org' _ocspFile = 'server.ocsp' _caCert = 'ca.pem' @@ -229,7 +237,7 @@ def testOCSPStapling(self): serialNumber = self.getOCSPSerial(output) self.assertTrue(serialNumber) - self.generateNewCertificateAndKey() + self.generateNewCertificateAndKey('server-ocsp') self.sendConsoleCommand("generateOCSPResponse('%s', '%s', '%s', '%s', 1, 0)" % (self._serverCert, self._caCert, self._caKey, self._ocspFile)) self.sendConsoleCommand("reloadAllCertificates()") @@ -243,8 +251,8 @@ class TestBrokenOCSPStaplingTLSOpenSSL(DNSDistOCSPStaplingTest): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _serverKey = 'server.key' - _serverCert = 'server.chain' + _serverKey = 'server-ocsp.key' + _serverCert = 'server-ocsp.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' # invalid OCSP file! diff --git a/regression-tests.dnsdist/test_TLS.py b/regression-tests.dnsdist/test_TLS.py index 12db4639453d..9803ed550f96 100644 --- a/regression-tests.dnsdist/test_TLS.py +++ b/regression-tests.dnsdist/test_TLS.py @@ -58,7 +58,7 @@ def testTLSSimple(self): self.assertEqual(names, ['tls.tests.dnsdist.org', 'powerdns.com', '127.0.0.1']) serialNumber = cert['serialNumber'] - self.generateNewCertificateAndKey() + self.generateNewCertificateAndKey('server-tls') self.sendConsoleCommand("reloadAllCertificates()") conn.close() @@ -268,8 +268,8 @@ class TestOpenSSL(DNSDistTest, TLSTests): _extraStartupSleep = 1 _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _serverKey = 'server.key' - _serverCert = 'server.chain' + _serverKey = 'server-tls.key' + _serverCert = 'server-tls.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' _tlsServerPort = pickAvailablePort() @@ -283,6 +283,13 @@ class TestOpenSSL(DNSDistTest, TLSTests): """ _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey'] + @classmethod + def setUpClass(cls): + cls.generateNewCertificateAndKey('server-tls') + cls.startResponders() + cls.startDNSDist() + cls.setUpSockets() + def testProvider(self): self.assertEqual(self.getTLSProvider(), "openssl") @@ -290,8 +297,8 @@ class TestGnuTLS(DNSDistTest, TLSTests): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _serverKey = 'server.key' - _serverCert = 'server.chain' + _serverKey = 'server-tls.key' + _serverCert = 'server-tls.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' _tlsServerPort = pickAvailablePort() @@ -305,6 +312,13 @@ class TestGnuTLS(DNSDistTest, TLSTests): """ _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey'] + @classmethod + def setUpClass(cls): + cls.generateNewCertificateAndKey('server-tls') + cls.startResponders() + cls.startDNSDist() + cls.setUpSockets() + def testProvider(self): self.assertEqual(self.getTLSProvider(), "gnutls") @@ -481,7 +495,7 @@ def testProtocolDOT(self): class TestPKCSTLSCertificate(DNSDistTest, TLSTests): _consoleKey = DNSDistTest.generateConsoleKey() _consoleKeyB64 = base64.b64encode(_consoleKey).decode('ascii') - _serverCert = 'server.p12' + _serverCert = 'server-tls.p12' _pkcsPassphrase = 'passw0rd' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' @@ -495,3 +509,10 @@ class TestPKCSTLSCertificate(DNSDistTest, TLSTests): addAction(SNIRule("powerdns.com"), SpoofAction("1.2.3.4")) """ _config_params = ['_consoleKeyB64', '_consolePort', '_testServerPort', '_serverCert', '_pkcsPassphrase', '_tlsServerPort'] + + @classmethod + def setUpClass(cls): + cls.generateNewCertificateAndKey('server-tls') + cls.startResponders() + cls.startDNSDist() + cls.setUpSockets() From 1ac498120e2af31f9b57072ffd6102f42154f4aa Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 14 Sep 2023 08:35:05 +0200 Subject: [PATCH 707/909] builder: drop ubuntu kinetic, it is EOL --- .github/workflows/builder.yml | 1 - .../Dockerfile.target.ubuntu-kinetic | 36 ------------------- .../Dockerfile.target.ubuntu-kinetic-amd64 | 1 - .../Dockerfile.target.ubuntu-kinetic-arm64 | 1 - 4 files changed, 39 deletions(-) delete mode 100644 builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic delete mode 120000 builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic-amd64 delete mode 120000 builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic-arm64 diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index a81d0be78309..09a98dc112f4 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -22,7 +22,6 @@ jobs: - el-8 - centos-8-stream - centos-9-stream - - ubuntu-kinetic - ubuntu-lunar - debian-bookworm - amazon-2023 diff --git a/builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic b/builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic deleted file mode 100644 index 666501fdbadd..000000000000 --- a/builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic +++ /dev/null @@ -1,36 +0,0 @@ -# First do the source builds -@INCLUDE Dockerfile.target.sdist - -@IF [ ${BUILDER_TARGET} = ubuntu-kinetic ] -FROM ubuntu:kinetic as dist-base -@ENDIF -@IF [ ${BUILDER_TARGET} = ubuntu-kinetic-amd64 ] -FROM amd64/ubuntu:kinetic as dist-base -@ENDIF -@IF [ ${BUILDER_TARGET} = ubuntu-kinetic-arm64 ] -FROM arm64v8/ubuntu:kinetic as dist-base -@ENDIF - -ARG BUILDER_CACHE_BUSTER= -ARG APT_URL -RUN apt-get update && apt-get -y dist-upgrade - -@INCLUDE Dockerfile.debbuild-prepare - -@IF [ -n "$M_authoritative$M_all" ] -ADD builder-support/debian/authoritative/debian-buster/ pdns-${BUILDER_VERSION}/debian/ -@ENDIF - -@IF [ -n "$M_recursor$M_all" ] -ADD builder-support/debian/recursor/debian-buster/ pdns-recursor-${BUILDER_VERSION}/debian/ -@ENDIF - -@IF [ -n "$M_dnsdist$M_all" ] -ADD builder-support/debian/dnsdist/debian-buster/ dnsdist-${BUILDER_VERSION}/debian/ -@ENDIF - -@INCLUDE Dockerfile.debbuild - -# Do a test install and verify -# Can be skipped with skiptests=1 in the environment -# @EXEC [ "$skiptests" = "" ] && include Dockerfile.debtest diff --git a/builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic-amd64 b/builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic-amd64 deleted file mode 120000 index 7a8e3adf4e03..000000000000 --- a/builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic-amd64 +++ /dev/null @@ -1 +0,0 @@ -Dockerfile.target.ubuntu-kinetic \ No newline at end of file diff --git a/builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic-arm64 b/builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic-arm64 deleted file mode 120000 index 7a8e3adf4e03..000000000000 --- a/builder-support/dockerfiles/Dockerfile.target.ubuntu-kinetic-arm64 +++ /dev/null @@ -1 +0,0 @@ -Dockerfile.target.ubuntu-kinetic \ No newline at end of file From c8734ecd8cca0089a8a9c032bfab1069f60381e6 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 12 Sep 2023 12:34:43 +0200 Subject: [PATCH 708/909] auth: add default-catalog-zone setting --- docs/settings.rst | 12 ++++++++++++ pdns/auth-main.cc | 13 +++++++++++++ pdns/ws-auth.cc | 7 +++++++ regression-tests.api/runtests.py | 1 + regression-tests.api/test_Zones.py | 5 ++++- 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/docs/settings.rst b/docs/settings.rst index 95d3956baad6..d8bed0d47ce1 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -366,6 +366,18 @@ The value of :ref:`metadata-api-rectify` if it is not set on the zone. .. note:: Pre 4.2.0 the default was always no. +.. _setting-default-catalog-zone: + +``default-catalog-zone`` +------------------------ + +- String: +- Default: empty + +.. versionadded:: 4.8.3 + +When a primary zone is created via the API, and the request does not specify a catalog zone, the name given here will be used. + .. _setting-default-ksk-algorithms: .. _setting-default-ksk-algorithm: diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index c28931fe3f2b..e3d4b39b097f 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -328,6 +328,8 @@ static void declareArguments() ::arg().setSwitch("consistent-backends", "Assume individual zones are not divided over backends. Send only ANY lookup operations to the backend to reduce the number of lookups") = "yes"; ::arg().set("rng", "Specify the random number generator to use. Valid values are auto,sodium,openssl,getrandom,arc4random,urandom.") = "auto"; + + ::arg().set("default-catalog-zone", "Catalog zone to assign newly created primary zones (via the API) to") = ""; #ifdef ENABLE_GSS_TSIG ::arg().setSwitch("enable-gss-tsig", "Enable GSS TSIG processing") = "no"; #endif @@ -1482,6 +1484,17 @@ int main(int argc, char** argv) g_log << Logger::Error << "Exiting because: " << PE.reason << endl; exit(1); } + + try { + auto defaultCatalog = ::arg()["default-catalog-zone"]; + if (!defaultCatalog.empty()) { + auto defCatalog = DNSName(defaultCatalog); + } + } + catch (const std::exception& e) { + g_log << Logger::Error << "Invalid value '" << ::arg()["default-catalog-zone"] << "' for default-catalog-zone: " << e.what() << endl; + exit(1); + } S.blacklist("special-memory-usage"); DLOG(g_log << Logger::Warning << "Verbose logging in effect" << endl); diff --git a/pdns/ws-auth.cc b/pdns/ws-auth.cc index fc8d7832fa3a..20bac3e34980 100644 --- a/pdns/ws-auth.cc +++ b/pdns/ws-auth.cc @@ -1872,6 +1872,13 @@ static void apiServerZonesPost(HttpRequest* req, HttpResponse* resp) { updateDomainSettingsFromDocument(B, di, zonename, document, !new_records.empty()); + if (!catalog && kind == DomainInfo::Master) { + auto defaultCatalog = ::arg()["default-catalog-zone"]; + if (!defaultCatalog.empty()) { + di.backend->setCatalog(zonename, DNSName(defaultCatalog)); + } + } + di.backend->commitTransaction(); g_zoneCache.add(zonename, static_cast(di.id)); // make new zone visible diff --git a/regression-tests.api/runtests.py b/regression-tests.api/runtests.py index 50065051d1ac..51e603e4b351 100755 --- a/regression-tests.api/runtests.py +++ b/regression-tests.api/runtests.py @@ -75,6 +75,7 @@ launch+=bind bind-config=bindbackend.conf loglevel=5 +default-catalog-zone=default-catalog.example.com """ BINDBACKEND_CONF_TPL = """ diff --git a/regression-tests.api/test_Zones.py b/regression-tests.api/test_Zones.py index 7257168bb312..8193070a6053 100644 --- a/regression-tests.api/test_Zones.py +++ b/regression-tests.api/test_Zones.py @@ -239,13 +239,16 @@ def test_create_zone_with_catalog(self): def test_create_zone_with_account(self): # soa_edit_api wins over serial - name, payload, data = self.create_zone(account='anaccount', serial=10) + name, payload, data = self.create_zone(account='anaccount', serial=10, kind='Master') print(data) for k in ('account', ): self.assertIn(k, data) if k in payload: self.assertEqual(data[k], payload[k]) + # as we did not set a catalog in our request, check that the default catalog was applied + self.assertEqual(data['catalog'], "default-catalog.example.com.") + def test_create_zone_default_soa_edit_api(self): name, payload, data = self.create_zone() print(data) From 8298e5d4011949dd5a26937abe7db52f43e2ab84 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 14 Sep 2023 11:12:07 +0200 Subject: [PATCH 709/909] dnsdist: Ensure our unit tests can be run in random order --- pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc | 20 +++---- pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc | 1 + .../dnsdistdist/test-dnsdistnghttp2_common.hh | 2 - pdns/dnsdistdist/test-dnsdisttcp_cc.cc | 54 +++++++++++++------ 4 files changed, 50 insertions(+), 27 deletions(-) diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc index 2c98427c0693..75b256d7e457 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc @@ -448,23 +448,27 @@ struct TestFixture { TestFixture() { - s_steps.clear(); - s_connectionContexts.clear(); - s_connectionBuffers.clear(); - s_connectionID = 0; - s_mplexer = std::make_unique(); + reset(); } TestFixture(const TestFixture&) = delete; TestFixture(TestFixture&&) = delete; TestFixture& operator=(const TestFixture&) = delete; TestFixture& operator=(TestFixture&&) = delete; ~TestFixture() + { + reset(); + } +private: + void reset() { s_steps.clear(); s_connectionContexts.clear(); s_connectionBuffers.clear(); s_connectionID = 0; - s_mplexer.reset(); + /* we _NEED_ to set this function to empty otherwise we might get what was set + by the last test, and we might not like it at all */ + s_processQuery = nullptr; + g_proxyProtocolACL.clear(); } }; @@ -500,10 +504,6 @@ BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) pwR.xfr32BitInt(0x01020304); pwR.commit(); - /* we _NEED_ to set this function to empty otherwise we might get what was set - by the last test, and we might not like it at all */ - s_processQuery = nullptr; - { /* dnsdist drops the query right away after receiving it, client closes the connection */ s_connectionContexts[counter++] = ExpectedData{{}, {query}, {response}, {403U}}; diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc index a7afea2063e1..b971e4ac1517 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2_cc.cc @@ -70,6 +70,7 @@ struct ExpectedData static std::deque s_steps; static std::map s_responses; +static std::unique_ptr s_mplexer; std::ostream& operator<<(std::ostream& os, const ExpectedStep::ExpectedRequest d); diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2_common.hh b/pdns/dnsdistdist/test-dnsdistnghttp2_common.hh index 5c79679aba0f..b6f9bdd10bb2 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2_common.hh +++ b/pdns/dnsdistdist/test-dnsdistnghttp2_common.hh @@ -153,5 +153,3 @@ static ComboAddress getBackendAddress(const std::string& lastDigit, uint16_t por return ComboAddress("192.0.2." + lastDigit, port); } - -static std::unique_ptr s_mplexer; diff --git a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc index 296cd44cb62e..14a13cde8a2e 100644 --- a/pdns/dnsdistdist/test-dnsdisttcp_cc.cc +++ b/pdns/dnsdistdist/test-dnsdisttcp_cc.cc @@ -435,6 +435,39 @@ static void prependPayloadEditingID(PacketBuffer& buffer, const PacketBuffer& pa buffer.insert(buffer.begin(), newPayload.begin(), newPayload.end()); } +struct TestFixture +{ + TestFixture() + { + reset(); + } + TestFixture(const TestFixture&) = delete; + TestFixture(TestFixture&&) = delete; + TestFixture& operator=(const TestFixture&) = delete; + TestFixture& operator=(TestFixture&&) = delete; + ~TestFixture() + { + reset(); + } + + static void reset() + { + s_steps.clear(); + s_readBuffer.clear(); + s_writeBuffer.clear(); + s_backendReadBuffer.clear(); + s_backendWriteBuffer.clear(); + + g_proxyProtocolACL.clear(); + g_verbose = false; + IncomingTCPConnectionState::clearAllDownstreamConnections(); + + /* we _NEED_ to set this function to empty otherwise we might get what was set + by the last test, and we might not like it at all */ + s_processQuery = nullptr; + } +}; + static void testInit(const std::string& name, TCPClientThreadData& threadData) { #ifdef DEBUGLOG_ENABLED @@ -443,22 +476,13 @@ static void testInit(const std::string& name, TCPClientThreadData& threadData) (void) name; #endif - s_steps.clear(); - s_readBuffer.clear(); - s_writeBuffer.clear(); - s_backendReadBuffer.clear(); - s_backendWriteBuffer.clear(); - - g_proxyProtocolACL.clear(); - g_verbose = false; - IncomingTCPConnectionState::clearAllDownstreamConnections(); - + TestFixture::reset(); threadData.mplexer = std::make_unique(); } #define TEST_INIT(str) testInit(str, threadData) -BOOST_AUTO_TEST_CASE(test_IncomingConnection_SelfAnswered) +BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_SelfAnswered, TestFixture) { auto local = getBackendAddress("1", 80); ClientState localCS(local, true, false, false, "", {}); @@ -705,7 +729,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_SelfAnswered) } } -BOOST_AUTO_TEST_CASE(test_IncomingConnectionWithProxyProtocol_SelfAnswered) +BOOST_FIXTURE_TEST_CASE(test_IncomingConnectionWithProxyProtocol_SelfAnswered, TestFixture) { auto local = getBackendAddress("1", 80); ClientState localCS(local, true, false, false, "", {}); @@ -835,7 +859,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionWithProxyProtocol_SelfAnswered) } } -BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) +BOOST_FIXTURE_TEST_CASE(test_IncomingConnection_BackendNoOOOR, TestFixture) { auto local = getBackendAddress("1", 80); ClientState localCS(local, true, false, false, "", {}); @@ -1735,7 +1759,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnection_BackendNoOOOR) } } -BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) +BOOST_FIXTURE_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR, TestFixture) { auto local = getBackendAddress("1", 80); ClientState localCS(local, true, false, false, "", {}); @@ -3875,7 +3899,7 @@ BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendOOOR) } } -BOOST_AUTO_TEST_CASE(test_IncomingConnectionOOOR_BackendNotOOOR) +BOOST_FIXTURE_TEST_CASE(test_IncomingConnectionOOOR_BackendNotOOOR, TestFixture) { auto local = getBackendAddress("1", 80); ClientState localCS(local, true, false, false, "", {}); From c50861010b65ab402bc4477be6a5377e22c11003 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 14 Sep 2023 11:20:11 +0200 Subject: [PATCH 710/909] dnsdist: Appease the formatting gods --- pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc index 75b256d7e457..2a479bf2be68 100644 --- a/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc +++ b/pdns/dnsdistdist/test-dnsdistnghttp2-in_cc.cc @@ -458,6 +458,7 @@ struct TestFixture { reset(); } + private: void reset() { From 55f6756bb282f2fdd68951bb2e342a48204608aa Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 14 Sep 2023 09:31:38 +0200 Subject: [PATCH 711/909] use allowerasing to allow replacement of curl-minimal with curl --- builder-support/dockerfiles/Dockerfile.rpmbuild | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/builder-support/dockerfiles/Dockerfile.rpmbuild b/builder-support/dockerfiles/Dockerfile.rpmbuild index 48bd68eb76b4..82334e51f1d2 100644 --- a/builder-support/dockerfiles/Dockerfile.rpmbuild +++ b/builder-support/dockerfiles/Dockerfile.rpmbuild @@ -4,7 +4,7 @@ RUN touch /var/lib/rpm/* && if $(grep -q 'release 7' /etc/redhat-release); then yum install -y rpm-build rpmdevtools python2 python3 curl "@Development Tools"; \ else \ yum upgrade -y && \ - yum install -y rpm-build rpmdevtools python3 curl "@Development Tools"; \ + yum install --allowerasing -y rpm-build rpmdevtools python3 curl "@Development Tools"; \ fi RUN mkdir /dist /pdns From 98014b10cfbec0515759ef8953b64bfce2a371cc Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 14 Sep 2023 12:02:15 +0200 Subject: [PATCH 712/909] rec: Clarify file name and placement rules for converted old-style files --- pdns/recursordist/docs/appendices/yamlconversion.rst | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/docs/appendices/yamlconversion.rst b/pdns/recursordist/docs/appendices/yamlconversion.rst index d846eb6ff4c8..d3c263cf7c35 100644 --- a/pdns/recursordist/docs/appendices/yamlconversion.rst +++ b/pdns/recursordist/docs/appendices/yamlconversion.rst @@ -49,8 +49,10 @@ Consult :doc:`../yamlsettings` for details on how settings spread over multiple The contents of the report can be used to produce YAML settings equivalent to the old-style settings. This is a manual step and consists of copy-pasting the sections of the conversion report to individual files. -Any settings filename in the include directory should end with ``.yml``. -It is possible to put associated files (like a ``recursor.forward_zones_file``) into the include dir, but do *not* let these files end in ``.yml``, as ``.yml`` files will be interpreted as full configuration files, while the associated settings files are YAML sequences of a specific type. + +Any converted settings filename in the **include** directory should end with ``.yml``. +The names of associated files (like a ``recursor.forward_zones_file``) should also end in ``.yml``, but should *not* be put into the **include** directory, as they do not contain full configuration YAML clauses but YAML sequences of a specific type. +The associated files *can* be put in the **config** directory, the directory that is searched for a ``recursor.conf`` or ``recursor.yml`` file. API Managed Files ----------------- From 1237c7f4c55f1e1fba7ba58e95636d18e1a9f823 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 15 Sep 2023 11:32:33 +0200 Subject: [PATCH 713/909] dnsdist: Prevent spurious failures of the async unit tests The events should be triggered either almost immediately or after 10 ms, but we have seen many spurious failures on our CI, likely because the box is overloaded, so sleep for up to 100 ms to be sure. I managed to reproduce the issue locally by running this command in parallel of the tests, for reference: `stress --cpu `. --- pdns/dnsdistdist/test-dnsdistasync.cc | 28 ++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/pdns/dnsdistdist/test-dnsdistasync.cc b/pdns/dnsdistdist/test-dnsdistasync.cc index d74d2e64b5d6..82ed4b15e54e 100644 --- a/pdns/dnsdistdist/test-dnsdistasync.cc +++ b/pdns/dnsdistdist/test-dnsdistasync.cc @@ -112,23 +112,28 @@ BOOST_AUTO_TEST_CASE(test_TimeoutFailClose) auto holder = std::make_unique(false); uint16_t asyncID = 1; uint16_t queryID = 42; - struct timeval ttd; - gettimeofday(&ttd, nullptr); - // timeout in 10 ms - const timeval add{0, 10000}; - ttd = ttd + add; + struct timeval ttd{ + }; std::shared_ptr sender{nullptr}; { + // timeout in 10 ms + const timeval add{0, 10000}; auto query = std::make_unique(); sender = query->d_sender; BOOST_REQUIRE(sender != nullptr); + gettimeofday(&ttd, nullptr); + ttd = ttd + add; holder->push(asyncID, queryID, ttd, std::move(query)); BOOST_CHECK(!holder->empty()); } - // sleep for 20 ms, to be sure - usleep(20000); + // the event should be triggered after 10 ms, but we have seen + // many spurious failures on our CI, likely because the box is + // overloaded, so sleep for up to 100 ms to be sure + for (size_t counter = 0; !holder->empty() && counter < 10; counter++) { + usleep(10000); + } BOOST_CHECK(holder->empty()); BOOST_CHECK(sender->errorRaised); @@ -155,8 +160,13 @@ BOOST_AUTO_TEST_CASE(test_AddingExpiredEvent) holder->push(asyncID, queryID, ttd, std::move(query)); } - // sleep for 20 ms - usleep(20000); + // the expired event should be triggered almost immediately, + // but we have seen many spurious failures on our CI, + // likely because the box is overloaded, so sleep for up to + // 100 ms to be sure + for (size_t counter = 0; !holder->empty() && counter < 10; counter++) { + usleep(10000); + } BOOST_CHECK(holder->empty()); BOOST_CHECK(sender->errorRaised); From 34eed7b84f246d2f213d60ceae0ed9bea487a895 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 15 Sep 2023 11:39:39 +0200 Subject: [PATCH 714/909] dnsdist: Uglify the code to make the formatter happy --- pdns/dnsdistdist/test-dnsdistasync.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/test-dnsdistasync.cc b/pdns/dnsdistdist/test-dnsdistasync.cc index 82ed4b15e54e..713c5ad71f24 100644 --- a/pdns/dnsdistdist/test-dnsdistasync.cc +++ b/pdns/dnsdistdist/test-dnsdistasync.cc @@ -112,7 +112,8 @@ BOOST_AUTO_TEST_CASE(test_TimeoutFailClose) auto holder = std::make_unique(false); uint16_t asyncID = 1; uint16_t queryID = 42; - struct timeval ttd{ + struct timeval ttd + { }; std::shared_ptr sender{nullptr}; From 75cbd47beade8b16736f0d191c6e93b3aec96cb7 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 15 Sep 2023 14:02:25 +0200 Subject: [PATCH 715/909] dnsdist: Add ChangeLog and update secpoll for 1.9.0-alpha1 --- docs/secpoll.zone | 3 +- pdns/dnsdistdist/docs/changelog.rst | 61 +++++++++++++++++++++++++ pdns/dnsdistdist/docs/upgrade_guide.rst | 2 + 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 49b741c2ea17..07ae7eac50d0 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023091300 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023091801 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -516,3 +516,4 @@ dnsdist-1.8.0-rc2.security-status 60 IN TXT "2 Unsuppor dnsdist-1.8.0-rc3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" dnsdist-1.8.0.security-status 60 IN TXT "1 OK" dnsdist-1.8.1.security-status 60 IN TXT "1 OK" +dnsdist-1.9.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (no known vulnerabilities)" diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index 6801e82cb837..c5c61708db69 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -1,6 +1,67 @@ Changelog ========= +.. changelog:: + :version: 1.9.0-alpha1 + :released: 18th of September 2023 + + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading. + + .. change:: + :tags: Improvements, DNS over HTTPS + :pullreq: 12678 + + Add support for incoming DoH via nghttp2 + + .. change:: + :tags: Improvements + :pullreq: 13145 + + Fix building our fuzzing targets from a dist tarball + + .. change:: + :tags: Removals + :pullreq: 13168 + + Change the default for building with net-snmp from `auto` to `no` + + .. change:: + :tags: Improvements + :pullreq: 13135 + + Add a DNSHeader:getTC() Lua binding + + .. change:: + :tags: New Features + :pullreq: 13013 + :tickets: 13007 + + Add Lua bindings to access selector and action + + .. change:: + :tags: Improvements + :pullreq: 13088 + + Stop passing -u dnsdist -g dnsdist on systemd's ExecStart + + .. change:: + :tags: Improvements, Metrics + :pullreq: 13009 + + Add metrics for health-check failures + + .. change:: + :tags: Improvements + :pullreq: 12931 + + Use arc4random only for random values + + .. change:: + :tags: New Features + :pullreq: 12689 + + Add an option to write `grepq`'s output to a file + .. changelog:: :version: 1.8.1 :released: 8th of September 2023 diff --git a/pdns/dnsdistdist/docs/upgrade_guide.rst b/pdns/dnsdistdist/docs/upgrade_guide.rst index 575dd56faeaa..9efab181f360 100644 --- a/pdns/dnsdistdist/docs/upgrade_guide.rst +++ b/pdns/dnsdistdist/docs/upgrade_guide.rst @@ -11,6 +11,8 @@ the library used when dnsdist is built with support for both ``h2o`` and ``nghtt Note that ``nghttp2`` only supports HTTP/2, and not HTTP/1, while ``h2o`` supported both. This is not an issue for actual DNS over HTTPS clients that support HTTP/2, but might be one in setups running dnsdist behind a reverse-proxy that does not support HTTP/1. See :doc:`guides/dns-over-https` for some work-around. +SNMP support is no longer enabled by default during ``configure``, requiring ``--with-net-snmp`` to be built. + 1.7.x to 1.8.0 -------------- From 70846323e026f6cc26edfbe6cf8575271475e99f Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 18 Sep 2023 10:00:02 +0200 Subject: [PATCH 716/909] secpoll: Don't advise updating from dnsdist's pre-release 1.9.0-alpha1 --- docs/secpoll.zone | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 07ae7eac50d0..e815725a20a8 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023091801 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023091802 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -516,4 +516,4 @@ dnsdist-1.8.0-rc2.security-status 60 IN TXT "2 Unsuppor dnsdist-1.8.0-rc3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" dnsdist-1.8.0.security-status 60 IN TXT "1 OK" dnsdist-1.8.1.security-status 60 IN TXT "1 OK" -dnsdist-1.9.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (no known vulnerabilities)" +dnsdist-1.9.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release (no known vulnerabilities)" From 2f00085feb1fea53635d49c3731693a04a565d60 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 18 Sep 2023 09:45:47 +0200 Subject: [PATCH 717/909] dnsdist: Fix too short underline for latency-doh-avg1000000 title --- pdns/dnsdistdist/docs/statistics.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/statistics.rst b/pdns/dnsdistdist/docs/statistics.rst index 6f3c93236b10..0d5b5ed1c52f 100644 --- a/pdns/dnsdistdist/docs/statistics.rst +++ b/pdns/dnsdistdist/docs/statistics.rst @@ -142,7 +142,7 @@ latency-doh-avg10000 Average response latency, in microseconds, of the last 10000 packets received over DoH. latency-doh-avg1000000 ---------------------- +---------------------- Average response latency, in microseconds, of the last 1000000 packets received over DoH. latency-dot-avg100 From 080ab56d4d23e71718a53205c5c00bf15e713fff Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 18 Sep 2023 10:54:12 +0200 Subject: [PATCH 718/909] add a missing space to format the changelog correctly --- pdns/dnsdistdist/docs/changelog.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index c5c61708db69..79778a8ae24d 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -25,7 +25,7 @@ Changelog Change the default for building with net-snmp from `auto` to `no` - .. change:: + .. change:: :tags: Improvements :pullreq: 13135 From b42157951dfe7974dad561f0bc8da9c3194203be Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Thu, 14 Sep 2023 09:14:41 +0200 Subject: [PATCH 719/909] builder: add ubuntu-mantic target --- .github/workflows/builder.yml | 1 + .../Dockerfile.target.ubuntu-mantic | 36 +++++++++++++++++++ .../Dockerfile.target.ubuntu-mantic-amd64 | 1 + .../Dockerfile.target.ubuntu-mantic-arm64 | 1 + 4 files changed, 39 insertions(+) create mode 100644 builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic create mode 120000 builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic-amd64 create mode 120000 builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic-arm64 diff --git a/.github/workflows/builder.yml b/.github/workflows/builder.yml index 09a98dc112f4..8c18ec5ba106 100644 --- a/.github/workflows/builder.yml +++ b/.github/workflows/builder.yml @@ -23,6 +23,7 @@ jobs: - centos-8-stream - centos-9-stream - ubuntu-lunar + - ubuntu-mantic - debian-bookworm - amazon-2023 fail-fast: false diff --git a/builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic b/builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic new file mode 100644 index 000000000000..2dbc488e6955 --- /dev/null +++ b/builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic @@ -0,0 +1,36 @@ +# First do the source builds +@INCLUDE Dockerfile.target.sdist + +@IF [ ${BUILDER_TARGET} = ubuntu-mantic ] +FROM ubuntu:mantic as dist-base +@ENDIF +@IF [ ${BUILDER_TARGET} = ubuntu-mantic-amd64 ] +FROM amd64/ubuntu:mantic as dist-base +@ENDIF +@IF [ ${BUILDER_TARGET} = ubuntu-mantic-arm64 ] +FROM arm64v8/ubuntu:mantic as dist-base +@ENDIF + +ARG BUILDER_CACHE_BUSTER= +ARG APT_URL +RUN apt-get update && apt-get -y dist-upgrade + +@INCLUDE Dockerfile.debbuild-prepare + +@IF [ -n "$M_authoritative$M_all" ] +ADD builder-support/debian/authoritative/debian-buster/ pdns-${BUILDER_VERSION}/debian/ +@ENDIF + +@IF [ -n "$M_recursor$M_all" ] +ADD builder-support/debian/recursor/debian-buster/ pdns-recursor-${BUILDER_VERSION}/debian/ +@ENDIF + +@IF [ -n "$M_dnsdist$M_all" ] +ADD builder-support/debian/dnsdist/debian-buster/ dnsdist-${BUILDER_VERSION}/debian/ +@ENDIF + +@INCLUDE Dockerfile.debbuild + +# Do a test install and verify +# Can be skipped with skiptests=1 in the environment +# @EXEC [ "$skiptests" = "" ] && include Dockerfile.debtest diff --git a/builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic-amd64 b/builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic-amd64 new file mode 120000 index 000000000000..17efdefeb176 --- /dev/null +++ b/builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic-amd64 @@ -0,0 +1 @@ +Dockerfile.target.ubuntu-mantic \ No newline at end of file diff --git a/builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic-arm64 b/builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic-arm64 new file mode 120000 index 000000000000..17efdefeb176 --- /dev/null +++ b/builder-support/dockerfiles/Dockerfile.target.ubuntu-mantic-arm64 @@ -0,0 +1 @@ +Dockerfile.target.ubuntu-mantic \ No newline at end of file From 11c65aeda2aef3aabeeff9aa1491bc84954ed905 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 18 Sep 2023 11:38:10 +0200 Subject: [PATCH 720/909] Prevent lookups for unsupported qtypes or rcode != 0 to submit refresh tasks --- pdns/recursordist/rec-taskqueue.cc | 5 +++++ pdns/recursordist/rec-taskqueue.hh | 4 ++++ pdns/recursordist/recpacketcache.cc | 18 +++++++++++------- pdns/recursordist/recpacketcache.hh | 2 +- 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/pdns/recursordist/rec-taskqueue.cc b/pdns/recursordist/rec-taskqueue.cc index 29cc6d75c889..8526e8d4c964 100644 --- a/pdns/recursordist/rec-taskqueue.cc +++ b/pdns/recursordist/rec-taskqueue.cc @@ -336,3 +336,8 @@ uint64_t getResolveTaskExceptions() { return s_almost_expired_tasks.exceptions; } + +bool taskQTypeIsSupported(QType qtype) +{ + return !SyncRes::isUnsupported(qtype); +} diff --git a/pdns/recursordist/rec-taskqueue.hh b/pdns/recursordist/rec-taskqueue.hh index 425cb55ac05f..73eedeecede7 100644 --- a/pdns/recursordist/rec-taskqueue.hh +++ b/pdns/recursordist/rec-taskqueue.hh @@ -23,6 +23,7 @@ #include #include +#include class DNSName; union ComboAddress; @@ -54,3 +55,6 @@ uint64_t getResolveTaskExceptions(); uint64_t getAlmostExpiredTasksPushed(); uint64_t getAlmostExpiredTasksRun(); uint64_t getAlmostExpiredTaskExceptions(); + +bool taskQTypeIsSupported(QType qtype); + diff --git a/pdns/recursordist/recpacketcache.cc b/pdns/recursordist/recpacketcache.cc index 184555ebd8e7..77dc63e1e126 100644 --- a/pdns/recursordist/recpacketcache.cc +++ b/pdns/recursordist/recpacketcache.cc @@ -126,12 +126,16 @@ bool RecursorPacketCache::checkResponseMatches(MapCombo::LockedContent& shard, s *age = static_cast(now - iter->d_creation); // we know ttl is > 0 auto ttl = static_cast(iter->d_ttd - now); - if (s_refresh_ttlperc > 0 && !iter->d_submitted) { - const uint32_t deadline = iter->getOrigTTL() * s_refresh_ttlperc / 100; - const bool almostExpired = ttl <= deadline; - if (almostExpired) { - iter->d_submitted = true; - pushAlmostExpiredTask(qname, qtype, iter->d_ttd, Netmask()); + if (s_refresh_ttlperc > 0 && !iter->d_submitted && taskQTypeIsSupported(qtype)) { + const dnsheader_aligned header(iter->d_packet.data()); + const auto* headerPtr = header.get(); + if (headerPtr->rcode == RCode::NoError) { + const uint32_t deadline = iter->getOrigTTL() * s_refresh_ttlperc / 100; + const bool almostExpired = ttl <= deadline; + if (almostExpired) { + iter->d_submitted = true; + pushAlmostExpiredTask(qname, qtype, iter->d_ttd, Netmask()); + } } } *responsePacket = iter->d_packet; @@ -244,7 +248,7 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, seq_idx.erase(seq_idx.begin()); map.d_entriesCount--; } - assert(map.d_entriesCount == shard->d_map.size()); // XXX + assert(map.d_entriesCount == shard->d_map.size()); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clib implementation } void RecursorPacketCache::doPruneTo(size_t maxSize) diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index 5ff974fefdce..2e847687a127 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -208,7 +208,7 @@ private: } static bool qrMatch(const packetCache_t::index::type::iterator& iter, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass); - bool checkResponseMatches(MapCombo::LockedContent& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); + static bool checkResponseMatches(MapCombo::LockedContent& shard, std::pair::type::iterator, packetCache_t::index::type::iterator> range, const std::string& queryPacket, const DNSName& qname, uint16_t qtype, uint16_t qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, OptPBData* pbdata); void setShardSizes(size_t shardSize); From b2e8acfaa79b55b2e0f36dc0c2e76868cf19f5bd Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 18 Sep 2023 13:47:19 +0200 Subject: [PATCH 721/909] dnsdist: Enable back h2o support in our packages As we promised to do. --- builder-support/debian/dnsdist/debian-buster/rules | 1 + builder-support/specs/dnsdist.spec | 1 + 2 files changed, 2 insertions(+) diff --git a/builder-support/debian/dnsdist/debian-buster/rules b/builder-support/debian/dnsdist/debian-buster/rules index 962ef5a56a63..e9a2a8cf1a36 100755 --- a/builder-support/debian/dnsdist/debian-buster/rules +++ b/builder-support/debian/dnsdist/debian-buster/rules @@ -53,6 +53,7 @@ override_dh_auto_configure: --enable-dnscrypt \ --enable-dnstap \ --with-gnutls \ + --with-h2o \ --with-net-snmp \ --with-libcap \ --with-libsodium \ diff --git a/builder-support/specs/dnsdist.spec b/builder-support/specs/dnsdist.spec index 0e027abd886d..6d64d3fee7a2 100644 --- a/builder-support/specs/dnsdist.spec +++ b/builder-support/specs/dnsdist.spec @@ -80,6 +80,7 @@ export RANLIB=gcc-ranlib --enable-unit-tests \ --enable-lto=thin \ --enable-dns-over-tls \ + --with-h2o \ %if 0%{?suse_version} --disable-dnscrypt \ --without-libsodium \ From e59c85697971a3376a06fc15e0fffc54244f50c5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 18 Sep 2023 13:47:44 +0200 Subject: [PATCH 722/909] dnsdist: Document that h2o support is no longer built by default --- pdns/dnsdistdist/docs/upgrade_guide.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/upgrade_guide.rst b/pdns/dnsdistdist/docs/upgrade_guide.rst index 9efab181f360..661370f6db1d 100644 --- a/pdns/dnsdistdist/docs/upgrade_guide.rst +++ b/pdns/dnsdistdist/docs/upgrade_guide.rst @@ -5,7 +5,7 @@ Upgrade Guide -------------- dnsdist now supports a new library for dealing with incoming DNS over HTTPS queries: ``nghttp2``. The previously used library, ``h2o``, can still be used -but is now deprecated and will be removed in the future, as it is unfortunately no longer maintained in a way that is suitable for use as a library +but is now deprecated, disabled by default (see ``--with-h2o`` to enable it back) and will be removed in the future, as it is unfortunately no longer maintained in a way that is suitable for use as a library (see https://github.com/h2o/h2o/issues/3230). See the ``library`` parameter on the :func:`addDOHLocal` directive for more information on how to select the library used when dnsdist is built with support for both ``h2o`` and ``nghttp2``. The default is now ``nghttp2`` whenever possible. Note that ``nghttp2`` only supports HTTP/2, and not HTTP/1, while ``h2o`` supported both. This is not an issue for actual DNS over HTTPS clients that From 0cfda14990dd9dd9e231f319360bb32aa818ff33 Mon Sep 17 00:00:00 2001 From: dmachard <5562930+dmachard@users.noreply.github.com> Date: Mon, 18 Sep 2023 18:25:26 +0200 Subject: [PATCH 723/909] dnsdist: add lua binding to downstream addr --- pdns/dnsdist-lua-bindings-dnsquestion.cc | 11 +++++++++++ pdns/dnsdistdist/docs/reference/dq.rst | 10 +++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdist-lua-bindings-dnsquestion.cc b/pdns/dnsdist-lua-bindings-dnsquestion.cc index f71a9bbf4d97..7427f18f6ddd 100644 --- a/pdns/dnsdist-lua-bindings-dnsquestion.cc +++ b/pdns/dnsdist-lua-bindings-dnsquestion.cc @@ -500,5 +500,16 @@ class AsynchronousObject auto query = dnsdist::getInternalQueryFromDQ(dr, false); return dnsdist::queueQueryResumptionEvent(std::move(query)); }); + + luaCtx.registerMember("selectedBackend", + []( const DNSResponse& dr) -> const ComboAddress { + if (dr.d_downstream == nullptr) { + return ComboAddress(); + } else { + return dr.d_downstream->d_config.remote; + } + }, + [](DNSResponse& dr, const ComboAddress newSelectedBackend) { (void) newSelectedBackend; } + ); #endif /* DISABLE_NON_FFI_DQ_BINDINGS */ } diff --git a/pdns/dnsdistdist/docs/reference/dq.rst b/pdns/dnsdistdist/docs/reference/dq.rst index ef9c531b3e7b..1d301588eb1c 100644 --- a/pdns/dnsdistdist/docs/reference/dq.rst +++ b/pdns/dnsdistdist/docs/reference/dq.rst @@ -403,7 +403,15 @@ DNSResponse object - ``useECS`` If the value is really needed while the response is being processed, it is possible to set a tag while the query is processed, as tags will be passed to the response object. - It also has one additional method: + The DNSResponse object has one additional attribute: + + .. attribute:: DNSResponse.selectedBackend + + .. versionadded:: 1.9.0 + + :ref:`ComboAddress` of the selected backend. + + It also has additional methods: .. method:: DNSResponse:editTTLs(func) From 662dda3ead35bb59fd5ab4e45b7626fe54b2a6f0 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 19 Sep 2023 08:57:15 +0200 Subject: [PATCH 724/909] Some delinting of common cache code --- pdns/cachecleaner.hh | 4 ++-- pdns/recursordist/negcache.cc | 12 ++++++------ pdns/recursordist/negcache.hh | 22 +++++++++++++++++++++- pdns/recursordist/recpacketcache.cc | 12 ++++++------ pdns/recursordist/recpacketcache.hh | 29 ++++++++++++++++++++++++----- pdns/recursordist/recursor_cache.cc | 8 ++++---- pdns/recursordist/recursor_cache.hh | 23 +++++++++++++++++++++-- 7 files changed, 84 insertions(+), 26 deletions(-) diff --git a/pdns/cachecleaner.hh b/pdns/cachecleaner.hh index 9ec8e13c22ce..8373ae6f01c6 100644 --- a/pdns/cachecleaner.hh +++ b/pdns/cachecleaner.hh @@ -167,7 +167,7 @@ uint64_t pruneMutexCollectionsVector(C& container, std::vector& maps, uint64_ container.preRemoval(*shard, *i); i = sidx.erase(i); erased++; - --content.d_entriesCount; + content.decEntriesCount(); } else { ++i; @@ -226,7 +226,7 @@ uint64_t pruneMutexCollectionsVector(C& container, std::vector& maps, uint64_ for (auto i = sidx.begin(); i != sidx.end() && removed < toTrimForThisShard; removed++) { container.preRemoval(*shard, *i); i = sidx.erase(i); - --content.d_entriesCount; + content.decEntriesCount(); ++totErased; if (--toTrim == 0) { return totErased; diff --git a/pdns/recursordist/negcache.cc b/pdns/recursordist/negcache.cc index 57ac811e1300..be67da138bac 100644 --- a/pdns/recursordist/negcache.cc +++ b/pdns/recursordist/negcache.cc @@ -39,7 +39,7 @@ size_t NegCache::size() const { size_t count = 0; for (const auto& map : d_maps) { - count += map.d_entriesCount; + count += map.getEntriesCount(); } return count; } @@ -161,7 +161,7 @@ void NegCache::add(const NegCacheEntry& ne) auto content = map.lock(); inserted = lruReplacingInsert(content->d_map, ne); if (inserted) { - ++map.d_entriesCount; + map.incEntriesCount(); } } @@ -229,7 +229,7 @@ size_t NegCache::wipe(const DNSName& name, bool subtree) break; i = m->d_map.erase(i); ret++; - --map.d_entriesCount; + map.decEntriesCount(); } } return ret; @@ -242,7 +242,7 @@ size_t NegCache::wipe(const DNSName& name, bool subtree) while (i != range.second) { i = content->d_map.erase(i); ret++; - --map.d_entriesCount; + map.decEntriesCount(); } return ret; } @@ -258,7 +258,7 @@ size_t NegCache::wipeTyped(const DNSName& qname, QType qtype) if (i->d_qtype == QType::ENT || i->d_qtype == qtype) { i = content->d_map.erase(i); ++ret; - --map.d_entriesCount; + map.decEntriesCount(); } else { ++i; @@ -275,7 +275,7 @@ void NegCache::clear() for (auto& map : d_maps) { auto m = map.lock(); m->d_map.clear(); - map.d_entriesCount = 0; + map.clearEntriesCount(); } } diff --git a/pdns/recursordist/negcache.hh b/pdns/recursordist/negcache.hh index 90d64ee822fb..1ac2855e31f1 100644 --- a/pdns/recursordist/negcache.hh +++ b/pdns/recursordist/negcache.hh @@ -141,7 +141,6 @@ private: uint64_t d_acquired_count{0}; void invalidate() {} }; - pdns::stat_t d_entriesCount{0}; LockGuardedTryHolder lock() { @@ -154,8 +153,29 @@ private: return locked; } + [[nodiscard]] auto getEntriesCount() const + { + return d_entriesCount.load(); + } + + void incEntriesCount() + { + ++d_entriesCount; + } + + void decEntriesCount() + { + --d_entriesCount; + } + + void clearEntriesCount() + { + d_entriesCount = 0; + } + private: LockGuarded d_content; + pdns::stat_t d_entriesCount{0}; }; vector d_maps; diff --git a/pdns/recursordist/recpacketcache.cc b/pdns/recursordist/recpacketcache.cc index 77dc63e1e126..4ae3cb51704e 100644 --- a/pdns/recursordist/recpacketcache.cc +++ b/pdns/recursordist/recpacketcache.cc @@ -24,7 +24,7 @@ uint64_t RecursorPacketCache::size() const { uint64_t count = 0; for (const auto& map : d_maps) { - count += map.d_entriesCount; + count += map.getEntriesCount(); } return count; } @@ -92,7 +92,7 @@ uint64_t RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qt } if (qtype == 0xffff || iter->d_type == qtype) { iter = idx.erase(iter); - map.d_entriesCount--; + map.decEntriesCount(); count++; } else { @@ -235,20 +235,20 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, return; } - struct Entry entry(qname, qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState); + struct Entry entry(DNSName(qname), qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState); if (pbdata) { entry.d_pbdata = std::move(*pbdata); } shard->d_map.insert(entry); - map.d_entriesCount++; + map.incEntriesCount(); if (shard->d_map.size() > shard->d_shardSize) { auto& seq_idx = shard->d_map.get(); seq_idx.erase(seq_idx.begin()); - map.d_entriesCount--; + map.decEntriesCount(); } - assert(map.d_entriesCount == shard->d_map.size()); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clib implementation + assert(map.getEntriesCount() == shard->d_map.size()); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clib implementation } void RecursorPacketCache::doPruneTo(size_t maxSize) diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index 2e847687a127..5a8c23a60613 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -21,7 +21,7 @@ */ #pragma once #include -#include +#include #include "dns.hh" #include "namespaces.hh" #include @@ -104,9 +104,9 @@ public: private: struct Entry { - Entry(const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& packet, std::string&& query, bool tcp, - uint32_t qhash, time_t ttd, time_t now, uint32_t tag, vState vstate) : - d_name(qname), d_packet(std::move(packet)), d_query(std::move(query)), d_ttd(ttd), d_creation(now), d_qhash(qhash), d_tag(tag), d_type(qtype), d_class(qclass), d_vstate(vstate), d_tcp(tcp) + Entry(DNSName&& qname, uint16_t qtype, uint16_t qclass, std::string&& packet, std::string&& query, bool tcp, + uint32_t qhash, time_t ttd, time_t now, uint32_t tag, vState vstate) : // NOLINT + d_name(std::move(qname)), d_packet(std::move(packet)), d_query(std::move(query)), d_ttd(ttd), d_creation(now), d_qhash(qhash), d_tag(tag), d_type(qtype), d_class(qclass), d_vstate(vstate), d_tcp(tcp) { } @@ -157,8 +157,12 @@ private: struct MapCombo { MapCombo() = default; + ~MapCombo() = default; MapCombo(const MapCombo&) = delete; + MapCombo(MapCombo&&) = delete; MapCombo& operator=(const MapCombo&) = delete; + MapCombo& operator=(MapCombo&&) = delete; + struct LockedContent { packetCache_t d_map; @@ -169,7 +173,6 @@ private: uint64_t d_acquired_count{0}; void invalidate() {} }; - pdns::stat_t d_entriesCount{0}; LockGuardedTryHolder lock() { @@ -182,8 +185,24 @@ private: return locked; } + [[nodiscard]] auto getEntriesCount() const + { + return d_entriesCount.load(); + } + + void incEntriesCount() + { + ++d_entriesCount; + } + + void decEntriesCount() + { + --d_entriesCount; + } + private: LockGuarded d_content; + pdns::stat_t d_entriesCount{0}; }; vector d_maps; diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index 60116e9ff141..d3e434017eec 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -63,7 +63,7 @@ size_t MemRecursorCache::size() const { size_t count = 0; for (const auto& shard : d_maps) { - count += shard.d_entriesCount; + count += shard.getEntriesCount(); } return count; } @@ -548,7 +548,7 @@ void MemRecursorCache::replace(time_t now, const DNSName& qname, const QType qt, cache_t::iterator stored = lockedShard->d_map.find(key); if (stored == lockedShard->d_map.end()) { stored = lockedShard->d_map.insert(CacheEntry(key, auth)).first; - ++shard.d_entriesCount; + shard.incEntriesCount(); isNew = true; } @@ -641,7 +641,7 @@ size_t MemRecursorCache::doWipeCache(const DNSName& name, bool sub, const QType if (i->d_qtype == qtype || qtype == 0xffff) { i = idx.erase(i); count++; - --shard.d_entriesCount; + shard.decEntriesCount(); } else { ++i; @@ -670,7 +670,7 @@ size_t MemRecursorCache::doWipeCache(const DNSName& name, bool sub, const QType if (i->d_qtype == qtype || qtype == 0xffff) { count++; i = idx.erase(i); - --mc.d_entriesCount; + mc.decEntriesCount(); } else { ++i; diff --git a/pdns/recursordist/recursor_cache.hh b/pdns/recursordist/recursor_cache.hh index 379249b61002..7cc2f0316c05 100644 --- a/pdns/recursordist/recursor_cache.hh +++ b/pdns/recursordist/recursor_cache.hh @@ -249,8 +249,6 @@ private: } }; - pdns::stat_t d_entriesCount{0}; - LockGuardedTryHolder lock() { auto locked = d_content.try_lock(); @@ -262,8 +260,29 @@ private: return locked; } + [[nodiscard]] auto getEntriesCount() const + { + return d_entriesCount.load(); + } + + void incEntriesCount() + { + ++d_entriesCount; + } + + void decEntriesCount() + { + --d_entriesCount; + } + + void clearEntriesCount() + { + d_entriesCount = 0; + } + private: LockGuarded d_content; + pdns::stat_t d_entriesCount{0}; }; vector d_maps; From 94ec52cd67180c6b1a3ecf3feb2e2f0d2b5dc27f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Sat, 16 Sep 2023 14:58:25 +0200 Subject: [PATCH 725/909] rec: Fix sysconfdir handling in new settings code Partly from @RvdE Fixes #13259 --- pdns/recursordist/docs/settings.rst | 2 +- pdns/recursordist/docs/yamlsettings.rst | 2 +- pdns/recursordist/settings/generate.py | 6 ++++-- pdns/recursordist/settings/rust/Makefile.am | 2 +- pdns/recursordist/settings/table.py | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 23682e1a01f8..89c14d3d46ce 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -363,7 +363,7 @@ Time to wait for data from TCP clients. ~~~~~~~~~~~~~~ - String -- Default: /etc/powerdns +- Default: SYSCONFDIR - YAML setting: :ref:`setting-yaml-recursor.config_dir` diff --git a/pdns/recursordist/docs/yamlsettings.rst b/pdns/recursordist/docs/yamlsettings.rst index ccaa639cc3dc..5e9baea4398c 100644 --- a/pdns/recursordist/docs/yamlsettings.rst +++ b/pdns/recursordist/docs/yamlsettings.rst @@ -2030,7 +2030,7 @@ Either do not ``chroot`` on these systems or set the 'Type' of this service to ' ^^^^^^^^^^^^^^^^^^^^^^^ - String -- Default: ``/etc/powerdns`` +- Default: ``SYSCONFDIR`` - Old style setting: :ref:`setting-config-dir` diff --git a/pdns/recursordist/settings/generate.py b/pdns/recursordist/settings/generate.py index 84051fb6cd59..5129da3105f9 100644 --- a/pdns/recursordist/settings/generate.py +++ b/pdns/recursordist/settings/generate.py @@ -209,7 +209,8 @@ def gen_cxx_defineoldsettings(file, entries): elif entry['type'] == LType.Command: file.write(f" ::arg().setCmd({oldname}, {helptxt});\n") else: - file.write(f" ::arg().set({oldname}, {helptxt}) = {quote(entry['default'])};\n") + cxxdef = 'SYSCONFDIR' if entry['default'] == 'SYSCONFDIR' else quote(entry['default']) + file.write(f" ::arg().set({oldname}, {helptxt}) = {cxxdef};\n") file.write('}\n\n') def gen_cxx_oldstylesettingstobridgestruct(file, entries): @@ -402,7 +403,8 @@ def gen_rust_default_functions(entry, name, rust_type): return gen_rust_authzonevec_default_functions(name) ret = f'// DEFAULT HANDLING for {name}\n' ret += f'fn default_value_{name}() -> {rust_type} {{\n' - ret += f" String::from({quote(entry['default'])})\n" + rustdef = 'env!("SYSCONFDIR")' if entry['default'] == 'SYSCONFDIR' else quote(entry['default']) + ret += f" String::from({rustdef})\n" ret += '}\n' if rust_type == 'String': rust_type = 'str' diff --git a/pdns/recursordist/settings/rust/Makefile.am b/pdns/recursordist/settings/rust/Makefile.am index ac1a27e330ff..1f95a6f77de3 100644 --- a/pdns/recursordist/settings/rust/Makefile.am +++ b/pdns/recursordist/settings/rust/Makefile.am @@ -11,7 +11,7 @@ EXTRA_DIST = \ # should actually end up in a target specific dir... libsettings.a lib.rs.h: src/bridge.rs src/lib.rs src/helpers.rs Cargo.toml Cargo.lock build.rs - $(CARGO) build --release $(RUST_TARGET) + SYSCONFDIR=$(sysconfdir) $(CARGO) build --release $(RUST_TARGET) cp target/$(RUSTC_TARGET_ARCH)/release/libsettings.a libsettings.a cp target/$(RUSTC_TARGET_ARCH)/cxxbridge/settings/src/lib.rs.h lib.rs.h cp target/$(RUSTC_TARGET_ARCH)/cxxbridge/rust/cxx.h cxx.h diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index e57ea13940b1..02dd1ab92898 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -379,7 +379,7 @@ 'name' : 'config_dir', 'section' : 'recursor', 'type' : LType.String, - 'default' : '/etc/powerdns', + 'default' : 'SYSCONFDIR', 'help' : 'Location of configuration directory (recursor.conf)', 'doc' : ''' Location of configuration directory (``recursor.conf``). From dbe7b146f967e98a516f4ecb1df6057bf67724d8 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 19 Sep 2023 09:24:52 +0200 Subject: [PATCH 726/909] Small fixes in comments and log messages from review --- pdns/recursordist/rec-main.cc | 4 ++-- pdns/recursordist/rec-tcp.cc | 12 ++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index dc192506f5e7..9303399531e5 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -223,8 +223,8 @@ int RecThreadInfo::runThreads(Logr::log_t log) const auto cpusMap = parseCPUMap(log); if (RecThreadInfo::numDistributors() + RecThreadInfo::numUDPWorkers() == 1) { - SLOG(g_log << Logger::Warning << "Operating with single distributor/worker thread" << endl, - log->info(Logr::Notice, "Operating with single distributor/worker thread")); + SLOG(g_log << Logger::Warning << "Operating with single UDP distributor/worker thread" << endl, + log->info(Logr::Notice, "Operating with single UDP distributor/worker thread")); /* This thread handles the web server, carbon, statistics and the control channel */ unsigned int currentThreadId = 0; diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index a5a921cd49a3..ca3c3b3e3687 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -27,6 +27,8 @@ #include "mplexer.hh" #include "uuid-utils.hh" +// OLD PRE 5.0.0 situation: +// // When pdns-distributes-queries is false with reuseport true (the default since 4.9.0), TCP queries // are read and handled by worker threads. If the kernel balancing is OK for TCP sockets (observed // to be good on Debian bullseye, but not good on e.g. MacOS), the TCP handling is no extra burden. @@ -34,7 +36,7 @@ // queries do get distributed round-robin over the worker threads. Do note the TCP queries might // need to wait until the g_maxUDPQueriesPerRound is reached. // -// In the case of pdns-distributes-queries true and reuseport false the queries are read and +// In the case of pdns-distributes-queries true and reuseport false the queries were read and // initially processed by the distributor thread(s). // // Initial processing consist of parsing, calling gettag and checking if we have a packet cache @@ -43,18 +45,20 @@ // final answer will be sent by the same distributor thread that originally picked up the query. // // Changing this, and having incoming TCP queries handled by worker threads is somewhat more complex -// than UDP, as the socket must remain avaiable in the distributor thread (for reading more +// than UDP, as the socket must remain available in the distributor thread (for reading more // queries), but the TCP socket must also be passed to a worker thread so it can write its // answer. The in-flight bookkeeping also has to be aware of how a query is handled to do the // accounting properly. I am not sure if changing the current setup is worth all this trouble, // especially since the default is now to not use pdns-distributes-queries, which works well in many // cases. // +// NEW SITUATION SINCE 5.0.0: +// // The drawback mentioned in https://github.com/PowerDNS/pdns/issues/8394 are not longer true, so an // alternative approach would be to introduce dedicated TCP worker thread(s). // -// And this approach was implemented in https://github.com/PowerDNS/pdns/pull/13195. The distributor -// and worker thread(s) now no longe process TCP queries. +// This approach was implemented in https://github.com/PowerDNS/pdns/pull/13195. The distributor and +// worker thread(s) now no longer process TCP queries. size_t g_tcpMaxQueriesPerConn; unsigned int g_maxTCPPerClient; From bc3700f87912cfb5e43587e12b5c9f1d9d72c16f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Sat, 16 Sep 2023 15:57:27 +0200 Subject: [PATCH 727/909] Improve config-dir docs a bit --- pdns/recursordist/docs/settings.rst | 3 ++- pdns/recursordist/docs/yamlsettings.rst | 3 ++- pdns/recursordist/settings/table.py | 5 +++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 89c14d3d46ce..ba9e877f1ba4 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -367,8 +367,9 @@ Time to wait for data from TCP clients. - YAML setting: :ref:`setting-yaml-recursor.config_dir` -Location of configuration directory (``recursor.conf``). +Location of configuration directory (where ``recursor.conf`` or ``recursor.yml`` is stored). Usually ``/etc/powerdns``, but this depends on ``SYSCONFDIR`` during compile-time. +Use default or set on command line. .. _setting-config-name: diff --git a/pdns/recursordist/docs/yamlsettings.rst b/pdns/recursordist/docs/yamlsettings.rst index 5e9baea4398c..cec4d93b08fb 100644 --- a/pdns/recursordist/docs/yamlsettings.rst +++ b/pdns/recursordist/docs/yamlsettings.rst @@ -2034,8 +2034,9 @@ Either do not ``chroot`` on these systems or set the 'Type' of this service to ' - Old style setting: :ref:`setting-config-dir` -Location of configuration directory (``recursor.conf``). +Location of configuration directory (where ``recursor.conf`` or ``recursor.yml`` is stored). Usually ``/etc/powerdns``, but this depends on ``SYSCONFDIR`` during compile-time. +Use default or set on command line. .. _setting-yaml-recursor.config_name: diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index 02dd1ab92898..6178aac50f6b 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -380,10 +380,11 @@ 'section' : 'recursor', 'type' : LType.String, 'default' : 'SYSCONFDIR', - 'help' : 'Location of configuration directory (recursor.conf)', + 'help' : 'Location of configuration directory (recursor.conf or recursor.yml)', 'doc' : ''' -Location of configuration directory (``recursor.conf``). +Location of configuration directory (where ``recursor.conf`` or ``recursor.yml`` is stored). Usually ``/etc/powerdns``, but this depends on ``SYSCONFDIR`` during compile-time. +Use default or set on command line. ''', }, { From 4e3713e67b867d0477c96c0f1dba5cd5d95bcfdf Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 19 Sep 2023 09:47:31 +0200 Subject: [PATCH 728/909] rec: allow loglevel to be set to levels < 3 Fixes #13264 Also document what happens if quiet is set. --- pdns/recursordist/docs/settings.rst | 6 +++++- pdns/recursordist/docs/yamlsettings.rst | 6 +++++- pdns/recursordist/rec-main.cc | 3 --- pdns/recursordist/settings/table.py | 6 ++++-- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst index 23682e1a01f8..ac2dbea96319 100644 --- a/pdns/recursordist/docs/settings.rst +++ b/pdns/recursordist/docs/settings.rst @@ -1229,6 +1229,9 @@ This feature is intended to facilitate ip-failover setups, but it may also mask ``loglevel`` ~~~~~~~~~~~~ +.. versionchanged:: 5.0.0 + + Previous version would not allow setting a level below ``3 (error)``. - Integer - Default: 6 @@ -1236,9 +1239,10 @@ This feature is intended to facilitate ip-failover setups, but it may also mask - YAML setting: :ref:`setting-yaml-logging.loglevel` Amount of logging. The higher the number, the more lines logged. -Corresponds to 'syslog' level values (e.g. 0 = emergency, 1 = alert, 2 = critical, 3 = error, 4 = warning, 5 = notice, 6 = info, 7 = debug). +Corresponds to ``syslog`` level values (e.g. 0 = ``emergency``, 1 = ``alert``, 2 = ``critical``, 3 = ``error``, 4 = ``warning``, 5 = ``notice``, 6 = ``info``, 7 = ``debug``). Each level includes itself plus the lower levels before it. Not recommended to set this below 3. +If :ref:`setting-quiet` is ``no/false``, :ref:`setting-loglevel` will be minimally set to ``6 (info)``. .. _setting-log-common-errors: diff --git a/pdns/recursordist/docs/yamlsettings.rst b/pdns/recursordist/docs/yamlsettings.rst index ccaa639cc3dc..9d82b106c2d0 100644 --- a/pdns/recursordist/docs/yamlsettings.rst +++ b/pdns/recursordist/docs/yamlsettings.rst @@ -1065,6 +1065,9 @@ Do not pass names like 'local0'! ``logging.loglevel`` ^^^^^^^^^^^^^^^^^^^^ +.. versionchanged:: 5.0.0 + + Previous version would not allow setting a level below ``3 (error)``. - Integer - Default: ``6`` @@ -1072,9 +1075,10 @@ Do not pass names like 'local0'! - Old style setting: :ref:`setting-loglevel` Amount of logging. The higher the number, the more lines logged. -Corresponds to 'syslog' level values (e.g. 0 = emergency, 1 = alert, 2 = critical, 3 = error, 4 = warning, 5 = notice, 6 = info, 7 = debug). +Corresponds to ``syslog`` level values (e.g. 0 = ``emergency``, 1 = ``alert``, 2 = ``critical``, 3 = ``error``, 4 = ``warning``, 5 = ``notice``, 6 = ``info``, 7 = ``debug``). Each level includes itself plus the lower levels before it. Not recommended to set this below 3. +If :ref:`setting-yaml-logging.quiet` is ``no/false``, :ref:`setting-yaml-logging.loglevel` will be minimally set to ``6 (info)``. .. _setting-yaml-logging.protobuf_use_kernel_timestamp: diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 10469fb44508..2769e9e2ccc7 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -3282,9 +3282,6 @@ int main(int argc, char** argv) g_slogStructured = ::arg().mustDo("structured-logging"); s_structured_logger_backend = ::arg()["structured-logging-backend"]; - if (s_logUrgency < Logger::Error) { - s_logUrgency = Logger::Error; - } if (!g_quiet && s_logUrgency < Logger::Info) { // Logger::Info=6, Logger::Debug=7 s_logUrgency = Logger::Info; // if you do --quiet=no, you need Info to also see the query log } diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index e57ea13940b1..127603bb1ca9 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -1238,11 +1238,13 @@ 'help' : 'Amount of logging. Higher is more. Do not set below 3', 'doc' : ''' Amount of logging. The higher the number, the more lines logged. -Corresponds to 'syslog' level values (e.g. 0 = emergency, 1 = alert, 2 = critical, 3 = error, 4 = warning, 5 = notice, 6 = info, 7 = debug). +Corresponds to ``syslog`` level values (e.g. 0 = ``emergency``, 1 = ``alert``, 2 = ``critical``, 3 = ``error``, 4 = ``warning``, 5 = ``notice``, 6 = ``info``, 7 = ``debug``). Each level includes itself plus the lower levels before it. Not recommended to set this below 3. +If :ref:`setting-quiet` is ``no/false``, :ref:`setting-loglevel` will be minimally set to ``6 (info)``. ''', - }, + 'versionchanged': ('5.0.0', 'Previous version would not allow setting a level below ``3 (error)``.') + }, { 'name' : 'common_errors', 'section' : 'logging', From 9dd36cf5271ab176132507887db533a191e06894 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 19 Sep 2023 13:07:08 +0200 Subject: [PATCH 729/909] rec: Switch randomization of unit tests back on The mthread fixes from #13251 should allow that now --- pdns/recursordist/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index 39f8c2ebf52d..f75a0962d35b 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -93,7 +93,7 @@ TESTS=test_libcrypto if UNIT_TESTS noinst_PROGRAMS = testrunner -TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message BOOST_TEST_RANDOM=0 SRCDIR='$(srcdir)' +TESTS_ENVIRONMENT = env BOOST_TEST_LOG_LEVEL=message BOOST_TEST_RANDOM=1 SRCDIR='$(srcdir)' TESTS += testrunner else check-local: From ab86fe94fccc1f04c1a247aa94183bd4e82bd3d0 Mon Sep 17 00:00:00 2001 From: dmachard <5562930+dmachard@users.noreply.github.com> Date: Tue, 19 Sep 2023 17:47:44 +0200 Subject: [PATCH 730/909] wrap DownstreamState instead of ComboAddress --- pdns/dnsdist-lua-bindings-dnsquestion.cc | 13 +++---------- pdns/dnsdistdist/docs/reference/dq.rst | 8 +++----- 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/pdns/dnsdist-lua-bindings-dnsquestion.cc b/pdns/dnsdist-lua-bindings-dnsquestion.cc index 7427f18f6ddd..057f71c9073a 100644 --- a/pdns/dnsdist-lua-bindings-dnsquestion.cc +++ b/pdns/dnsdist-lua-bindings-dnsquestion.cc @@ -501,15 +501,8 @@ class AsynchronousObject return dnsdist::queueQueryResumptionEvent(std::move(query)); }); - luaCtx.registerMember("selectedBackend", - []( const DNSResponse& dr) -> const ComboAddress { - if (dr.d_downstream == nullptr) { - return ComboAddress(); - } else { - return dr.d_downstream->d_config.remote; - } - }, - [](DNSResponse& dr, const ComboAddress newSelectedBackend) { (void) newSelectedBackend; } - ); + luaCtx.registerFunction(DNSResponse::*)(void)const>("getSelectedBackend", [](const DNSResponse& dr) { + return dr.d_downstream; + }); #endif /* DISABLE_NON_FFI_DQ_BINDINGS */ } diff --git a/pdns/dnsdistdist/docs/reference/dq.rst b/pdns/dnsdistdist/docs/reference/dq.rst index 1d301588eb1c..08bb84cde74d 100644 --- a/pdns/dnsdistdist/docs/reference/dq.rst +++ b/pdns/dnsdistdist/docs/reference/dq.rst @@ -403,15 +403,13 @@ DNSResponse object - ``useECS`` If the value is really needed while the response is being processed, it is possible to set a tag while the query is processed, as tags will be passed to the response object. - The DNSResponse object has one additional attribute: + It also has additional methods: - .. attribute:: DNSResponse.selectedBackend + .. method:: DNSResponse.getSelectedBackend() -> Server .. versionadded:: 1.9.0 - :ref:`ComboAddress` of the selected backend. - - It also has additional methods: + Get the selected backend :class:`Server` or nil .. method:: DNSResponse:editTTLs(func) From 1e325a929a3dd6e1eca1f52cb854bbb3eeb57009 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 19 Sep 2023 11:03:43 +0200 Subject: [PATCH 731/909] Add test for TTL perc bug found while working on issue #13266 --- pdns/recursordist/test-recpacketcache_cc.cc | 64 ++++++++++++++++++++- pdns/recursordist/test-syncres_cc.cc | 2 + 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/test-recpacketcache_cc.cc b/pdns/recursordist/test-recpacketcache_cc.cc index e0494fe18ac9..8b0787d7f52c 100644 --- a/pdns/recursordist/test-recpacketcache_cc.cc +++ b/pdns/recursordist/test-recpacketcache_cc.cc @@ -10,6 +10,8 @@ #include "dns_random.hh" #include "iputils.hh" #include "recpacketcache.hh" +#include "taskqueue.hh" +#include "rec-taskqueue.hh" #include BOOST_AUTO_TEST_SUITE(test_recpacketcache_cc) @@ -80,6 +82,66 @@ BOOST_AUTO_TEST_CASE(test_recPacketCacheSimple) BOOST_CHECK_EQUAL(rpc.size(), 0U); } +BOOST_AUTO_TEST_CASE(test_recPacketCacheSimpleWithRefresh) +{ + RecursorPacketCache::s_refresh_ttlperc = 30; + RecursorPacketCache rpc(1000); + string fpacket; + unsigned int tag = 0; + uint32_t age = 0; + uint32_t qhash = 0; + uint32_t ttd = 3600; + BOOST_CHECK_EQUAL(rpc.size(), 0U); + + DNSName qname("www.powerdns.com"); + vector packet; + DNSPacketWriter pw(packet, qname, QType::A); + pw.getHeader()->rd = true; + pw.getHeader()->qr = false; + pw.getHeader()->id = dns_random_uint16(); + string qpacket((const char*)&packet[0], packet.size()); + pw.startRecord(qname, QType::A, ttd); + + time_t now = time(nullptr); + + BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash), false); + + ARecordContent ar("127.0.0.1"); + ar.toPacket(pw); + pw.commit(); + string rpacket((const char*)&packet[0], packet.size()); + + rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), now, ttd, vState::Indeterminate, boost::none, false); + BOOST_CHECK_EQUAL(rpc.size(), 1U); + uint32_t qhash2 = 0; + bool found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash2); + BOOST_CHECK_EQUAL(found, true); + BOOST_CHECK_EQUAL(qhash, qhash2); + BOOST_CHECK_EQUAL(fpacket, rpacket); + + BOOST_REQUIRE_EQUAL(getTaskSize(), 0U); + + // Half of time has passed, no task should have been submitted + now += ttd / 2; + found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash2); + BOOST_CHECK_EQUAL(found, true); + BOOST_CHECK_EQUAL(qhash, qhash2); + BOOST_CHECK_EQUAL(fpacket, rpacket); + + BOOST_REQUIRE_EQUAL(getTaskSize(), 0U); + + // 75% of time has passed, task should have been submitted as refresh perc is 30 and (100-75) = 25 <= 30 + now += ttd / 4; + found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash2); + BOOST_CHECK_EQUAL(found, true); + BOOST_CHECK_EQUAL(qhash, qhash2); + BOOST_CHECK_EQUAL(fpacket, rpacket); + + BOOST_REQUIRE_EQUAL(getTaskSize(), 1U); + auto task = taskQueuePop(); + BOOST_CHECK_EQUAL(task.d_qname, qname); +} + BOOST_AUTO_TEST_CASE(test_recPacketCacheSimplePost2038) { RecursorPacketCache rpc(1000); @@ -275,7 +337,7 @@ BOOST_AUTO_TEST_CASE(test_recPacketCache_Tags) BOOST_AUTO_TEST_CASE(test_recPacketCache_TCP) { /* Insert a response with UDP, the exact same query with a TCP flag - should lead to a miss. + should lead to a miss. */ RecursorPacketCache rpc(1000); string fpacket; diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index 179d6b0269c0..044af5533229 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -7,6 +7,7 @@ #include "root-dnssec.hh" #include "rec-taskqueue.hh" #include "test-syncres_cc.hh" +#include "recpacketcache.hh" GlobalStateHolder g_luaconfs; GlobalStateHolder g_xdnssec; @@ -139,6 +140,7 @@ void initSR(bool debug) g_log.toConsole(Logger::Error); } + RecursorPacketCache::s_refresh_ttlperc = 0; MemRecursorCache::s_maxServedStaleExtensions = 0; NegCache::s_maxServedStaleExtensions = 0; g_recCache = std::make_unique(); From a6b423a2c0965d8306bcd3e73e9f800dd957e25a Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 19 Sep 2023 11:13:23 +0200 Subject: [PATCH 732/909] Reformat and use specific NOLINT --- pdns/recursordist/rec-taskqueue.hh | 1 - pdns/recursordist/recpacketcache.hh | 15 +++++++++++++-- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/rec-taskqueue.hh b/pdns/recursordist/rec-taskqueue.hh index 73eedeecede7..13658055c59d 100644 --- a/pdns/recursordist/rec-taskqueue.hh +++ b/pdns/recursordist/rec-taskqueue.hh @@ -57,4 +57,3 @@ uint64_t getAlmostExpiredTasksRun(); uint64_t getAlmostExpiredTaskExceptions(); bool taskQTypeIsSupported(QType qtype); - diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index 5a8c23a60613..22207068a9b4 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -105,8 +105,19 @@ private: struct Entry { Entry(DNSName&& qname, uint16_t qtype, uint16_t qclass, std::string&& packet, std::string&& query, bool tcp, - uint32_t qhash, time_t ttd, time_t now, uint32_t tag, vState vstate) : // NOLINT - d_name(std::move(qname)), d_packet(std::move(packet)), d_query(std::move(query)), d_ttd(ttd), d_creation(now), d_qhash(qhash), d_tag(tag), d_type(qtype), d_class(qclass), d_vstate(vstate), d_tcp(tcp) + // NOLINTNEXTLINE(bugprone-easily-swappable-parameters) + uint32_t qhash, time_t ttd, time_t now, uint32_t tag, vState vstate) : + d_name(std::move(qname)), + d_packet(std::move(packet)), + d_query(std::move(query)), + d_ttd(ttd), + d_creation(now), + d_qhash(qhash), + d_tag(tag), + d_type(qtype), + d_class(qclass), + d_vstate(vstate), + d_tcp(tcp) { } From 19dbd4894ea330cd928488ce08590d21888496a3 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 21 Sep 2023 08:43:29 +0200 Subject: [PATCH 733/909] rec: Clear taskQueue at start of tets run Not all tests leave an empty queue. Test that use syncres get an auto clear, but this test does not use syncres. --- pdns/recursordist/test-recpacketcache_cc.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pdns/recursordist/test-recpacketcache_cc.cc b/pdns/recursordist/test-recpacketcache_cc.cc index 8b0787d7f52c..a3d783b0910d 100644 --- a/pdns/recursordist/test-recpacketcache_cc.cc +++ b/pdns/recursordist/test-recpacketcache_cc.cc @@ -93,6 +93,8 @@ BOOST_AUTO_TEST_CASE(test_recPacketCacheSimpleWithRefresh) uint32_t ttd = 3600; BOOST_CHECK_EQUAL(rpc.size(), 0U); + taskQueueClear(); + DNSName qname("www.powerdns.com"); vector packet; DNSPacketWriter pw(packet, qname, QType::A); From e9ca1b280b02b2ab12d11934cce0b18684b4d076 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 22 Sep 2023 11:05:46 +0200 Subject: [PATCH 734/909] dnsscope: Add a `--port` option to select a custom port --- pdns/dnsscope.cc | 305 +++++++++++++++++++++++++---------------------- 1 file changed, 161 insertions(+), 144 deletions(-) diff --git a/pdns/dnsscope.cc b/pdns/dnsscope.cc index 06c45dd4e22a..5e52d407a5f9 100644 --- a/pdns/dnsscope.cc +++ b/pdns/dnsscope.cc @@ -146,6 +146,7 @@ try ("filter-name,f", po::value(), "Do statistics only for queries within this domain") ("load-stats,l", po::value()->default_value(""), "if set, emit per-second load statistics (questions, answers, outstanding)") ("no-servfail-stats", "Don't include servfails in response time stats") + ("port", po::value()->default_value(0), "The source and destination port to consider. Default is looking at packets from and to ports 53 and 5300") ("servfail-tree", "Figure out subtrees that generate servfails") ("stats-dir", po::value()->default_value("."), "Directory where statistics will be saved") ("write-failures,w", po::value()->default_value(""), "if set, write weird packets to this PCAP file") @@ -217,6 +218,7 @@ try std::unordered_set requestors, recipients, rdnonra; typedef vector > pcounts_t; pcounts_t pcounts; + const uint16_t port = g_vm["port"].as(); OPTRecordContent::report(); for(unsigned int fno=0; fno < files.size(); ++fno) { @@ -228,164 +230,179 @@ try EDNSOpts edo; while(pr.getUDPPacket()) { - if((ntohs(pr.d_udp->uh_dport)==5300 || ntohs(pr.d_udp->uh_sport)==5300 || - ntohs(pr.d_udp->uh_dport)==53 || ntohs(pr.d_udp->uh_sport)==53) && - pr.d_len > 12) { - try { - if((pr.d_ip->ip_v == 4 && !doIPv4) || (pr.d_ip->ip_v == 6 && !doIPv6)) - continue; - if(pr.d_ip->ip_v == 4) { - uint16_t frag = ntohs(pr.d_ip->ip_off); - if((frag & IP_MF) || (frag & IP_OFFMASK)) { // more fragments or IS a fragment - fragmented++; - continue; - } - } - uint16_t qtype; - DNSName qname((const char*)pr.d_payload, pr.d_len, 12, false, &qtype); - struct dnsheader header; - memcpy(&header, (struct dnsheader*)pr.d_payload, 12); - - if(haveRDFilter && header.rd != rdFilter) { - rdFilterMismatch++; - continue; - } - - if(!filtername.empty() && !qname.isPartOf(filtername)) { - nameMismatch++; + if (pr.d_len <= 12) { + // non-DNS ip + nonDNSIP++; + continue; + } + if (port > 0 && + (ntohs(pr.d_udp->uh_dport) != port && ntohs(pr.d_udp->uh_sport) != port)) { + // non-DNS ip + nonDNSIP++; + continue; + } + + if (port == 0 && + (ntohs(pr.d_udp->uh_dport) != 5300 && ntohs(pr.d_udp->uh_sport) != 5300 && + ntohs(pr.d_udp->uh_dport) != 53 && ntohs(pr.d_udp->uh_sport) != 53)) { + // non-DNS ip + nonDNSIP++; + continue; + } + + try { + if ((pr.d_ip->ip_v == 4 && !doIPv4) || (pr.d_ip->ip_v == 6 && !doIPv6)) { + continue; + } + + if (pr.d_ip->ip_v == 4) { + uint16_t frag = ntohs(pr.d_ip->ip_off); + if((frag & IP_MF) || (frag & IP_OFFMASK)) { // more fragments or IS a fragment + fragmented++; continue; } + } + uint16_t qtype; + DNSName qname((const char*)pr.d_payload, pr.d_len, 12, false, &qtype); + struct dnsheader header; + memcpy(&header, (struct dnsheader*)pr.d_payload, 12); + + if(haveRDFilter && header.rd != rdFilter) { + rdFilterMismatch++; + continue; + } + + if(!filtername.empty() && !qname.isPartOf(filtername)) { + nameMismatch++; + continue; + } + + if(!header.qr) { + uint16_t udpsize, z; + if(getEDNSUDPPayloadSizeAndZ((const char*)pr.d_payload, pr.d_len, &udpsize, &z)) { + edns++; + if(z & EDNSOpts::DNSSECOK) + dnssecOK++; + if(header.cd) + dnssecCD++; + if(header.ad) + dnssecAD++; + } + } + + if(pr.d_ip->ip_v == 4) + ++ipv4DNSPackets; + else + ++ipv6DNSPackets; - if(!header.qr) { - uint16_t udpsize, z; - if(getEDNSUDPPayloadSizeAndZ((const char*)pr.d_payload, pr.d_len, &udpsize, &z)) { - edns++; - if(z & EDNSOpts::DNSSECOK) - dnssecOK++; - if(header.cd) - dnssecCD++; - if(header.ad) - dnssecAD++; + if(pr.d_pheader.ts.tv_sec != lastsec) { + LiveCounts lc; + if(lastsec) { + lc.questions = queries; + lc.answers = answers; + lc.outstanding = liveQuestions(); + + LiveCounts diff = lc - lastcounts; + pcounts.emplace_back(pr.d_pheader.ts.tv_sec, diff); + } + lastsec = pr.d_pheader.ts.tv_sec; + lastcounts = lc; + } + + if(lowestTime) { lowestTime = min((time_t)lowestTime, (time_t)pr.d_pheader.ts.tv_sec); } + else { lowestTime = pr.d_pheader.ts.tv_sec; } + highestTime=max((time_t)highestTime, (time_t)pr.d_pheader.ts.tv_sec); + + QuestionIdentifier qi=QuestionIdentifier::create(pr.getSource(), pr.getDest(), header, qname, qtype); + + if(!header.qr) { // question + // cout<<"Query "<ip_v == 4) - ++ipv4DNSPackets; - else - ++ipv6DNSPackets; + if(header.ra) { + ComboAddress rem = pr.getDest(); + rem.sin4.sin_port=0; + recipients.insert(rem); + } - if(pr.d_pheader.ts.tv_sec != lastsec) { - LiveCounts lc; - if(lastsec) { - lc.questions = queries; - lc.answers = answers; - lc.outstanding = liveQuestions(); + QuestionData& qd=statmap[qi]; + if(!qd.d_qcount) { + // cout<<"Untracked answer: "<write(); - parsefail++; - continue; - } + if(!qd.d_qcount || qd.d_qcount == qd.d_answercount) { + // cout<<"Clearing state for "<write(); + parsefail++; + continue; } } - cout<<"PCAP contained "< Date: Fri, 22 Sep 2023 11:17:09 +0200 Subject: [PATCH 735/909] dnsscope: Add the new `--port` option to the man page --- docs/manpages/dnsscope.1.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/manpages/dnsscope.1.rst b/docs/manpages/dnsscope.1.rst index 3945d9ebbcba..0cd0518584c8 100644 --- a/docs/manpages/dnsscope.1.rst +++ b/docs/manpages/dnsscope.1.rst @@ -27,6 +27,7 @@ INFILE --full-histogram Write out histogram with specified bin-size to 'full-histogram' --log-histogram Write out a log-histogram of response times to 'log-histogram' --no-servfail-stats Remove servfail responses from latency statistics +--port The source and destination port to consider. Default is looking at packets from and to ports 53 and 5300. --servfail-tree Figure out subtrees that generate servfails. --stats-dir Drop statistics files in this directory. Defaults to ./ -l, --load-stats Emit per-second load statistics (questions, answers, outstanding). From fdcc46e44f19cac1372d5f9a066d7e25fc200449 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 22 Sep 2023 11:35:47 +0200 Subject: [PATCH 736/909] rec: modify docs publishing workflow to generate docs Some of our docs are now generated, generate them before building and publishing Fixes #13234 --- .github/workflows/documentation.yml | 2 + pdns/recursordist/docs/.gitignore | 2 + pdns/recursordist/docs/settings.rst | 3124 ---------------------- pdns/recursordist/docs/yamlsettings.rst | 3195 ----------------------- tasks.py | 4 + 5 files changed, 8 insertions(+), 6319 deletions(-) delete mode 100644 pdns/recursordist/docs/settings.rst delete mode 100644 pdns/recursordist/docs/yamlsettings.rst diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml index 25a89a6e9619..c4285310d7cf 100644 --- a/.github/workflows/documentation.yml +++ b/.github/workflows/documentation.yml @@ -59,6 +59,8 @@ jobs: if: ${{github.ref_name == 'master' && steps.setup-ssh.outputs.have_ssh_key != ''}} # Rec + - run: inv ci-docs-rec-generate + working-directory: ./pdns/recursordist/settings - run: inv ci-docs-build working-directory: ./pdns/recursordist - run: mv html rec-html-docs diff --git a/pdns/recursordist/docs/.gitignore b/pdns/recursordist/docs/.gitignore index e35d8850c968..d0c946e6363e 100644 --- a/pdns/recursordist/docs/.gitignore +++ b/pdns/recursordist/docs/.gitignore @@ -1 +1,3 @@ _build +/settings.rst +/yamlsettings.rst diff --git a/pdns/recursordist/docs/settings.rst b/pdns/recursordist/docs/settings.rst deleted file mode 100644 index f3e1a5a764a9..000000000000 --- a/pdns/recursordist/docs/settings.rst +++ /dev/null @@ -1,3124 +0,0 @@ -.. THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir - START INCLUDE docs-old-preamble-in.rst - -PowerDNS Recursor Settings -========================== -Each setting can appear on the command line, prefixed by ``--``, or in the configuration file. -The command line overrides the configuration file. - -.. note:: - Starting with version 5.0.0, :program:`Recursor` supports a new YAML syntax for configuration files. - A configuration using the old style syntax can be converted to a YAML configuration using the instructions in :doc:`appendices/yamlconversion`. - In a future release support for the "old-style" settings will be dropped. - -.. note:: - Settings marked as ``Boolean`` can either be set to an empty value, which means **on**, or to ``no`` or ``off`` which means **off**. - Anything else means **on**. - - For example: - - - ``serve-rfc1918`` on its own means: do serve those zones. - - ``serve-rfc1918 = off`` or ``serve-rfc1918 = no`` means: do not serve those zones. - - Anything else means: do serve those zones. - -You can use ``+=`` syntax to set some variables incrementally, but this -requires you to have at least one non-incremental setting for the -variable to act as base setting. This is mostly useful for -:ref:`setting-include-dir` directive. An example:: - - forward-zones = foo.example.com=192.168.100.1; - forward-zones += bar.example.com=[1234::abcde]:5353; - -When a list of **Netmasks** is mentioned, a list of subnets can be specified. -A subnet that is not followed by ``/`` will be interpreted as a ``/32`` or ``/128`` subnet (a single address), depending on address family. -For most settings, it is possible to exclude ranges by prefixing an item with the negation character ``!``. -For example:: - - allow-from = 2001:DB8::/32, 128.66.0.0/16, !128.66.1.2 - -In this case the address ``128.66.1.2`` is excluded from the addresses allowed access. - -The Settings ------------- -.. END INCLUDE docs-old-preamble-in.rst - -.. _setting-aggressive-nsec-cache-size: - -``aggressive-nsec-cache-size`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Integer -- Default: 100000 - -- YAML setting: :ref:`setting-yaml-dnssec.aggressive_nsec_cache_size` - -The number of records to cache in the aggressive cache. If set to a value greater than 0, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in :rfc:`8198`. -To use this, DNSSEC processing or validation must be enabled by setting :ref:`setting-dnssec` to ``process``, ``log-fail`` or ``validate``. - -.. _setting-aggressive-cache-min-nsec3-hit-ratio: - -``aggressive-cache-min-nsec3-hit-ratio`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.9.0 - -- Integer -- Default: 2000 - -- YAML setting: :ref:`setting-yaml-dnssec.aggressive_cache_min_nsec3_hit_ratio` - -The limit for which to put NSEC3 records into the aggressive cache. -A value of ``n`` means that an NSEC3 record is only put into the aggressive cache if the estimated probability of a random name hitting the NSEC3 record is higher than ``1/n``. -A higher ``n`` will cause more records to be put into the aggressive cache, e.g. a value of 4000 will cause records to be put in the aggressive cache even if the estimated probability of hitting them is twice as low as would be the case for ``n=2000``. -A value of 0 means no NSEC3 records will be put into the aggressive cache. - -For large zones the effectiveness of the NSEC3 cache is reduced since each NSEC3 record only covers a randomly distributed subset of all possible names. -This setting avoids doing unnecessary work for such large zones. - -.. _setting-allow-from: - -``allow-from`` -~~~~~~~~~~~~~~ - -- Comma separated list of IP addresses or subnets, negation supported -- Default: 127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10 - -- YAML setting: :ref:`setting-yaml-incoming.allow_from` - -Netmasks (both IPv4 and IPv6) that are allowed to use the server. -The default allows access only from :rfc:`1918` private IP addresses. -An empty value means no checking is done, all clients are allowed. -Due to the aggressive nature of the internet these days, it is highly recommended to not open up the recursor for the entire internet. -Questions from IP addresses not listed here are ignored and do not get an answer. - -When the Proxy Protocol is enabled (see :ref:`setting-proxy-protocol-from`), the recursor will check the address of the client IP advertised in the Proxy Protocol header instead of the one of the proxy. - -Note that specifying an IP address without a netmask uses an implicit netmask of /32 or /128. - -.. _setting-allow-from-file: - -``allow-from-file`` -~~~~~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-incoming.allow_from_file` - -Like :ref:`setting-allow-from`, except reading from file. -Overrides the :ref:`setting-allow-from` setting. To use this feature, supply one netmask per line, with optional comments preceded by a '#'. - -.. _setting-allow-notify-for: - -``allow-notify-for`` -~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Comma separated list of strings -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-incoming.allow_notify_for` - -Domain names specified in this list are used to permit incoming -NOTIFY operations to wipe any cache entries that match the domain -name. If this list is empty, all NOTIFY operations will be ignored. - -.. _setting-allow-notify-for-file: - -``allow-notify-for-file`` -~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-incoming.allow_notify_for_file` - -Like :ref:`setting-allow-notify-for`, except reading from file. To use this -feature, supply one domain name per line, with optional comments -preceded by a '#'. - -NOTIFY-allowed zones can also be specified using :ref:`setting-forward-zones-file`. - -.. _setting-allow-notify-from: - -``allow-notify-from`` -~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Comma separated list of IP addresses or subnets, negation supported -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-incoming.allow_notify_from` - -Netmasks (both IPv4 and IPv6) that are allowed to issue NOTIFY operations -to the server. NOTIFY operations from IP addresses not listed here are -ignored and do not get an answer. - -When the Proxy Protocol is enabled (see :ref:`setting-proxy-protocol-from`), the -recursor will check the address of the client IP advertised in the -Proxy Protocol header instead of the one of the proxy. - -Note that specifying an IP address without a netmask uses an implicit -netmask of /32 or /128. - -NOTIFY operations received from a client listed in one of these netmasks -will be accepted and used to wipe any cache entries whose zones match -the zone specified in the NOTIFY operation, but only if that zone (or -one of its parents) is included in :ref:`setting-allow-notify-for`, -:ref:`setting-allow-notify-for-file`, or :ref:`setting-forward-zones-file` with a '^' prefix. - -.. _setting-allow-notify-from-file: - -``allow-notify-from-file`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-incoming.allow_notify_from_file` - -Like :ref:`setting-allow-notify-from`, except reading from file. To use this -feature, supply one netmask per line, with optional comments preceded -by a '#'. - -.. _setting-any-to-tcp: - -``any-to-tcp`` -~~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-recursor.any_to_tcp` - -Answer questions for the ANY type on UDP with a truncated packet that refers the remote server to TCP. -Useful for mitigating ANY reflection attacks. - -.. _setting-allow-trust-anchor-query: - -``allow-trust-anchor-query`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.3.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-recursor.allow_trust_anchor_query` - -Allow ``trustanchor.server CH TXT`` and ``negativetrustanchor.server CH TXT`` queries to view the configured :doc:`DNSSEC ` (negative) trust anchors. - -.. _setting-api-config-dir: - -``api-config-dir`` -~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.0.0 - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-webservice.api_dir` - -Directory where the REST API stores its configuration and zones. -For configuration updates to work, :ref:`setting-include-dir` should have the same value. - -.. _setting-api-key: - -``api-key`` -~~~~~~~~~~~ -.. versionadded:: 4.0.0 -.. versionchanged:: 4.6.0 - - This setting now accepts a hashed and salted version. - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-webservice.api_key` - -Static pre-shared authentication key for access to the REST API. Since 4.6.0 the key can be hashed and salted using ``rec_control hash-password`` instead of being stored in the configuration in plaintext, but the plaintext version is still supported. - -.. _setting-auth-zones: - -``auth-zones`` -~~~~~~~~~~~~~~ - -- Comma separated list of 'zonename=filename' pairs -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.auth_zones` - -Zones read from these files (in BIND format) are served authoritatively (but without the AA bit set in responses). -DNSSEC is not supported. Example: - -.. code-block:: none - - auth-zones=example.org=/var/zones/example.org, powerdns.com=/var/zones/powerdns.com - -.. _setting-carbon-interval: - -``carbon-interval`` -~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 30 - -- YAML setting: :ref:`setting-yaml-carbon.interval` - -If sending carbon updates, this is the interval between them in seconds. -See :doc:`metrics`. - -.. _setting-carbon-namespace: - -``carbon-namespace`` -~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- String -- Default: pdns - -- YAML setting: :ref:`setting-yaml-carbon.ns` - -Change the namespace or first string of the metric key. The default is pdns. - -.. _setting-carbon-ourname: - -``carbon-ourname`` -~~~~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-carbon.ourname` - -If sending carbon updates, if set, this will override our hostname. -Be careful not to include any dots in this setting, unless you know what you are doing. -See :ref:`metricscarbon`. - -.. _setting-carbon-instance: - -``carbon-instance`` -~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- String -- Default: recursor - -- YAML setting: :ref:`setting-yaml-carbon.instance` - -Change the instance or third string of the metric key. The default is recursor. - -.. _setting-carbon-server: - -``carbon-server`` -~~~~~~~~~~~~~~~~~ - -- Comma separated list or IPs of IP:port combinations -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-carbon.server` - -If set to an IP or IPv6 address, will send all available metrics to this server via the carbon protocol, which is used by graphite and metronome. Moreover you can specify more than one server using a comma delimited list, ex: carbon-server=10.10.10.10,10.10.10.20. -You may specify an alternate port by appending :port, for example: ``127.0.0.1:2004``. -See :doc:`metrics`. - -.. _setting-chroot: - -``chroot`` -~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.chroot` - -If set, chroot to this directory for more security. -This is not recommended; instead, we recommend containing PowerDNS using operating system features. -We ship systemd unit files with our packages to make this easy. - -Make sure that ``/dev/log`` is available from within the chroot. -Logging will silently fail over time otherwise (on logrotate). - -When using ``chroot``, all other paths (except for :ref:`setting-config-dir`) set in the configuration are relative to the new root. - -When running on a system where systemd manages services, ``chroot`` does not work out of the box, as PowerDNS cannot use the ``NOTIFY_SOCKET``. -Either do not ``chroot`` on these systems or set the 'Type' of this service to 'simple' instead of 'notify' (refer to the systemd documentation on how to modify unit-files). - -.. _setting-client-tcp-timeout: - -``client-tcp-timeout`` -~~~~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 2 - -- YAML setting: :ref:`setting-yaml-incoming.tcp_timeout` - -Time to wait for data from TCP clients. - -.. _setting-config-dir: - -``config-dir`` -~~~~~~~~~~~~~~ - -- String -- Default: SYSCONFDIR - -- YAML setting: :ref:`setting-yaml-recursor.config_dir` - -Location of configuration directory (where ``recursor.conf`` or ``recursor.yml`` is stored). -Usually ``/etc/powerdns``, but this depends on ``SYSCONFDIR`` during compile-time. -Use default or set on command line. - -.. _setting-config-name: - -``config-name`` -~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.config_name` - -When running multiple recursors on the same server, read settings from :file:`recursor-{name}.conf`, this will also rename the binary image. - -.. _setting-cpu-map: - -``cpu-map`` -~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.cpu_map` - -Set CPU affinity for threads, asking the scheduler to run those threads on a single CPU, or a set of CPUs. -This parameter accepts a space separated list of thread-id=cpu-id, or thread-id=cpu-id-1,cpu-id-2,...,cpu-id-N. -For example, to make the worker thread 0 run on CPU id 0 and the worker thread 1 on CPUs 1 and 2:: - -.. code-block:: yaml - - recursor: - cpu_map: 0=0 1=1,2 - -The thread handling the control channel, the webserver and other internal stuff has been assigned id 0, the distributor -threads if any are assigned id 1 and counting, and the worker threads follow behind. -The number of distributor threads is determined by :ref:`setting-distributor-threads`, the number of worker threads is determined by the :ref:`setting-threads` setting. - -This parameter is only available if the OS provides the ``pthread_setaffinity_np()`` function. - -Note that depending on the configuration the Recursor can start more threads. -Typically these threads will sleep most of the time. -These threads cannot be specified in this setting as their thread-ids are left unspecified. - -.. _setting-daemon: - -``daemon`` -~~~~~~~~~~ -.. versionchanged:: 4.0.0 - - Default is now ``no``, was ``yes`` before. - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-recursor.daemon` - -Operate in the background. - -.. _setting-dont-throttle-names: - -``dont-throttle-names`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Comma separated list of strings -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-outgoing.dont_throttle_names` - -When an authoritative server does not answer a query or sends a reply the recursor does not like, it is throttled. -Any servers' name suffix-matching the supplied names will never be throttled. - -.. warning:: - Most servers on the internet do not respond for a good reason (overloaded or unreachable), ``dont-throttle-names`` could make this load on the upstream server even higher, resulting in further service degradation. - -.. _setting-dont-throttle-netmasks: - -``dont-throttle-netmasks`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Comma separated list of IP addresses or subnets, negation supported -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-outgoing.dont_throttle_netmasks` - -When an authoritative server does not answer a query or sends a reply the recursor does not like, it is throttled. -Any servers matching the supplied netmasks will never be throttled. - -This can come in handy on lossy networks when forwarding, where the same server is configured multiple times (e.g. with ``forward-zones-recurse=example.com=192.0.2.1;192.0.2.1``). -By default, the PowerDNS Recursor would throttle the 'first' server on a timeout and hence not retry the 'second' one. -In this case, ``dont-throttle-netmasks`` could be set to ``192.0.2.1``. - -.. warning:: - Most servers on the internet do not respond for a good reason (overloaded or unreachable), ``dont-throttle-netmasks`` could make this load on the upstream server even higher, resulting in further service degradation. - -.. _setting-disable-packetcache: - -``disable-packetcache`` -~~~~~~~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-packetcache.disable` - -Turn off the packet cache. Useful when running with Lua scripts that can not be cached, though individual query caching can be controlled from Lua as well. - -.. _setting-disable-syslog: - -``disable-syslog`` -~~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-logging.disable_syslog` - -Do not log to syslog, only to stdout. -Use this setting when running inside a supervisor that handles logging (like systemd). -**Note**: do not use this setting in combination with :ref:`setting-daemon` as all logging will disappear. - -.. _setting-distribution-load-factor: - -``distribution-load-factor`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.12 - -- Double -- Default: 0.0 - -- YAML setting: :ref:`setting-yaml-incoming.distribution_load_factor` - -If :ref:`setting-pdns-distributes-queries` is set and this setting is set to another value -than 0, the distributor thread will use a bounded load-balancing algorithm while -distributing queries to worker threads, making sure that no thread is assigned -more queries than distribution-load-factor times the average number of queries -currently processed by all the workers. -For example, with a value of 1.25, no server should get more than 125 % of the -average load. This helps making sure that all the workers have roughly the same -share of queries, even if the incoming traffic is very skewed, with a larger -number of requests asking for the same qname. - -.. _setting-distribution-pipe-buffer-size: - -``distribution-pipe-buffer-size`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-incoming.distribution_pipe_buffer_size` - -Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread. -Requires support for `F_SETPIPE_SZ` which is present in Linux since 2.6.35. The actual size might be rounded up to -a multiple of a page size. 0 means that the OS default size is used. -A large buffer might allow the recursor to deal with very short-lived load spikes during which a worker thread gets -overloaded, but it will be at the cost of an increased latency. - -.. _setting-distributor-threads: - -``distributor-threads`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Integer -- Default: 1 if :ref:`setting-pdns-distributes-queries` is set, 0 otherwise - -- YAML setting: :ref:`setting-yaml-incoming.distributor_threads` - -If :ref:`setting-pdns-distributes-queries` is set, spawn this number of distributor threads on startup. Distributor threads -handle incoming queries and distribute them to other threads based on a hash of the query. - -.. _setting-dot-to-auth-names: - -``dot-to-auth-names`` -~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Comma separated list of strings -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-outgoing.dot_to_auth_names` - -Force DoT to the listed authoritative nameservers. For this to work, DoT support has to be compiled in. -Currently, the certificate is not checked for validity in any way. - -.. _setting-dot-to-port-853: - -``dot-to-port-853`` -~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-outgoing.dot_to_port_853` - -Enable DoT to forwarders that specify port 853. - -.. _setting-dns64-prefix: - -``dns64-prefix`` -~~~~~~~~~~~~~~~~ -.. versionadded:: 4.4.0 - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.dns64_prefix` - -Enable DNS64 (:rfc:`6147`) support using the supplied /96 IPv6 prefix. This will generate 'fake' ``AAAA`` records for names -with only ``A`` records, as well as 'fake' ``PTR`` records to make sure that reverse lookup of DNS64-generated IPv6 addresses -generate the right name. -See :doc:`dns64` for more flexible but slower alternatives using Lua. - -.. _setting-dnssec: - -``dnssec`` -~~~~~~~~~~ -.. versionadded:: 4.0.0 -.. versionchanged:: 4.5.0 - - The default changed from ``process-no-validate`` to ``process`` - -- String -- Default: process - -- YAML setting: :ref:`setting-yaml-dnssec.validation` - -One of ``off``, ``process-no-validate``, ``process``, ``log-fail``, ``validate`` - -Set the mode for DNSSEC processing, as detailed in :doc:`dnssec`. - -``off`` - No DNSSEC processing whatsoever. - Ignore DO-bits in queries, don't request any DNSSEC information from authoritative servers. - This behaviour is similar to PowerDNS Recursor pre-4.0. -``process-no-validate`` - Respond with DNSSEC records to clients that ask for it, set the DO bit on all outgoing queries. - Don't do any validation. -``process`` - Respond with DNSSEC records to clients that ask for it, set the DO bit on all outgoing queries. - Do validation for clients that request it (by means of the AD- bit or DO-bit in the query). -``log-fail`` - Similar behaviour to ``process``, but validate RRSIGs on responses and log bogus responses. -``validate`` - Full blown DNSSEC validation. Send SERVFAIL to clients on bogus responses. - -.. _setting-dnssec-disabled-algorithms: - -``dnssec-disabled-algorithms`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.9.0 - -- Comma separated list of strings -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-dnssec.disabled_algorithms` - -A list of DNSSEC algorithm numbers that should be considered disabled. -These algorithms will not be used to validate DNSSEC signatures. -Zones (only) signed with these algorithms will be considered ``Insecure``. - -If this setting is empty (the default), :program:`Recursor` will determine which algorithms to disable automatically. -This is done for specific algorithms only, currently algorithms 5 (``RSASHA1``) and 7 (``RSASHA1NSEC3SHA1``). - -This is important on systems that have a default strict crypto policy, like RHEL9 derived systems. -On such systems not disabling some algorithms (or changing the security policy) will make affected zones to be considered ``Bogus`` as using these algorithms fails. - -.. _setting-dnssec-log-bogus: - -``dnssec-log-bogus`` -~~~~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-dnssec.log_bogus` - -Log every DNSSEC validation failure. -**Note**: This is not logged per-query but every time records are validated as Bogus. - -.. _setting-dont-query: - -``dont-query`` -~~~~~~~~~~~~~~ - -- Comma separated list of IP addresses or subnets, negation supported -- Default: 127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10, 0.0.0.0/8, 192.0.0.0/24, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::/96, ::ffff:0:0/96, 100::/64, 2001:db8::/32 - -- YAML setting: :ref:`setting-yaml-outgoing.dont_query` - -The DNS is a public database, but sometimes contains delegations to private IP addresses, like for example 127.0.0.1. -This can have odd effects, depending on your network, and may even be a security risk. -Therefore, the PowerDNS Recursor by default does not query private space IP addresses. -This setting can be used to expand or reduce the limitations. - -Queries for names in forward zones and to addresses as configured in any of the settings :ref:`setting-forward-zones`, :ref:`setting-forward-zones-file` or :ref:`setting-forward-zones-recurse` are performed regardless of these limitations. - -.. _setting-ecs-add-for: - -``ecs-add-for`` -~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Comma separated list of IP addresses or subnets, negation supported -- Default: 0.0.0.0/0, ::/0, !127.0.0.0/8, !10.0.0.0/8, !100.64.0.0/10, !169.254.0.0/16, !192.168.0.0/16, !172.16.0.0/12, !::1/128, !fc00::/7, !fe80::/10 - -- YAML setting: :ref:`setting-yaml-ecs.add_for` - -List of requestor netmasks for which the requestor IP Address should be used as the :rfc:`EDNS Client Subnet <7871>` for outgoing queries. Outgoing queries for requestors that do not match this list will use the :ref:`setting-ecs-scope-zero-address` instead. -Valid incoming ECS values from :ref:`setting-use-incoming-edns-subnet` are not replaced. - -Regardless of the value of this setting, ECS values are only sent for outgoing queries matching the conditions in the :ref:`setting-edns-subnet-allow-list` setting. This setting only controls the actual value being sent. - -This defaults to not using the requestor address inside RFC1918 and similar 'private' IP address spaces. - -.. _setting-ecs-ipv4-bits: - -``ecs-ipv4-bits`` -~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 - -- Integer -- Default: 24 - -- YAML setting: :ref:`setting-yaml-ecs.ipv4_bits` - -Number of bits of client IPv4 address to pass when sending EDNS Client Subnet address information. - -.. _setting-ecs-ipv4-cache-bits: - -``ecs-ipv4-cache-bits`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.12 - -- Integer -- Default: 24 - -- YAML setting: :ref:`setting-yaml-ecs.ipv4_cache_bits` - -Maximum number of bits of client IPv4 address used by the authoritative server (as indicated by the EDNS Client Subnet scope in the answer) for an answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-cache-limit-ttl``. -That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. - -.. _setting-ecs-ipv6-bits: - -``ecs-ipv6-bits`` -~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 - -- Integer -- Default: 56 - -- YAML setting: :ref:`setting-yaml-ecs.ipv6_bits` - -Number of bits of client IPv6 address to pass when sending EDNS Client Subnet address information. - -.. _setting-ecs-ipv6-cache-bits: - -``ecs-ipv6-cache-bits`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.12 - -- Integer -- Default: 56 - -- YAML setting: :ref:`setting-yaml-ecs.ipv6_cache_bits` - -Maximum number of bits of client IPv6 address used by the authoritative server (as indicated by the EDNS Client Subnet scope in the answer) for an answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-cache-limit-ttl``. -That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. - -.. _setting-ecs-ipv4-never-cache: - -``ecs-ipv4-never-cache`` -~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-ecs.ipv4_never_cache` - -When set, never cache replies carrying EDNS IPv4 Client Subnet scope in the record cache. -In this case the decision made by ```ecs-ipv4-cache-bits`` and ``ecs-cache-limit-ttl`` is no longer relevant. - -.. _setting-ecs-ipv6-never-cache: - -``ecs-ipv6-never-cache`` -~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-ecs.ipv6_never_cache` - -When set, never cache replies carrying EDNS IPv6 Client Subnet scope in the record cache. -In this case the decision made by ```ecs-ipv6-cache-bits`` and ``ecs-cache-limit-ttl`` is no longer relevant. - -.. _setting-ecs-minimum-ttl-override: - -``ecs-minimum-ttl-override`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.5.0 - - Old versions used default 0. - -- Integer -- Default: 1 - -- YAML setting: :ref:`setting-yaml-ecs.minimum_ttl_override` - -This setting artificially raises the TTLs of records in the ANSWER section of ECS-specific answers to be at least this long. -Setting this to a value greater than 1 technically is an RFC violation, but might improve performance a lot. -Using a value of 0 impacts performance of TTL 0 records greatly, since it forces the recursor to contact -authoritative servers every time a client requests them. -Can be set at runtime using ``rec_control set-ecs-minimum-ttl 3600``. - -.. _setting-ecs-cache-limit-ttl: - -``ecs-cache-limit-ttl`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.12 - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-ecs.cache_limit_ttl` - -The minimum TTL for an ECS-specific answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-ipv4-cache-bits`` or ``ecs-ipv6-cache-bits``. -That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. - -.. _setting-ecs-scope-zero-address: - -``ecs-scope-zero-address`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-ecs.scope_zero_address` - -The IP address sent via EDNS Client Subnet to authoritative servers listed in -:ref:`setting-edns-subnet-allow-list` when :ref:`setting-use-incoming-edns-subnet` is set and the query has -an ECS source prefix-length set to 0. -The default is to look for the first usable (not an ``any`` one) address in -:ref:`setting-query-local-address` (starting with IPv4). If no suitable address is -found, the recursor fallbacks to sending 127.0.0.1. - -.. _setting-edns-outgoing-bufsize: - -``edns-outgoing-bufsize`` -~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.2.0 - - Before 4.2.0, the default was 1680 - -- Integer -- Default: 1232 - -- YAML setting: :ref:`setting-yaml-outgoing.edns_bufsize` - -.. note:: Why 1232? - - 1232 is the largest number of payload bytes that can fit in the smallest IPv6 packet. - IPv6 has a minimum MTU of 1280 bytes (:rfc:`RFC 8200, section 5 <8200#section-5>`), minus 40 bytes for the IPv6 header, minus 8 bytes for the UDP header gives 1232, the maximum payload size for the DNS response. - -This is the value set for the EDNS0 buffer size in outgoing packets. -Lower this if you experience timeouts. - -.. _setting-edns-padding-from: - -``edns-padding-from`` -~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-incoming.edns_padding_from` - -List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that :ref:`setting-edns-padding-mode` applies. - -.. _setting-edns-padding-mode: - -``edns-padding-mode`` -~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- String -- Default: padded-queries-only - -- YAML setting: :ref:`setting-yaml-incoming.edns_padding_mode` - -One of ``always``, ``padded-queries-only``. -Whether to add EDNS padding to all responses (``always``) or only to responses for queries containing the EDNS padding option (``padded-queries-only``, the default). -In both modes, padding will only be added to responses for queries coming from :ref:`setting-edns-padding-from` sources. - -.. _setting-edns-padding-out: - -``edns-padding-out`` -~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.8.0 - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-outgoing.edns_padding` - -Whether to add EDNS padding to outgoing DoT queries. - -.. _setting-edns-padding-tag: - -``edns-padding-tag`` -~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Integer -- Default: 7830 - -- YAML setting: :ref:`setting-yaml-incoming.edns_padding_tag` - -The packetcache tag to use for padded responses, to prevent a client not allowed by the :ref::`setting-edns-padding-from` list to be served a cached answer generated for an allowed one. This -effectively divides the packet cache in two when :ref:`setting-edns-padding-from` is used. Note that this will not override a tag set from one of the ``Lua`` hooks. - -.. _setting-edns-subnet-whitelist: - -``edns-subnet-whitelist`` -~~~~~~~~~~~~~~~~~~~~~~~~~ -.. deprecated:: 4.5.0 - - Use :ref:`setting-edns-subnet-allow-list`. - -- String -- Default: (empty) - -- YAML setting does not exist - - - -.. _setting-edns-subnet-allow-list: - -``edns-subnet-allow-list`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Comma separated list of strings -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-outgoing.edns_subnet_allow_list` - -List of netmasks and domains that :rfc:`EDNS Client Subnet <7871>` should be enabled for in outgoing queries. - -For example, an EDNS Client Subnet option containing the address of the initial requestor (but see :ref:`setting-ecs-add-for`) will be added to an outgoing query sent to server 192.0.2.1 for domain X if 192.0.2.1 matches one of the supplied netmasks, or if X matches one of the supplied domains. -The initial requestor address will be truncated to 24 bits for IPv4 (see :ref:`setting-ecs-ipv4-bits`) and to 56 bits for IPv6 (see :ref:`setting-ecs-ipv6-bits`), as recommended in the privacy section of RFC 7871. - - -Note that this setting describes the destination of outgoing queries, not the sources of incoming queries, nor the subnets described in the EDNS Client Subnet option. - -By default, this option is empty, meaning no EDNS Client Subnet information is sent. - -.. _setting-entropy-source: - -``entropy-source`` -~~~~~~~~~~~~~~~~~~ - -- String -- Default: /dev/urandom - -- YAML setting: :ref:`setting-yaml-recursor.entropy_source` - -PowerDNS can read entropy from a (hardware) source. -This is used for generating random numbers which are very hard to predict. -Generally on UNIX platforms, this source will be ``/dev/urandom``, which will always supply random numbers, even if entropy is lacking. -Change to ``/dev/random`` if PowerDNS should block waiting for enough entropy to arrive. - -.. _setting-etc-hosts-file: - -``etc-hosts-file`` -~~~~~~~~~~~~~~~~~~ - -- String -- Default: /etc/hosts - -- YAML setting: :ref:`setting-yaml-recursor.etc_hosts_file` - -The path to the /etc/hosts file, or equivalent. -This file can be used to serve data authoritatively using :ref:`setting-export-etc-hosts`. - -.. _setting-event-trace-enabled: - -``event-trace-enabled`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-recursor.event_trace_enabled` - -Enable the recording and logging of ref:`event traces`. This is an experimental feature and subject to change. -Possible values are 0: (disabled), 1 (add information to protobuf logging messages) and 2 (write to log) and 3 (both). - -.. _setting-export-etc-hosts: - -``export-etc-hosts`` -~~~~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-recursor.export_etc_hosts` - -If set, this flag will export the host names and IP addresses mentioned in ``/etc/hosts``. - -.. _setting-export-etc-hosts-search-suffix: - -``export-etc-hosts-search-suffix`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.export_etc_hosts_search_suffix` - -If set, all hostnames in the :ref:`setting-export-etc-hosts` file are loaded in canonical form, based on this suffix, unless the name contains a '.', in which case the name is unchanged. -So an entry called 'pc' with ``export-etc-hosts-search-suffix='home.com'`` will lead to the generation of 'pc.home.com' within the recursor. -An entry called 'server1.home' will be stored as 'server1.home', regardless of this setting. - -.. _setting-extended-resolution-errors: - -``extended-resolution-errors`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-recursor.extended_resolution_errors` - -If set, the recursor will add an EDNS Extended Error (:rfc:`8914`) to responses when resolution failed, like DNSSEC validation errors, explaining the reason it failed. This setting is not needed to allow setting custom error codes from Lua or from a RPZ hit. - -.. _setting-forward-zones: - -``forward-zones`` -~~~~~~~~~~~~~~~~~ - -- Comma separated list of 'zonename=IP' pairs -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.forward_zones` - -Queries for zones listed here will be forwarded to the IP address listed. i.e. - -.. code-block:: none - - forward-zones=example.org=203.0.113.210, powerdns.com=2001:DB8::BEEF:5 - -Multiple IP addresses can be specified and port numbers other than 53 can be configured: - -.. code-block:: none - - forward-zones=example.org=203.0.113.210:5300;127.0.0.1, powerdns.com=127.0.0.1;198.51.100.10:530;[2001:DB8::1:3]:5300 - -Forwarded queries have the ``recursion desired (RD)`` bit set to ``0``, meaning that this setting is intended to forward queries to authoritative servers. -If an ``NS`` record set for a subzone of the forwarded zone is learned, that record set will be used to determine addresses for name servers of the subzone. -This allows e.g. a forward to a local authoritative server holding a copy of the root zone, delegations received from that server will work. - -**IMPORTANT**: When using DNSSEC validation (which is default), forwards to non-delegated (e.g. internal) zones that have a DNSSEC signed parent zone will validate as Bogus. -To prevent this, add a Negative Trust Anchor (NTA) for this zone in the :ref:`setting-lua-config-file` with ``addNTA('your.zone', 'A comment')``. -If this forwarded zone is signed, instead of adding NTA, add the DS record to the :ref:`setting-lua-config-file`. -See the :doc:`dnssec` information. - -.. _setting-forward-zones-file: - -``forward-zones-file`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.0.0 - - (Old style settings only) Comments are allowed, everything behind ``#`` is ignored. -.. versionchanged:: 4.6.0 - - (Old style settings only) Zones prefixed with a ``^`` are added to the :ref:`setting-allow-notify-for` list. Both prefix characters can be used if desired, in any order. - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.forward_zones_file` - -Same as :ref:`setting-forward-zones`, parsed from a file. Only 1 zone is allowed per line, specified as follows: - -.. code-block:: none - - example.org=203.0.113.210, 192.0.2.4:5300 - -Zones prefixed with a ``+`` are treated as with -:ref:`setting-forward-zones-recurse`. Default behaviour without ``+`` is as with -:ref:`setting-forward-zones`. - -The DNSSEC notes from :ref:`setting-forward-zones` apply here as well. - -.. _setting-forward-zones-recurse: - -``forward-zones-recurse`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Comma separated list of 'zonename=IP' pairs -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.forward_zones_recurse` - -Like regular :ref:`setting-forward-zones`, but forwarded queries have the ``recursion desired (RD)`` bit set to ``1``, meaning that this setting is intended to forward queries to other recursive servers. -In contrast to regular forwarding, the rule that delegations of the forwarded subzones are respected is not active. -This is because we rely on the forwarder to resolve the query fully. - -See :ref:`setting-forward-zones` for additional options (such as supplying multiple recursive servers) and an important note about DNSSEC. - -.. _setting-gettag-needs-edns-options: - -``gettag-needs-edns-options`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-incoming.gettag_needs_edns_options` - -If set, EDNS options in incoming queries are extracted and passed to the :func:`gettag` hook in the ``ednsoptions`` table. - -.. _setting-hint-file: - -``hint-file`` -~~~~~~~~~~~~~ -.. versionchanged:: 4.6.2 - - Introduced the value ``no`` to disable root-hints processing. -.. versionchanged:: 4.9.0 - - Introduced the value ``no-refresh`` to disable both root-hints processing and periodic refresh of the cached root `NS` records. - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.hint_file` - -If set, the root-hints are read from this file. If empty, the default built-in root hints are used. - -In some special cases, processing the root hints is not needed, for example when forwarding all queries to another recursor. -For these special cases, it is possible to disable the processing of root hints by setting the value to ``no`` or ``no-refresh``. -See :ref:`handling-of-root-hints` for more information on root hints handling. - -.. _setting-ignore-unknown-settings: - -``ignore-unknown-settings`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Comma separated list of strings -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.ignore_unknown_settings` - -Names of settings to be ignored while parsing configuration files, if the setting -name is unknown to PowerDNS. - -Useful during upgrade testing. - -.. _setting-include-dir: - -``include-dir`` -~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.include_dir` - -Directory to scan for additional config files. All files that end with .conf are loaded in order using ``POSIX`` as locale. - -.. _setting-latency-statistic-size: - -``latency-statistic-size`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 10000 - -- YAML setting: :ref:`setting-yaml-recursor.latency_statistic_size` - -Indication of how many queries will be averaged to get the average latency reported by the 'qa-latency' metric. - -.. _setting-local-address: - -``local-address`` -~~~~~~~~~~~~~~~~~ - -- Comma separated list or IPs of IP:port combinations -- Default: 127.0.0.1 - -- YAML setting: :ref:`setting-yaml-incoming.listen` - -Local IP addresses to which we bind. Each address specified can -include a port number; if no port is included then the -:ref:`setting-local-port` port will be used for that address. If a -port number is specified, it must be separated from the address with a -':'; for an IPv6 address the address must be enclosed in square -brackets. - -Examples:: - - local-address=127.0.0.1 ::1 - local-address=0.0.0.0:5353 - local-address=[::]:8053 - local-address=127.0.0.1:53, [::1]:5353 - -.. _setting-local-port: - -``local-port`` -~~~~~~~~~~~~~~ - -- Integer -- Default: 53 - -- YAML setting: :ref:`setting-yaml-incoming.port` - -Local port to bind to. -If an address in :ref:`setting-local-address` does not have an explicit port, this port is used. - -.. _setting-log-timestamp: - -``log-timestamp`` -~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-logging.timestamp` - - - -.. _setting-non-local-bind: - -``non-local-bind`` -~~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-incoming.non_local_bind` - -Bind to addresses even if one or more of the :ref:`setting-local-address`'s do not exist on this server. -Setting this option will enable the needed socket options to allow binding to non-local addresses. -This feature is intended to facilitate ip-failover setups, but it may also mask configuration issues and for this reason it is disabled by default. - -.. _setting-loglevel: - -``loglevel`` -~~~~~~~~~~~~ -.. versionchanged:: 5.0.0 - - Previous version would not allow setting a level below ``3 (error)``. - -- Integer -- Default: 6 - -- YAML setting: :ref:`setting-yaml-logging.loglevel` - -Amount of logging. The higher the number, the more lines logged. -Corresponds to ``syslog`` level values (e.g. 0 = ``emergency``, 1 = ``alert``, 2 = ``critical``, 3 = ``error``, 4 = ``warning``, 5 = ``notice``, 6 = ``info``, 7 = ``debug``). -Each level includes itself plus the lower levels before it. -Not recommended to set this below 3. -If :ref:`setting-quiet` is ``no/false``, :ref:`setting-loglevel` will be minimally set to ``6 (info)``. - -.. _setting-log-common-errors: - -``log-common-errors`` -~~~~~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-logging.common_errors` - -Some DNS errors occur rather frequently and are no cause for alarm. - -.. _setting-log-rpz-changes: - -``log-rpz-changes`` -~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-logging.rpz_changes` - -Log additions and removals to RPZ zones at Info (6) level instead of Debug (7). - -.. _setting-logging-facility: - -``logging-facility`` -~~~~~~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-logging.facility` - -If set to a digit, logging is performed under this LOCAL facility. -See :ref:`logging`. -Do not pass names like 'local0'! - -.. _setting-lowercase-outgoing: - -``lowercase-outgoing`` -~~~~~~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-outgoing.lowercase` - -Set to true to lowercase the outgoing queries. -When set to 'no' (the default) a query from a client using mixed case in the DNS labels (such as a user entering mixed-case names or `draft-vixie-dnsext-dns0x20-00 `_), PowerDNS preserves the case of the query. -Broken authoritative servers might give a wrong or broken answer on this encoding. -Setting ``lowercase-outgoing`` to 'yes' makes the PowerDNS Recursor lowercase all the labels in the query to the authoritative servers, but still return the proper case to the client requesting. - -.. _setting-lua-config-file: - -``lua-config-file`` -~~~~~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.lua_config_file` - -If set, and Lua support is compiled in, this will load an additional configuration file for newer features and more complicated setups. -See :doc:`lua-config/index` for the options that can be set in this file. - -.. _setting-lua-dns-script: - -``lua-dns-script`` -~~~~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.lua_dns_script` - -Path to a lua file to manipulate the Recursor's answers. See :doc:`lua-scripting/index` for more information. - -.. _setting-lua-maintenance-interval: - -``lua-maintenance-interval`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Integer -- Default: 1 - -- YAML setting: :ref:`setting-yaml-recursor.lua_maintenance_interval` - -The interval between calls to the Lua user defined `maintenance()` function in seconds. -See :ref:`hooks-maintenance-callback` - -.. _setting-max-busy-dot-probes: - -``max-busy-dot-probes`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.7.0 - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-outgoing.max_busy_dot_probes` - -Limit the maximum number of simultaneous DoT probes the Recursor will schedule. -The default value 0 means no DoT probes are scheduled. - -DoT probes are used to check if an authoritative server's IP address supports DoT. -If the probe determines an IP address supports DoT, the Recursor will use DoT to contact it for subsequent queries until a failure occurs. -After a failure, the Recursor will stop using DoT for that specific IP address for a while. -The results of probes are remembered and can be viewed by the ``rec_control dump-dot-probe-map`` command. -If the maximum number of pending probes is reached, no probes will be scheduled, even if no DoT status is known for an address. -If the result of a probe is not yet available, the Recursor will contact the authoritative server in the regular way, unless an authoritative server is configured to be contacted over DoT always using :ref:`setting-dot-to-auth-names`. -In that case no probe will be scheduled. - -.. note:: - DoT probing is an experimental feature. - Please test thoroughly to determine if it is suitable in your specific production environment before enabling. - -.. _setting-max-cache-bogus-ttl: - -``max-cache-bogus-ttl`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Integer -- Default: 3600 - -- YAML setting: :ref:`setting-yaml-recordcache.max_cache_bogus_ttl` - -Maximum number of seconds to cache an item in the DNS cache (negative or positive) if its DNSSEC validation failed, no matter what the original TTL specified, to reduce the impact of a broken domain. - -.. _setting-max-cache-entries: - -``max-cache-entries`` -~~~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 1000000 - -- YAML setting: :ref:`setting-yaml-recordcache.max_entries` - -Maximum number of DNS record cache entries, shared by all threads since 4.4.0. -Each entry associates a name and type with a record set. -The size of the negative cache is 10% of this number. - -.. _setting-max-cache-ttl: - -``max-cache-ttl`` -~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.1.0 - - The minimum value of this setting is 15. i.e. setting this to lower than 15 will make this value 15. - -- Integer -- Default: 86400 - -- YAML setting: :ref:`setting-yaml-recordcache.max_ttl` - -Maximum number of seconds to cache an item in the DNS cache, no matter what the original TTL specified. -This value also controls the refresh period of cached root data. -See :ref:`handling-of-root-hints` for more information on this. - -.. _setting-max-concurrent-requests-per-tcp-connection: - -``max-concurrent-requests-per-tcp-connection`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.3.0 - -- Integer -- Default: 10 - -- YAML setting: :ref:`setting-yaml-incoming.max_concurrent_requests_per_tcp_connection` - -Maximum number of incoming requests handled concurrently per tcp -connection. This number must be larger than 0 and smaller than 65536 -and also smaller than `max-mthreads`. - -.. _setting-max-include-depth: - -``max-include-depth`` -~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Integer -- Default: 20 - -- YAML setting: :ref:`setting-yaml-recursor.max_include_depth` - -Maximum number of nested ``$INCLUDE`` directives while processing a zone file. -Zero mean no ``$INCLUDE`` directives will be accepted. - -.. _setting-max-generate-steps: - -``max-generate-steps`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.3.0 - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-recursor.max_generate_steps` - -Maximum number of steps for a '$GENERATE' directive when parsing a -zone file. This is a protection measure to prevent consuming a lot of -CPU and memory when untrusted zones are loaded. Default to 0 which -means unlimited. - -.. _setting-max-mthreads: - -``max-mthreads`` -~~~~~~~~~~~~~~~~ - -- Integer -- Default: 2048 - -- YAML setting: :ref:`setting-yaml-recursor.max_mthreads` - -Maximum number of simultaneous MTasker threads. - -.. _setting-max-packetcache-entries: - -``max-packetcache-entries`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 500000 - -- YAML setting: :ref:`setting-yaml-packetcache.max_entries` - -Maximum number of Packet Cache entries. Sharded and shared by all threads since 4.9.0. - -.. _setting-max-qperq: - -``max-qperq`` -~~~~~~~~~~~~~ - -- Integer -- Default: 60 - -- YAML setting: :ref:`setting-yaml-recursor.max_qperq` - -The maximum number of outgoing queries that will be sent out during the resolution of a single client query. -This is used to limit endlessly chasing CNAME redirections. -If qname-minimization is enabled, the number will be forced to be 100 -at a minimum to allow for the extra queries qname-minimization generates when the cache is empty. - -.. _setting-max-ns-address-qperq: - -``max-ns-address-qperq`` -~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.16 -.. versionadded:: 4.2.2 -.. versionadded:: 4.3.1 - -- Integer -- Default: 10 - -- YAML setting: :ref:`setting-yaml-recursor.max_ns_address_qperq` - -The maximum number of outgoing queries with empty replies for -resolving nameserver names to addresses we allow during the resolution -of a single client query. If IPv6 is enabled, an A and a AAAA query -for a name counts as 1. If a zone publishes more than this number of -NS records, the limit is further reduced for that zone by lowering -it by the number of NS records found above the -:ref:`setting-max-ns-address-qperq` value. The limit wil not be reduced to a -number lower than 5. - -.. _setting-max-ns-per-resolve: - -``max-ns-per-resolve`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.8.0 -.. versionadded:: 4.7.3 -.. versionadded:: 4.6.4 -.. versionadded:: 4.5.11 - -- Integer -- Default: 13 - -- YAML setting: :ref:`setting-yaml-recursor.max_ns_per_resolve` - -The maximum number of NS records that will be considered to select a nameserver to contact to resolve a name. -If a zone has more than :ref:`setting-max-ns-per-resolve` NS records, a random sample of this size will be used. -If :ref:`setting-max-ns-per-resolve` is zero, no limit applies. - -.. _setting-max-negative-ttl: - -``max-negative-ttl`` -~~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 3600 - -- YAML setting: :ref:`setting-yaml-recordcache.max_negative_ttl` - -A query for which there is authoritatively no answer is cached to quickly deny a record's existence later on, without putting a heavy load on the remote server. -In practice, caches can become saturated with hundreds of thousands of hosts which are tried only once. -This setting, which defaults to 3600 seconds, puts a maximum on the amount of time negative entries are cached. - -.. _setting-max-recursion-depth: - -``max-recursion-depth`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.1.0 - - Before 4.1.0, this settings was unlimited. -.. versionchanged:: 4.9.0 - - Before 4.9.0 this setting's default was 40 and the limit on ``CNAME`` chains (fixed at 16) acted as a bound on he recursion depth. - -- Integer -- Default: 16 - -- YAML setting: :ref:`setting-yaml-recursor.max_recursion_depth` - -Total maximum number of internal recursion calls the server may use to answer a single query. -0 means unlimited. -The value of :ref:`setting-stack-size` should be increased together with this one to prevent the stack from overflowing. -If :ref:`setting-qname-minimization` is enabled, the fallback code in case of a failing resolve is allowed an additional `max-recursion-depth/2`. - -.. _setting-max-tcp-clients: - -``max-tcp-clients`` -~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 128 - -- YAML setting: :ref:`setting-yaml-incoming.max_tcp_clients` - -Maximum number of simultaneous incoming TCP connections allowed. - -.. _setting-max-tcp-per-client: - -``max-tcp-per-client`` -~~~~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-incoming.max_tcp_per_client` - -Maximum number of simultaneous incoming TCP connections allowed per client (remote IP address). - 0 means unlimited. - -.. _setting-max-tcp-queries-per-connection: - -``max-tcp-queries-per-connection`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-incoming.max_tcp_queries_per_connection` - -Maximum number of DNS queries in a TCP connection. -0 means unlimited. - -.. _setting-max-total-msec: - -``max-total-msec`` -~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 7000 - -- YAML setting: :ref:`setting-yaml-recursor.max_total_msec` - -Total maximum number of milliseconds of wallclock time the server may use to answer a single query. -0 means unlimited. - -.. _setting-max-udp-queries-per-round: - -``max-udp-queries-per-round`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.4 - -- Integer -- Default: 10000 - -- YAML setting: :ref:`setting-yaml-incoming.max_udp_queries_per_round` - -Under heavy load the recursor might be busy processing incoming UDP queries for a long while before there is no more of these, and might therefore -neglect scheduling new ``mthreads``, handling responses from authoritative servers or responding to :doc:`rec_control ` -requests. -This setting caps the maximum number of incoming UDP DNS queries processed in a single round of looping on ``recvmsg()`` after being woken up by the multiplexer, before -returning back to normal processing and handling other events. - -.. _setting-minimum-ttl-override: - -``minimum-ttl-override`` -~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.5.0 - - Old versions used default 0. - -- Integer -- Default: 1 - -- YAML setting: :ref:`setting-yaml-recursor.minimum_ttl_override` - -This setting artificially raises all TTLs to be at least this long. -Setting this to a value greater than 1 technically is an RFC violation, but might improve performance a lot. -Using a value of 0 impacts performance of TTL 0 records greatly, since it forces the recursor to contact -authoritative servers each time a client requests them. -Can be set at runtime using ``rec_control set-minimum-ttl 3600``. - -.. _setting-new-domain-tracking: - -``new-domain-tracking`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-nod.tracking` - -Whether to track newly observed domains, i.e. never seen before. This -is a probabilistic algorithm, using a stable bloom filter to store -records of previously seen domains. When enabled for the first time, -all domains will appear to be newly observed, so the feature is best -left enabled for e.g. a week or longer before using the results. Note -that this feature is optional and must be enabled at compile-time, -thus it may not be available in all pre-built packages. -If protobuf is enabled and configured, then the newly observed domain -status will appear as a flag in Response messages. - -.. _setting-new-domain-log: - -``new-domain-log`` -~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-nod.log` - -If a newly observed domain is detected, log that domain in the -recursor log file. The log line looks something like:: - - Jul 18 11:31:25 Newly observed domain nod=sdfoijdfio.com - -.. _setting-new-domain-lookup: - -``new-domain-lookup`` -~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-nod.lookup` - -If a domain is specified, then each time a newly observed domain is -detected, the recursor will perform an A record lookup of '.'. For example if 'new-domain-lookup' -is configured as 'nod.powerdns.com', and a new domain 'xyz123.tv' is -detected, then an A record lookup will be made for -'xyz123.tv.nod.powerdns.com'. This feature gives a way to share the -newly observed domain with partners, vendors or security teams. The -result of the DNS lookup will be ignored by the recursor. - -.. _setting-new-domain-db-size: - -``new-domain-db-size`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Integer -- Default: 67108864 - -- YAML setting: :ref:`setting-yaml-nod.db_size` - -The default size of the stable bloom filter used to store previously -observed domains is 67108864. To change the number of cells, use this -setting. For each cell, the SBF uses 1 bit of memory, and one byte of -disk for the persistent file. -If there are already persistent files saved to disk, this setting will -have no effect unless you remove the existing files. - -.. _setting-new-domain-history-dir: - -``new-domain-history-dir`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- String -- Default: /usr/local/var/lib/pdns-recursor/nod - -- YAML setting: :ref:`setting-yaml-nod.history_dir` - -This setting controls which directory is used to store the on-disk -cache of previously observed domains. - -The default depends on ``LOCALSTATEDIR`` when building the software. -Usually this comes down to ``/var/lib/pdns-recursor/nod`` or ``/usr/local/var/lib/pdns-recursor/nod``). - -The newly observed domain feature uses a stable bloom filter to store -a history of previously observed domains. The data structure is -synchronized to disk every 10 minutes, and is also initialized from -disk on startup. This ensures that previously observed domains are -preserved across recursor restarts. -If you change the new-domain-db-size setting, you must remove any files -from this directory. - -.. _setting-new-domain-whitelist: - -``new-domain-whitelist`` -~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 -.. deprecated:: 4.5.0 - - Use :ref:`setting-new-domain-ignore-list`. - -- String -- Default: (empty) - -- YAML setting does not exist - - - -.. _setting-new-domain-ignore-list: - -``new-domain-ignore-list`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Comma separated list of strings -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-nod.ignore_list` - -This setting is a list of all domains (and implicitly all subdomains) -that will never be considered a new domain. For example, if the domain -'xyz123.tv' is in the list, then 'foo.bar.xyz123.tv' will never be -considered a new domain. One use-case for the ignore list is to never -reveal details of internal subdomains via the new-domain-lookup -feature. - -.. _setting-new-domain-pb-tag: - -``new-domain-pb-tag`` -~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- String -- Default: pdns-nod - -- YAML setting: :ref:`setting-yaml-nod.pb_tag` - -If protobuf is configured, then this tag will be added to all protobuf response messages when -a new domain is observed. - -.. _setting-network-timeout: - -``network-timeout`` -~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 1500 - -- YAML setting: :ref:`setting-yaml-outgoing.network_timeout` - -Number of milliseconds to wait for a remote authoritative server to respond. - -.. _setting-non-resolving-ns-max-fails: - -``non-resolving-ns-max-fails`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Integer -- Default: 5 - -- YAML setting: :ref:`setting-yaml-recursor.non_resolving_ns_max_fails` - -Number of failed address resolves of a nameserver name to start throttling it, 0 is disabled. -Nameservers matching :ref:`setting-dont-throttle-names` will not be throttled. - -.. _setting-non-resolving-ns-throttle-time: - -``non-resolving-ns-throttle-time`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Integer -- Default: 60 - -- YAML setting: :ref:`setting-yaml-recursor.non_resolving_ns_throttle_time` - -Number of seconds to throttle a nameserver with a name failing to resolve. - -.. _setting-nothing-below-nxdomain: - -``nothing-below-nxdomain`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.3.0 - -- String -- Default: dnssec - -- YAML setting: :ref:`setting-yaml-recursor.nothing_below_nxdomain` - -- One of ``no``, ``dnssec``, ``yes``. - -The type of :rfc:`8020` handling using cached NXDOMAIN responses. -This RFC specifies that NXDOMAIN means that the DNS tree under the denied name MUST be empty. -When an NXDOMAIN exists in the cache for a shorter name than the qname, no lookup is done and an NXDOMAIN is sent to the client. - -For instance, when ``foo.example.net`` is negatively cached, any query -matching ``*.foo.example.net`` will be answered with NXDOMAIN directly -without consulting authoritative servers. - -``no`` - No :rfc:`8020` processing is done. - -``dnssec`` - :rfc:`8020` processing is only done using cached NXDOMAIN records that are - DNSSEC validated. - -``yes`` - :rfc:`8020` processing is done using any non-Bogus NXDOMAIN record - available in the cache. - -.. _setting-nsec3-max-iterations: - -``nsec3-max-iterations`` -~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 -.. versionchanged:: 4.5.2 - - Default is now 150, was 2500 before. - -- Integer -- Default: 150 - -- YAML setting: :ref:`setting-yaml-dnssec.nsec3_max_iterations` - -Maximum number of iterations allowed for an NSEC3 record. -If an answer containing an NSEC3 record with more iterations is received, its DNSSEC validation status is treated as Insecure. - -.. _setting-packetcache-ttl: - -``packetcache-ttl`` -~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.9.0 - - The default was changed from 3600 (1 hour) to 86400 (24 hours). - -- Integer -- Default: 86400 - -- YAML setting: :ref:`setting-yaml-packetcache.ttl` - -Maximum number of seconds to cache an item in the packet cache, no matter what the original TTL specified. - -.. _setting-packetcache-negative-ttl: - -``packetcache-negative-ttl`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.9.0 - -- Integer -- Default: 60 - -- YAML setting: :ref:`setting-yaml-packetcache.negative_ttl` - -Maximum number of seconds to cache an ``NxDomain`` or ``NoData`` answer in the packetcache. -This setting's maximum is capped to :ref:`setting-packetcache-ttl`. -i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-negative-ttl`` at the default will lower ``packetcache-negative-ttl`` to ``15``. - -.. _setting-packetcache-servfail-ttl: - -``packetcache-servfail-ttl`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -'versionchanged': ('4.0.0', "This setting's maximum is capped to :ref:`setting-packetcache-ttl`. - i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-servfail-ttl`` at the default will lower ``packetcache-servfail-ttl`` to ``15``.") - -- Integer -- Default: 60 - -- YAML setting: :ref:`setting-yaml-packetcache.servfail_ttl` - -Maximum number of seconds to cache an answer indicating a failure to resolve in the packet cache. -Before version 4.6.0 only ``ServFail`` answers were considered as such. Starting with 4.6.0, all responses with a code other than ``NoError`` and ``NXDomain``, or without records in the answer and authority sections, are considered as a failure to resolve. -Since 4.9.0, negative answers are handled separately from resolving failures. - -.. _setting-packetcache-shards: - -``packetcache-shards`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.9.0 - -- Integer -- Default: 1024 - -- YAML setting: :ref:`setting-yaml-packetcache.shards` - -Sets the number of shards in the packet cache. If you have high contention as reported by ``packetcache-contented/packetcache-acquired``, -you can try to enlarge this value or run with fewer threads. - -.. _setting-pdns-distributes-queries: - -``pdns-distributes-queries`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.9.0 - - Default changed to ``no``, previously it was ``yes``. - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-incoming.pdns_distributes_queries` - -If set, PowerDNS will use distinct threads to listen to client sockets and distribute that work to worker-threads using a hash of the query. -This feature should maximize the cache hit ratio on versions before 4.9.0. -To use more than one thread set :ref:`setting-distributor-threads` in version 4.2.0 or newer. -Enabling should improve performance on systems where :ref:`setting-reuseport` does not have the effect of -balancing the queries evenly over multiple worker threads. - -.. _setting-protobuf-use-kernel-timestamp: - -``protobuf-use-kernel-timestamp`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-logging.protobuf_use_kernel_timestamp` - -Whether to compute the latency of responses in protobuf messages using the timestamp set by the kernel when the query packet was received (when available), instead of computing it based on the moment we start processing the query. - -.. _setting-proxy-protocol-from: - -``proxy-protocol-from`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.4.0 - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-incoming.proxy_protocol_from` - -Ranges that are required to send a Proxy Protocol version 2 header in front of UDP and TCP queries, to pass the original source and destination addresses and ports to the recursor, as well as custom values. -Queries that are not prefixed with such a header will not be accepted from clients in these ranges. Queries prefixed by headers from clients that are not listed in these ranges will be dropped. - -Note that once a Proxy Protocol header has been received, the source address from the proxy header instead of the address of the proxy will be checked against the :ref:`setting-allow-from` ACL. - -The dnsdist docs have `more information about the PROXY protocol `_. - -.. _setting-proxy-protocol-maximum-size: - -``proxy-protocol-maximum-size`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.4.0 - -- Integer -- Default: 512 - -- YAML setting: :ref:`setting-yaml-incoming.proxy_protocol_maximum_size` - -The maximum size, in bytes, of a Proxy Protocol payload (header, addresses and ports, and TLV values). Queries with a larger payload will be dropped. - -.. _setting-public-suffix-list-file: - -``public-suffix-list-file`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.public_suffix_list_file` - -Path to the Public Suffix List file, if any. If set, PowerDNS will try to load the Public Suffix List from this file instead of using the built-in list. The PSL is used to group the queries by relevant domain names when displaying the top queries. - -.. _setting-qname-minimization: - -``qname-minimization`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.3.0 - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-recursor.qname_minimization` - -Enable Query Name Minimization. This implements a relaxed form of Query Name Mimimization as -described in :rfc:`7816`. - -.. _setting-query-local-address: - -``query-local-address`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.4.0 - - IPv6 addresses can be set with this option as well. - -- Comma separated list of IP addresses or subnets, negation supported -- Default: 0.0.0.0 - -- YAML setting: :ref:`setting-yaml-outgoing.source_address` - -Send out local queries from this address, or addresses. By adding multiple -addresses, increased spoofing resilience is achieved. When no address of a certain -address family is configured, there are *no* queries sent with that address family. -In the default configuration this means that IPv6 is not used for outgoing queries. - -.. _setting-quiet: - -``quiet`` -~~~~~~~~~ - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-logging.quiet` - -Don't log queries. - -.. _setting-record-cache-locked-ttl-perc: - -``record-cache-locked-ttl-perc`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.8.0 - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-recordcache.locked_ttl_perc` - -Replace record sets in the record cache only after this percentage of the original TTL has passed. -The PowerDNS Recursor already has several mechanisms to protect against spoofing attempts. -This adds an extra layer of protection---as it limits the window of time cache updates are accepted---at the cost of a less efficient record cache. - -The default value of 0 means no extra locking occurs. -When non-zero, record sets received (e.g. in the Additional Section) will not replace existing record sets in the record cache until the given percentage of the original TTL has expired. -A value of 100 means only expired record sets will be replaced. - -There are a few cases where records will be replaced anyway: - -- Record sets that are expired will always be replaced. -- Authoritative record sets will replace unauthoritative record sets unless DNSSEC validation of the new record set failed. -- If the new record set belongs to a DNSSEC-secure zone and successfully passed validation it will replace an existing entry. -- Record sets produced by :ref:`setting-refresh-on-ttl-perc` tasks will also replace existing record sets. - -.. _setting-record-cache-shards: - -``record-cache-shards`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.4.0 - -- Integer -- Default: 1024 - -- YAML setting: :ref:`setting-yaml-recordcache.shards` - -Sets the number of shards in the record cache. If you have high -contention as reported by -``record-cache-contented/record-cache-acquired``, you can try to -enlarge this value or run with fewer threads. - -.. _setting-refresh-on-ttl-perc: - -``refresh-on-ttl-perc`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-recordcache.refresh_on_ttl_perc` - -Sets the 'refresh almost expired' percentage of the record cache. Whenever a record is fetched from the packet or record cache -and only ``refresh-on-ttl-perc`` percent or less of its original TTL is left, a task is queued to refetch the name/type combination to -update the record cache. In most cases this causes future queries to always see a non-expired record cache entry. -A typical value is 10. If the value is zero, this functionality is disabled. - -.. _setting-reuseport: - -``reuseport`` -~~~~~~~~~~~~~ -.. versionchanged:: 4.9.0 - - The default is changed to ``yes``, previously it was ``no``. If ``SO_REUSEPORT`` support is not available, the setting defaults to ``no``. - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-incoming.reuseport` - -If ``SO_REUSEPORT`` support is available, allows multiple threads and processes to open listening sockets for the same port. - -Since 4.1.0, when :ref:`setting-pdns-distributes-queries` is disabled and :ref:`setting-reuseport` is enabled, every worker-thread will open a separate listening socket to let the kernel distribute the incoming queries instead of running a distributor thread (which could otherwise be a bottleneck) and avoiding thundering herd issues, thus leading to much higher performance on multi-core boxes. - -.. _setting-rng: - -``rng`` -~~~~~~~ - -- String -- Default: auto - -- YAML setting: :ref:`setting-yaml-recursor.rng` - -- String -- Default: auto - -Specify which random number generator to use. Permissible choices are - - auto - choose automatically - - sodium - Use libsodium ``randombytes_uniform`` - - openssl - Use libcrypto ``RAND_bytes`` - - getrandom - Use libc getrandom, falls back to urandom if it does not really work - - arc4random - Use BSD ``arc4random_uniform`` - - urandom - Use ``/dev/urandom`` - - kiss - Use simple settable deterministic RNG. **FOR TESTING PURPOSES ONLY!** - -.. _setting-root-nx-trust: - -``root-nx-trust`` -~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.0.0 - - Default is ``yes`` now, was ``no`` before 4.0.0 - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-recursor.root_nx_trust` - -If set, an NXDOMAIN from the root-servers will serve as a blanket NXDOMAIN for the entire TLD the query belonged to. -The effect of this is far fewer queries to the root-servers. - -.. _setting-save-parent-ns-set: - -``save-parent-ns-set`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.7.0 - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-recursor.save_parent_ns_set` - -If set, a parent (non-authoritative) ``NS`` set is saved if it contains more entries than a newly encountered child (authoritative) ``NS`` set for the same domain. -The saved parent ``NS`` set is tried if resolution using the child ``NS`` set fails. - -.. _setting-security-poll-suffix: - -``security-poll-suffix`` -~~~~~~~~~~~~~~~~~~~~~~~~ - -- String -- Default: secpoll.powerdns.com. - -- YAML setting: :ref:`setting-yaml-recursor.security_poll_suffix` - -Domain name from which to query security update notifications. -Setting this to an empty string disables secpoll. - -.. _setting-serve-rfc1918: - -``serve-rfc1918`` -~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-recursor.serve_rfc1918` - -This makes the server authoritatively aware of: ``10.in-addr.arpa``, ``168.192.in-addr.arpa``, ``16-31.172.in-addr.arpa``, which saves load on the AS112 servers. -Individual parts of these zones can still be loaded or forwarded. - -.. _setting-serve-stale-extensions: - -``serve-stale-extensions`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.8.0 - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-recursor.serve_stale_extensions` - -Maximum number of times an expired record's TTL is extended by 30s when serving stale. -Extension only occurs if a record cannot be refreshed. -A value of 0 means the ``Serve Stale`` mechanism is not used. -To allow records becoming stale to be served for an hour, use a value of 120. -See :ref:`serve-stale` for a description of the Serve Stale mechanism. - -.. _setting-server-down-max-fails: - -``server-down-max-fails`` -~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 64 - -- YAML setting: :ref:`setting-yaml-recursor.server_down_max_fails` - -If a server has not responded in any way this many times in a row, no longer send it any queries for :ref:`setting-server-down-throttle-time` seconds. -Afterwards, we will try a new packet, and if that also gets no response at all, we again throttle for :ref:`setting-server-down-throttle-time` seconds. -Even a single response packet will drop the block. - -.. _setting-server-down-throttle-time: - -``server-down-throttle-time`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 60 - -- YAML setting: :ref:`setting-yaml-recursor.server_down_throttle_time` - -Throttle a server that has failed to respond :ref:`setting-server-down-max-fails` times for this many seconds. - -.. _setting-server-id: - -``server-id`` -~~~~~~~~~~~~~ - -- String -- Default: *runtime determined* - -- YAML setting: :ref:`setting-yaml-recursor.server_id` - -The reply given by The PowerDNS recursor to a query for 'id.server' with its hostname, useful for in clusters. -When a query contains the :rfc:`NSID EDNS0 Option <5001>`, this value is returned in the response as the NSID value. - -This setting can be used to override the answer given to these queries. -Set to 'disabled' to disable NSID and 'id.server' answers. - -Query example (where 192.0.2.14 is your server): - -.. code-block:: sh - - dig @192.0.2.14 CHAOS TXT id.server. - dig @192.0.2.14 example.com IN A +nsid - -.. _setting-setgid: - -``setgid`` -~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.setgid` - -PowerDNS can change its user and group id after binding to its socket. -Can be used for better :doc:`security `. - -.. _setting-setuid: - -``setuid`` -~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.setuid` - -PowerDNS can change its user and group id after binding to its socket. -Can be used for better :doc:`security `. - -.. _setting-signature-inception-skew: - -``signature-inception-skew`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.5 -.. versionchanged:: 4.2.0 - - Default is now 60, was 0 before. - -- Integer -- Default: 60 - -- YAML setting: :ref:`setting-yaml-dnssec.signature_inception_skew` - -Allow the signature inception to be off by this number of seconds. Negative values are not allowed. - -.. _setting-single-socket: - -``single-socket`` -~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-outgoing.single_socket` - -Use only a single socket for outgoing queries. - -.. _setting-snmp-agent: - -``snmp-agent`` -~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-snmp.agent` - -If set to true and PowerDNS has been compiled with SNMP support, it will register as an SNMP agent to provide statistics and be able to send traps. - -.. _setting-snmp-master-socket: - -``snmp-master-socket`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 -.. deprecated:: 4.5.0 - - Use :ref:`setting-snmp-daemon-socket`. - -- String -- Default: (empty) - -- YAML setting does not exist - - - -.. _setting-snmp-daemon-socket: - -``snmp-daemon-socket`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-snmp.daemon_socket` - -If not empty and ``snmp-agent`` is set to true, indicates how PowerDNS should contact the SNMP daemon to register as an SNMP agent. - -.. _setting-socket-dir: - -``socket-dir`` -~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.socket_dir` - -Where to store the control socket and pidfile. -The default depends on ``LOCALSTATEDIR`` or the ``--with-socketdir`` setting when building (usually ``/var/run`` or ``/run``). - -When using :ref:`setting-chroot` the default becomes ``/``. - -.. _setting-socket-group: - -``socket-group`` -~~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.socket_group` - -Group and mode of the controlsocket. -Owner and group can be specified by name, mode is in octal. - -.. _setting-socket-mode: - -``socket-mode`` -~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.socket_mode` - -Mode of the controlsocket. -Owner and group can be specified by name, mode is in octal. - -.. _setting-socket-owner: - -``socket-owner`` -~~~~~~~~~~~~~~~~ - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-recursor.socket_owner` - -Owner of the controlsocket. -Owner and group can be specified by name, mode is in octal. - -.. _setting-spoof-nearmiss-max: - -``spoof-nearmiss-max`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.5.0 - - Older versions used 20 as the default value. - -- Integer -- Default: 1 - -- YAML setting: :ref:`setting-yaml-recursor.spoof_nearmiss_max` - -If set to non-zero, PowerDNS will assume it is being spoofed after seeing this many answers with the wrong id. - -.. _setting-stack-cache-size: - -``stack-cache-size`` -~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.9.0 - -- Integer -- Default: 100 - -- YAML setting: :ref:`setting-yaml-recursor.stack_cache_size` - -Maximum number of mthread stacks that can be cached for later reuse, per thread. Caching these stacks reduces the CPU load at the cost of a slightly higher memory usage, each cached stack consuming `stack-size` bytes of memory. -It makes no sense to cache more stacks than the value of `max-mthreads`, since there will never be more stacks than that in use at a given time. - -.. _setting-stack-size: - -``stack-size`` -~~~~~~~~~~~~~~ - -- Integer -- Default: 200000 - -- YAML setting: :ref:`setting-yaml-recursor.stack_size` - -Size in bytes of the stack of each mthread. - -.. _setting-statistics-interval: - -``statistics-interval`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 - -- Integer -- Default: 1800 - -- YAML setting: :ref:`setting-yaml-logging.statistics_interval` - -Interval between logging statistical summary on recursor performance. -Use 0 to disable. - -.. _setting-stats-api-blacklist: - -``stats-api-blacklist`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 -.. deprecated:: 4.5.0 - - Use :ref:`setting-stats-api-disabled-list`. - -- Comma separated list of strings -- Default: - -- YAML setting does not exist - - - -.. _setting-stats-api-disabled-list: - -``stats-api-disabled-list`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Comma separated list of strings -- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\* - -- YAML setting: :ref:`setting-yaml-recursor.stats_api_disabled_list` - -A list of comma-separated statistic names, that are disabled when retrieving the complete list of statistics via the API for performance reasons. -These statistics can still be retrieved individually by specifically asking for it. - -.. _setting-stats-carbon-blacklist: - -``stats-carbon-blacklist`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 -.. deprecated:: 4.5.0 - - Use :ref:`setting-stats-carbon-disabled-list`. - -- Comma separated list of strings -- Default: - -- YAML setting does not exist - - - -.. _setting-stats-carbon-disabled-list: - -``stats-carbon-disabled-list`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Comma separated list of strings -- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\* - -- YAML setting: :ref:`setting-yaml-recursor.stats_carbon_disabled_list` - -A list of comma-separated statistic names, that are prevented from being exported via carbon for performance reasons. - -.. _setting-stats-rec-control-blacklist: - -``stats-rec-control-blacklist`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 -.. deprecated:: 4.5.0 - - Use :ref:`setting-stats-rec-control-disabled-list`. - -- Comma separated list of strings -- Default: - -- YAML setting does not exist - - - -.. _setting-stats-rec-control-disabled-list: - -``stats-rec-control-disabled-list`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Comma separated list of strings -- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\* - -- YAML setting: :ref:`setting-yaml-recursor.stats_rec_control_disabled_list` - -A list of comma-separated statistic names, that are disabled when retrieving the complete list of statistics via `rec_control get-all`, for performance reasons. -These statistics can still be retrieved individually. - -.. _setting-stats-ringbuffer-entries: - -``stats-ringbuffer-entries`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 10000 - -- YAML setting: :ref:`setting-yaml-recursor.stats_ringbuffer_entries` - -Number of entries in the remotes ringbuffer, which keeps statistics on who is querying your server. -Can be read out using ``rec_control top-remotes``. - -.. _setting-stats-snmp-blacklist: - -``stats-snmp-blacklist`` -~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 -.. deprecated:: 4.5.0 - - Use :ref:`setting-stats-snmp-disabled-list`. - -- Comma separated list of strings -- Default: - -- YAML setting does not exist - - - -.. _setting-stats-snmp-disabled-list: - -``stats-snmp-disabled-list`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Comma separated list of strings -- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\* - -- YAML setting: :ref:`setting-yaml-recursor.stats_snmp_disabled_list` - -A list of comma-separated statistic names, that are prevented from being exported via SNMP, for performance reasons. - -.. _setting-structured-logging: - -``structured-logging`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-logging.structured_logging` - -Prefer structured logging when both an old style and a structured log messages is available. - -.. _setting-structured-logging-backend: - -``structured-logging-backend`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.8.0 - -- String -- Default: default - -- YAML setting: :ref:`setting-yaml-logging.structured_logging_backend` - -The backend used for structured logging output. -This setting must be set on the command line (``--structured-logging-backend=...``) to be effective. -Available backends are: - -- ``default``: use the traditional logging system to output structured logging information. -- ``systemd-journal``: use systemd-journal. - When using this backend, provide ``-o verbose`` or simular output option to ``journalctl`` to view the full information. - -.. _setting-tcp-fast-open: - -``tcp-fast-open`` -~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.1.0 - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-incoming.tcp_fast_open` - -Enable TCP Fast Open support, if available, on the listening sockets. -The numerical value supplied is used as the queue size, 0 meaning disabled. See :ref:`tcp-fast-open-support`. - -.. _setting-tcp-fast-open-connect: - -``tcp-fast-open-connect`` -~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-outgoing.tcp_fast_open_connect` - -Enable TCP Fast Open Connect support, if available, on the outgoing connections to authoritative servers. See :ref:`tcp-fast-open-support`. - -.. _setting-tcp-out-max-idle-ms: - -``tcp-out-max-idle-ms`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Integer -- Default: 10000 - -- YAML setting: :ref:`setting-yaml-outgoing.tcp_max_idle_ms` - -Time outgoing TCP/DoT connections are left idle in milliseconds or 0 if no limit. After having been idle for this time, the connection is eligible for closing. - -.. _setting-tcp-out-max-idle-per-auth: - -``tcp-out-max-idle-per-auth`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Integer -- Default: 10 - -- YAML setting: :ref:`setting-yaml-outgoing.tcp_max_idle_per_auth` - -Maximum number of idle outgoing TCP/DoT connections to a specific IP per thread, 0 means do not keep idle connections open. - -.. _setting-tcp-out-max-queries: - -``tcp-out-max-queries`` -~~~~~~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 0 - -- YAML setting: :ref:`setting-yaml-outgoing.tcp_max_queries` - -Maximum total number of queries per outgoing TCP/DoT connection, 0 means no limit. After this number of queries, the connection is -closed and a new one will be created if needed. - -.. _setting-tcp-out-max-idle-per-thread: - -``tcp-out-max-idle-per-thread`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Integer -- Default: 100 - -- YAML setting: :ref:`setting-yaml-outgoing.tcp_max_idle_per_thread` - -Maximum number of idle outgoing TCP/DoT connections per thread, 0 means do not keep idle connections open. - -.. _setting-threads: - -``threads`` -~~~~~~~~~~~ - -- Integer -- Default: 2 - -- YAML setting: :ref:`setting-yaml-recursor.threads` - -Spawn this number of threads on startup. - -.. _setting-tcp-threads: - -``tcp-threads`` -~~~~~~~~~~~~~~~ -.. versionadded:: 5.0.0 - -- Integer -- Default: 1 - -- YAML setting: :ref:`setting-yaml-recursor.tcp_threads` - -Spawn this number of TCP processing threads on startup. - -.. _setting-trace: - -``trace`` -~~~~~~~~~ - -- String -- Default: no - -- YAML setting: :ref:`setting-yaml-logging.trace` - -One of ``no``, ``yes`` or ``fail``. -If turned on, output impressive heaps of logging. -May destroy performance under load. -To log only queries resulting in a ``ServFail`` answer from the resolving process, this value can be set to ``fail``, but note that the performance impact is still large. -Also note that queries that do produce a result but with a failing DNSSEC validation are not written to the log - -.. _setting-udp-source-port-min: - -``udp-source-port-min`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Integer -- Default: 1024 - -- YAML setting: :ref:`setting-yaml-outgoing.udp_source_port_min` - -This option sets the low limit of UDP port number to bind on. - -In combination with :ref:`setting-udp-source-port-max` it configures the UDP -port range to use. Port numbers are randomized within this range on -initialization, and exceptions can be configured with :ref:`setting-udp-source-port-avoid` - -.. _setting-udp-source-port-max: - -``udp-source-port-max`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Integer -- Default: 65535 - -- YAML setting: :ref:`setting-yaml-outgoing.udp_source_port_max` - -This option sets the maximum limit of UDP port number to bind on. - -See :ref:`setting-udp-source-port-min`. - -.. _setting-udp-source-port-avoid: - -``udp-source-port-avoid`` -~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Comma separated list of strings -- Default: 11211 - -- YAML setting: :ref:`setting-yaml-outgoing.udp_source_port_avoid` - -A list of comma-separated UDP port numbers to avoid when binding. -Ex: `5300,11211` - -See :ref:`setting-udp-source-port-min`. - -.. _setting-udp-truncation-threshold: - -``udp-truncation-threshold`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.2.0 - - Before 4.2.0, the default was 1680. - -- Integer -- Default: 1232 - -- YAML setting: :ref:`setting-yaml-incoming.udp_truncation_threshold` - -EDNS0 allows for large UDP response datagrams, which can potentially raise performance. -Large responses however also have downsides in terms of reflection attacks. -This setting limits the accepted size. -Maximum value is 65535, but values above 4096 should probably not be attempted. - -To know why 1232, see the note at :ref:`setting-edns-outgoing-bufsize`. - -.. _setting-unique-response-tracking: - -``unique-response-tracking`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-nod.unique_response_tracking` - -Whether to track unique DNS responses, i.e. never seen before combinations -of the triplet (query name, query type, RR[rrname, rrtype, rrdata]). -This can be useful for tracking potentially suspicious domains and -behaviour, e.g. DNS fast-flux. -If protobuf is enabled and configured, then the Protobuf Response message -will contain a flag with udr set to true for each RR that is considered -unique, i.e. never seen before. -This feature uses a probabilistic data structure (stable bloom filter) to -track unique responses, which can have false positives as well as false -negatives, thus it is a best-effort feature. Increasing the number of cells -in the SBF using the unique-response-db-size setting can reduce FPs and FNs. - -.. _setting-unique-response-log: - -``unique-response-log`` -~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-nod.unique_response_log` - -Whether to log when a unique response is detected. The log line -looks something like: - -Oct 24 12:11:27 Unique response observed: qname=foo.com qtype=A rrtype=AAAA rrname=foo.com rrcontent=1.2.3.4 - -.. _setting-unique-response-db-size: - -``unique-response-db-size`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- Integer -- Default: 67108864 - -- YAML setting: :ref:`setting-yaml-nod.unique_response_db_size` - -The default size of the stable bloom filter used to store previously -observed responses is 67108864. To change the number of cells, use this -setting. For each cell, the SBF uses 1 bit of memory, and one byte of -disk for the persistent file. -If there are already persistent files saved to disk, this setting will -have no effect unless you remove the existing files. - -.. _setting-unique-response-history-dir: - -``unique-response-history-dir`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- String -- Default: /usr/local/var/lib/pdns-recursor/udr - -- YAML setting: :ref:`setting-yaml-nod.unique_response_history_dir` - -This setting controls which directory is used to store the on-disk -cache of previously observed responses. - -The default depends on ``LOCALSTATEDIR`` when building the software. -Usually this comes down to ``/var/lib/pdns-recursor/udr`` or ``/usr/local/var/lib/pdns-recursor/udr``). - -The newly observed domain feature uses a stable bloom filter to store -a history of previously observed responses. The data structure is -synchronized to disk every 10 minutes, and is also initialized from -disk on startup. This ensures that previously observed responses are -preserved across recursor restarts. If you change the -unique-response-db-size, you must remove any files from this directory. - -.. _setting-unique-response-pb-tag: - -``unique-response-pb-tag`` -~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- String -- Default: pdns-udr - -- YAML setting: :ref:`setting-yaml-nod.unique_response_pb_tag` - -If protobuf is configured, then this tag will be added to all protobuf response messages when -a unique DNS response is observed. - -.. _setting-use-incoming-edns-subnet: - -``use-incoming-edns-subnet`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-incoming.use_incoming_edns_subnet` - -Whether to process and pass along a received EDNS Client Subnet to authoritative servers. -The ECS information will only be sent for netmasks and domains listed in :ref:`setting-edns-subnet-allow-list` and will be truncated if the received scope exceeds :ref:`setting-ecs-ipv4-bits` for IPv4 or :ref:`setting-ecs-ipv6-bits` for IPv6. - -.. _setting-version-string: - -``version-string`` -~~~~~~~~~~~~~~~~~~ - -- String -- Default: *runtime determined* - -- YAML setting: :ref:`setting-yaml-recursor.version_string` - -By default, PowerDNS replies to the 'version.bind' query with its version number. -Security conscious users may wish to override the reply PowerDNS issues. - -.. _setting-webserver: - -``webserver`` -~~~~~~~~~~~~~ - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-webservice.webserver` - -Start the webserver (for REST API). - -.. _setting-webserver-address: - -``webserver-address`` -~~~~~~~~~~~~~~~~~~~~~ - -- String -- Default: 127.0.0.1 - -- YAML setting: :ref:`setting-yaml-webservice.address` - -IP address for the webserver to listen on. - -.. _setting-webserver-allow-from: - -``webserver-allow-from`` -~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.1.0 - - Default is now 127.0.0.1,::1, was 0.0.0.0/0,::/0 before. - -- Comma separated list of IP addresses or subnets, negation supported -- Default: 127.0.0.1, ::1 - -- YAML setting: :ref:`setting-yaml-webservice.allow_from` - -These IPs and subnets are allowed to access the webserver. Note that -specifying an IP address without a netmask uses an implicit netmask -of /32 or /128. - -.. _setting-webserver-hash-plaintext-credentials: - -``webserver-hash-plaintext-credentials`` -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.6.0 - -- Boolean -- Default: no - -- YAML setting: :ref:`setting-yaml-webservice.hash_plaintext_credentials` - -Whether passwords and API keys supplied in the configuration as plaintext should be hashed during startup, to prevent the plaintext versions from staying in memory. Doing so increases significantly the cost of verifying credentials and is thus disabled by default. -Note that this option only applies to credentials stored in the configuration as plaintext, but hashed credentials are supported without enabling this option. - -.. _setting-webserver-loglevel: - -``webserver-loglevel`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.2.0 - -- String -- Default: normal - -- YAML setting: :ref:`setting-yaml-webservice.loglevel` - -One of ``one``, ``normal``, ``detailed``. -The amount of logging the webserver must do. 'none' means no useful webserver information will be logged. -When set to 'normal', the webserver will log a line per request that should be familiar:: - - [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 'GET /api/v1/servers/localhost/bla HTTP/1.1' 404 196 - -When set to 'detailed', all information about the request and response are logged:: - - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Request Details: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Headers: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept-encoding: gzip, deflate - [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept-language: en-US,en;q=0.5 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e connection: keep-alive - [webserver] e235780e-a5cf-415e-9326-9d33383e739e dnt: 1 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e host: 127.0.0.1:8081 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e upgrade-insecure-requests: 1 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e No body - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Response details: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Headers: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Connection: close - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Content-Length: 49 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Content-Type: text/html; charset=utf-8 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Server: PowerDNS/0.0.15896.0.gaba8bab3ab - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Full body: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Not Found

        Not Found

        - [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 'GET /api/v1/servers/localhost/bla HTTP/1.1' 404 196 - -The value between the hooks is a UUID that is generated for each request. This can be used to find all lines related to a single request. - -.. note:: - The webserver logs these line on the NOTICE level. The :ref:`setting-loglevel` seting must be 5 or higher for these lines to end up in the log. - -.. _setting-webserver-password: - -``webserver-password`` -~~~~~~~~~~~~~~~~~~~~~~ -.. versionchanged:: 4.6.0 - - This setting now accepts a hashed and salted version. - -- String -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-webservice.password` - -Password required to access the webserver. Since 4.6.0 the password can be hashed and salted using ``rec_control hash-password`` instead of being present in the configuration in plaintext, but the plaintext version is still supported. - -.. _setting-webserver-port: - -``webserver-port`` -~~~~~~~~~~~~~~~~~~ - -- Integer -- Default: 8082 - -- YAML setting: :ref:`setting-yaml-webservice.port` - -TCP port where the webserver should listen on. - -.. _setting-write-pid: - -``write-pid`` -~~~~~~~~~~~~~ - -- Boolean -- Default: yes - -- YAML setting: :ref:`setting-yaml-recursor.write_pid` - -If a PID file should be written to :ref:`setting-socket-dir` - -.. _setting-x-dnssec-names: - -``x-dnssec-names`` -~~~~~~~~~~~~~~~~~~ -.. versionadded:: 4.5.0 - -- Comma separated list of strings -- Default: (empty) - -- YAML setting: :ref:`setting-yaml-dnssec.x_dnssec_names` - -List of names whose DNSSEC validation metrics will be counted in a separate set of metrics that start -with ``x-dnssec-result-``. -The names are suffix-matched. -This can be used to not count known failing (test) name validations in the ordinary DNSSEC metrics. - diff --git a/pdns/recursordist/docs/yamlsettings.rst b/pdns/recursordist/docs/yamlsettings.rst deleted file mode 100644 index 223c0424033b..000000000000 --- a/pdns/recursordist/docs/yamlsettings.rst +++ /dev/null @@ -1,3195 +0,0 @@ -.. THIS IS A GENERATED FILE. DO NOT EDIT. SOURCE: see settings dir - START INCLUDE docs-new-preamble-in.rst - -PowerDNS Recursor New Style (YAML) Settings -=========================================== - -Each setting can appear on the command line, prefixed by ``--`` and using the old style name, or in configuration files. -Settings on the command line are processed after the file-based settings are processed. - -.. note:: - Starting with version 5.0.0., :program:`Recursor` supports a new YAML syntax for configuration files - as described here. - A configuration using the old style syntax can be converted to a YAML configuration using the instructions in :doc:`appendices/yamlconversion`. - In a future release support for the "old-style" settings will be dropped. - - -YAML settings file ------------------- -Please refer to e.g. ``_ -for a description of YAML syntax. - -A :program:`Recursor` configuration file has several sections. For example, ``incoming`` for -settings related to receiving queries and ``dnssec`` for settings related to DNSSEC processing. - -An example :program:`Recursor` YAML configuration file looks like: - -.. code-block:: yaml - - dnssec: - log_bogus: true - incoming: - listen: - - 0.0.0.0:5301 - - '[::]:5301' - recursor: - extended_resolution_errors: true - forward_zones: - - zone: example.com - forwarders: - - 127.0.0.1:5301 - outgoing: - query_local_address: - - 0.0.0.0 - - '::' - logging: - loglevel: 6 - -Take care when listing IPv6 addresses, as characters used for these are special to YAML. -If in doubt, quote any string containing ``:``, ``[`` or ``]`` and use (online) tools to check your YAML syntax. -Specify an empty sequence using ``[]``. - -The main setting file is called ``recursor.yml`` and will be processed first. -This settings file might refer to other files via the `recursor.include_dir`_ setting. -The next section will describe how settings specified in multiple files are merged. - -Merging multiple setting files ------------------------------- -If `recursor.include_dir`_ is set, all ``.yml`` files in it will be processed in alphabetical order, modifying the settings processed so far. - -For simple values like an boolean or number setting, a value in the processed file will overwrite an existing setting. - -For values of type sequence, the new value will *replace* the existing value if the existing value is equal to the ``default`` or if the new value is marked with the ``!override`` tag. -Otherwise, the existing value will be *extended* with the new value by appending the new sequence to the existing. - -For example, with the above example ``recursor.yml`` and an include directory containing a file ``extra.yml``: - -.. code-block:: yaml - - dnssec: - log_bogus: false - recursor: - forward_zones: - - zone: example.net - forwarders: - - '::1' - outgoing: - query_local_address: !override - - 0.0.0.0 - dont_query: [] - -After merging, ``dnssec.log_bogus`` will be ``false``, the sequence of ``recursor.forward_zones`` will contain 2 zones and the ``outgoing`` addresses used will contain one entry, as the ``extra.yml`` entry has overwritten the existing one. - -``outgoing.dont-query`` has a non-empty sequence as default value. The main ``recursor.yml`` did not set it, so before processing ``extra.yml`` had the default value. -After processing ``extra.yml`` the value will be set to the empty sequence, as existing default values are overwritten by new values. - -.. warning:: - The merging process does not process values deeper than the second level. - For example if the main ``recursor.yml`` specified a forward zone - - .. code-block:: yaml - - forward_zones: - - zone: example.net - forwarders: - - '::1' - - and another settings file contains - - .. code-block:: yaml - - forward_zones: - - zone: example.net - forwarders: - - '::2' - - The result will *not* be a a single forward with two IP addresses, but two entries for ``example.net``. - It depends on the specific setting how the sequence is processed further. - In the future we might add a check for this case. - -Socket Address -^^^^^^^^^^^^^^ -A socket address is either an IP or and IP:port combination -For example: - -.. code-block:: yaml - - some_key: 127.0.0.1 - another_key: '[::1]:8080' - -Subnet -^^^^^^ -A subnet is a single IP address or an IP address followed by a slash and a prefix length. -If no prefix length is specified, ``/32`` or ``/128`` is assumed, indicating a single IP address. -Subnets can also be prefixed with a ``!``, specifying negation. -This can be used to deny addresses from a previously allowed range. - -For example, ``alow-from`` takes a sequence of subnets: - -.. code-block:: yaml - - allow_from: - - '2001:DB8::/32' - - 128.66.0.0/16 - - !128.66.1.2 - -In this case the address ``128.66.1.2`` is excluded from the addresses allowed access. - -Forward Zone -^^^^^^^^^^^^ -A forward zone is defined as: - -.. code-block:: yaml - - zone: zonename - forwarders: - - Socket Address - - ... - recurse: Boolean, default false - allow_notify: Boolean, default false - -An example of a ``forward_zones`` entry, which consists of a sequence of forward zone entries: - -.. code-block:: yaml - - - zone: example1.com - forwarders: - - 127.0.0.1 - - 127.0.0.1:5353 - - '[::1]53' - - zone: example2.com - forwarders: - - '::1' - recurse: true - notify_allowed: true - - -Auth Zone -^^^^^^^^^ -A auth zone is defined as: - -.. code-block:: yaml - - zone: name - file: filename - -An example of a ``auth_zones`` entry, consisting of a sequence of auth zones: - -.. code-block:: yaml - - auth_zones: - - zone: example.com - file: zones/example.com.zone - - zone: example.net - file: zones/example.net.zone - -The YAML settings ------------------ - -.. END INCLUDE docs-new-preamble-in.rst - -.. _setting-yaml-carbon.instance: - -``carbon.instance`` -^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- String -- Default: ``recursor`` - -- Old style setting: :ref:`setting-carbon-instance` - -Change the instance or third string of the metric key. The default is recursor. - -.. _setting-yaml-carbon.interval: - -``carbon.interval`` -^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``30`` - -- Old style setting: :ref:`setting-carbon-interval` - -If sending carbon updates, this is the interval between them in seconds. -See :doc:`metrics`. - -.. _setting-yaml-carbon.ns: - -``carbon.ns`` -^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- String -- Default: ``pdns`` - -- Old style setting: :ref:`setting-carbon-namespace` - -Change the namespace or first string of the metric key. The default is pdns. - -.. _setting-yaml-carbon.ourname: - -``carbon.ourname`` -^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-carbon-ourname` - -If sending carbon updates, if set, this will override our hostname. -Be careful not to include any dots in this setting, unless you know what you are doing. -See :ref:`metricscarbon`. - -.. _setting-yaml-carbon.server: - -``carbon.server`` -^^^^^^^^^^^^^^^^^ - -- Sequence of `Socket Address`_ (IP or IP:port combinations) -- Default: ``[]`` - -- Old style setting: :ref:`setting-carbon-server` - -Will send all available metrics to these servers via the carbon protocol, which is used by graphite and metronome. -See :doc:`metrics`. - -.. _setting-yaml-dnssec.aggressive_cache_min_nsec3_hit_ratio: - -``dnssec.aggressive_cache_min_nsec3_hit_ratio`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.9.0 - -- Integer -- Default: ``2000`` - -- Old style setting: :ref:`setting-aggressive-cache-min-nsec3-hit-ratio` - -The limit for which to put NSEC3 records into the aggressive cache. -A value of ``n`` means that an NSEC3 record is only put into the aggressive cache if the estimated probability of a random name hitting the NSEC3 record is higher than ``1/n``. -A higher ``n`` will cause more records to be put into the aggressive cache, e.g. a value of 4000 will cause records to be put in the aggressive cache even if the estimated probability of hitting them is twice as low as would be the case for ``n=2000``. -A value of 0 means no NSEC3 records will be put into the aggressive cache. - -For large zones the effectiveness of the NSEC3 cache is reduced since each NSEC3 record only covers a randomly distributed subset of all possible names. -This setting avoids doing unnecessary work for such large zones. - -.. _setting-yaml-dnssec.aggressive_nsec_cache_size: - -``dnssec.aggressive_nsec_cache_size`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Integer -- Default: ``100000`` - -- Old style setting: :ref:`setting-aggressive-nsec-cache-size` - -The number of records to cache in the aggressive cache. If set to a value greater than 0, the recursor will cache NSEC and NSEC3 records to generate negative answers, as defined in :rfc:`8198`. -To use this, DNSSEC processing or validation must be enabled by setting :ref:`setting-yaml-dnssec.validation` to ``process``, ``log-fail`` or ``validate``. - -.. _setting-yaml-dnssec.disabled_algorithms: - -``dnssec.disabled_algorithms`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.9.0 - -- Sequence of strings -- Default: ``[]`` - -- Old style setting: :ref:`setting-dnssec-disabled-algorithms` - -A list of DNSSEC algorithm numbers that should be considered disabled. -These algorithms will not be used to validate DNSSEC signatures. -Zones (only) signed with these algorithms will be considered ``Insecure``. - -If this setting is empty (the default), :program:`Recursor` will determine which algorithms to disable automatically. -This is done for specific algorithms only, currently algorithms 5 (``RSASHA1``) and 7 (``RSASHA1NSEC3SHA1``). - -This is important on systems that have a default strict crypto policy, like RHEL9 derived systems. -On such systems not disabling some algorithms (or changing the security policy) will make affected zones to be considered ``Bogus`` as using these algorithms fails. - -.. _setting-yaml-dnssec.log_bogus: - -``dnssec.log_bogus`` -^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-dnssec-log-bogus` - -Log every DNSSEC validation failure. -**Note**: This is not logged per-query but every time records are validated as Bogus. - -.. _setting-yaml-dnssec.nsec3_max_iterations: - -``dnssec.nsec3_max_iterations`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.0 -.. versionchanged:: 4.5.2 - - Default is now 150, was 2500 before. - -- Integer -- Default: ``150`` - -- Old style setting: :ref:`setting-nsec3-max-iterations` - -Maximum number of iterations allowed for an NSEC3 record. -If an answer containing an NSEC3 record with more iterations is received, its DNSSEC validation status is treated as Insecure. - -.. _setting-yaml-dnssec.signature_inception_skew: - -``dnssec.signature_inception_skew`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.5 -.. versionchanged:: 4.2.0 - - Default is now 60, was 0 before. - -- Integer -- Default: ``60`` - -- Old style setting: :ref:`setting-signature-inception-skew` - -Allow the signature inception to be off by this number of seconds. Negative values are not allowed. - -.. _setting-yaml-dnssec.validation: - -``dnssec.validation`` -^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.0.0 -.. versionchanged:: 4.5.0 - - The default changed from ``process-no-validate`` to ``process`` - -- String -- Default: ``process`` - -- Old style setting: :ref:`setting-dnssec` - -One of ``off``, ``process-no-validate``, ``process``, ``log-fail``, ``validate`` - -Set the mode for DNSSEC processing, as detailed in :doc:`dnssec`. - -``off`` - No DNSSEC processing whatsoever. - Ignore DO-bits in queries, don't request any DNSSEC information from authoritative servers. - This behaviour is similar to PowerDNS Recursor pre-4.0. -``process-no-validate`` - Respond with DNSSEC records to clients that ask for it, set the DO bit on all outgoing queries. - Don't do any validation. -``process`` - Respond with DNSSEC records to clients that ask for it, set the DO bit on all outgoing queries. - Do validation for clients that request it (by means of the AD- bit or DO-bit in the query). -``log-fail`` - Similar behaviour to ``process``, but validate RRSIGs on responses and log bogus responses. -``validate`` - Full blown DNSSEC validation. Send SERVFAIL to clients on bogus responses. - -.. _setting-yaml-dnssec.x_dnssec_names: - -``dnssec.x_dnssec_names`` -^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Sequence of strings -- Default: ``[]`` - -- Old style setting: :ref:`setting-x-dnssec-names` - -List of names whose DNSSEC validation metrics will be counted in a separate set of metrics that start -with ``x-dnssec-result-``. -The names are suffix-matched. -This can be used to not count known failing (test) name validations in the ordinary DNSSEC metrics. - -.. _setting-yaml-ecs.add_for: - -``ecs.add_for`` -^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) -- Default: ``[0.0.0.0/0, ::/0, !127.0.0.0/8, !10.0.0.0/8, !100.64.0.0/10, !169.254.0.0/16, !192.168.0.0/16, !172.16.0.0/12, !::1/128, !fc00::/7, !fe80::/10]`` - -- Old style setting: :ref:`setting-ecs-add-for` - -List of requestor netmasks for which the requestor IP Address should be used as the :rfc:`EDNS Client Subnet <7871>` for outgoing queries. Outgoing queries for requestors that do not match this list will use the :ref:`setting-yaml-ecs.scope_zero_address` instead. -Valid incoming ECS values from :ref:`setting-yaml-incoming.use_incoming_edns_subnet` are not replaced. - -Regardless of the value of this setting, ECS values are only sent for outgoing queries matching the conditions in the :ref:`setting-yaml-outgoing.edns_subnet_allow_list` setting. This setting only controls the actual value being sent. - -This defaults to not using the requestor address inside RFC1918 and similar 'private' IP address spaces. - -.. _setting-yaml-ecs.cache_limit_ttl: - -``ecs.cache_limit_ttl`` -^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.12 - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-ecs-cache-limit-ttl` - -The minimum TTL for an ECS-specific answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-ipv4-cache-bits`` or ``ecs-ipv6-cache-bits``. -That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. - -.. _setting-yaml-ecs.ipv4_bits: - -``ecs.ipv4_bits`` -^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.0 - -- Integer -- Default: ``24`` - -- Old style setting: :ref:`setting-ecs-ipv4-bits` - -Number of bits of client IPv4 address to pass when sending EDNS Client Subnet address information. - -.. _setting-yaml-ecs.ipv4_cache_bits: - -``ecs.ipv4_cache_bits`` -^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.12 - -- Integer -- Default: ``24`` - -- Old style setting: :ref:`setting-ecs-ipv4-cache-bits` - -Maximum number of bits of client IPv4 address used by the authoritative server (as indicated by the EDNS Client Subnet scope in the answer) for an answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-cache-limit-ttl``. -That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. - -.. _setting-yaml-ecs.ipv4_never_cache: - -``ecs.ipv4_never_cache`` -^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-ecs-ipv4-never-cache` - -When set, never cache replies carrying EDNS IPv4 Client Subnet scope in the record cache. -In this case the decision made by ```ecs-ipv4-cache-bits`` and ``ecs-cache-limit-ttl`` is no longer relevant. - -.. _setting-yaml-ecs.ipv6_bits: - -``ecs.ipv6_bits`` -^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.0 - -- Integer -- Default: ``56`` - -- Old style setting: :ref:`setting-ecs-ipv6-bits` - -Number of bits of client IPv6 address to pass when sending EDNS Client Subnet address information. - -.. _setting-yaml-ecs.ipv6_cache_bits: - -``ecs.ipv6_cache_bits`` -^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.12 - -- Integer -- Default: ``56`` - -- Old style setting: :ref:`setting-ecs-ipv6-cache-bits` - -Maximum number of bits of client IPv6 address used by the authoritative server (as indicated by the EDNS Client Subnet scope in the answer) for an answer to be inserted into the query cache. This condition applies in conjunction with ``ecs-cache-limit-ttl``. -That is, only if both the limits apply, the record will not be cached. This decision can be overridden by ``ecs-ipv4-never-cache`` and ``ecs-ipv6-never-cache``. - -.. _setting-yaml-ecs.ipv6_never_cache: - -``ecs.ipv6_never_cache`` -^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-ecs-ipv6-never-cache` - -When set, never cache replies carrying EDNS IPv6 Client Subnet scope in the record cache. -In this case the decision made by ```ecs-ipv6-cache-bits`` and ``ecs-cache-limit-ttl`` is no longer relevant. - -.. _setting-yaml-ecs.minimum_ttl_override: - -``ecs.minimum_ttl_override`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.5.0 - - Old versions used default 0. - -- Integer -- Default: ``1`` - -- Old style setting: :ref:`setting-ecs-minimum-ttl-override` - -This setting artificially raises the TTLs of records in the ANSWER section of ECS-specific answers to be at least this long. -Setting this to a value greater than 1 technically is an RFC violation, but might improve performance a lot. -Using a value of 0 impacts performance of TTL 0 records greatly, since it forces the recursor to contact -authoritative servers every time a client requests them. -Can be set at runtime using ``rec_control set-ecs-minimum-ttl 3600``. - -.. _setting-yaml-ecs.scope_zero_address: - -``ecs.scope_zero_address`` -^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.0 - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-ecs-scope-zero-address` - -The IP address sent via EDNS Client Subnet to authoritative servers listed in -:ref:`setting-yaml-outgoing.edns_subnet_allow_list` when :ref:`setting-yaml-incoming.use_incoming_edns_subnet` is set and the query has -an ECS source prefix-length set to 0. -The default is to look for the first usable (not an ``any`` one) address in -:ref:`setting-yaml-outgoing.source_address` (starting with IPv4). If no suitable address is -found, the recursor fallbacks to sending 127.0.0.1. - -.. _setting-yaml-incoming.allow_from: - -``incoming.allow_from`` -^^^^^^^^^^^^^^^^^^^^^^^ - -- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) -- Default: ``[127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10]`` - -- Old style setting: :ref:`setting-allow-from` - -Netmasks (both IPv4 and IPv6) that are allowed to use the server. -The default allows access only from :rfc:`1918` private IP addresses. -An empty value means no checking is done, all clients are allowed. -Due to the aggressive nature of the internet these days, it is highly recommended to not open up the recursor for the entire internet. -Questions from IP addresses not listed here are ignored and do not get an answer. - -When the Proxy Protocol is enabled (see :ref:`setting-yaml-incoming.proxy_protocol_from`), the recursor will check the address of the client IP advertised in the Proxy Protocol header instead of the one of the proxy. - -Note that specifying an IP address without a netmask uses an implicit netmask of /32 or /128. - -.. _setting-yaml-incoming.allow_from_file: - -``incoming.allow_from_file`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-allow-from-file` - -Like :ref:`setting-yaml-incoming.allow_from`, except reading a sequence of `Subnet`_ from file. -Overrides the :ref:`setting-yaml-incoming.allow_from` setting. Example content of th specified file: - -.. code-block:: yaml - - - 127.0.01 - - ::1 - -.. _setting-yaml-incoming.allow_notify_for: - -``incoming.allow_notify_for`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Sequence of strings -- Default: ``[]`` - -- Old style setting: :ref:`setting-allow-notify-for` - -Domain names specified in this list are used to permit incoming -NOTIFY operations to wipe any cache entries that match the domain -name. If this list is empty, all NOTIFY operations will be ignored. - -.. _setting-yaml-incoming.allow_notify_for_file: - -``incoming.allow_notify_for_file`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-allow-notify-for-file` - -Like :ref:`setting-yaml-incoming.allow_notify_for`, except reading a sequence of names from file. Example contents of specified file: - -.. code-block:: yaml - - - example.com - - example.org - -.. _setting-yaml-incoming.allow_notify_from: - -``incoming.allow_notify_from`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) -- Default: ``[]`` - -- Old style setting: :ref:`setting-allow-notify-from` - -Subnets (both IPv4 and IPv6) that are allowed to issue NOTIFY operations -to the server. NOTIFY operations from IP addresses not listed here are -ignored and do not get an answer. - -When the Proxy Protocol is enabled (see :ref:`setting-yaml-incoming.proxy_protocol_from`), the -recursor will check the address of the client IP advertised in the -Proxy Protocol header instead of the one of the proxy. - -Note that specifying an IP address without a netmask uses an implicit -netmask of /32 or /128. - -NOTIFY operations received from a client listed in one of these netmasks -will be accepted and used to wipe any cache entries whose zones match -the zone specified in the NOTIFY operation, but only if that zone (or -one of its parents) is included in :ref:`setting-yaml-incoming.allow_notify_for`, -:ref:`setting-yaml-incoming.allow_notify_for_file`, or :ref:`setting-yaml-recursor.forward_zones_file` with a ``allow_notify`` set to ``true``. - -.. _setting-yaml-incoming.allow_notify_from_file: - -``incoming.allow_notify_from_file`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-allow-notify-from-file` - -Like :ref:`setting-yaml-incoming.allow_notify_from`, except reading a sequence of `Subnet`_ from file. - -.. _setting-yaml-incoming.distribution_load_factor: - -``incoming.distribution_load_factor`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.12 - -- Double -- Default: ``0.0`` - -- Old style setting: :ref:`setting-distribution-load-factor` - -If :ref:`setting-yaml-incoming.pdns_distributes_queries` is set and this setting is set to another value -than 0, the distributor thread will use a bounded load-balancing algorithm while -distributing queries to worker threads, making sure that no thread is assigned -more queries than distribution-load-factor times the average number of queries -currently processed by all the workers. -For example, with a value of 1.25, no server should get more than 125 % of the -average load. This helps making sure that all the workers have roughly the same -share of queries, even if the incoming traffic is very skewed, with a larger -number of requests asking for the same qname. - -.. _setting-yaml-incoming.distribution_pipe_buffer_size: - -``incoming.distribution_pipe_buffer_size`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-distribution-pipe-buffer-size` - -Size in bytes of the internal buffer of the pipe used by the distributor to pass incoming queries to a worker thread. -Requires support for `F_SETPIPE_SZ` which is present in Linux since 2.6.35. The actual size might be rounded up to -a multiple of a page size. 0 means that the OS default size is used. -A large buffer might allow the recursor to deal with very short-lived load spikes during which a worker thread gets -overloaded, but it will be at the cost of an increased latency. - -.. _setting-yaml-incoming.distributor_threads: - -``incoming.distributor_threads`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Integer -- Default: 1 if :ref:`setting-pdns-distributes-queries` is set, 0 otherwise - -- Old style setting: :ref:`setting-distributor-threads` - -If :ref:`setting-yaml-incoming.pdns_distributes_queries` is set, spawn this number of distributor threads on startup. Distributor threads -handle incoming queries and distribute them to other threads based on a hash of the query. - -.. _setting-yaml-incoming.edns_padding_from: - -``incoming.edns_padding_from`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-edns-padding-from` - -List of netmasks (proxy IP in case of proxy-protocol presence, client IP otherwise) for which EDNS padding will be enabled in responses, provided that :ref:`setting-yaml-incoming.edns_padding_mode` applies. - -.. _setting-yaml-incoming.edns_padding_mode: - -``incoming.edns_padding_mode`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- String -- Default: ``padded-queries-only`` - -- Old style setting: :ref:`setting-edns-padding-mode` - -One of ``always``, ``padded-queries-only``. -Whether to add EDNS padding to all responses (``always``) or only to responses for queries containing the EDNS padding option (``padded-queries-only``, the default). -In both modes, padding will only be added to responses for queries coming from :ref:`setting-yaml-incoming.edns_padding_from` sources. - -.. _setting-yaml-incoming.edns_padding_tag: - -``incoming.edns_padding_tag`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Integer -- Default: ``7830`` - -- Old style setting: :ref:`setting-edns-padding-tag` - -The packetcache tag to use for padded responses, to prevent a client not allowed by the :ref::`setting-edns-padding-from` list to be served a cached answer generated for an allowed one. This -effectively divides the packet cache in two when :ref:`setting-yaml-incoming.edns_padding_from` is used. Note that this will not override a tag set from one of the ``Lua`` hooks. - -.. _setting-yaml-incoming.gettag_needs_edns_options: - -``incoming.gettag_needs_edns_options`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-gettag-needs-edns-options` - -If set, EDNS options in incoming queries are extracted and passed to the :func:`gettag` hook in the ``ednsoptions`` table. - -.. _setting-yaml-incoming.listen: - -``incoming.listen`` -^^^^^^^^^^^^^^^^^^^ - -- Sequence of `Socket Address`_ (IP or IP:port combinations) -- Default: ``[127.0.0.1]`` - -- Old style setting: :ref:`setting-local-address` - -Local IP addresses to which we bind. Each address specified can -include a port number; if no port is included then the -:ref:`setting-yaml-incoming.port` port will be used for that address. If a -port number is specified, it must be separated from the address with a -':'; for an IPv6 address the address must be enclosed in square -brackets. - -Examples:: - - local-address=127.0.0.1 ::1 - local-address=0.0.0.0:5353 - local-address=[::]:8053 - local-address=127.0.0.1:53, [::1]:5353 - -.. _setting-yaml-incoming.max_concurrent_requests_per_tcp_connection: - -``incoming.max_concurrent_requests_per_tcp_connection`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.3.0 - -- Integer -- Default: ``10`` - -- Old style setting: :ref:`setting-max-concurrent-requests-per-tcp-connection` - -Maximum number of incoming requests handled concurrently per tcp -connection. This number must be larger than 0 and smaller than 65536 -and also smaller than `max-mthreads`. - -.. _setting-yaml-incoming.max_tcp_clients: - -``incoming.max_tcp_clients`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``128`` - -- Old style setting: :ref:`setting-max-tcp-clients` - -Maximum number of simultaneous incoming TCP connections allowed. - -.. _setting-yaml-incoming.max_tcp_per_client: - -``incoming.max_tcp_per_client`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-max-tcp-per-client` - -Maximum number of simultaneous incoming TCP connections allowed per client (remote IP address). - 0 means unlimited. - -.. _setting-yaml-incoming.max_tcp_queries_per_connection: - -``incoming.max_tcp_queries_per_connection`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.0 - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-max-tcp-queries-per-connection` - -Maximum number of DNS queries in a TCP connection. -0 means unlimited. - -.. _setting-yaml-incoming.max_udp_queries_per_round: - -``incoming.max_udp_queries_per_round`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.4 - -- Integer -- Default: ``10000`` - -- Old style setting: :ref:`setting-max-udp-queries-per-round` - -Under heavy load the recursor might be busy processing incoming UDP queries for a long while before there is no more of these, and might therefore -neglect scheduling new ``mthreads``, handling responses from authoritative servers or responding to :doc:`rec_control ` -requests. -This setting caps the maximum number of incoming UDP DNS queries processed in a single round of looping on ``recvmsg()`` after being woken up by the multiplexer, before -returning back to normal processing and handling other events. - -.. _setting-yaml-incoming.non_local_bind: - -``incoming.non_local_bind`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-non-local-bind` - -Bind to addresses even if one or more of the :ref:`setting-yaml-incoming.listen`'s do not exist on this server. -Setting this option will enable the needed socket options to allow binding to non-local addresses. -This feature is intended to facilitate ip-failover setups, but it may also mask configuration issues and for this reason it is disabled by default. - -.. _setting-yaml-incoming.pdns_distributes_queries: - -``incoming.pdns_distributes_queries`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.9.0 - - Default changed to ``no``, previously it was ``yes``. - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-pdns-distributes-queries` - -If set, PowerDNS will use distinct threads to listen to client sockets and distribute that work to worker-threads using a hash of the query. -This feature should maximize the cache hit ratio on versions before 4.9.0. -To use more than one thread set :ref:`setting-yaml-incoming.distributor_threads` in version 4.2.0 or newer. -Enabling should improve performance on systems where :ref:`setting-yaml-incoming.reuseport` does not have the effect of -balancing the queries evenly over multiple worker threads. - -.. _setting-yaml-incoming.port: - -``incoming.port`` -^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``53`` - -- Old style setting: :ref:`setting-local-port` - -Local port to bind to. -If an address in :ref:`setting-yaml-incoming.listen` does not have an explicit port, this port is used. - -.. _setting-yaml-incoming.proxy_protocol_from: - -``incoming.proxy_protocol_from`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.4.0 - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-proxy-protocol-from` - -Ranges that are required to send a Proxy Protocol version 2 header in front of UDP and TCP queries, to pass the original source and destination addresses and ports to the recursor, as well as custom values. -Queries that are not prefixed with such a header will not be accepted from clients in these ranges. Queries prefixed by headers from clients that are not listed in these ranges will be dropped. - -Note that once a Proxy Protocol header has been received, the source address from the proxy header instead of the address of the proxy will be checked against the :ref:`setting-yaml-incoming.allow_from` ACL. - -The dnsdist docs have `more information about the PROXY protocol `_. - -.. _setting-yaml-incoming.proxy_protocol_maximum_size: - -``incoming.proxy_protocol_maximum_size`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.4.0 - -- Integer -- Default: ``512`` - -- Old style setting: :ref:`setting-proxy-protocol-maximum-size` - -The maximum size, in bytes, of a Proxy Protocol payload (header, addresses and ports, and TLV values). Queries with a larger payload will be dropped. - -.. _setting-yaml-incoming.reuseport: - -``incoming.reuseport`` -^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.9.0 - - The default is changed to ``yes``, previously it was ``no``. If ``SO_REUSEPORT`` support is not available, the setting defaults to ``no``. - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-reuseport` - -If ``SO_REUSEPORT`` support is available, allows multiple threads and processes to open listening sockets for the same port. - -Since 4.1.0, when :ref:`setting-yaml-incoming.pdns_distributes_queries` is disabled and :ref:`setting-yaml-incoming.reuseport` is enabled, every worker-thread will open a separate listening socket to let the kernel distribute the incoming queries instead of running a distributor thread (which could otherwise be a bottleneck) and avoiding thundering herd issues, thus leading to much higher performance on multi-core boxes. - -.. _setting-yaml-incoming.tcp_fast_open: - -``incoming.tcp_fast_open`` -^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.0 - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-tcp-fast-open` - -Enable TCP Fast Open support, if available, on the listening sockets. -The numerical value supplied is used as the queue size, 0 meaning disabled. See :ref:`tcp-fast-open-support`. - -.. _setting-yaml-incoming.tcp_timeout: - -``incoming.tcp_timeout`` -^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``2`` - -- Old style setting: :ref:`setting-client-tcp-timeout` - -Time to wait for data from TCP clients. - -.. _setting-yaml-incoming.udp_truncation_threshold: - -``incoming.udp_truncation_threshold`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.2.0 - - Before 4.2.0, the default was 1680. - -- Integer -- Default: ``1232`` - -- Old style setting: :ref:`setting-udp-truncation-threshold` - -EDNS0 allows for large UDP response datagrams, which can potentially raise performance. -Large responses however also have downsides in terms of reflection attacks. -This setting limits the accepted size. -Maximum value is 65535, but values above 4096 should probably not be attempted. - -To know why 1232, see the note at :ref:`setting-yaml-outgoing.edns_bufsize`. - -.. _setting-yaml-incoming.use_incoming_edns_subnet: - -``incoming.use_incoming_edns_subnet`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-use-incoming-edns-subnet` - -Whether to process and pass along a received EDNS Client Subnet to authoritative servers. -The ECS information will only be sent for netmasks and domains listed in :ref:`setting-yaml-outgoing.edns_subnet_allow_list` and will be truncated if the received scope exceeds :ref:`setting-yaml-ecs.ipv4_bits` for IPv4 or :ref:`setting-yaml-ecs.ipv6_bits` for IPv6. - -.. _setting-yaml-logging.common_errors: - -``logging.common_errors`` -^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-log-common-errors` - -Some DNS errors occur rather frequently and are no cause for alarm. - -.. _setting-yaml-logging.disable_syslog: - -``logging.disable_syslog`` -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-disable-syslog` - -Do not log to syslog, only to stdout. -Use this setting when running inside a supervisor that handles logging (like systemd). -**Note**: do not use this setting in combination with :ref:`setting-yaml-recursor.daemon` as all logging will disappear. - -.. _setting-yaml-logging.facility: - -``logging.facility`` -^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-logging-facility` - -If set to a digit, logging is performed under this LOCAL facility. -See :ref:`logging`. -Do not pass names like 'local0'! - -.. _setting-yaml-logging.loglevel: - -``logging.loglevel`` -^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 5.0.0 - - Previous version would not allow setting a level below ``3 (error)``. - -- Integer -- Default: ``6`` - -- Old style setting: :ref:`setting-loglevel` - -Amount of logging. The higher the number, the more lines logged. -Corresponds to ``syslog`` level values (e.g. 0 = ``emergency``, 1 = ``alert``, 2 = ``critical``, 3 = ``error``, 4 = ``warning``, 5 = ``notice``, 6 = ``info``, 7 = ``debug``). -Each level includes itself plus the lower levels before it. -Not recommended to set this below 3. -If :ref:`setting-yaml-logging.quiet` is ``no/false``, :ref:`setting-yaml-logging.loglevel` will be minimally set to ``6 (info)``. - -.. _setting-yaml-logging.protobuf_use_kernel_timestamp: - -``logging.protobuf_use_kernel_timestamp`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-protobuf-use-kernel-timestamp` - -Whether to compute the latency of responses in protobuf messages using the timestamp set by the kernel when the query packet was received (when available), instead of computing it based on the moment we start processing the query. - -.. _setting-yaml-logging.quiet: - -``logging.quiet`` -^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-quiet` - -Don't log queries. - -.. _setting-yaml-logging.rpz_changes: - -``logging.rpz_changes`` -^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-log-rpz-changes` - -Log additions and removals to RPZ zones at Info (6) level instead of Debug (7). - -.. _setting-yaml-logging.statistics_interval: - -``logging.statistics_interval`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.0 - -- Integer -- Default: ``1800`` - -- Old style setting: :ref:`setting-statistics-interval` - -Interval between logging statistical summary on recursor performance. -Use 0 to disable. - -.. _setting-yaml-logging.structured_logging: - -``logging.structured_logging`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-structured-logging` - -Prefer structured logging when both an old style and a structured log messages is available. - -.. _setting-yaml-logging.structured_logging_backend: - -``logging.structured_logging_backend`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.8.0 - -- String -- Default: ``default`` - -- Old style setting: :ref:`setting-structured-logging-backend` - -The backend used for structured logging output. -This setting must be set on the command line (``--structured-logging-backend=...``) to be effective. -Available backends are: - -- ``default``: use the traditional logging system to output structured logging information. -- ``systemd-journal``: use systemd-journal. - When using this backend, provide ``-o verbose`` or simular output option to ``journalctl`` to view the full information. - -.. _setting-yaml-logging.timestamp: - -``logging.timestamp`` -^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-log-timestamp` - - - -.. _setting-yaml-logging.trace: - -``logging.trace`` -^^^^^^^^^^^^^^^^^ - -- String -- Default: ``no`` - -- Old style setting: :ref:`setting-trace` - -One of ``no``, ``yes`` or ``fail``. -If turned on, output impressive heaps of logging. -May destroy performance under load. -To log only queries resulting in a ``ServFail`` answer from the resolving process, this value can be set to ``fail``, but note that the performance impact is still large. -Also note that queries that do produce a result but with a failing DNSSEC validation are not written to the log - -.. _setting-yaml-nod.db_size: - -``nod.db_size`` -^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Integer -- Default: ``67108864`` - -- Old style setting: :ref:`setting-new-domain-db-size` - -The default size of the stable bloom filter used to store previously -observed domains is 67108864. To change the number of cells, use this -setting. For each cell, the SBF uses 1 bit of memory, and one byte of -disk for the persistent file. -If there are already persistent files saved to disk, this setting will -have no effect unless you remove the existing files. - -.. _setting-yaml-nod.history_dir: - -``nod.history_dir`` -^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- String -- Default: ``/usr/local/var/lib/pdns-recursor/nod`` - -- Old style setting: :ref:`setting-new-domain-history-dir` - -This setting controls which directory is used to store the on-disk -cache of previously observed domains. - -The default depends on ``LOCALSTATEDIR`` when building the software. -Usually this comes down to ``/var/lib/pdns-recursor/nod`` or ``/usr/local/var/lib/pdns-recursor/nod``). - -The newly observed domain feature uses a stable bloom filter to store -a history of previously observed domains. The data structure is -synchronized to disk every 10 minutes, and is also initialized from -disk on startup. This ensures that previously observed domains are -preserved across recursor restarts. -If you change the new-domain-db-size setting, you must remove any files -from this directory. - -.. _setting-yaml-nod.ignore_list: - -``nod.ignore_list`` -^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Sequence of strings -- Default: ``[]`` - -- Old style setting: :ref:`setting-new-domain-ignore-list` - -This setting is a list of all domains (and implicitly all subdomains) -that will never be considered a new domain. For example, if the domain -'xyz123.tv' is in the list, then 'foo.bar.xyz123.tv' will never be -considered a new domain. One use-case for the ignore list is to never -reveal details of internal subdomains via the new-domain-lookup -feature. - -.. _setting-yaml-nod.log: - -``nod.log`` -^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-new-domain-log` - -If a newly observed domain is detected, log that domain in the -recursor log file. The log line looks something like:: - - Jul 18 11:31:25 Newly observed domain nod=sdfoijdfio.com - -.. _setting-yaml-nod.lookup: - -``nod.lookup`` -^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-new-domain-lookup` - -If a domain is specified, then each time a newly observed domain is -detected, the recursor will perform an A record lookup of '.'. For example if 'new-domain-lookup' -is configured as 'nod.powerdns.com', and a new domain 'xyz123.tv' is -detected, then an A record lookup will be made for -'xyz123.tv.nod.powerdns.com'. This feature gives a way to share the -newly observed domain with partners, vendors or security teams. The -result of the DNS lookup will be ignored by the recursor. - -.. _setting-yaml-nod.pb_tag: - -``nod.pb_tag`` -^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- String -- Default: ``pdns-nod`` - -- Old style setting: :ref:`setting-new-domain-pb-tag` - -If protobuf is configured, then this tag will be added to all protobuf response messages when -a new domain is observed. - -.. _setting-yaml-nod.tracking: - -``nod.tracking`` -^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-new-domain-tracking` - -Whether to track newly observed domains, i.e. never seen before. This -is a probabilistic algorithm, using a stable bloom filter to store -records of previously seen domains. When enabled for the first time, -all domains will appear to be newly observed, so the feature is best -left enabled for e.g. a week or longer before using the results. Note -that this feature is optional and must be enabled at compile-time, -thus it may not be available in all pre-built packages. -If protobuf is enabled and configured, then the newly observed domain -status will appear as a flag in Response messages. - -.. _setting-yaml-nod.unique_response_db_size: - -``nod.unique_response_db_size`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Integer -- Default: ``67108864`` - -- Old style setting: :ref:`setting-unique-response-db-size` - -The default size of the stable bloom filter used to store previously -observed responses is 67108864. To change the number of cells, use this -setting. For each cell, the SBF uses 1 bit of memory, and one byte of -disk for the persistent file. -If there are already persistent files saved to disk, this setting will -have no effect unless you remove the existing files. - -.. _setting-yaml-nod.unique_response_history_dir: - -``nod.unique_response_history_dir`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- String -- Default: ``/usr/local/var/lib/pdns-recursor/udr`` - -- Old style setting: :ref:`setting-unique-response-history-dir` - -This setting controls which directory is used to store the on-disk -cache of previously observed responses. - -The default depends on ``LOCALSTATEDIR`` when building the software. -Usually this comes down to ``/var/lib/pdns-recursor/udr`` or ``/usr/local/var/lib/pdns-recursor/udr``). - -The newly observed domain feature uses a stable bloom filter to store -a history of previously observed responses. The data structure is -synchronized to disk every 10 minutes, and is also initialized from -disk on startup. This ensures that previously observed responses are -preserved across recursor restarts. If you change the -unique-response-db-size, you must remove any files from this directory. - -.. _setting-yaml-nod.unique_response_log: - -``nod.unique_response_log`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-unique-response-log` - -Whether to log when a unique response is detected. The log line -looks something like: - -Oct 24 12:11:27 Unique response observed: qname=foo.com qtype=A rrtype=AAAA rrname=foo.com rrcontent=1.2.3.4 - -.. _setting-yaml-nod.unique_response_pb_tag: - -``nod.unique_response_pb_tag`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- String -- Default: ``pdns-udr`` - -- Old style setting: :ref:`setting-unique-response-pb-tag` - -If protobuf is configured, then this tag will be added to all protobuf response messages when -a unique DNS response is observed. - -.. _setting-yaml-nod.unique_response_tracking: - -``nod.unique_response_tracking`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-unique-response-tracking` - -Whether to track unique DNS responses, i.e. never seen before combinations -of the triplet (query name, query type, RR[rrname, rrtype, rrdata]). -This can be useful for tracking potentially suspicious domains and -behaviour, e.g. DNS fast-flux. -If protobuf is enabled and configured, then the Protobuf Response message -will contain a flag with udr set to true for each RR that is considered -unique, i.e. never seen before. -This feature uses a probabilistic data structure (stable bloom filter) to -track unique responses, which can have false positives as well as false -negatives, thus it is a best-effort feature. Increasing the number of cells -in the SBF using the unique-response-db-size setting can reduce FPs and FNs. - -.. _setting-yaml-outgoing.dont_query: - -``outgoing.dont_query`` -^^^^^^^^^^^^^^^^^^^^^^^ - -- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) -- Default: ``[127.0.0.0/8, 10.0.0.0/8, 100.64.0.0/10, 169.254.0.0/16, 192.168.0.0/16, 172.16.0.0/12, ::1/128, fc00::/7, fe80::/10, 0.0.0.0/8, 192.0.0.0/24, 192.0.2.0/24, 198.51.100.0/24, 203.0.113.0/24, 240.0.0.0/4, ::/96, ::ffff:0:0/96, 100::/64, 2001:db8::/32]`` - -- Old style setting: :ref:`setting-dont-query` - -The DNS is a public database, but sometimes contains delegations to private IP addresses, like for example 127.0.0.1. -This can have odd effects, depending on your network, and may even be a security risk. -Therefore, the PowerDNS Recursor by default does not query private space IP addresses. -This setting can be used to expand or reduce the limitations. - -Queries for names in forward zones and to addresses as configured in any of the settings :ref:`setting-yaml-recursor.forward_zones`, :ref:`setting-yaml-recursor.forward_zones_file` or :ref:`setting-yaml-recursor.forward_zones_recurse` are performed regardless of these limitations. - -.. _setting-yaml-outgoing.dont_throttle_names: - -``outgoing.dont_throttle_names`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Sequence of strings -- Default: ``[]`` - -- Old style setting: :ref:`setting-dont-throttle-names` - -When an authoritative server does not answer a query or sends a reply the recursor does not like, it is throttled. -Any servers' name suffix-matching the supplied names will never be throttled. - -.. warning:: - Most servers on the internet do not respond for a good reason (overloaded or unreachable), ``dont-throttle-names`` could make this load on the upstream server even higher, resulting in further service degradation. - -.. _setting-yaml-outgoing.dont_throttle_netmasks: - -``outgoing.dont_throttle_netmasks`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) -- Default: ``[]`` - -- Old style setting: :ref:`setting-dont-throttle-netmasks` - -When an authoritative server does not answer a query or sends a reply the recursor does not like, it is throttled. -Any servers matching the supplied netmasks will never be throttled. - -This can come in handy on lossy networks when forwarding, where the same server is configured multiple times (e.g. with ``forward-zones-recurse=example.com=192.0.2.1;192.0.2.1``). -By default, the PowerDNS Recursor would throttle the 'first' server on a timeout and hence not retry the 'second' one. -In this case, ``dont-throttle-netmasks`` could be set to ``192.0.2.1``. - -.. warning:: - Most servers on the internet do not respond for a good reason (overloaded or unreachable), ``dont-throttle-netmasks`` could make this load on the upstream server even higher, resulting in further service degradation. - -.. _setting-yaml-outgoing.dot_to_auth_names: - -``outgoing.dot_to_auth_names`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Sequence of strings -- Default: ``[]`` - -- Old style setting: :ref:`setting-dot-to-auth-names` - -Force DoT to the listed authoritative nameservers. For this to work, DoT support has to be compiled in. -Currently, the certificate is not checked for validity in any way. - -.. _setting-yaml-outgoing.dot_to_port_853: - -``outgoing.dot_to_port_853`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-dot-to-port-853` - -Enable DoT to forwarders that specify port 853. - -.. _setting-yaml-outgoing.edns_bufsize: - -``outgoing.edns_bufsize`` -^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.2.0 - - Before 4.2.0, the default was 1680 - -- Integer -- Default: ``1232`` - -- Old style setting: :ref:`setting-edns-outgoing-bufsize` - -.. note:: Why 1232? - - 1232 is the largest number of payload bytes that can fit in the smallest IPv6 packet. - IPv6 has a minimum MTU of 1280 bytes (:rfc:`RFC 8200, section 5 <8200#section-5>`), minus 40 bytes for the IPv6 header, minus 8 bytes for the UDP header gives 1232, the maximum payload size for the DNS response. - -This is the value set for the EDNS0 buffer size in outgoing packets. -Lower this if you experience timeouts. - -.. _setting-yaml-outgoing.edns_padding: - -``outgoing.edns_padding`` -^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.8.0 - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-edns-padding-out` - -Whether to add EDNS padding to outgoing DoT queries. - -.. _setting-yaml-outgoing.edns_subnet_allow_list: - -``outgoing.edns_subnet_allow_list`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Sequence of strings -- Default: ``[]`` - -- Old style setting: :ref:`setting-edns-subnet-allow-list` - -List of netmasks and domains that :rfc:`EDNS Client Subnet <7871>` should be enabled for in outgoing queries. - -For example, an EDNS Client Subnet option containing the address of the initial requestor (but see :ref:`setting-yaml-ecs.add_for`) will be added to an outgoing query sent to server 192.0.2.1 for domain X if 192.0.2.1 matches one of the supplied netmasks, or if X matches one of the supplied domains. -The initial requestor address will be truncated to 24 bits for IPv4 (see :ref:`setting-yaml-ecs.ipv4_bits`) and to 56 bits for IPv6 (see :ref:`setting-yaml-ecs.ipv6_bits`), as recommended in the privacy section of RFC 7871. - - -Note that this setting describes the destination of outgoing queries, not the sources of incoming queries, nor the subnets described in the EDNS Client Subnet option. - -By default, this option is empty, meaning no EDNS Client Subnet information is sent. - -.. _setting-yaml-outgoing.lowercase: - -``outgoing.lowercase`` -^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-lowercase-outgoing` - -Set to true to lowercase the outgoing queries. -When set to 'no' (the default) a query from a client using mixed case in the DNS labels (such as a user entering mixed-case names or `draft-vixie-dnsext-dns0x20-00 `_), PowerDNS preserves the case of the query. -Broken authoritative servers might give a wrong or broken answer on this encoding. -Setting ``lowercase-outgoing`` to 'yes' makes the PowerDNS Recursor lowercase all the labels in the query to the authoritative servers, but still return the proper case to the client requesting. - -.. _setting-yaml-outgoing.max_busy_dot_probes: - -``outgoing.max_busy_dot_probes`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.7.0 - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-max-busy-dot-probes` - -Limit the maximum number of simultaneous DoT probes the Recursor will schedule. -The default value 0 means no DoT probes are scheduled. - -DoT probes are used to check if an authoritative server's IP address supports DoT. -If the probe determines an IP address supports DoT, the Recursor will use DoT to contact it for subsequent queries until a failure occurs. -After a failure, the Recursor will stop using DoT for that specific IP address for a while. -The results of probes are remembered and can be viewed by the ``rec_control dump-dot-probe-map`` command. -If the maximum number of pending probes is reached, no probes will be scheduled, even if no DoT status is known for an address. -If the result of a probe is not yet available, the Recursor will contact the authoritative server in the regular way, unless an authoritative server is configured to be contacted over DoT always using :ref:`setting-yaml-outgoing.dot_to_auth_names`. -In that case no probe will be scheduled. - -.. note:: - DoT probing is an experimental feature. - Please test thoroughly to determine if it is suitable in your specific production environment before enabling. - -.. _setting-yaml-outgoing.network_timeout: - -``outgoing.network_timeout`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``1500`` - -- Old style setting: :ref:`setting-network-timeout` - -Number of milliseconds to wait for a remote authoritative server to respond. - -.. _setting-yaml-outgoing.single_socket: - -``outgoing.single_socket`` -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-single-socket` - -Use only a single socket for outgoing queries. - -.. _setting-yaml-outgoing.source_address: - -``outgoing.source_address`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.4.0 - - IPv6 addresses can be set with this option as well. - -- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) -- Default: ``[0.0.0.0]`` - -- Old style setting: :ref:`setting-query-local-address` - -Send out local queries from this address, or addresses. By adding multiple -addresses, increased spoofing resilience is achieved. When no address of a certain -address family is configured, there are *no* queries sent with that address family. -In the default configuration this means that IPv6 is not used for outgoing queries. - -.. _setting-yaml-outgoing.tcp_fast_open_connect: - -``outgoing.tcp_fast_open_connect`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-tcp-fast-open-connect` - -Enable TCP Fast Open Connect support, if available, on the outgoing connections to authoritative servers. See :ref:`tcp-fast-open-support`. - -.. _setting-yaml-outgoing.tcp_max_idle_ms: - -``outgoing.tcp_max_idle_ms`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Integer -- Default: ``10000`` - -- Old style setting: :ref:`setting-tcp-out-max-idle-ms` - -Time outgoing TCP/DoT connections are left idle in milliseconds or 0 if no limit. After having been idle for this time, the connection is eligible for closing. - -.. _setting-yaml-outgoing.tcp_max_idle_per_auth: - -``outgoing.tcp_max_idle_per_auth`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Integer -- Default: ``10`` - -- Old style setting: :ref:`setting-tcp-out-max-idle-per-auth` - -Maximum number of idle outgoing TCP/DoT connections to a specific IP per thread, 0 means do not keep idle connections open. - -.. _setting-yaml-outgoing.tcp_max_idle_per_thread: - -``outgoing.tcp_max_idle_per_thread`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Integer -- Default: ``100`` - -- Old style setting: :ref:`setting-tcp-out-max-idle-per-thread` - -Maximum number of idle outgoing TCP/DoT connections per thread, 0 means do not keep idle connections open. - -.. _setting-yaml-outgoing.tcp_max_queries: - -``outgoing.tcp_max_queries`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-tcp-out-max-queries` - -Maximum total number of queries per outgoing TCP/DoT connection, 0 means no limit. After this number of queries, the connection is -closed and a new one will be created if needed. - -.. _setting-yaml-outgoing.udp_source_port_avoid: - -``outgoing.udp_source_port_avoid`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Sequence of strings -- Default: ``[11211]`` - -- Old style setting: :ref:`setting-udp-source-port-avoid` - -A sequence of UDP port numbers to avoid when binding. For example: - -.. code-block:: yaml - - outgoing: - udp_source_port_avoid: - - 5300 - - 11211 - -See :ref:`setting-yaml-outgoing.udp_source_port_min`. - -.. _setting-yaml-outgoing.udp_source_port_max: - -``outgoing.udp_source_port_max`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Integer -- Default: ``65535`` - -- Old style setting: :ref:`setting-udp-source-port-max` - -This option sets the maximum limit of UDP port number to bind on. - -See :ref:`setting-yaml-outgoing.udp_source_port_min`. - -.. _setting-yaml-outgoing.udp_source_port_min: - -``outgoing.udp_source_port_min`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Integer -- Default: ``1024`` - -- Old style setting: :ref:`setting-udp-source-port-min` - -This option sets the low limit of UDP port number to bind on. - -In combination with :ref:`setting-yaml-outgoing.udp_source_port_max` it configures the UDP -port range to use. Port numbers are randomized within this range on -initialization, and exceptions can be configured with :ref:`setting-yaml-outgoing.udp_source_port_avoid` - -.. _setting-yaml-packetcache.disable: - -``packetcache.disable`` -^^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-disable-packetcache` - -Turn off the packet cache. Useful when running with Lua scripts that can not be cached, though individual query caching can be controlled from Lua as well. - -.. _setting-yaml-packetcache.max_entries: - -``packetcache.max_entries`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``500000`` - -- Old style setting: :ref:`setting-max-packetcache-entries` - -Maximum number of Packet Cache entries. Sharded and shared by all threads since 4.9.0. - -.. _setting-yaml-packetcache.negative_ttl: - -``packetcache.negative_ttl`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.9.0 - -- Integer -- Default: ``60`` - -- Old style setting: :ref:`setting-packetcache-negative-ttl` - -Maximum number of seconds to cache an ``NxDomain`` or ``NoData`` answer in the packetcache. -This setting's maximum is capped to :ref:`setting-yaml-packetcache.ttl`. -i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-negative-ttl`` at the default will lower ``packetcache-negative-ttl`` to ``15``. - -.. _setting-yaml-packetcache.servfail_ttl: - -``packetcache.servfail_ttl`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -'versionchanged': ('4.0.0', "This setting's maximum is capped to :ref:`setting-yaml-packetcache.ttl`. - i.e. setting ``packetcache-ttl=15`` and keeping ``packetcache-servfail-ttl`` at the default will lower ``packetcache-servfail-ttl`` to ``15``.") - -- Integer -- Default: ``60`` - -- Old style setting: :ref:`setting-packetcache-servfail-ttl` - -Maximum number of seconds to cache an answer indicating a failure to resolve in the packet cache. -Before version 4.6.0 only ``ServFail`` answers were considered as such. Starting with 4.6.0, all responses with a code other than ``NoError`` and ``NXDomain``, or without records in the answer and authority sections, are considered as a failure to resolve. -Since 4.9.0, negative answers are handled separately from resolving failures. - -.. _setting-yaml-packetcache.shards: - -``packetcache.shards`` -^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.9.0 - -- Integer -- Default: ``1024`` - -- Old style setting: :ref:`setting-packetcache-shards` - -Sets the number of shards in the packet cache. If you have high contention as reported by ``packetcache-contented/packetcache-acquired``, -you can try to enlarge this value or run with fewer threads. - -.. _setting-yaml-packetcache.ttl: - -``packetcache.ttl`` -^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.9.0 - - The default was changed from 3600 (1 hour) to 86400 (24 hours). - -- Integer -- Default: ``86400`` - -- Old style setting: :ref:`setting-packetcache-ttl` - -Maximum number of seconds to cache an item in the packet cache, no matter what the original TTL specified. - -.. _setting-yaml-recordcache.locked_ttl_perc: - -``recordcache.locked_ttl_perc`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.8.0 - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-record-cache-locked-ttl-perc` - -Replace record sets in the record cache only after this percentage of the original TTL has passed. -The PowerDNS Recursor already has several mechanisms to protect against spoofing attempts. -This adds an extra layer of protection---as it limits the window of time cache updates are accepted---at the cost of a less efficient record cache. - -The default value of 0 means no extra locking occurs. -When non-zero, record sets received (e.g. in the Additional Section) will not replace existing record sets in the record cache until the given percentage of the original TTL has expired. -A value of 100 means only expired record sets will be replaced. - -There are a few cases where records will be replaced anyway: - -- Record sets that are expired will always be replaced. -- Authoritative record sets will replace unauthoritative record sets unless DNSSEC validation of the new record set failed. -- If the new record set belongs to a DNSSEC-secure zone and successfully passed validation it will replace an existing entry. -- Record sets produced by :ref:`setting-yaml-recordcache.refresh_on_ttl_perc` tasks will also replace existing record sets. - -.. _setting-yaml-recordcache.max_cache_bogus_ttl: - -``recordcache.max_cache_bogus_ttl`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Integer -- Default: ``3600`` - -- Old style setting: :ref:`setting-max-cache-bogus-ttl` - -Maximum number of seconds to cache an item in the DNS cache (negative or positive) if its DNSSEC validation failed, no matter what the original TTL specified, to reduce the impact of a broken domain. - -.. _setting-yaml-recordcache.max_entries: - -``recordcache.max_entries`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``1000000`` - -- Old style setting: :ref:`setting-max-cache-entries` - -Maximum number of DNS record cache entries, shared by all threads since 4.4.0. -Each entry associates a name and type with a record set. -The size of the negative cache is 10% of this number. - -.. _setting-yaml-recordcache.max_negative_ttl: - -``recordcache.max_negative_ttl`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``3600`` - -- Old style setting: :ref:`setting-max-negative-ttl` - -A query for which there is authoritatively no answer is cached to quickly deny a record's existence later on, without putting a heavy load on the remote server. -In practice, caches can become saturated with hundreds of thousands of hosts which are tried only once. -This setting, which defaults to 3600 seconds, puts a maximum on the amount of time negative entries are cached. - -.. _setting-yaml-recordcache.max_ttl: - -``recordcache.max_ttl`` -^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.1.0 - - The minimum value of this setting is 15. i.e. setting this to lower than 15 will make this value 15. - -- Integer -- Default: ``86400`` - -- Old style setting: :ref:`setting-max-cache-ttl` - -Maximum number of seconds to cache an item in the DNS cache, no matter what the original TTL specified. -This value also controls the refresh period of cached root data. -See :ref:`handling-of-root-hints` for more information on this. - -.. _setting-yaml-recordcache.refresh_on_ttl_perc: - -``recordcache.refresh_on_ttl_perc`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-refresh-on-ttl-perc` - -Sets the 'refresh almost expired' percentage of the record cache. Whenever a record is fetched from the packet or record cache -and only ``refresh-on-ttl-perc`` percent or less of its original TTL is left, a task is queued to refetch the name/type combination to -update the record cache. In most cases this causes future queries to always see a non-expired record cache entry. -A typical value is 10. If the value is zero, this functionality is disabled. - -.. _setting-yaml-recordcache.shards: - -``recordcache.shards`` -^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.4.0 - -- Integer -- Default: ``1024`` - -- Old style setting: :ref:`setting-record-cache-shards` - -Sets the number of shards in the record cache. If you have high -contention as reported by -``record-cache-contented/record-cache-acquired``, you can try to -enlarge this value or run with fewer threads. - -.. _setting-yaml-recursor.allow_trust_anchor_query: - -``recursor.allow_trust_anchor_query`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.3.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-allow-trust-anchor-query` - -Allow ``trustanchor.server CH TXT`` and ``negativetrustanchor.server CH TXT`` queries to view the configured :doc:`DNSSEC ` (negative) trust anchors. - -.. _setting-yaml-recursor.any_to_tcp: - -``recursor.any_to_tcp`` -^^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-any-to-tcp` - -Answer questions for the ANY type on UDP with a truncated packet that refers the remote server to TCP. -Useful for mitigating ANY reflection attacks. - -.. _setting-yaml-recursor.auth_zones: - -``recursor.auth_zones`` -^^^^^^^^^^^^^^^^^^^^^^^ - -- Sequence of `Auth Zone`_ -- Default: ``[]`` - -- Old style setting: :ref:`setting-auth-zones` - -Zones read from these files (in BIND format) are served authoritatively (but without the AA bit set in responses). -DNSSEC is not supported. Example: - -.. code-block:: yaml - - recursor: - auth-zones: - - zone: example.org - file: /var/zones/example.org - - zone: powerdns.com - file: /var/zones/powerdns.com - -.. _setting-yaml-recursor.chroot: - -``recursor.chroot`` -^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-chroot` - -If set, chroot to this directory for more security. -This is not recommended; instead, we recommend containing PowerDNS using operating system features. -We ship systemd unit files with our packages to make this easy. - -Make sure that ``/dev/log`` is available from within the chroot. -Logging will silently fail over time otherwise (on logrotate). - -When using ``chroot``, all other paths (except for :ref:`setting-yaml-recursor.config_dir`) set in the configuration are relative to the new root. - -When running on a system where systemd manages services, ``chroot`` does not work out of the box, as PowerDNS cannot use the ``NOTIFY_SOCKET``. -Either do not ``chroot`` on these systems or set the 'Type' of this service to 'simple' instead of 'notify' (refer to the systemd documentation on how to modify unit-files). - -.. _setting-yaml-recursor.config_dir: - -``recursor.config_dir`` -^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: ``SYSCONFDIR`` - -- Old style setting: :ref:`setting-config-dir` - -Location of configuration directory (where ``recursor.conf`` or ``recursor.yml`` is stored). -Usually ``/etc/powerdns``, but this depends on ``SYSCONFDIR`` during compile-time. -Use default or set on command line. - -.. _setting-yaml-recursor.config_name: - -``recursor.config_name`` -^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-config-name` - -When running multiple recursors on the same server, read settings from :file:`recursor-{name}.conf`, this will also rename the binary image. - -.. _setting-yaml-recursor.cpu_map: - -``recursor.cpu_map`` -^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-cpu-map` - -Set CPU affinity for threads, asking the scheduler to run those threads on a single CPU, or a set of CPUs. -This parameter accepts a space separated list of thread-id=cpu-id, or thread-id=cpu-id-1,cpu-id-2,...,cpu-id-N. -For example, to make the worker thread 0 run on CPU id 0 and the worker thread 1 on CPUs 1 and 2:: - -.. code-block:: yaml - - recursor: - cpu_map: 0=0 1=1,2 - -The thread handling the control channel, the webserver and other internal stuff has been assigned id 0, the distributor -threads if any are assigned id 1 and counting, and the worker threads follow behind. -The number of distributor threads is determined by :ref:`setting-yaml-incoming.distributor_threads`, the number of worker threads is determined by the :ref:`setting-yaml-recursor.threads` setting. - -This parameter is only available if the OS provides the ``pthread_setaffinity_np()`` function. - -Note that depending on the configuration the Recursor can start more threads. -Typically these threads will sleep most of the time. -These threads cannot be specified in this setting as their thread-ids are left unspecified. - -.. _setting-yaml-recursor.daemon: - -``recursor.daemon`` -^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.0.0 - - Default is now ``no``, was ``yes`` before. - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-daemon` - -Operate in the background. - -.. _setting-yaml-recursor.dns64_prefix: - -``recursor.dns64_prefix`` -^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.4.0 - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-dns64-prefix` - -Enable DNS64 (:rfc:`6147`) support using the supplied /96 IPv6 prefix. This will generate 'fake' ``AAAA`` records for names -with only ``A`` records, as well as 'fake' ``PTR`` records to make sure that reverse lookup of DNS64-generated IPv6 addresses -generate the right name. -See :doc:`dns64` for more flexible but slower alternatives using Lua. - -.. _setting-yaml-recursor.entropy_source: - -``recursor.entropy_source`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: ``/dev/urandom`` - -- Old style setting: :ref:`setting-entropy-source` - -PowerDNS can read entropy from a (hardware) source. -This is used for generating random numbers which are very hard to predict. -Generally on UNIX platforms, this source will be ``/dev/urandom``, which will always supply random numbers, even if entropy is lacking. -Change to ``/dev/random`` if PowerDNS should block waiting for enough entropy to arrive. - -.. _setting-yaml-recursor.etc_hosts_file: - -``recursor.etc_hosts_file`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: ``/etc/hosts`` - -- Old style setting: :ref:`setting-etc-hosts-file` - -The path to the /etc/hosts file, or equivalent. -This file can be used to serve data authoritatively using :ref:`setting-yaml-recursor.export_etc_hosts`. - -.. _setting-yaml-recursor.event_trace_enabled: - -``recursor.event_trace_enabled`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-event-trace-enabled` - -Enable the recording and logging of ref:`event traces`. This is an experimental feature and subject to change. -Possible values are 0: (disabled), 1 (add information to protobuf logging messages) and 2 (write to log) and 3 (both). - -.. _setting-yaml-recursor.export_etc_hosts: - -``recursor.export_etc_hosts`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-export-etc-hosts` - -If set, this flag will export the host names and IP addresses mentioned in ``/etc/hosts``. - -.. _setting-yaml-recursor.export_etc_hosts_search_suffix: - -``recursor.export_etc_hosts_search_suffix`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-export-etc-hosts-search-suffix` - -If set, all hostnames in the :ref:`setting-yaml-recursor.export_etc_hosts` file are loaded in canonical form, based on this suffix, unless the name contains a '.', in which case the name is unchanged. -So an entry called 'pc' with ``export-etc-hosts-search-suffix='home.com'`` will lead to the generation of 'pc.home.com' within the recursor. -An entry called 'server1.home' will be stored as 'server1.home', regardless of this setting. - -.. _setting-yaml-recursor.extended_resolution_errors: - -``recursor.extended_resolution_errors`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-extended-resolution-errors` - -If set, the recursor will add an EDNS Extended Error (:rfc:`8914`) to responses when resolution failed, like DNSSEC validation errors, explaining the reason it failed. This setting is not needed to allow setting custom error codes from Lua or from a RPZ hit. - -.. _setting-yaml-recursor.forward_zones: - -``recursor.forward_zones`` -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Sequence of `Forward Zone`_ -- Default: ``[]`` - -- Old style setting: :ref:`setting-forward-zones` - -Queries for zones listed here will be forwarded to the IP address listed. i.e. - -.. code-block:: yaml - - recursor: - forward-zones: - - zone: example.org - forwarders: - - 203.0.113.210 - - zone: powerdns.com - forwarders: - - 2001:DB8::BEEF:5 - -Multiple IP addresses can be specified and port numbers other than 53 can be configured: - -.. code-block:: yaml - - recursor: - forward-zones: - - zone: example.org - forwarders: - - 203.0.113.210:5300 - - 127.0.0.1 - - zone: powerdns.com - forwarders: - - 127.0.0.1 - - 198.51.100.10:530 - - '[2001:DB8::1:3]:5300' - -Forwarded queries have the ``recursion desired (RD)`` bit set to ``0``, meaning that this setting is intended to forward queries to authoritative servers. -If an ``NS`` record set for a subzone of the forwarded zone is learned, that record set will be used to determine addresses for name servers of the subzone. -This allows e.g. a forward to a local authoritative server holding a copy of the root zone, delegations received from that server will work. - -**IMPORTANT**: When using DNSSEC validation (which is default), forwards to non-delegated (e.g. internal) zones that have a DNSSEC signed parent zone will validate as Bogus. -To prevent this, add a Negative Trust Anchor (NTA) for this zone in the :ref:`setting-yaml-recursor.lua_config_file` with ``addNTA('your.zone', 'A comment')``. -If this forwarded zone is signed, instead of adding NTA, add the DS record to the :ref:`setting-yaml-recursor.lua_config_file`. -See the :doc:`dnssec` information. - -.. _setting-yaml-recursor.forward_zones_file: - -``recursor.forward_zones_file`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.0.0 - - (Old style settings only) Comments are allowed, everything behind ``#`` is ignored. -.. versionchanged:: 4.6.0 - - (Old style settings only) Zones prefixed with a ``^`` are added to the :ref:`setting-allow-notify-for` list. Both prefix characters can be used if desired, in any order. - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-forward-zones-file` - -Same as :ref:`setting-yaml-recursor.forward_zones`, parsed from a file as a sequence of `ZoneForward`. - -.. code-block:: yaml - - - zone: example1.com - forwarders: - - 127.0.0.1 - - 127.0.0.1:5353 - - '[::1]53' - - zone: example2.com - forwarders: - - ::1 - recurse: true - notify_allowed: true - -The DNSSEC notes from :ref:`setting-yaml-recursor.forward_zones` apply here as well. - -.. _setting-yaml-recursor.forward_zones_recurse: - -``recursor.forward_zones_recurse`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Sequence of `Forward Zone`_ -- Default: ``[]`` - -- Old style setting: :ref:`setting-forward-zones-recurse` - -Like regular :ref:`setting-yaml-recursor.forward_zones`, but forwarded queries have the ``recursion desired (RD)`` bit set to ``1``, meaning that this setting is intended to forward queries to other recursive servers. -In contrast to regular forwarding, the rule that delegations of the forwarded subzones are respected is not active. -This is because we rely on the forwarder to resolve the query fully. - -See :ref:`setting-yaml-recursor.forward_zones` for additional options (such as supplying multiple recursive servers) and an important note about DNSSEC. - -.. _setting-yaml-recursor.hint_file: - -``recursor.hint_file`` -^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.6.2 - - Introduced the value ``no`` to disable root-hints processing. -.. versionchanged:: 4.9.0 - - Introduced the value ``no-refresh`` to disable both root-hints processing and periodic refresh of the cached root `NS` records. - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-hint-file` - -If set, the root-hints are read from this file. If empty, the default built-in root hints are used. - -In some special cases, processing the root hints is not needed, for example when forwarding all queries to another recursor. -For these special cases, it is possible to disable the processing of root hints by setting the value to ``no`` or ``no-refresh``. -See :ref:`handling-of-root-hints` for more information on root hints handling. - -.. _setting-yaml-recursor.ignore_unknown_settings: - -``recursor.ignore_unknown_settings`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Sequence of strings -- Default: ``[]`` - -- Old style setting: :ref:`setting-ignore-unknown-settings` - -Names of settings to be ignored while parsing configuration files, if the setting -name is unknown to PowerDNS. - -Useful during upgrade testing. - -.. _setting-yaml-recursor.include_dir: - -``recursor.include_dir`` -^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-include-dir` - -Directory to scan for additional config files. All files that end with .conf are loaded in order using ``POSIX`` as locale. - -.. _setting-yaml-recursor.latency_statistic_size: - -``recursor.latency_statistic_size`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``10000`` - -- Old style setting: :ref:`setting-latency-statistic-size` - -Indication of how many queries will be averaged to get the average latency reported by the 'qa-latency' metric. - -.. _setting-yaml-recursor.lua_config_file: - -``recursor.lua_config_file`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-lua-config-file` - -If set, and Lua support is compiled in, this will load an additional configuration file for newer features and more complicated setups. -See :doc:`lua-config/index` for the options that can be set in this file. - -.. _setting-yaml-recursor.lua_dns_script: - -``recursor.lua_dns_script`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-lua-dns-script` - -Path to a lua file to manipulate the Recursor's answers. See :doc:`lua-scripting/index` for more information. - -.. _setting-yaml-recursor.lua_maintenance_interval: - -``recursor.lua_maintenance_interval`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- Integer -- Default: ``1`` - -- Old style setting: :ref:`setting-lua-maintenance-interval` - -The interval between calls to the Lua user defined `maintenance()` function in seconds. -See :ref:`hooks-maintenance-callback` - -.. _setting-yaml-recursor.max_generate_steps: - -``recursor.max_generate_steps`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.3.0 - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-max-generate-steps` - -Maximum number of steps for a '$GENERATE' directive when parsing a -zone file. This is a protection measure to prevent consuming a lot of -CPU and memory when untrusted zones are loaded. Default to 0 which -means unlimited. - -.. _setting-yaml-recursor.max_include_depth: - -``recursor.max_include_depth`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Integer -- Default: ``20`` - -- Old style setting: :ref:`setting-max-include-depth` - -Maximum number of nested ``$INCLUDE`` directives while processing a zone file. -Zero mean no ``$INCLUDE`` directives will be accepted. - -.. _setting-yaml-recursor.max_mthreads: - -``recursor.max_mthreads`` -^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``2048`` - -- Old style setting: :ref:`setting-max-mthreads` - -Maximum number of simultaneous MTasker threads. - -.. _setting-yaml-recursor.max_ns_address_qperq: - -``recursor.max_ns_address_qperq`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.1.16 -.. versionadded:: 4.2.2 -.. versionadded:: 4.3.1 - -- Integer -- Default: ``10`` - -- Old style setting: :ref:`setting-max-ns-address-qperq` - -The maximum number of outgoing queries with empty replies for -resolving nameserver names to addresses we allow during the resolution -of a single client query. If IPv6 is enabled, an A and a AAAA query -for a name counts as 1. If a zone publishes more than this number of -NS records, the limit is further reduced for that zone by lowering -it by the number of NS records found above the -:ref:`setting-yaml-recursor.max_ns_address_qperq` value. The limit wil not be reduced to a -number lower than 5. - -.. _setting-yaml-recursor.max_ns_per_resolve: - -``recursor.max_ns_per_resolve`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.8.0 -.. versionadded:: 4.7.3 -.. versionadded:: 4.6.4 -.. versionadded:: 4.5.11 - -- Integer -- Default: ``13`` - -- Old style setting: :ref:`setting-max-ns-per-resolve` - -The maximum number of NS records that will be considered to select a nameserver to contact to resolve a name. -If a zone has more than :ref:`setting-yaml-recursor.max_ns_per_resolve` NS records, a random sample of this size will be used. -If :ref:`setting-yaml-recursor.max_ns_per_resolve` is zero, no limit applies. - -.. _setting-yaml-recursor.max_qperq: - -``recursor.max_qperq`` -^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``60`` - -- Old style setting: :ref:`setting-max-qperq` - -The maximum number of outgoing queries that will be sent out during the resolution of a single client query. -This is used to limit endlessly chasing CNAME redirections. -If qname-minimization is enabled, the number will be forced to be 100 -at a minimum to allow for the extra queries qname-minimization generates when the cache is empty. - -.. _setting-yaml-recursor.max_recursion_depth: - -``recursor.max_recursion_depth`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.1.0 - - Before 4.1.0, this settings was unlimited. -.. versionchanged:: 4.9.0 - - Before 4.9.0 this setting's default was 40 and the limit on ``CNAME`` chains (fixed at 16) acted as a bound on he recursion depth. - -- Integer -- Default: ``16`` - -- Old style setting: :ref:`setting-max-recursion-depth` - -Total maximum number of internal recursion calls the server may use to answer a single query. -0 means unlimited. -The value of :ref:`setting-yaml-recursor.stack_size` should be increased together with this one to prevent the stack from overflowing. -If :ref:`setting-yaml-recursor.qname_minimization` is enabled, the fallback code in case of a failing resolve is allowed an additional `max-recursion-depth/2`. - -.. _setting-yaml-recursor.max_total_msec: - -``recursor.max_total_msec`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``7000`` - -- Old style setting: :ref:`setting-max-total-msec` - -Total maximum number of milliseconds of wallclock time the server may use to answer a single query. -0 means unlimited. - -.. _setting-yaml-recursor.minimum_ttl_override: - -``recursor.minimum_ttl_override`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.5.0 - - Old versions used default 0. - -- Integer -- Default: ``1`` - -- Old style setting: :ref:`setting-minimum-ttl-override` - -This setting artificially raises all TTLs to be at least this long. -Setting this to a value greater than 1 technically is an RFC violation, but might improve performance a lot. -Using a value of 0 impacts performance of TTL 0 records greatly, since it forces the recursor to contact -authoritative servers each time a client requests them. -Can be set at runtime using ``rec_control set-minimum-ttl 3600``. - -.. _setting-yaml-recursor.non_resolving_ns_max_fails: - -``recursor.non_resolving_ns_max_fails`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Integer -- Default: ``5`` - -- Old style setting: :ref:`setting-non-resolving-ns-max-fails` - -Number of failed address resolves of a nameserver name to start throttling it, 0 is disabled. -Nameservers matching :ref:`setting-yaml-outgoing.dont_throttle_names` will not be throttled. - -.. _setting-yaml-recursor.non_resolving_ns_throttle_time: - -``recursor.non_resolving_ns_throttle_time`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Integer -- Default: ``60`` - -- Old style setting: :ref:`setting-non-resolving-ns-throttle-time` - -Number of seconds to throttle a nameserver with a name failing to resolve. - -.. _setting-yaml-recursor.nothing_below_nxdomain: - -``recursor.nothing_below_nxdomain`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.3.0 - -- String -- Default: ``dnssec`` - -- Old style setting: :ref:`setting-nothing-below-nxdomain` - -- One of ``no``, ``dnssec``, ``yes``. - -The type of :rfc:`8020` handling using cached NXDOMAIN responses. -This RFC specifies that NXDOMAIN means that the DNS tree under the denied name MUST be empty. -When an NXDOMAIN exists in the cache for a shorter name than the qname, no lookup is done and an NXDOMAIN is sent to the client. - -For instance, when ``foo.example.net`` is negatively cached, any query -matching ``*.foo.example.net`` will be answered with NXDOMAIN directly -without consulting authoritative servers. - -``no`` - No :rfc:`8020` processing is done. - -``dnssec`` - :rfc:`8020` processing is only done using cached NXDOMAIN records that are - DNSSEC validated. - -``yes`` - :rfc:`8020` processing is done using any non-Bogus NXDOMAIN record - available in the cache. - -.. _setting-yaml-recursor.public_suffix_list_file: - -``recursor.public_suffix_list_file`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-public-suffix-list-file` - -Path to the Public Suffix List file, if any. If set, PowerDNS will try to load the Public Suffix List from this file instead of using the built-in list. The PSL is used to group the queries by relevant domain names when displaying the top queries. - -.. _setting-yaml-recursor.qname_minimization: - -``recursor.qname_minimization`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.3.0 - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-qname-minimization` - -Enable Query Name Minimization. This implements a relaxed form of Query Name Mimimization as -described in :rfc:`7816`. - -.. _setting-yaml-recursor.rng: - -``recursor.rng`` -^^^^^^^^^^^^^^^^ - -- String -- Default: ``auto`` - -- Old style setting: :ref:`setting-rng` - -- String -- Default: auto - -Specify which random number generator to use. Permissible choices are - - auto - choose automatically - - sodium - Use libsodium ``randombytes_uniform`` - - openssl - Use libcrypto ``RAND_bytes`` - - getrandom - Use libc getrandom, falls back to urandom if it does not really work - - arc4random - Use BSD ``arc4random_uniform`` - - urandom - Use ``/dev/urandom`` - - kiss - Use simple settable deterministic RNG. **FOR TESTING PURPOSES ONLY!** - -.. _setting-yaml-recursor.root_nx_trust: - -``recursor.root_nx_trust`` -^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.0.0 - - Default is ``yes`` now, was ``no`` before 4.0.0 - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-root-nx-trust` - -If set, an NXDOMAIN from the root-servers will serve as a blanket NXDOMAIN for the entire TLD the query belonged to. -The effect of this is far fewer queries to the root-servers. - -.. _setting-yaml-recursor.save_parent_ns_set: - -``recursor.save_parent_ns_set`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.7.0 - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-save-parent-ns-set` - -If set, a parent (non-authoritative) ``NS`` set is saved if it contains more entries than a newly encountered child (authoritative) ``NS`` set for the same domain. -The saved parent ``NS`` set is tried if resolution using the child ``NS`` set fails. - -.. _setting-yaml-recursor.security_poll_suffix: - -``recursor.security_poll_suffix`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: ``secpoll.powerdns.com.`` - -- Old style setting: :ref:`setting-security-poll-suffix` - -Domain name from which to query security update notifications. -Setting this to an empty string disables secpoll. - -.. _setting-yaml-recursor.serve_rfc1918: - -``recursor.serve_rfc1918`` -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-serve-rfc1918` - -This makes the server authoritatively aware of: ``10.in-addr.arpa``, ``168.192.in-addr.arpa``, ``16-31.172.in-addr.arpa``, which saves load on the AS112 servers. -Individual parts of these zones can still be loaded or forwarded. - -.. _setting-yaml-recursor.serve_stale_extensions: - -``recursor.serve_stale_extensions`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.8.0 - -- Integer -- Default: ``0`` - -- Old style setting: :ref:`setting-serve-stale-extensions` - -Maximum number of times an expired record's TTL is extended by 30s when serving stale. -Extension only occurs if a record cannot be refreshed. -A value of 0 means the ``Serve Stale`` mechanism is not used. -To allow records becoming stale to be served for an hour, use a value of 120. -See :ref:`serve-stale` for a description of the Serve Stale mechanism. - -.. _setting-yaml-recursor.server_down_max_fails: - -``recursor.server_down_max_fails`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``64`` - -- Old style setting: :ref:`setting-server-down-max-fails` - -If a server has not responded in any way this many times in a row, no longer send it any queries for :ref:`setting-yaml-recursor.server_down_throttle_time` seconds. -Afterwards, we will try a new packet, and if that also gets no response at all, we again throttle for :ref:`setting-yaml-recursor.server_down_throttle_time` seconds. -Even a single response packet will drop the block. - -.. _setting-yaml-recursor.server_down_throttle_time: - -``recursor.server_down_throttle_time`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``60`` - -- Old style setting: :ref:`setting-server-down-throttle-time` - -Throttle a server that has failed to respond :ref:`setting-yaml-recursor.server_down_max_fails` times for this many seconds. - -.. _setting-yaml-recursor.server_id: - -``recursor.server_id`` -^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: ``*runtime determined*`` - -- Old style setting: :ref:`setting-server-id` - -The reply given by The PowerDNS recursor to a query for 'id.server' with its hostname, useful for in clusters. -When a query contains the :rfc:`NSID EDNS0 Option <5001>`, this value is returned in the response as the NSID value. - -This setting can be used to override the answer given to these queries. -Set to 'disabled' to disable NSID and 'id.server' answers. - -Query example (where 192.0.2.14 is your server): - -.. code-block:: sh - - dig @192.0.2.14 CHAOS TXT id.server. - dig @192.0.2.14 example.com IN A +nsid - -.. _setting-yaml-recursor.setgid: - -``recursor.setgid`` -^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-setgid` - -PowerDNS can change its user and group id after binding to its socket. -Can be used for better :doc:`security `. - -.. _setting-yaml-recursor.setuid: - -``recursor.setuid`` -^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-setuid` - -PowerDNS can change its user and group id after binding to its socket. -Can be used for better :doc:`security `. - -.. _setting-yaml-recursor.socket_dir: - -``recursor.socket_dir`` -^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-socket-dir` - -Where to store the control socket and pidfile. -The default depends on ``LOCALSTATEDIR`` or the ``--with-socketdir`` setting when building (usually ``/var/run`` or ``/run``). - -When using :ref:`setting-yaml-recursor.chroot` the default becomes ``/``. - -.. _setting-yaml-recursor.socket_group: - -``recursor.socket_group`` -^^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-socket-group` - -Group and mode of the controlsocket. -Owner and group can be specified by name, mode is in octal. - -.. _setting-yaml-recursor.socket_mode: - -``recursor.socket_mode`` -^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-socket-mode` - -Mode of the controlsocket. -Owner and group can be specified by name, mode is in octal. - -.. _setting-yaml-recursor.socket_owner: - -``recursor.socket_owner`` -^^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-socket-owner` - -Owner of the controlsocket. -Owner and group can be specified by name, mode is in octal. - -.. _setting-yaml-recursor.spoof_nearmiss_max: - -``recursor.spoof_nearmiss_max`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.5.0 - - Older versions used 20 as the default value. - -- Integer -- Default: ``1`` - -- Old style setting: :ref:`setting-spoof-nearmiss-max` - -If set to non-zero, PowerDNS will assume it is being spoofed after seeing this many answers with the wrong id. - -.. _setting-yaml-recursor.stack_cache_size: - -``recursor.stack_cache_size`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.9.0 - -- Integer -- Default: ``100`` - -- Old style setting: :ref:`setting-stack-cache-size` - -Maximum number of mthread stacks that can be cached for later reuse, per thread. Caching these stacks reduces the CPU load at the cost of a slightly higher memory usage, each cached stack consuming `stack-size` bytes of memory. -It makes no sense to cache more stacks than the value of `max-mthreads`, since there will never be more stacks than that in use at a given time. - -.. _setting-yaml-recursor.stack_size: - -``recursor.stack_size`` -^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``200000`` - -- Old style setting: :ref:`setting-stack-size` - -Size in bytes of the stack of each mthread. - -.. _setting-yaml-recursor.stats_api_disabled_list: - -``recursor.stats_api_disabled_list`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Sequence of strings -- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\* - -- Old style setting: :ref:`setting-stats-api-disabled-list` - -A sequence of statistic names, that are disabled when retrieving the complete list of statistics via the API for performance reasons. -These statistics can still be retrieved individually by specifically asking for it. - -.. _setting-yaml-recursor.stats_carbon_disabled_list: - -``recursor.stats_carbon_disabled_list`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Sequence of strings -- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\* - -- Old style setting: :ref:`setting-stats-carbon-disabled-list` - -A sequence of statistic names, that are prevented from being exported via carbon for performance reasons. - -.. _setting-yaml-recursor.stats_rec_control_disabled_list: - -``recursor.stats_rec_control_disabled_list`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Sequence of strings -- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\*, cumul-answers-\*, cumul-auth4answers-\*, cumul-auth6answers-\* - -- Old style setting: :ref:`setting-stats-rec-control-disabled-list` - -A sequence of statistic names, that are disabled when retrieving the complete list of statistics via `rec_control get-all`, for performance reasons. -These statistics can still be retrieved individually. - -.. _setting-yaml-recursor.stats_ringbuffer_entries: - -``recursor.stats_ringbuffer_entries`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``10000`` - -- Old style setting: :ref:`setting-stats-ringbuffer-entries` - -Number of entries in the remotes ringbuffer, which keeps statistics on who is querying your server. -Can be read out using ``rec_control top-remotes``. - -.. _setting-yaml-recursor.stats_snmp_disabled_list: - -``recursor.stats_snmp_disabled_list`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- Sequence of strings -- Default: cache-bytes, packetcache-bytes, special-memory-usage, ecs-v4-response-bits-\*, ecs-v6-response-bits-\* - -- Old style setting: :ref:`setting-stats-snmp-disabled-list` - -A sequence of statistic names, that are prevented from being exported via SNMP, for performance reasons. - -.. _setting-yaml-recursor.tcp_threads: - -``recursor.tcp_threads`` -^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 5.0.0 - -- Integer -- Default: ``1`` - -- Old style setting: :ref:`setting-tcp-threads` - -Spawn this number of TCP processing threads on startup. - -.. _setting-yaml-recursor.threads: - -``recursor.threads`` -^^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``2`` - -- Old style setting: :ref:`setting-threads` - -Spawn this number of threads on startup. - -.. _setting-yaml-recursor.version_string: - -``recursor.version_string`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: ``*runtime determined*`` - -- Old style setting: :ref:`setting-version-string` - -By default, PowerDNS replies to the 'version.bind' query with its version number. -Security conscious users may wish to override the reply PowerDNS issues. - -.. _setting-yaml-recursor.write_pid: - -``recursor.write_pid`` -^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``true`` - -- Old style setting: :ref:`setting-write-pid` - -If a PID file should be written to :ref:`setting-yaml-recursor.socket_dir` - -.. _setting-yaml-snmp.agent: - -``snmp.agent`` -^^^^^^^^^^^^^^ -.. versionadded:: 4.1.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-snmp-agent` - -If set to true and PowerDNS has been compiled with SNMP support, it will register as an SNMP agent to provide statistics and be able to send traps. - -.. _setting-yaml-snmp.daemon_socket: - -``snmp.daemon_socket`` -^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.5.0 - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-snmp-daemon-socket` - -If not empty and ``snmp-agent`` is set to true, indicates how PowerDNS should contact the SNMP daemon to register as an SNMP agent. - -.. _setting-yaml-webservice.address: - -``webservice.address`` -^^^^^^^^^^^^^^^^^^^^^^ - -- String -- Default: ``127.0.0.1`` - -- Old style setting: :ref:`setting-webserver-address` - -IP address for the webserver to listen on. - -.. _setting-yaml-webservice.allow_from: - -``webservice.allow_from`` -^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.1.0 - - Default is now 127.0.0.1,::1, was 0.0.0.0/0,::/0 before. - -- Sequence of `Subnet`_ (IP addresses or subnets, negation supported) -- Default: ``[127.0.0.1, ::1]`` - -- Old style setting: :ref:`setting-webserver-allow-from` - -These IPs and subnets are allowed to access the webserver. Note that -specifying an IP address without a netmask uses an implicit netmask -of /32 or /128. - -.. _setting-yaml-webservice.api_dir: - -``webservice.api_dir`` -^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.0.0 - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-api-config-dir` - -Directory where the REST API stores its configuration and zones. -For configuration updates to work, :ref:`setting-yaml-recursor.include_dir` should have the same value. - -.. _setting-yaml-webservice.api_key: - -``webservice.api_key`` -^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.0.0 -.. versionchanged:: 4.6.0 - - This setting now accepts a hashed and salted version. - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-api-key` - -Static pre-shared authentication key for access to the REST API. Since 4.6.0 the key can be hashed and salted using ``rec_control hash-password`` instead of being stored in the configuration in plaintext, but the plaintext version is still supported. - -.. _setting-yaml-webservice.hash_plaintext_credentials: - -``webservice.hash_plaintext_credentials`` -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.6.0 - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-webserver-hash-plaintext-credentials` - -Whether passwords and API keys supplied in the configuration as plaintext should be hashed during startup, to prevent the plaintext versions from staying in memory. Doing so increases significantly the cost of verifying credentials and is thus disabled by default. -Note that this option only applies to credentials stored in the configuration as plaintext, but hashed credentials are supported without enabling this option. - -.. _setting-yaml-webservice.loglevel: - -``webservice.loglevel`` -^^^^^^^^^^^^^^^^^^^^^^^ -.. versionadded:: 4.2.0 - -- String -- Default: ``normal`` - -- Old style setting: :ref:`setting-webserver-loglevel` - -One of ``one``, ``normal``, ``detailed``. -The amount of logging the webserver must do. 'none' means no useful webserver information will be logged. -When set to 'normal', the webserver will log a line per request that should be familiar:: - - [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 'GET /api/v1/servers/localhost/bla HTTP/1.1' 404 196 - -When set to 'detailed', all information about the request and response are logged:: - - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Request Details: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Headers: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept-encoding: gzip, deflate - [webserver] e235780e-a5cf-415e-9326-9d33383e739e accept-language: en-US,en;q=0.5 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e connection: keep-alive - [webserver] e235780e-a5cf-415e-9326-9d33383e739e dnt: 1 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e host: 127.0.0.1:8081 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e upgrade-insecure-requests: 1 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e user-agent: Mozilla/5.0 (X11; Linux x86_64; rv:64.0) Gecko/20100101 Firefox/64.0 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e No body - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Response details: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Headers: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Connection: close - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Content-Length: 49 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Content-Type: text/html; charset=utf-8 - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Server: PowerDNS/0.0.15896.0.gaba8bab3ab - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Full body: - [webserver] e235780e-a5cf-415e-9326-9d33383e739e Not Found

        Not Found

        - [webserver] e235780e-a5cf-415e-9326-9d33383e739e 127.0.0.1:55376 'GET /api/v1/servers/localhost/bla HTTP/1.1' 404 196 - -The value between the hooks is a UUID that is generated for each request. This can be used to find all lines related to a single request. - -.. note:: - The webserver logs these line on the NOTICE level. The :ref:`setting-yaml-logging.loglevel` seting must be 5 or higher for these lines to end up in the log. - -.. _setting-yaml-webservice.password: - -``webservice.password`` -^^^^^^^^^^^^^^^^^^^^^^^ -.. versionchanged:: 4.6.0 - - This setting now accepts a hashed and salted version. - -- String -- Default: (empty) - -- Old style setting: :ref:`setting-webserver-password` - -Password required to access the webserver. Since 4.6.0 the password can be hashed and salted using ``rec_control hash-password`` instead of being present in the configuration in plaintext, but the plaintext version is still supported. - -.. _setting-yaml-webservice.port: - -``webservice.port`` -^^^^^^^^^^^^^^^^^^^ - -- Integer -- Default: ``8082`` - -- Old style setting: :ref:`setting-webserver-port` - -TCP port where the webserver should listen on. - -.. _setting-yaml-webservice.webserver: - -``webservice.webserver`` -^^^^^^^^^^^^^^^^^^^^^^^^ - -- Boolean -- Default: ``false`` - -- Old style setting: :ref:`setting-webserver` - -Start the webserver (for REST API). - diff --git a/tasks.py b/tasks.py index bfac782ce84b..a0be2530dca0 100644 --- a/tasks.py +++ b/tasks.py @@ -306,6 +306,10 @@ def install_dnsdist_build_deps(c): def ci_autoconf(c): c.run('autoreconf -vfi') +@task +def ci_docs_rec_generate(c): + c.run('python3 generate.py') + @task def ci_docs_build(c): c.run('make -f Makefile.sphinx -C docs html') From 8578aee2da944d02e84656b52fc3d2f4c28c44f6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 22 Sep 2023 12:20:42 +0200 Subject: [PATCH 737/909] Include table.py in files to be spell-checked --- .github/actions/spell-check/only.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/spell-check/only.txt b/.github/actions/spell-check/only.txt index b8e3d5334e1a..d4d5dca9fbd1 100644 --- a/.github/actions/spell-check/only.txt +++ b/.github/actions/spell-check/only.txt @@ -1,2 +1,3 @@ /docs/ ^docs/ +pdns/recursordist/settings/table.py From f422459ebd936de61d97fa5a82d1b73b74639b7f Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 22 Sep 2023 12:08:18 +0200 Subject: [PATCH 738/909] Spelcheck words --- .github/actions/spell-check/expect.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index b5892c7e8bc0..e36cb503194c 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -286,6 +286,7 @@ Dessel destname Detlef devicename +devonly devtoolset DHCID dhcpd @@ -345,6 +346,7 @@ dnsviz dnswasher dnszone Dobrawy +docdefault docnamecachelookup documentclass documentwrapper From f31a4248bc7ef0267d2abad0c6a3ad6e99d61075 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 22 Sep 2023 09:55:14 +0200 Subject: [PATCH 739/909] Resolve NS names without QName Minimization. The assumption being that using Qname Minimization for infra queries does not enhance privacy, but increases query load. Also determine max-qperq bound dynamically --- pdns/recursordist/rec-main.cc | 7 +------ pdns/recursordist/syncres.cc | 17 +++++++++++++---- pdns/recursordist/test-syncres_cc5.cc | 18 ++++++++++++------ 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 09bf5acf8dd5..d46be550149c 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1644,6 +1644,7 @@ static int initSyncRes(Logr::log_t log) SyncRes::s_nonresolvingnsmaxfails = ::arg().asNum("non-resolving-ns-max-fails"); SyncRes::s_nonresolvingnsthrottletime = ::arg().asNum("non-resolving-ns-throttle-time"); SyncRes::s_serverID = ::arg()["server-id"]; + // This bound is dynamically adjusted in SyncRes, depending on qname minimization being active SyncRes::s_maxqperq = ::arg().asNum("max-qperq"); SyncRes::s_maxnsperresolve = ::arg().asNum("max-ns-per-resolve"); SyncRes::s_maxnsaddressqperq = ::arg().asNum("max-ns-address-qperq"); @@ -1686,12 +1687,6 @@ static int initSyncRes(Logr::log_t log) SyncRes::s_qnameminimization = ::arg().mustDo("qname-minimization"); - if (SyncRes::s_qnameminimization) { - // With an empty cache, a rev ipv6 query with dnssec enabled takes - // almost 100 queries. Default maxqperq is 60. - SyncRes::s_maxqperq = std::max(SyncRes::s_maxqperq, static_cast(100)); - } - SyncRes::s_hardenNXD = SyncRes::HardenNXD::DNSSEC; string value = ::arg()["nothing-below-nxdomain"]; if (value == "yes") { diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 2a5b46ae4eb3..780264ed9071 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -2107,7 +2107,7 @@ vector SyncRes::getAddrs(const DNSName& qname, unsigned int depth, Context newContext1; cset.clear(); // Go out to get A's - if (s_doIPv4 && doResolve(qname, QType::A, cset, depth + 1, beenthere, newContext1) == 0) { // this consults cache, OR goes out + if (s_doIPv4 && doResolveNoQNameMinimization(qname, QType::A, cset, depth + 1, beenthere, newContext1) == 0) { // this consults cache, OR goes out for (auto const& i : cset) { if (i.d_type == QType::A) { if (auto rec = getRR(i)) { @@ -2120,7 +2120,7 @@ vector SyncRes::getAddrs(const DNSName& qname, unsigned int depth, if (ret.empty()) { // We only go out immediately to find IPv6 records if we did not find any IPv4 ones. Context newContext2; - if (doResolve(qname, QType::AAAA, cset, depth + 1, beenthere, newContext2) == 0) { // this consults cache, OR goes out + if (doResolveNoQNameMinimization(qname, QType::AAAA, cset, depth + 1, beenthere, newContext2) == 0) { // this consults cache, OR goes out for (const auto& i : cset) { if (i.d_type == QType::AAAA) { if (auto rec = getRR(i)) { @@ -3420,8 +3420,17 @@ vector SyncRes::retrieveAddressesForNS(const std::string& prefix, void SyncRes::checkMaxQperQ(const DNSName& qname) const { - if (d_outqueries + d_throttledqueries > s_maxqperq) { - throw ImmediateServFailException("more than " + std::to_string(s_maxqperq) + " (max-qperq) queries sent or throttled while resolving " + qname.toLogString()); + auto bound = s_maxqperq; + if (d_qNameMinimization) { + // With an empty cache, a rev ipv6 query with dnssec enabled takes + // almost 100 queries. Default maxqperq is 60 + // Note: This no longer seems to be true. The examples taken from #8646 take now way less + // queries. The main reason seems to be a much better zone cut determination. + bound = std::max(100U, bound); + } + + if (d_outqueries + d_throttledqueries > bound) { + throw ImmediateServFailException("more than " + std::to_string(bound) + " (adjusted max-qperq) queries sent or throttled while resolving " + qname.toLogString()); } } diff --git a/pdns/recursordist/test-syncres_cc5.cc b/pdns/recursordist/test-syncres_cc5.cc index bb893939f1b6..367a68a6cee1 100644 --- a/pdns/recursordist/test-syncres_cc5.cc +++ b/pdns/recursordist/test-syncres_cc5.cc @@ -1969,8 +1969,11 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm) DNSName auth(domain); DNSName com("com."); DNSName net("net."); + DNSName nsone("nsone.net."); + DNSName hero("herokuapp.com."); + DNSName p03nsone("dns1.p03.nsone.net."); - //cerr << ip.toString() << ": " << domain << '|' << QType(type).getName() << endl; + // cerr << ip.toString() << ": " << domain << '|' << QType(type).toString() << endl; if (type == QType::DS || type == QType::DNSKEY) { return genericDSAndDNSKEYHandler(res, domain, auth, type, keys); } @@ -1990,6 +1993,13 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm) addRRSIG(keys, res->d_records, g_rootdnsname, 300); addRecordToLW(res, "a.gtld-servers.net.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL, 3600); } + else if (domain == p03nsone && type == QType::A) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, nsone, QType::NS, "dns1.p01.nsone.net.", DNSResourceRecord::AUTHORITY, 3600); + addNSECRecordToLW(nsone, DNSName("zzz.nsone.net."), {QType::NS, QType::SOA, QType::RRSIG, QType::DNSKEY}, 600, res->d_records); + addRRSIG(keys, res->d_records, net, 300); + addRecordToLW(res, "dns1.p01.nsone.net", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, 3600); + } else { BOOST_ASSERT(0); } @@ -1997,8 +2007,6 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm) } else if (ip == ComboAddress("192.0.2.1:53")) { - DNSName hero("herokuapp.com."); - DNSName nsone("nsone.net."); if (domain == hero && type == QType::NS) { setLWResult(res, 0, false, false, true); addRecordToLW(res, hero, QType::NS, "dns1.p03.nsone.net.", DNSResourceRecord::AUTHORITY, 3600); @@ -2018,11 +2026,9 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm) return LWResult::Result::Success; } else if (ip == ComboAddress("192.0.2.2:53")) { - DNSName hero("herokuapp.com."); DNSName p01("p01.nsone.net."); DNSName p03("p03.nsone.net."); DNSName p01nsone("dns1.p01.nsone.net."); - DNSName p03nsone("dns1.p03.nsone.net."); if (domain == hero && type == QType::NS) { setLWResult(res, 0, true, false, true); addRecordToLW(res, hero, QType::NS, "dns1.p03.nsone.net.", DNSResourceRecord::ANSWER, 3600); @@ -2058,7 +2064,7 @@ BOOST_AUTO_TEST_CASE(test_dnssec_incomplete_cache_zonecut_qm) BOOST_CHECK_EQUAL(res, RCode::NoError); BOOST_CHECK_EQUAL(sr->getValidationState(), vState::Secure); BOOST_REQUIRE_EQUAL(ret.size(), 2U); - BOOST_CHECK_EQUAL(queriesCount, 10U); + BOOST_CHECK_EQUAL(queriesCount, 8U); ret.clear(); res = sr->beginResolve(DNSName("dns1.p03.nsone.net."), QType(QType::A), QClass::IN, ret); From 0ef8a18539a44274d66c832525f1dfd88b661613 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 19 Sep 2023 14:43:42 +0200 Subject: [PATCH 740/909] Put files generated by settings/generate.py into tarball So dists do not have to run python to generate them. Previously python was a hidden dependency. --- pdns/recursordist/settings/Makefile.am | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/pdns/recursordist/settings/Makefile.am b/pdns/recursordist/settings/Makefile.am index 536dc712e706..08e05e10a167 100644 --- a/pdns/recursordist/settings/Makefile.am +++ b/pdns/recursordist/settings/Makefile.am @@ -1,25 +1,30 @@ +# It's a bit dirty that this Makefile also generates a file inside rust/src (lib.rs). + EXTRA_DIST = \ + cxxsettings-generated.cc \ cxxsettings-private.hh \ cxxsettings.hh \ - docs-old-preamble-in.rst \ docs-new-preamble-in.rst \ + docs-old-preamble-in.rst \ generate.py \ rust-bridge-in.rs \ rust-preamble-in.rs \ - table.py + table.py \ + rust/src/lib.rs -all: cxxsettings-generated.cc +all: cxxsettings-generated.cc rust/src/lib.rs -BUILT_SOURCES=cxxsettings-generated.cc +BUILT_SOURCES=cxxsettings-generated.cc rust/src/lib.rs -# It's a bit dirty that this target also generates a file inside rust/src (lib.rs). Also, we need to -# clean in the Rust dir, as in some cases the Serde/CXX derive/generate code does not get re-run by -# cargo after rust/src/lib.rs changed because of a generate.py run. In that case we end up with an -# rust/src/lib.rs.h that does not contain e.g. field name or field type changes. -cxxsettings-generated.cc: table.py generate.py rust-preamble-in.rs rust-bridge-in.rs docs-old-preamble-in.rst docs-new-preamble-in.rst +# We need to clean in the Rust dir, as in some cases the Serde/CXX derive/generate code does not get +# re-run by cargo after rust/src/lib.rs changed because of a generate.py run. In that case we end up +# with an rust/src/lib.rs.h that does not contain e.g. field name or field type changes. +# +# Use patterns to avoid having two instances of generate run simultaneously, a well know hack for GNU make +cxxsettings-generated%cc rust/src/lib%rs: table.py generate.py rust-preamble-in.rs rust-bridge-in.rs docs-old-preamble-in.rst docs-new-preamble-in.rst $(MAKE) -C rust clean $(PYTHON) generate.py clean-local: - rm -f cxxsettings-generated.cc settings-old-generated.rst + rm -f cxxsettings-generated.cc rust/src/lib.rs From 752aae9ff60ae10c502959d0d4d6c01bfef23099 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 22 Sep 2023 16:11:56 +0200 Subject: [PATCH 741/909] Remove "Previously acknowledged words that are now absent" --- .github/actions/spell-check/expect.txt | 7 ------- 1 file changed, 7 deletions(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index e36cb503194c..fd2ba46eeedf 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -517,7 +517,6 @@ gpgsqlbackend gprof gpsqlbackend grepq -grpc GSQ gsql gsqlite @@ -527,7 +526,6 @@ gsub gtld guilabel Gyselinck -hackerone Hakulinen Hannu Harker @@ -810,7 +808,6 @@ metricnames metricscarbon Meulen Michiel -middleware Miek Miell Mieslinger @@ -1044,7 +1041,6 @@ pipermail Plusnet plzz pmtmr -pnds Poelov pointsize polarssl @@ -1382,7 +1378,6 @@ taskqueue tbhandler tcely TCounters -tcp tcpconnecttimeouts tcpdump TCPKEEPALIVE @@ -1417,8 +1412,6 @@ tinydns tinydnsbackend tisr tlsa -tlsresumptions -tmp tmpfs tobool toctree From 7858770321b5ef3a126c41c9b68eca5fc0470c53 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Fri, 22 Sep 2023 18:15:19 -0400 Subject: [PATCH 742/909] Remove versioning from Debian/Ubuntu Debian 9 / Ubuntu Bionic are no longer supported, but conveniently the build instructions are not really release specific. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e427d37891ac..5594817e9999 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ COMPILING Authoritative Server The PowerDNS Authoritative Server depends on Boost, OpenSSL and Lua, and requires a compiler with C++-2017 support. -On Debian 9, the following is useful: +On Debian, the following is useful: ```sh apt install g++ libboost-all-dev libtool make pkg-config default-libmysqlclient-dev libssl-dev libluajit-5.1-dev python3-venv @@ -63,7 +63,7 @@ When building from git, the following packages are also required: apt install autoconf automake ragel bison flex ``` -For Ubuntu 18.04 (Bionic Beaver), the following packages should be installed: +For Ubuntu, the following packages should be installed: ```sh apt install libcurl4-openssl-dev luajit lua-yaml-dev libyaml-cpp-dev libtolua-dev lua5.3 autoconf automake ragel bison flex g++ libboost-all-dev libtool make pkg-config libssl-dev lua-yaml-dev libyaml-cpp-dev libluajit-5.1-dev libcurl4 gawk libsqlite3-dev python3-venv From 92e3654a088c6c75b8e8e8caf7b823cc388b1e2a Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Sat, 23 Sep 2023 00:30:34 +0200 Subject: [PATCH 743/909] sdig: add rudimentary EDE output --- pdns/Makefile.am | 1 + pdns/ednsextendederror.cc | 65 +++++++++++++++++++++++++ pdns/ednsextendederror.hh | 66 +++++++++++++++++++++++++ pdns/recursordist/ednsextendederror.cc | 66 +------------------------ pdns/recursordist/ednsextendederror.hh | 67 +------------------------- pdns/sdig.cc | 6 +++ 6 files changed, 140 insertions(+), 131 deletions(-) create mode 100644 pdns/ednsextendederror.cc create mode 100644 pdns/ednsextendederror.hh mode change 100644 => 120000 pdns/recursordist/ednsextendederror.cc mode change 100644 => 120000 pdns/recursordist/ednsextendederror.hh diff --git a/pdns/Makefile.am b/pdns/Makefile.am index b5eef7a5444a..b22bcfdc3cc8 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -554,6 +554,7 @@ sdig_SOURCES = \ dnsrecords.cc \ dnswriter.cc dnswriter.hh \ dolog.hh \ + ednsextendederror.cc ednsextendederror.hh \ ednssubnet.cc iputils.cc \ libssl.cc libssl.hh \ logger.cc \ diff --git a/pdns/ednsextendederror.cc b/pdns/ednsextendederror.cc new file mode 100644 index 000000000000..5010e3dba52d --- /dev/null +++ b/pdns/ednsextendederror.cc @@ -0,0 +1,65 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include + +#include "ednsextendederror.hh" + +static bool getEDNSExtendedErrorOptFromStringView(const std::string_view& option, EDNSExtendedError& eee) +{ + if (option.size() < sizeof(uint16_t)) { + return false; + } + eee.infoCode = static_cast(option.at(0)) * 256 + static_cast(option.at(1)); + + if (option.size() > sizeof(uint16_t)) { + eee.extraText = std::string(&option.at(sizeof(uint16_t)), option.size() - sizeof(uint16_t)); + } + + return true; +} + +bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee) +{ + return getEDNSExtendedErrorOptFromStringView(std::string_view(option), eee); +} + +bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee) +{ + return getEDNSExtendedErrorOptFromStringView(std::string_view(option, len), eee); +} + +string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee) +{ + if (eee.extraText.size() > static_cast(std::numeric_limits::max() - 2)) { + throw std::runtime_error("Trying to create an EDNS Extended Error option with an extra text of size " + std::to_string(eee.extraText.size())); + } + + string ret; + ret.reserve(sizeof(uint16_t) + eee.extraText.size()); + ret.resize(sizeof(uint16_t)); + + ret[0] = static_cast(static_cast(eee.infoCode) / 256); + ret[1] = static_cast(static_cast(eee.infoCode) % 256); + ret.append(eee.extraText); + + return ret; +} diff --git a/pdns/ednsextendederror.hh b/pdns/ednsextendederror.hh new file mode 100644 index 000000000000..5b264fcf69b6 --- /dev/null +++ b/pdns/ednsextendederror.hh @@ -0,0 +1,66 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once +#include "namespaces.hh" + +struct EDNSExtendedError +{ + enum class code : uint16_t + { + Other = 0, + UnsupportedDNSKEYAlgorithm = 1, + UnsupportedDSDigestType = 2, + StaleAnswer = 3, + ForgedAnswer = 4, + DNSSECIndeterminate = 5, + DNSSECBogus = 6, + SignatureExpired = 7, + SignatureNotYetValid = 8, + DNSKEYMissing = 9, + RRSIGsMissing = 10, + NoZoneKeyBitSet = 11, + NSECMissing = 12, + CachedError = 13, + NotReady = 14, + Blocked = 15, + Censored = 16, + Filtered = 17, + Prohibited = 18, + StaleNXDOMAINAnswer = 19, + NotAuthoritative = 20, + NotSupported = 21, + NoReachableAuthority = 22, + NetworkError = 23, + InvalidData = 24, + SignatureExpiredBeforeValid = 25, + TooEarly = 26, + UnsupportedNSEC3IterationsValue = 27, + UnableToConformToPolicy = 28, + Synthesized = 29, + }; + uint16_t infoCode; + std::string extraText; +}; + +bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee); +bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee); +string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee); diff --git a/pdns/recursordist/ednsextendederror.cc b/pdns/recursordist/ednsextendederror.cc deleted file mode 100644 index 5010e3dba52d..000000000000 --- a/pdns/recursordist/ednsextendederror.cc +++ /dev/null @@ -1,65 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#include - -#include "ednsextendederror.hh" - -static bool getEDNSExtendedErrorOptFromStringView(const std::string_view& option, EDNSExtendedError& eee) -{ - if (option.size() < sizeof(uint16_t)) { - return false; - } - eee.infoCode = static_cast(option.at(0)) * 256 + static_cast(option.at(1)); - - if (option.size() > sizeof(uint16_t)) { - eee.extraText = std::string(&option.at(sizeof(uint16_t)), option.size() - sizeof(uint16_t)); - } - - return true; -} - -bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee) -{ - return getEDNSExtendedErrorOptFromStringView(std::string_view(option), eee); -} - -bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee) -{ - return getEDNSExtendedErrorOptFromStringView(std::string_view(option, len), eee); -} - -string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee) -{ - if (eee.extraText.size() > static_cast(std::numeric_limits::max() - 2)) { - throw std::runtime_error("Trying to create an EDNS Extended Error option with an extra text of size " + std::to_string(eee.extraText.size())); - } - - string ret; - ret.reserve(sizeof(uint16_t) + eee.extraText.size()); - ret.resize(sizeof(uint16_t)); - - ret[0] = static_cast(static_cast(eee.infoCode) / 256); - ret[1] = static_cast(static_cast(eee.infoCode) % 256); - ret.append(eee.extraText); - - return ret; -} diff --git a/pdns/recursordist/ednsextendederror.cc b/pdns/recursordist/ednsextendederror.cc new file mode 120000 index 000000000000..4f6ced0eb166 --- /dev/null +++ b/pdns/recursordist/ednsextendederror.cc @@ -0,0 +1 @@ +../ednsextendederror.cc \ No newline at end of file diff --git a/pdns/recursordist/ednsextendederror.hh b/pdns/recursordist/ednsextendederror.hh deleted file mode 100644 index 5b264fcf69b6..000000000000 --- a/pdns/recursordist/ednsextendederror.hh +++ /dev/null @@ -1,66 +0,0 @@ -/* - * This file is part of PowerDNS or dnsdist. - * Copyright -- PowerDNS.COM B.V. and its contributors - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of version 2 of the GNU General Public License as - * published by the Free Software Foundation. - * - * In addition, for the avoidance of any doubt, permission is granted to - * link this program with OpenSSL and to (re)distribute the binaries - * produced as the result of such linking. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ -#pragma once -#include "namespaces.hh" - -struct EDNSExtendedError -{ - enum class code : uint16_t - { - Other = 0, - UnsupportedDNSKEYAlgorithm = 1, - UnsupportedDSDigestType = 2, - StaleAnswer = 3, - ForgedAnswer = 4, - DNSSECIndeterminate = 5, - DNSSECBogus = 6, - SignatureExpired = 7, - SignatureNotYetValid = 8, - DNSKEYMissing = 9, - RRSIGsMissing = 10, - NoZoneKeyBitSet = 11, - NSECMissing = 12, - CachedError = 13, - NotReady = 14, - Blocked = 15, - Censored = 16, - Filtered = 17, - Prohibited = 18, - StaleNXDOMAINAnswer = 19, - NotAuthoritative = 20, - NotSupported = 21, - NoReachableAuthority = 22, - NetworkError = 23, - InvalidData = 24, - SignatureExpiredBeforeValid = 25, - TooEarly = 26, - UnsupportedNSEC3IterationsValue = 27, - UnableToConformToPolicy = 28, - Synthesized = 29, - }; - uint16_t infoCode; - std::string extraText; -}; - -bool getEDNSExtendedErrorOptFromString(const char* option, unsigned int len, EDNSExtendedError& eee); -bool getEDNSExtendedErrorOptFromString(const string& option, EDNSExtendedError& eee); -string makeEDNSExtendedErrorOptString(const EDNSExtendedError& eee); diff --git a/pdns/recursordist/ednsextendederror.hh b/pdns/recursordist/ednsextendederror.hh new file mode 120000 index 000000000000..2e5eee192724 --- /dev/null +++ b/pdns/recursordist/ednsextendederror.hh @@ -0,0 +1 @@ +../ednsextendederror.hh \ No newline at end of file diff --git a/pdns/sdig.cc b/pdns/sdig.cc index 87b4f558e471..05bfc7d6e8e3 100644 --- a/pdns/sdig.cc +++ b/pdns/sdig.cc @@ -6,6 +6,7 @@ #include "dnswriter.hh" #include "ednsoptions.hh" #include "ednssubnet.hh" +#include "ednsextendederror.hh" #include "misc.hh" #include "proxy-protocol.hh" #include "sstuff.hh" @@ -185,6 +186,11 @@ static void printReply(const string& reply, bool showflags, bool hidesoadetails, } } else if (iter->first == EDNSOptionCode::PADDING) { cerr << "EDNS Padding size: " << (iter->second.size()) << endl; + } else if (iter->first == EDNSOptionCode::EXTENDEDERROR) { + EDNSExtendedError eee; + if (getEDNSExtendedErrorOptFromString(iter->second, eee)) { + cerr << "EDNS Extended Error response: " << eee.infoCode << "/" << eee.extraText << endl; + } } else { cerr << "Have unknown option " << (int)iter->first << endl; } From 79e58176956ef40600971ac8e73048c61189ed7b Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 25 Sep 2023 08:53:48 +0200 Subject: [PATCH 744/909] Also submit resolve task for NS name -> AAAA with QM off --- pdns/recursordist/rec-taskqueue.cc | 21 ++++++++++++++++++--- pdns/recursordist/rec-taskqueue.hh | 2 +- pdns/recursordist/syncres.cc | 4 ++-- pdns/recursordist/test-rec-taskqueue.cc | 6 +++--- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/pdns/recursordist/rec-taskqueue.cc b/pdns/recursordist/rec-taskqueue.cc index 8526e8d4c964..9997991455b4 100644 --- a/pdns/recursordist/rec-taskqueue.cc +++ b/pdns/recursordist/rec-taskqueue.cc @@ -114,7 +114,8 @@ struct taskstats static struct taskstats s_almost_expired_tasks; static struct taskstats s_resolve_tasks; -static void resolve(const struct timeval& now, bool logErrors, const pdns::ResolveTask& task) noexcept +// forceNoQM is true means resolve using no qm, false means use default value +static void resolveInternal(const struct timeval& now, bool logErrors, const pdns::ResolveTask& task, bool forceNoQM) noexcept { auto log = g_slog->withName("taskq")->withValues("name", Logging::Loggable(task.d_qname), "qtype", Logging::Loggable(QType(task.d_qtype).toString()), "netmask", Logging::Loggable(task.d_netmask.empty() ? "" : task.d_netmask.toString())); const string msg = "Exception while running a background ResolveTask"; @@ -122,6 +123,9 @@ static void resolve(const struct timeval& now, bool logErrors, const pdns::Resol vector ret; resolver.setRefreshAlmostExpired(task.d_refreshMode); resolver.setQuerySource(task.d_netmask); + if (forceNoQM) { + resolver.setQNameMinimization(false); + } bool exceptionOccurred = true; try { log->info(Logr::Debug, "resolving", "refresh", Logging::Loggable(task.d_refreshMode)); @@ -166,6 +170,16 @@ static void resolve(const struct timeval& now, bool logErrors, const pdns::Resol } } +static void resolveForceNoQM(const struct timeval& now, bool logErrors, const pdns::ResolveTask& task) noexcept +{ + resolveInternal(now, logErrors, task, true); +} + +static void resolve(const struct timeval& now, bool logErrors, const pdns::ResolveTask& task) noexcept +{ + resolveInternal(now, logErrors, task, false); +} + static void tryDoT(const struct timeval& now, bool logErrors, const pdns::ResolveTask& task) noexcept { auto log = g_slog->withName("taskq")->withValues("method", Logging::Loggable("tryDoT"), "name", Logging::Loggable(task.d_qname), "qtype", Logging::Loggable(QType(task.d_qtype).toString()), "ip", Logging::Loggable(task.d_ip)); @@ -247,14 +261,15 @@ void pushAlmostExpiredTask(const DNSName& qname, uint16_t qtype, time_t deadline } } -void pushResolveTask(const DNSName& qname, uint16_t qtype, time_t now, time_t deadline) +void pushResolveTask(const DNSName& qname, uint16_t qtype, time_t now, time_t deadline, bool forceQMOff) { if (SyncRes::isUnsupported(qtype)) { auto log = g_slog->withName("taskq")->withValues("name", Logging::Loggable(qname), "qtype", Logging::Loggable(QType(qtype).toString())); log->error(Logr::Error, "Cannot push task", "qtype unsupported"); return; } - pdns::ResolveTask task{qname, qtype, deadline, false, resolve, {}, {}, {}}; + auto func = forceQMOff ? resolveForceNoQM : resolve; + pdns::ResolveTask task{qname, qtype, deadline, false, func, {}, {}, {}}; auto lock = s_taskQueue.lock(); bool inserted = lock->rateLimitSet.insert(now, task); if (inserted) { diff --git a/pdns/recursordist/rec-taskqueue.hh b/pdns/recursordist/rec-taskqueue.hh index 13658055c59d..e7bc855bd761 100644 --- a/pdns/recursordist/rec-taskqueue.hh +++ b/pdns/recursordist/rec-taskqueue.hh @@ -36,7 +36,7 @@ struct ResolveTask; void runTasks(size_t max, bool logErrors); bool runTaskOnce(bool logErrors); void pushAlmostExpiredTask(const DNSName& qname, uint16_t qtype, time_t deadline, const Netmask& netmask); -void pushResolveTask(const DNSName& qname, uint16_t qtype, time_t now, time_t deadline); +void pushResolveTask(const DNSName& qname, uint16_t qtype, time_t now, time_t deadline, bool forceQMOff); bool pushTryDoTTask(const DNSName& qname, uint16_t qtype, const ComboAddress& ipAddress, time_t deadline, const DNSName& nsname); void taskQueueClear(); pdns::ResolveTask taskQueuePop(); diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 780264ed9071..01cd9b8c6c46 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -608,7 +608,7 @@ void SyncRes::resolveAdditionals(const DNSName& qname, QType qtype, AdditionalMo // There are a few cases where an answer is neither stored in the record cache nor in the neg cache. // An example is a SOA-less NODATA response. Rate limiting will kick in if those tasks are pushed too often. // We might want to fix these cases (and always either store positive or negative) some day. - pushResolveTask(qname, qtype, d_now.tv_sec, d_now.tv_sec + 60); + pushResolveTask(qname, qtype, d_now.tv_sec, d_now.tv_sec + 60, false); additionalsNotInCache = true; } break; @@ -2151,7 +2151,7 @@ vector SyncRes::getAddrs(const DNSName& qname, unsigned int depth, NegCache::NegCacheEntry ne; bool inNegCache = g_negCache->get(qname, QType::AAAA, d_now, ne, false); if (!inNegCache) { - pushResolveTask(qname, QType::AAAA, d_now.tv_sec, d_now.tv_sec + 60); + pushResolveTask(qname, QType::AAAA, d_now.tv_sec, d_now.tv_sec + 60, true); } } } diff --git a/pdns/recursordist/test-rec-taskqueue.cc b/pdns/recursordist/test-rec-taskqueue.cc index 17ad0be38b44..b025a40fe346 100644 --- a/pdns/recursordist/test-rec-taskqueue.cc +++ b/pdns/recursordist/test-rec-taskqueue.cc @@ -30,17 +30,17 @@ BOOST_AUTO_TEST_CASE(test_almostexpired_queue_no_dups) BOOST_AUTO_TEST_CASE(test_resolve_queue_rate_limit) { taskQueueClear(); - pushResolveTask(DNSName("foo"), QType::AAAA, 0, 1); + pushResolveTask(DNSName("foo"), QType::AAAA, 0, 1, false); BOOST_CHECK_EQUAL(getTaskSize(), 1U); taskQueuePop(); BOOST_CHECK_EQUAL(getTaskSize(), 0U); // Should hit rate limiting - pushResolveTask(DNSName("foo"), QType::AAAA, 0, 1); + pushResolveTask(DNSName("foo"), QType::AAAA, 0, 1, false); BOOST_CHECK_EQUAL(getTaskSize(), 0U); // Should not hit rate limiting as time has passed - pushResolveTask(DNSName("foo"), QType::AAAA, 61, 62); + pushResolveTask(DNSName("foo"), QType::AAAA, 61, 62, false); BOOST_CHECK_EQUAL(getTaskSize(), 1U); } From c3e6947e189a4a591161f9304d62f7d6867c0e5b Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 25 Sep 2023 09:36:23 +0200 Subject: [PATCH 745/909] typo in comment Co-authored-by: Remi Gacogne --- pdns/recursordist/settings/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/settings/Makefile.am b/pdns/recursordist/settings/Makefile.am index 08e05e10a167..c22b081eebd0 100644 --- a/pdns/recursordist/settings/Makefile.am +++ b/pdns/recursordist/settings/Makefile.am @@ -20,7 +20,7 @@ BUILT_SOURCES=cxxsettings-generated.cc rust/src/lib.rs # re-run by cargo after rust/src/lib.rs changed because of a generate.py run. In that case we end up # with an rust/src/lib.rs.h that does not contain e.g. field name or field type changes. # -# Use patterns to avoid having two instances of generate run simultaneously, a well know hack for GNU make +# Use patterns to avoid having two instances of generate run simultaneously, a well-known hack for GNU make cxxsettings-generated%cc rust/src/lib%rs: table.py generate.py rust-preamble-in.rs rust-bridge-in.rs docs-old-preamble-in.rst docs-new-preamble-in.rst $(MAKE) -C rust clean $(PYTHON) generate.py From 314600f6b33658b3e4dc39ab222cebb232684082 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 13 Sep 2023 16:13:30 +0200 Subject: [PATCH 746/909] If we receive an answer from a nameserver, unthrottle it. Also throw a dice to use a fully throttled NS anyway once in a while. --- pdns/recursordist/syncres.cc | 25 +++++++++++++++++++++---- pdns/recursordist/syncres.hh | 1 + 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 2a5b46ae4eb3..7b7f2b96fccb 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -309,6 +309,10 @@ class Throttle : public boost::noncopyable d_cont.clear(); } + void clear(const Thing& thing) + { + d_cont.erase(thing); + } void prune(time_t now) { auto& ind = d_cont.template get(); @@ -1235,9 +1239,20 @@ bool SyncRes::isThrottled(time_t now, const ComboAddress& server, const DNSName& bool SyncRes::isThrottled(time_t now, const ComboAddress& server) { + // Give fully throttled servers a chance to be used, to avoid having one bad domain spoil the NS record for others + // If the NS answers, it will be unThrottled + if ((dns_random_uint32() & 0x7f) == 0) { + return false; + } return s_throttle.lock()->shouldThrottle(now, std::tuple(server, g_rootdnsname, 0)); } +void SyncRes::unThrottle(const ComboAddress& server, const DNSName& name, QType qtype) +{ + s_throttle.lock()->clear(std::tuple(server, g_rootdnsname, 0)); + s_throttle.lock()->clear(std::tuple(server, name, qtype)); +} + void SyncRes::doThrottle(time_t now, const ComboAddress& server, time_t duration, unsigned int tries) { s_throttle.lock()->throttle(now, std::tuple(server, g_rootdnsname, 0), duration, tries); @@ -5263,13 +5278,13 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, LOG(prefix << qname << ": Error resolving from " << remoteIP.toString() << (doTCP ? " over TCP" : "") << ", possible error: " << stringerror() << endl); } + // don't account for resource limits, they are our own fault + // And don't throttle when the IP address is on the dontThrottleNetmasks list or the name is part of dontThrottleNames if (resolveret != LWResult::Result::OSLimitError && !chained && !dontThrottle) { - // don't account for resource limits, they are our own fault - // And don't throttle when the IP address is on the dontThrottleNetmasks list or the name is part of dontThrottleNames s_nsSpeeds.lock()->find_or_enter(nsName.empty() ? DNSName(remoteIP.toStringWithPort()) : nsName, d_now).submit(remoteIP, 1000000, d_now); // 1 sec - // code below makes sure we don't filter COM or the root - if (s_serverdownmaxfails > 0 && (auth != g_rootdnsname) && s_fails.lock()->incr(remoteIP, d_now) >= s_serverdownmaxfails) { + // make sure we don't throttle the root + if (s_serverdownmaxfails > 0 && auth != g_rootdnsname && s_fails.lock()->incr(remoteIP, d_now) >= s_serverdownmaxfails) { LOG(prefix << qname << ": Max fails reached resolving on " << remoteIP.toString() << ". Going full throttle for " << s_serverdownthrottletime << " seconds" << endl); // mark server as down doThrottle(d_now.tv_sec, remoteIP, s_serverdownthrottletime, 10000); @@ -5327,6 +5342,8 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname, if (s_serverdownmaxfails > 0) { s_fails.lock()->clear(remoteIP); } + // Clear all throttles for this IP, both general and specific throttles for qname-qtype + unThrottle(remoteIP, qname, qtype); if (lwr.d_tcbit) { truncated = true; diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 9d40aa52fb75..568846640186 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -264,6 +264,7 @@ public: static bool isThrottled(time_t now, const ComboAddress& server); static void doThrottle(time_t now, const ComboAddress& server, time_t duration, unsigned int tries); static void doThrottle(time_t now, const ComboAddress& server, const DNSName& name, QType qtype, time_t duration, unsigned int tries); + static void unThrottle(const ComboAddress& server, const DNSName& qname, QType qtype); static uint64_t getFailedServersSize(); static void clearFailedServers(); From 5fba6d594d5678d667e9aa350b127f6ac7095050 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 19 Sep 2023 11:45:40 +0200 Subject: [PATCH 747/909] Make unthrottle n a var (setting not done yet) --- pdns/recursordist/syncres.cc | 7 ++++--- pdns/recursordist/syncres.hh | 1 + 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 7b7f2b96fccb..2fdf209df882 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -443,6 +443,7 @@ unsigned int SyncRes::s_packetcacheservfailttl; unsigned int SyncRes::s_packetcachenegativettl; unsigned int SyncRes::s_serverdownmaxfails; unsigned int SyncRes::s_serverdownthrottletime; +unsigned int SyncRes::s_unthrottle_n = 100; unsigned int SyncRes::s_nonresolvingnsmaxfails; unsigned int SyncRes::s_nonresolvingnsthrottletime; unsigned int SyncRes::s_ecscachelimitttl; @@ -1239,9 +1240,9 @@ bool SyncRes::isThrottled(time_t now, const ComboAddress& server, const DNSName& bool SyncRes::isThrottled(time_t now, const ComboAddress& server) { - // Give fully throttled servers a chance to be used, to avoid having one bad domain spoil the NS record for others - // If the NS answers, it will be unThrottled - if ((dns_random_uint32() & 0x7f) == 0) { + // Give fully throttled servers a chance to be used, to avoid having one bad domain spoil the NS record for others usingf the same NS + // If the NS answers, it will be unThrottled immediately + if (dns_random(s_unthrottle_n) == 0) { return false; } return s_throttle.lock()->shouldThrottle(now, std::tuple(server, g_rootdnsname, 0)); diff --git a/pdns/recursordist/syncres.hh b/pdns/recursordist/syncres.hh index 568846640186..9ae9297b873f 100644 --- a/pdns/recursordist/syncres.hh +++ b/pdns/recursordist/syncres.hh @@ -526,6 +526,7 @@ public: static unsigned int s_serverdownthrottletime; static unsigned int s_nonresolvingnsmaxfails; static unsigned int s_nonresolvingnsthrottletime; + static unsigned int s_unthrottle_n; static unsigned int s_ecscachelimitttl; static uint8_t s_ecsipv4limit; From 824408708e0e454d713213d2a6f84f2ba39e255e Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 22 Sep 2023 13:46:12 +0200 Subject: [PATCH 748/909] Implement setting and rewrite the unThrottle logic a bit --- pdns/recursordist/rec-main.cc | 1 + pdns/recursordist/settings/table.py | 13 +++++++++++++ pdns/recursordist/syncres.cc | 15 +++++++++------ 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 09bf5acf8dd5..43d125f236b0 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1641,6 +1641,7 @@ static int initSyncRes(Logr::log_t log) SyncRes::s_serverdownmaxfails = ::arg().asNum("server-down-max-fails"); SyncRes::s_serverdownthrottletime = ::arg().asNum("server-down-throttle-time"); + SyncRes::s_unthrottle_n = ::arg().asNum("server-down-use-probability"); SyncRes::s_nonresolvingnsmaxfails = ::arg().asNum("non-resolving-ns-max-fails"); SyncRes::s_nonresolvingnsthrottletime = ::arg().asNum("non-resolving-ns-throttle-time"); SyncRes::s_serverID = ::arg()["server-id"]; diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index b1f14c7fa6a0..ab7e1ceb8e96 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -2154,6 +2154,19 @@ Throttle a server that has failed to respond :ref:`setting-server-down-max-fails` times for this many seconds. ''', }, + { + 'name' : 'server_down_use_probability', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '25', + 'help' : 'Determines the probability of a server marked down to be used anyway', + 'doc' : ''' +This setting determines the probability of a server marked down to be used anyway. +A value of ``n`` means that the chance of a server marked down being used after it wins speed selection is is ``1/n``. +If this setting is zero this mechanism is not active. + ''', + 'versionadded': '5.0.0' + }, { 'name' : 'server_id', 'section' : 'recursor', diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 2fdf209df882..57a91f980d44 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -443,7 +443,7 @@ unsigned int SyncRes::s_packetcacheservfailttl; unsigned int SyncRes::s_packetcachenegativettl; unsigned int SyncRes::s_serverdownmaxfails; unsigned int SyncRes::s_serverdownthrottletime; -unsigned int SyncRes::s_unthrottle_n = 100; +unsigned int SyncRes::s_unthrottle_n; unsigned int SyncRes::s_nonresolvingnsmaxfails; unsigned int SyncRes::s_nonresolvingnsthrottletime; unsigned int SyncRes::s_ecscachelimitttl; @@ -1240,12 +1240,15 @@ bool SyncRes::isThrottled(time_t now, const ComboAddress& server, const DNSName& bool SyncRes::isThrottled(time_t now, const ComboAddress& server) { - // Give fully throttled servers a chance to be used, to avoid having one bad domain spoil the NS record for others usingf the same NS - // If the NS answers, it will be unThrottled immediately - if (dns_random(s_unthrottle_n) == 0) { - return false; + auto throttled = s_throttle.lock()->shouldThrottle(now, std::tuple(server, g_rootdnsname, 0)); + if (throttled) { + // Give fully throttled servers a chance to be used, to avoid having one bad zone spoil the NS + // record for others using the same NS. If the NS answers, it will be unThrottled immediately + if (s_unthrottle_n > 0 && dns_random(s_unthrottle_n) == 0) { + throttled = false; + } } - return s_throttle.lock()->shouldThrottle(now, std::tuple(server, g_rootdnsname, 0)); + return throttled; } void SyncRes::unThrottle(const ComboAddress& server, const DNSName& name, QType qtype) From 6861d004fb7cbf87b01ed04f50806a2b58fdddc0 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 25 Sep 2023 10:52:10 +0200 Subject: [PATCH 749/909] Rename setting and adapt docs text, as suggested by @ragogne --- pdns/recursordist/rec-main.cc | 2 +- pdns/recursordist/settings/table.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 43d125f236b0..fcf617d70dff 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1641,7 +1641,7 @@ static int initSyncRes(Logr::log_t log) SyncRes::s_serverdownmaxfails = ::arg().asNum("server-down-max-fails"); SyncRes::s_serverdownthrottletime = ::arg().asNum("server-down-throttle-time"); - SyncRes::s_unthrottle_n = ::arg().asNum("server-down-use-probability"); + SyncRes::s_unthrottle_n = ::arg().asNum("bypass-server-throttling-probability"); SyncRes::s_nonresolvingnsmaxfails = ::arg().asNum("non-resolving-ns-max-fails"); SyncRes::s_nonresolvingnsthrottletime = ::arg().asNum("non-resolving-ns-throttle-time"); SyncRes::s_serverID = ::arg()["server-id"]; diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index ab7e1ceb8e96..e833fb656406 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -2155,15 +2155,15 @@ ''', }, { - 'name' : 'server_down_use_probability', + 'name' : 'bypass_server_throttling_probability', 'section' : 'recursor', 'type' : LType.Uint64, 'default' : '25', 'help' : 'Determines the probability of a server marked down to be used anyway', 'doc' : ''' This setting determines the probability of a server marked down to be used anyway. -A value of ``n`` means that the chance of a server marked down being used after it wins speed selection is is ``1/n``. -If this setting is zero this mechanism is not active. +A value of ``n`` means that the chance of a server marked down still being used after it wins speed selection is is ``1/n``. +If this setting is zero throttled servers will never be selected to be used anyway. ''', 'versionadded': '5.0.0' }, From ca2609e6cc32f0bdb89356a8c6c269bdcecf5a29 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 25 Sep 2023 12:38:34 +0200 Subject: [PATCH 750/909] Don't chace CNAMEs for NS queries Also, if we encouter a NS record without associated address records, wipe it from cache. This latest part is not well tested yet and might have bad side effects. --- pdns/recursordist/syncres.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 2a5b46ae4eb3..0e4822bedeec 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -2078,7 +2078,7 @@ vector SyncRes::getAddrs(const DNSName& qname, unsigned int depth, const unsigned int startqueries = d_outqueries; d_requireAuthData = false; d_DNSSECValidationRequested = false; - d_followCNAME = true; + d_followCNAME = false; MemRecursorCache::Flags flags = MemRecursorCache::None; if (d_serveStale) { @@ -2269,6 +2269,7 @@ void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector else { *flawedNSSet = true; LOG(prefix << qname << ": NS in cache for '" << subdomain << "', but needs glue (" << nrr->getNS() << ") which we miss or is expired" << endl); + g_recCache->doWipeCache(subdomain, false, QType::NS); } } } From 06cc71a6d97633bcec9582de2ea635c11e1a4864 Mon Sep 17 00:00:00 2001 From: phonedph1 Date: Tue, 26 Sep 2023 18:35:46 -0600 Subject: [PATCH 751/909] brute force change --- pdns/dnsdist-carbon.cc | 2 +- pdns/dnsdist-web.cc | 6 +++--- pdns/dnsdistdist/docs/guides/webserver.rst | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/pdns/dnsdist-carbon.cc b/pdns/dnsdist-carbon.cc index d73d9ff8b7ef..90957ece9414 100644 --- a/pdns/dnsdist-carbon.cc +++ b/pdns/dnsdist-carbon.cc @@ -126,7 +126,7 @@ static bool doOneCarbonExport(const Carbon::Endpoint& endpoint) str << base << "tcpdiedreadingquery" << ' ' << front->tcpDiedReadingQuery.load() << " " << now << "\r\n"; str << base << "tcpdiedsendingresponse" << ' ' << front->tcpDiedSendingResponse.load() << " " << now << "\r\n"; str << base << "tcpgaveup" << ' ' << front->tcpGaveUp.load() << " " << now << "\r\n"; - str << base << "tcpclientimeouts" << ' ' << front->tcpClientTimeouts.load() << " " << now << "\r\n"; + str << base << "tcpclienttimeouts" << ' ' << front->tcpClientTimeouts.load() << " " << now << "\r\n"; str << base << "tcpdownstreamtimeouts" << ' ' << front->tcpDownstreamTimeouts.load() << " " << now << "\r\n"; str << base << "tcpcurrentconnections" << ' ' << front->tcpCurrentConnections.load() << " " << now << "\r\n"; str << base << "tcpmaxconcurrentconnections" << ' ' << front->tcpMaxConcurrentConnections.load() << " " << now << "\r\n"; diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index 50379859725c..082bcf56c98d 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -669,8 +669,8 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) output << "# TYPE " << frontsbase << "tcpdiedsendingresponse " << "counter" << "\n"; output << "# HELP " << frontsbase << "tcpgaveup " << "Amount of TCP connections terminated after too many attempts to get a connection to the backend" << "\n"; output << "# TYPE " << frontsbase << "tcpgaveup " << "counter" << "\n"; - output << "# HELP " << frontsbase << "tcpclientimeouts " << "Amount of TCP connections terminated by a timeout while reading from the client" << "\n"; - output << "# TYPE " << frontsbase << "tcpclientimeouts " << "counter" << "\n"; + output << "# HELP " << frontsbase << "tcpclienttimeouts " << "Amount of TCP connections terminated by a timeout while reading from the client" << "\n"; + output << "# TYPE " << frontsbase << "tcpclienttimeouts " << "counter" << "\n"; output << "# HELP " << frontsbase << "tcpdownstreamtimeouts " << "Amount of TCP connections terminated by a timeout while reading from the backend" << "\n"; output << "# TYPE " << frontsbase << "tcpdownstreamtimeouts " << "counter" << "\n"; output << "# HELP " << frontsbase << "tcpcurrentconnections " << "Amount of current incoming TCP connections from clients" << "\n"; @@ -718,7 +718,7 @@ static void handlePrometheus(const YaHTTP::Request& req, YaHTTP::Response& resp) output << frontsbase << "tcpdiedreadingquery" << label << front->tcpDiedReadingQuery.load() << "\n"; output << frontsbase << "tcpdiedsendingresponse" << label << front->tcpDiedSendingResponse.load() << "\n"; output << frontsbase << "tcpgaveup" << label << front->tcpGaveUp.load() << "\n"; - output << frontsbase << "tcpclientimeouts" << label << front->tcpClientTimeouts.load() << "\n"; + output << frontsbase << "tcpclienttimeouts" << label << front->tcpClientTimeouts.load() << "\n"; output << frontsbase << "tcpdownstreamtimeouts" << label << front->tcpDownstreamTimeouts.load() << "\n"; output << frontsbase << "tcpcurrentconnections" << label << front->tcpCurrentConnections.load() << "\n"; output << frontsbase << "tcpmaxconcurrentconnections" << label << front->tcpMaxConcurrentConnections.load() << "\n"; diff --git a/pdns/dnsdistdist/docs/guides/webserver.rst b/pdns/dnsdistdist/docs/guides/webserver.rst index 4a15a8c1e09b..2ad6c449568c 100755 --- a/pdns/dnsdistdist/docs/guides/webserver.rst +++ b/pdns/dnsdistdist/docs/guides/webserver.rst @@ -447,8 +447,8 @@ URL Endpoints # TYPE dnsdist_frontend_tcpdiedsendingresponse counter # HELP dnsdist_frontend_tcpgaveup Amount of TCP connections terminated after too many attempts to get a connection to the backend # TYPE dnsdist_frontend_tcpgaveup counter - # HELP dnsdist_frontend_tcpclientimeouts Amount of TCP connections terminated by a timeout while reading from the client - # TYPE dnsdist_frontend_tcpclientimeouts counter + # HELP dnsdist_frontend_tcpclienttimeouts Amount of TCP connections terminated by a timeout while reading from the client + # TYPE dnsdist_frontend_tcpclienttimeouts counter # HELP dnsdist_frontend_tcpdownstreamtimeouts Amount of TCP connections terminated by a timeout while reading from the backend # TYPE dnsdist_frontend_tcpdownstreamtimeouts counter # HELP dnsdist_frontend_tcpcurrentconnections Amount of current incoming TCP connections from clients @@ -477,7 +477,7 @@ URL Endpoints dnsdist_frontend_tcpdiedreadingquery{frontend="127.0.0.1:853",proto="TCP (DNS over TLS)",thread="0"} 0 dnsdist_frontend_tcpdiedsendingresponse{frontend="127.0.0.1:853",proto="TCP (DNS over TLS)",thread="0"} 0 dnsdist_frontend_tcpgaveup{frontend="127.0.0.1:853",proto="TCP (DNS over TLS)",thread="0"} 0 - dnsdist_frontend_tcpclientimeouts{frontend="127.0.0.1:853",proto="TCP (DNS over TLS)",thread="0"} 0 + dnsdist_frontend_tcpclienttimeouts{frontend="127.0.0.1:853",proto="TCP (DNS over TLS)",thread="0"} 0 dnsdist_frontend_tcpdownstreamtimeouts{frontend="127.0.0.1:853",proto="TCP (DNS over TLS)",thread="0"} 0 dnsdist_frontend_tcpcurrentconnections{frontend="127.0.0.1:853",proto="TCP (DNS over TLS)",thread="0"} 0 dnsdist_frontend_tcpmaxconcurrentconnections{frontend="127.0.0.1:853",proto="TCP (DNS over TLS)",thread="0"} 0 @@ -506,7 +506,7 @@ URL Endpoints dnsdist_frontend_tcpdiedreadingquery{frontend="[::1]:443",proto="TCP (DNS over HTTPS)",thread="0"} 0 dnsdist_frontend_tcpdiedsendingresponse{frontend="[::1]:443",proto="TCP (DNS over HTTPS)",thread="0"} 0 dnsdist_frontend_tcpgaveup{frontend="[::1]:443",proto="TCP (DNS over HTTPS)",thread="0"} 0 - dnsdist_frontend_tcpclientimeouts{frontend="[::1]:443",proto="TCP (DNS over HTTPS)",thread="0"} 0 + dnsdist_frontend_tcpclienttimeouts{frontend="[::1]:443",proto="TCP (DNS over HTTPS)",thread="0"} 0 dnsdist_frontend_tcpdownstreamtimeouts{frontend="[::1]:443",proto="TCP (DNS over HTTPS)",thread="0"} 0 dnsdist_frontend_tcpcurrentconnections{frontend="[::1]:443",proto="TCP (DNS over HTTPS)",thread="0"} 0 dnsdist_frontend_tcpmaxconcurrentconnections{frontend="[::1]:443",proto="TCP (DNS over HTTPS)",thread="0"} 0 @@ -538,7 +538,7 @@ URL Endpoints dnsdist_frontend_tcpdiedreadingquery{frontend="127.0.0.1:53",proto="TCP",thread="0"} 0 dnsdist_frontend_tcpdiedsendingresponse{frontend="127.0.0.1:53",proto="TCP",thread="0"} 0 dnsdist_frontend_tcpgaveup{frontend="127.0.0.1:53",proto="TCP",thread="0"} 0 - dnsdist_frontend_tcpclientimeouts{frontend="127.0.0.1:53",proto="TCP",thread="0"} 0 + dnsdist_frontend_tcpclienttimeouts{frontend="127.0.0.1:53",proto="TCP",thread="0"} 0 dnsdist_frontend_tcpdownstreamtimeouts{frontend="127.0.0.1:53",proto="TCP",thread="0"} 0 dnsdist_frontend_tcpcurrentconnections{frontend="127.0.0.1:53",proto="TCP",thread="0"} 0 dnsdist_frontend_tcpmaxconcurrentconnections{frontend="127.0.0.1:53",proto="TCP",thread="0"} 0 From 7ff419629cea549e8ac46d54d0d2c4c53d2079f7 Mon Sep 17 00:00:00 2001 From: phonedph1 Date: Tue, 26 Sep 2023 20:32:36 -0600 Subject: [PATCH 752/909] spelling --- .github/actions/spell-check/allow.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/actions/spell-check/allow.txt b/.github/actions/spell-check/allow.txt index 73351a6e1701..d51b7970d3a8 100644 --- a/.github/actions/spell-check/allow.txt +++ b/.github/actions/spell-check/allow.txt @@ -3546,7 +3546,7 @@ tcpavgqueriesperconnection tcpbench tcpbytesanswered tcpclient -tcpclientimeouts +tcpclienttimeouts tcpclientthreads tcpcurrentconnections tcpdiedreaddingresponse From 487dadecad3235a21389e6f2873aa5515f954b3c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 27 Sep 2023 09:46:16 +0200 Subject: [PATCH 753/909] When we have authoritative NS records in cache that do not lead to any usable address, wipe the NS records so a query of NS records to theprant leads to new NS records being inserted into the cache. Previously the presence of the authoritaivbe records would prevent that to happen. Queries would *use* the freshly retrieved parent records, but they would not end up in the cache (the presence of authoritative NS records prevents that) leading to repeated queries to the parent. --- pdns/recursordist/syncres.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 0e4822bedeec..26c38214d708 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -2233,7 +2233,7 @@ void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector vector ns; *flawedNSSet = false; - if (g_recCache->get(d_now.tv_sec, subdomain, QType::NS, flags, &ns, d_cacheRemote, d_routingTag) > 0) { + if (bool isAuth = false; g_recCache->get(d_now.tv_sec, subdomain, QType::NS, flags, &ns, d_cacheRemote, d_routingTag, nullptr, nullptr, nullptr, nullptr, &isAuth) > 0) { if (s_maxnsperresolve > 0 && ns.size() > s_maxnsperresolve) { vector selected; selected.reserve(s_maxnsperresolve); @@ -2269,10 +2269,15 @@ void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector else { *flawedNSSet = true; LOG(prefix << qname << ": NS in cache for '" << subdomain << "', but needs glue (" << nrr->getNS() << ") which we miss or is expired" << endl); - g_recCache->doWipeCache(subdomain, false, QType::NS); } } } + if (*flawedNSSet && bestns.empty() && isAuth) { + // The authoritative (child) NS records did not produce any usable addresses, wipe them, so + // these useless records do not prevent parent records to be inserted into the cache + LOG(prefix << qname << ": Wiping flawed authoritative NS records for " << subdomain << endl); + g_recCache->doWipeCache(subdomain, false, QType::NS); + } if (!bestns.empty()) { GetBestNSAnswer answer; From 8693e70b44906ac7b37fbc3d6b4219a5b0611e14 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 27 Sep 2023 09:05:49 +0200 Subject: [PATCH 754/909] rec: Fix log messages lacking priority --- pdns/recursordist/rec-zonetocache.cc | 28 ++++++++++++++-------------- pdns/unix_utility.cc | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/pdns/recursordist/rec-zonetocache.cc b/pdns/recursordist/rec-zonetocache.cc index 408f486eacd3..87746350033c 100644 --- a/pdns/recursordist/rec-zonetocache.cc +++ b/pdns/recursordist/rec-zonetocache.cc @@ -163,7 +163,7 @@ pdns::ZoneMD::Result ZoneData::getByAXFR(const RecZoneToCache::Config& config, p if (config.d_zonemd != pdns::ZoneMD::Config::Ignore) { bool validationDone, validationSuccess; zonemd.verify(validationDone, validationSuccess); - d_log->info("ZONEMD digest validation", "validationDone", Logging::Loggable(validationDone), + d_log->info(Logr::Info, "ZONEMD digest validation", "validationDone", Logging::Loggable(validationDone), "validationSuccess", Logging::Loggable(validationSuccess)); if (!validationDone) { return pdns::ZoneMD::Result::NoValidationDone; @@ -229,7 +229,7 @@ pdns::ZoneMD::Result ZoneData::processLines(const vector& lines, const R if (config.d_zonemd != pdns::ZoneMD::Config::Ignore) { bool validationDone, validationSuccess; zonemd.verify(validationDone, validationSuccess); - d_log->info("ZONEMD digest validation", "validationDone", Logging::Loggable(validationDone), + d_log->info(Logr::Info, "ZONEMD digest validation", "validationDone", Logging::Loggable(validationDone), "validationSuccess", Logging::Loggable(validationSuccess)); if (!validationDone) { return pdns::ZoneMD::Result::NoValidationDone; @@ -299,7 +299,7 @@ vState ZoneData::dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const } nsecValidationStatus = validateWithKeySet(d_now, d_zone, records, zonemd.getRRSIGs(), validKeys, std::nullopt); if (nsecValidationStatus != vState::Secure) { - d_log->info("NSEC3PARAMS records did not validate"); + d_log->info(Logr::Warning, "NSEC3PARAMS records did not validate"); return nsecValidationStatus; } // Valdidate the NSEC3 @@ -307,21 +307,21 @@ vState ZoneData::dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const csp.emplace(std::pair(zonemd.getNSEC3Label(), QType::NSEC3), nsec3s); } else { - d_log->info("No NSEC(3) records and/or RRSIGS found to deny ZONEMD"); + d_log->info(Logr::Warning, "No NSEC(3) records and/or RRSIGS found to deny ZONEMD"); return vState::BogusInvalidDenial; } if (nsecValidationStatus != vState::Secure) { - d_log->info("zone NSEC(3) record does not validate"); + d_log->info(Logr::Warning, "zone NSEC(3) record does not validate"); return nsecValidationStatus; } auto denial = getDenial(csp, d_zone, QType::ZONEMD, false, false, std::nullopt, true); if (denial == dState::NXQTYPE) { - d_log->info("Validated denial of absence of ZONEMD record"); + d_log->info(Logr::Info, "Validated denial of existence of ZONEMD record"); return vState::Secure; } - d_log->info("No ZONEMD record, but NSEC(3) record does not deny it"); + d_log->info(Logr::Warning, "No ZONEMD record, but NSEC(3) record does not deny it"); return vState::BogusInvalidDenial; } @@ -336,7 +336,7 @@ vState ZoneData::dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const void ZoneData::ZoneToCache(const RecZoneToCache::Config& config) { if (config.d_sources.size() > 1) { - d_log->info("Multiple sources not yet supported, using first"); + d_log->info(Logr::Notice, "Multiple sources not yet supported, using first"); } if (config.d_dnssec == pdns::ZoneMD::Config::Require && (g_dnssecmode == DNSSECMode::Off || g_dnssecmode == DNSSECMode::ProcessNoValidate)) { @@ -350,17 +350,17 @@ void ZoneData::ZoneToCache(const RecZoneToCache::Config& config) auto zonemd = pdns::ZoneMD(DNSName(config.d_zone)); pdns::ZoneMD::Result result = pdns::ZoneMD::Result::OK; if (config.d_method == "axfr") { - d_log->info("Getting zone by AXFR"); + d_log->info(Logr::Info, "Getting zone by AXFR"); result = getByAXFR(config, zonemd); } else { vector lines; if (config.d_method == "url") { - d_log->info("Getting zone by URL"); + d_log->info(Logr::Info, "Getting zone by URL"); lines = getURL(config); } else if (config.d_method == "file") { - d_log->info("Getting zone from file"); + d_log->info(Logr::Info, "Getting zone from file"); lines = getLinesFromFile(config.d_sources.at(0)); } result = processLines(lines, config, zonemd); @@ -370,7 +370,7 @@ void ZoneData::ZoneToCache(const RecZoneToCache::Config& config) if (config.d_dnssec == pdns::ZoneMD::Config::Require || (g_dnssecmode != DNSSECMode::Off && g_dnssecmode != DNSSECMode::ProcessNoValidate && config.d_dnssec != pdns::ZoneMD::Config::Ignore)) { size_t zonemdCount; auto validationStatus = dnssecValidate(zonemd, zonemdCount); - d_log->info("ZONEMD record related DNSSEC validation", "validationStatus", Logging::Loggable(validationStatus), + d_log->info(Logr::Info, "ZONEMD record related DNSSEC validation", "validationStatus", Logging::Loggable(validationStatus), "zonemdCount", Logging::Loggable(zonemdCount)); if (config.d_dnssec == pdns::ZoneMD::Config::Require && validationStatus != vState::Secure) { throw PDNSException("ZONEMD required DNSSEC validation failed"); @@ -459,7 +459,7 @@ void RecZoneToCache::ZoneToCache(const RecZoneToCache::Config& config, RecZoneTo ZoneData data(log, config.d_zone); data.ZoneToCache(config); state.d_waittime = config.d_refreshPeriod; - log->info("Loaded zone into cache", "refresh", Logging::Loggable(state.d_waittime)); + log->info(Logr::Info, "Loaded zone into cache", "refresh", Logging::Loggable(state.d_waittime)); } catch (const PDNSException& e) { log->error(Logr::Error, e.reason, "Unable to load zone into cache, will retry", "exception", Logging::Loggable("PDNSException"), "refresh", Logging::Loggable(state.d_waittime)); @@ -468,7 +468,7 @@ void RecZoneToCache::ZoneToCache(const RecZoneToCache::Config& config, RecZoneTo log->error(Logr::Error, e.what(), "Unable to load zone into cache, will retry", "exception", Logging::Loggable("std::runtime_error"), "refresh", Logging::Loggable(state.d_waittime)); } catch (...) { - log->info("Unable to load zone into cache, will retry", "refresh", Logging::Loggable(state.d_waittime)); + log->info(Logr::Error, "Unable to load zone into cache, will retry", "refresh", Logging::Loggable(state.d_waittime)); } state.d_lastrun = time(nullptr); return; diff --git a/pdns/unix_utility.cc b/pdns/unix_utility.cc index 2fb2d00e07ca..d6720ca74754 100644 --- a/pdns/unix_utility.cc +++ b/pdns/unix_utility.cc @@ -185,7 +185,7 @@ void Utility::dropUserPrivs( uid_t uid ) } else { SLOG(g_log<withName("runtime")->info("Set effective user", "uid", Logging::Loggable(uid))); + g_slog->withName("runtime")->info(Logr::Info, "Set effective user", "uid", Logging::Loggable(uid))); } } } From 24d8f14e8b0b480c714300cdcda7926777ab7d12 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 27 Sep 2023 17:01:14 +0200 Subject: [PATCH 755/909] delint --- pdns/recursordist/rec-zonetocache.cc | 105 ++++++++++++++------------- pdns/recursordist/rec-zonetocache.hh | 4 +- 2 files changed, 55 insertions(+), 54 deletions(-) diff --git a/pdns/recursordist/rec-zonetocache.cc b/pdns/recursordist/rec-zonetocache.cc index 87746350033c..10936401c0fd 100644 --- a/pdns/recursordist/rec-zonetocache.cc +++ b/pdns/recursordist/rec-zonetocache.cc @@ -40,7 +40,7 @@ struct ZoneData { - ZoneData(Logr::log_t log, const std::string& zone) : + ZoneData(const std::shared_ptr& log, const std::string& zone) : d_log(log), d_zone(zone), d_now(time(nullptr)) {} @@ -53,16 +53,16 @@ struct ZoneData // Maybe use a SuffixMatchTree? std::set d_delegations; - Logr::log_t d_log; + std::shared_ptr d_log; DNSName d_zone; time_t d_now; - bool isRRSetAuth(const DNSName& qname, QType qtype) const; - void parseDRForCache(DNSRecord& dr); - pdns::ZoneMD::Result getByAXFR(const RecZoneToCache::Config&, pdns::ZoneMD&); - pdns::ZoneMD::Result processLines(const std::vector& lines, const RecZoneToCache::Config& config, pdns::ZoneMD&); + [[nodiscard]] bool isRRSetAuth(const DNSName& qname, QType qtype) const; + void parseDRForCache(DNSRecord& resourceRecord); + pdns::ZoneMD::Result getByAXFR(const RecZoneToCache::Config& config, pdns::ZoneMD& zonemd); + pdns::ZoneMD::Result processLines(const std::vector& lines, const RecZoneToCache::Config& config, pdns::ZoneMD& zonemd); void ZoneToCache(const RecZoneToCache::Config& config); - vState dnssecValidate(pdns::ZoneMD&, size_t& zonemdCount) const; + vState dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const; }; bool ZoneData::isRRSetAuth(const DNSName& qname, QType qtype) const @@ -78,42 +78,43 @@ bool ZoneData::isRRSetAuth(const DNSName& qname, QType qtype) const break; } delegatedZone.chopOff(); - if (delegatedZone == g_rootdnsname || delegatedZone == d_zone) + if (delegatedZone == g_rootdnsname || delegatedZone == d_zone) { break; + } } return !isDelegated; } -void ZoneData::parseDRForCache(DNSRecord& dr) +void ZoneData::parseDRForCache(DNSRecord& dnsRecord) { - if (dr.d_class != QClass::IN) { + if (dnsRecord.d_class != QClass::IN) { return; } - const auto key = pair(dr.d_name, dr.d_type); + const auto key = pair(dnsRecord.d_name, dnsRecord.d_type); - dr.d_ttl += d_now; + dnsRecord.d_ttl += d_now; - switch (dr.d_type) { + switch (dnsRecord.d_type) { case QType::NSEC: case QType::NSEC3: break; case QType::RRSIG: { - const auto& rr = getRR(dr); - const auto sigkey = pair(key.first, rr->d_type); + const auto rrsig = getRR(dnsRecord); + const auto sigkey = pair(key.first, rrsig->d_type); auto found = d_sigs.find(sigkey); if (found != d_sigs.end()) { - found->second.push_back(rr); + found->second.push_back(rrsig); } else { vector> sigsrr; - sigsrr.push_back(rr); + sigsrr.push_back(rrsig); d_sigs.insert({sigkey, sigsrr}); } break; } case QType::NS: - if (dr.d_name != d_zone) { - d_delegations.insert(dr.d_name); + if (dnsRecord.d_name != d_zone) { + d_delegations.insert(dnsRecord.d_name); } break; default: @@ -122,12 +123,12 @@ void ZoneData::parseDRForCache(DNSRecord& dr) auto found = d_all.find(key); if (found != d_all.end()) { - found->second.push_back(dr); + found->second.push_back(dnsRecord); } else { - vector v; - v.push_back(dr); - d_all.insert({key, v}); + vector dnsRecords; + dnsRecords.push_back(dnsRecord); + d_all.insert({key, dnsRecords}); } } @@ -136,24 +137,24 @@ pdns::ZoneMD::Result ZoneData::getByAXFR(const RecZoneToCache::Config& config, p ComboAddress primary = ComboAddress(config.d_sources.at(0), 53); uint16_t axfrTimeout = config.d_timeout; size_t maxReceivedBytes = config.d_maxReceivedBytes; - const TSIGTriplet tt = config.d_tt; + const TSIGTriplet tsigTriplet = config.d_tt; ComboAddress local = config.d_local; if (local == ComboAddress()) { local = pdns::getQueryLocalAddress(primary.sin4.sin_family, 0); } - AXFRRetriever axfr(primary, d_zone, tt, &local, maxReceivedBytes, axfrTimeout); + AXFRRetriever axfr(primary, d_zone, tsigTriplet, &local, maxReceivedBytes, axfrTimeout); Resolver::res_t nop; vector chunk; time_t axfrStart = time(nullptr); time_t axfrNow = time(nullptr); - while (axfr.getChunk(nop, &chunk, (axfrStart + axfrTimeout - axfrNow))) { - for (auto& dr : chunk) { + while (axfr.getChunk(nop, &chunk, (axfrStart + axfrTimeout - axfrNow)) != 0) { + for (auto& dnsRecord : chunk) { if (config.d_zonemd != pdns::ZoneMD::Config::Ignore) { - zonemd.readRecord(dr); + zonemd.readRecord(dnsRecord); } - parseDRForCache(dr); + parseDRForCache(dnsRecord); } axfrNow = time(nullptr); if (axfrNow < axfrStart || axfrNow - axfrStart > axfrTimeout) { @@ -161,7 +162,8 @@ pdns::ZoneMD::Result ZoneData::getByAXFR(const RecZoneToCache::Config& config, p } } if (config.d_zonemd != pdns::ZoneMD::Config::Ignore) { - bool validationDone, validationSuccess; + bool validationDone = false; + bool validationSuccess = false; zonemd.verify(validationDone, validationSuccess); d_log->info(Logr::Info, "ZONEMD digest validation", "validationDone", Logging::Loggable(validationDone), "validationSuccess", Logging::Loggable(validationSuccess)); @@ -194,9 +196,9 @@ static std::vector getURL(const RecZoneToCache::Config& config) { std::vector lines; #ifdef HAVE_LIBCURL - MiniCurl mc; + MiniCurl miniCurl; ComboAddress local = config.d_local; - std::string reply = mc.getURL(config.d_sources.at(0), nullptr, local == ComboAddress() ? nullptr : &local, config.d_timeout, false, true); + std::string reply = miniCurl.getURL(config.d_sources.at(0), nullptr, local == ComboAddress() ? nullptr : &local, static_cast(config.d_timeout), false, true); if (config.d_maxReceivedBytes > 0 && reply.size() > config.d_maxReceivedBytes) { // We should actually detect this *during* the GET throw std::runtime_error("Retrieved data exceeds maxReceivedBytes"); @@ -220,14 +222,15 @@ pdns::ZoneMD::Result ZoneData::processLines(const vector& lines, const R zpt.setMaxIncludes(0); while (zpt.get(drr)) { - DNSRecord dr(drr); + DNSRecord dnsRecord(drr); if (config.d_zonemd != pdns::ZoneMD::Config::Ignore) { - zonemd.readRecord(dr); + zonemd.readRecord(dnsRecord); } - parseDRForCache(dr); + parseDRForCache(dnsRecord); } if (config.d_zonemd != pdns::ZoneMD::Config::Ignore) { - bool validationDone, validationSuccess; + bool validationDone = false; + bool validationSuccess = false; zonemd.verify(validationDone, validationSuccess); d_log->info(Logr::Info, "ZONEMD digest validation", "validationDone", Logging::Loggable(validationDone), "validationSuccess", Logging::Loggable(validationSuccess)); @@ -245,19 +248,19 @@ vState ZoneData::dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const { zonemdCount = 0; - SyncRes sr({d_now, 0}); - sr.setDoDNSSEC(true); - sr.setDNSSECValidationRequested(true); + SyncRes resolver({d_now, 0}); + resolver.setDoDNSSEC(true); + resolver.setDNSSECValidationRequested(true); dsmap_t dsmap; // Actually a set - vState dsState = sr.getDSRecords(d_zone, dsmap, false, 0, ""); + vState dsState = resolver.getDSRecords(d_zone, dsmap, false, 0, ""); if (dsState != vState::Secure) { return dsState; } skeyset_t dnsKeys; sortedRecords_t records; - if (zonemd.getDNSKEYs().size() == 0) { + if (zonemd.getDNSKEYs().empty()) { return vState::BogusUnableToGetDNSKEYs; } for (const auto& key : zonemd.getDNSKEYs()) { @@ -271,7 +274,7 @@ vState ZoneData::dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const return dnsKeyState; } - if (validKeys.size() == 0) { + if (validKeys.empty()) { return vState::BogusNoValidDNSKEY; } @@ -284,14 +287,14 @@ vState ZoneData::dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const const auto& nsec3s = zonemd.getNSEC3s(); cspmap_t csp; - vState nsecValidationStatus; + vState nsecValidationStatus = vState::Indeterminate; - if (nsecs.records.size() > 0 && nsecs.signatures.size() > 0) { + if (!nsecs.records.empty() && !nsecs.signatures.empty()) { // Valdidate the NSEC nsecValidationStatus = validateWithKeySet(d_now, d_zone, nsecs.records, nsecs.signatures, validKeys, std::nullopt); csp.emplace(std::pair(d_zone, QType::NSEC), nsecs); } - else if (nsec3s.records.size() > 0 && nsec3s.signatures.size() > 0) { + else if (!nsec3s.records.empty() && !nsec3s.signatures.empty()) { // Validate NSEC3PARAMS records.clear(); for (const auto& rec : zonemd.getNSEC3Params()) { @@ -336,7 +339,7 @@ vState ZoneData::dnssecValidate(pdns::ZoneMD& zonemd, size_t& zonemdCount) const void ZoneData::ZoneToCache(const RecZoneToCache::Config& config) { if (config.d_sources.size() > 1) { - d_log->info(Logr::Notice, "Multiple sources not yet supported, using first"); + d_log->info(Logr::Warning, "Multiple sources not yet supported, using first"); } if (config.d_dnssec == pdns::ZoneMD::Config::Require && (g_dnssecmode == DNSSECMode::Off || g_dnssecmode == DNSSECMode::ProcessNoValidate)) { @@ -368,7 +371,7 @@ void ZoneData::ZoneToCache(const RecZoneToCache::Config& config) // Validate DNSKEYs and ZONEMD, rest of records are validated on-demand by SyncRes if (config.d_dnssec == pdns::ZoneMD::Config::Require || (g_dnssecmode != DNSSECMode::Off && g_dnssecmode != DNSSECMode::ProcessNoValidate && config.d_dnssec != pdns::ZoneMD::Config::Ignore)) { - size_t zonemdCount; + size_t zonemdCount = 0; auto validationStatus = dnssecValidate(zonemd, zonemdCount); d_log->info(Logr::Info, "ZONEMD record related DNSSEC validation", "validationStatus", Logging::Loggable(validationStatus), "zonemdCount", Logging::Loggable(zonemdCount)); @@ -397,14 +400,13 @@ void ZoneData::ZoneToCache(const RecZoneToCache::Config& config) switch (qtype) { case QType::NSEC: case QType::NSEC3: - break; case QType::RRSIG: break; default: { vector> sigsrr; - auto it = d_sigs.find(key); - if (it != d_sigs.end()) { - sigsrr = it->second; + auto iter = d_sigs.find(key); + if (iter != d_sigs.end()) { + sigsrr = iter->second; } bool auth = isRRSetAuth(qname, qtype); // Same decision as updateCacheFromRecords() (we do not test for NSEC since we skip those completely) @@ -471,5 +473,4 @@ void RecZoneToCache::ZoneToCache(const RecZoneToCache::Config& config, RecZoneTo log->info(Logr::Error, "Unable to load zone into cache, will retry", "refresh", Logging::Loggable(state.d_waittime)); } state.d_lastrun = time(nullptr); - return; } diff --git a/pdns/recursordist/rec-zonetocache.hh b/pdns/recursordist/rec-zonetocache.hh index 317af52facbd..8d946cfd82d3 100644 --- a/pdns/recursordist/rec-zonetocache.hh +++ b/pdns/recursordist/rec-zonetocache.hh @@ -39,7 +39,7 @@ public: TSIGTriplet d_tt; // Authentication data size_t d_maxReceivedBytes{0}; // Maximum size time_t d_retryOnError{60}; // Retry on error - time_t d_refreshPeriod{24 * 3600}; // Time between refetch + time_t d_refreshPeriod{static_cast(24 *3600)}; // Time between refetch uint32_t d_timeout{20}; // timeout in seconds pdns::ZoneMD::Config d_zonemd{pdns::ZoneMD::Config::Validate}; pdns::ZoneMD::Config d_dnssec{pdns::ZoneMD::Config::Validate}; @@ -49,7 +49,7 @@ public: { time_t d_lastrun{0}; time_t d_waittime{0}; - uint64_t d_generation; + uint64_t d_generation{0}; }; static void maintainStates(const map&, map&, uint64_t mygeneration); From f39b15a71271afe6333e55f5994b680a68eeccbd Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 28 Sep 2023 14:13:59 +0200 Subject: [PATCH 756/909] dnsdist: Fix a race in the Async unit tests We used to set the `errorRaised` variable from the `AsynchronousHolder` thread then check its value from the main thread, which is correctly reported as TSAN as a data race. We do know that we have waited enough, and that otherwise it's fine to fail, but TSAN cannot know that. Switching to a `std::atomic` fixes it. --- pdns/dnsdistdist/test-dnsdistasync.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pdns/dnsdistdist/test-dnsdistasync.cc b/pdns/dnsdistdist/test-dnsdistasync.cc index 713c5ad71f24..044d5a02f30f 100644 --- a/pdns/dnsdistdist/test-dnsdistasync.cc +++ b/pdns/dnsdistdist/test-dnsdistasync.cc @@ -49,7 +49,7 @@ class DummyQuerySender : public TCPQuerySender errorRaised = true; } - bool errorRaised{false}; + std::atomic errorRaised{false}; }; struct DummyCrossProtocolQuery : public CrossProtocolQuery @@ -137,7 +137,7 @@ BOOST_AUTO_TEST_CASE(test_TimeoutFailClose) } BOOST_CHECK(holder->empty()); - BOOST_CHECK(sender->errorRaised); + BOOST_CHECK(sender->errorRaised.load()); holder->stop(); } @@ -170,7 +170,7 @@ BOOST_AUTO_TEST_CASE(test_AddingExpiredEvent) } BOOST_CHECK(holder->empty()); - BOOST_CHECK(sender->errorRaised); + BOOST_CHECK(sender->errorRaised.load()); holder->stop(); } From f8e1161f37e310279c635de0cc79c031b0e7e270 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 28 Sep 2023 15:32:29 +0200 Subject: [PATCH 757/909] dnsdist: Set proper levels when logging messages This PR re-evaluates the log level of all messages in the DNSdist code base. The rules are simple: - 'Error' should only be used when a critical service will not function properly - 'Warning' should be used when a non-essential feature may not be working as expected - 'Info' is for everything that should not go unnoticed but also cannot be triggered by an outside attacker, otherwise we might be flooding our logs - 'Verbose' can be used for everything else. There are a few exceptions, something we log at the 'info' level for events that might be happening a lot, but only when told to do so, like for example with verbose health-check reporting. --- pdns/dnsdist-console.cc | 4 +-- pdns/dnsdist-lua.cc | 28 +++++++++---------- pdns/dnsdist-tcp.cc | 18 ++++++------ pdns/dnsdist-web.cc | 8 +++--- pdns/dnsdist.cc | 6 ++-- pdns/dnsdistdist/dnsdist-kvs.cc | 20 ++++++------- .../dnsdist-lua-bindings-dnscrypt.cc | 18 ++++++------ pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 2 +- pdns/dnsdistdist/dnsdist-nghttp2.cc | 14 +++++----- pdns/dnsdistdist/dnsdist-secpoll.cc | 8 +++--- pdns/dnsdistdist/doh.cc | 8 +++--- pdns/tcpiohandler.cc | 4 +-- 12 files changed, 69 insertions(+), 69 deletions(-) diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index f2e381f222bd..d1a42663d130 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -988,7 +988,7 @@ static void controlClientThread(ConsoleConnection&& conn) } } catch (const std::exception& e) { - errlog("Got an exception in client connection from %s: %s", conn.getClient().toStringWithPort(), e.what()); + infolog("Got an exception in client connection from %s: %s", conn.getClient().toStringWithPort(), e.what()); } } @@ -1026,7 +1026,7 @@ void controlThread(int fd, ComboAddress local) t.detach(); } catch (const std::exception& e) { - errlog("Control connection died: %s", e.what()); + infolog("Control connection died: %s", e.what()); } } } diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index a3a9bf3bdc8d..6d1744506836 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -1595,9 +1595,9 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) g_frontends.push_back(std::move(cs)); } - catch (std::exception& e) { - errlog(e.what()); - g_outputBuffer = "Error: " + string(e.what()) + "\n"; + catch (const std::exception& e) { + errlog("Error during addDNSCryptBind() processing: %s", e.what()); + g_outputBuffer = "Error during addDNSCryptBind() processing: " + string(e.what()) + "\n"; } }); @@ -2560,13 +2560,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) result = g_dohlocals.at(index); } else { - errlog("Error: trying to get DOH frontend with index %zu but we only have %zu frontend(s)\n", index, g_dohlocals.size()); + errlog("Error: trying to get DOH frontend with index %d but we only have %d frontend(s)\n", index, g_dohlocals.size()); g_outputBuffer = "Error: trying to get DOH frontend with index " + std::to_string(index) + " but we only have " + std::to_string(g_dohlocals.size()) + " frontend(s)\n"; } } catch (const std::exception& e) { g_outputBuffer = "Error while trying to get DOH frontend with index " + std::to_string(index) + ": " + string(e.what()) + "\n"; - errlog("Error while trying to get DOH frontend with index %zu: %s\n", index, string(e.what())); + errlog("Error while trying to get DOH frontend with index %d: %s\n", index, string(e.what())); } #else g_outputBuffer="DNS over HTTPS support is not present!\n"; @@ -2755,13 +2755,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) result = g_tlslocals.at(index)->getContext(); } else { - errlog("Error: trying to get TLS context with index %zu but we only have %zu context(s)\n", index, g_tlslocals.size()); + errlog("Error: trying to get TLS context with index %d but we only have %d context(s)\n", index, g_tlslocals.size()); g_outputBuffer = "Error: trying to get TLS context with index " + std::to_string(index) + " but we only have " + std::to_string(g_tlslocals.size()) + " context(s)\n"; } } catch (const std::exception& e) { g_outputBuffer = "Error while trying to get TLS context with index " + std::to_string(index) + ": " + string(e.what()) + "\n"; - errlog("Error while trying to get TLS context with index %zu: %s\n", index, string(e.what())); + errlog("Error while trying to get TLS context with index %d: %s\n", index, string(e.what())); } #else g_outputBuffer="DNS over TLS support is not present!\n"; @@ -2778,13 +2778,13 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) result = g_tlslocals.at(index); } else { - errlog("Error: trying to get TLS frontend with index %zu but we only have %zu frontends\n", index, g_tlslocals.size()); + errlog("Error: trying to get TLS frontend with index %d but we only have %d frontends\n", index, g_tlslocals.size()); g_outputBuffer = "Error: trying to get TLS frontend with index " + std::to_string(index) + " but we only have " + std::to_string(g_tlslocals.size()) + " frontend(s)\n"; } } catch (const std::exception& e) { g_outputBuffer = "Error while trying to get TLS frontend with index " + std::to_string(index) + ": " + string(e.what()) + "\n"; - errlog("Error while trying to get TLS frontend with index %zu: %s\n", index, string(e.what())); + errlog("Error while trying to get TLS frontend with index %d: %s\n", index, string(e.what())); } #else g_outputBuffer="DNS over TLS support is not present!\n"; @@ -2971,7 +2971,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) auto result = dnsdist::metrics::declareCustomMetric(name, type, description, customName ? std::optional(*customName) : std::nullopt); if (result) { g_outputBuffer += *result + "\n"; - errlog("%s", *result); + errlog("Error in declareMetric: %s", *result); return false; } return true; @@ -2980,7 +2980,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) auto result = dnsdist::metrics::incrementCustomCounter(name, step ? *step : 1); if (const auto* errorStr = std::get_if(&result)) { g_outputBuffer = *errorStr + "'\n"; - errlog("%s", *errorStr); + errlog("Error in incMetric: %s", *errorStr); return static_cast(0); } return std::get(result); @@ -2989,7 +2989,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) auto result = dnsdist::metrics::decrementCustomCounter(name, step ? *step : 1); if (const auto* errorStr = std::get_if(&result)) { g_outputBuffer = *errorStr + "'\n"; - errlog("%s", *errorStr); + errlog("Error in decMetric: %s", *errorStr); return static_cast(0); } return std::get(result); @@ -2998,7 +2998,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) auto result = dnsdist::metrics::setCustomGauge(name, value); if (const auto* errorStr = std::get_if(&result)) { g_outputBuffer = *errorStr + "'\n"; - errlog("%s", *errorStr); + errlog("Error in setMetric: %s", *errorStr); return 0.; } return std::get(result); @@ -3007,7 +3007,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) auto result = dnsdist::metrics::getCustomMetric(name); if (const auto* errorStr = std::get_if(&result)) { g_outputBuffer = *errorStr + "'\n"; - errlog("%s", *errorStr); + errlog("Error in getMetric: %s", *errorStr); return 0.; } return std::get(result); diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index c55574ef27d4..7b94e00e5109 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -1446,43 +1446,43 @@ static void tcpClientThread(pdns::channel::Receiver&& queryRecei if (g_tcpStatesDumpRequested > 0) { /* no race here, we took the lock so it can only be increased in the meantime */ --g_tcpStatesDumpRequested; - errlog("Dumping the TCP states, as requested:"); + infolog("Dumping the TCP states, as requested:"); data.mplexer->runForAllWatchedFDs([](bool isRead, int fd, const FDMultiplexer::funcparam_t& param, struct timeval ttd) { struct timeval lnow; gettimeofday(&lnow, nullptr); if (ttd.tv_sec > 0) { - errlog("- Descriptor %d is in %s state, TTD in %d", fd, (isRead ? "read" : "write"), (ttd.tv_sec-lnow.tv_sec)); + infolog("- Descriptor %d is in %s state, TTD in %d", fd, (isRead ? "read" : "write"), (ttd.tv_sec-lnow.tv_sec)); } else { - errlog("- Descriptor %d is in %s state, no TTD set", fd, (isRead ? "read" : "write")); + infolog("- Descriptor %d is in %s state, no TTD set", fd, (isRead ? "read" : "write")); } if (param.type() == typeid(std::shared_ptr)) { auto state = boost::any_cast>(param); - errlog(" - %s", state->toString()); + infolog(" - %s", state->toString()); } #ifdef HAVE_NGHTTP2 else if (param.type() == typeid(std::shared_ptr)) { auto state = boost::any_cast>(param); - errlog(" - %s", state->toString()); + infolog(" - %s", state->toString()); } #endif /* HAVE_NGHTTP2 */ else if (param.type() == typeid(std::shared_ptr)) { auto conn = boost::any_cast>(param); - errlog(" - %s", conn->toString()); + infolog(" - %s", conn->toString()); } else if (param.type() == typeid(TCPClientThreadData*)) { - errlog(" - Worker thread pipe"); + infolog(" - Worker thread pipe"); } }); - errlog("The TCP/DoT client cache has %d active and %d idle outgoing connections cached", t_downstreamTCPConnectionsManager.getActiveCount(), t_downstreamTCPConnectionsManager.getIdleCount()); + infolog("The TCP/DoT client cache has %d active and %d idle outgoing connections cached", t_downstreamTCPConnectionsManager.getActiveCount(), t_downstreamTCPConnectionsManager.getIdleCount()); } } } } catch (const std::exception& e) { - errlog("Error in TCP worker thread: %s", e.what()); + warnlog("Error in TCP worker thread: %s", e.what()); } } } diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index 50379859725c..4ceacaa991ae 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -225,7 +225,7 @@ bool addMetricDefinition(const dnsdist::prometheus::PrometheusMetricDefinition& static bool apiWriteConfigFile(const string& filebasename, const string& content) { if (!g_apiReadWrite) { - errlog("Not writing content to %s since the API is read-only", filebasename); + warnlog("Not writing content to %s since the API is read-only", filebasename); return false; } @@ -1757,10 +1757,10 @@ static void connectionThread(WebClientConnection&& conn) vinfolog("Webserver thread died with parse error exception while processing a request from %s: %s", conn.getClient().toStringWithPort(), e.what()); } catch (const std::exception& e) { - errlog("Webserver thread died with exception while processing a request from %s: %s", conn.getClient().toStringWithPort(), e.what()); + vinfolog("Webserver thread died with exception while processing a request from %s: %s", conn.getClient().toStringWithPort(), e.what()); } catch (...) { - errlog("Webserver thread died with exception while processing a request from %s", conn.getClient().toStringWithPort()); + vinfolog("Webserver thread died with exception while processing a request from %s", conn.getClient().toStringWithPort()); } } @@ -1843,7 +1843,7 @@ void dnsdistWebserverThread(int sock, const ComboAddress& local) t.detach(); } catch (const std::exception& e) { - errlog("Had an error accepting new webserver connection: %s", e.what()); + vinfolog("Had an error accepting new webserver connection: %s", e.what()); } } } diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index a23c03f0485b..cde7fd061bd2 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -338,7 +338,7 @@ bool responseContentMatches(const PacketBuffer& response, const DNSName& qname, } catch (const std::exception& e) { if (remote && response.size() > 0 && static_cast(response.size()) > sizeof(dnsheader)) { - infolog("Backend %s sent us a response with id %d that did not parse: %s", remote->d_config.remote.toStringWithPort(), ntohs(dh->id), e.what()); + vinfolog("Backend %s sent us a response with id %d that did not parse: %s", remote->d_config.remote.toStringWithPort(), ntohs(dh->id), e.what()); } ++dnsdist::metrics::g_stats.nonCompliantResponses; if (remote) { @@ -1956,9 +1956,9 @@ static void maintThread() (*f)(); secondsToWaitLog = 0; } - catch(const std::exception &e) { + catch (const std::exception &e) { if (secondsToWaitLog <= 0) { - infolog("Error during execution of maintenance function: %s", e.what()); + warnlog("Error during execution of maintenance function: %s", e.what()); secondsToWaitLog = 61; } secondsToWaitLog -= interval; diff --git a/pdns/dnsdistdist/dnsdist-kvs.cc b/pdns/dnsdistdist/dnsdist-kvs.cc index c2b6272ac4a0..d20aa1e980ea 100644 --- a/pdns/dnsdistdist/dnsdist-kvs.cc +++ b/pdns/dnsdistdist/dnsdist-kvs.cc @@ -96,8 +96,8 @@ bool LMDBKVStore::getValue(const std::string& key, std::string& value) return false; } } - catch(const std::exception& e) { - warnlog("Error while looking up key '%s' from LMDB file '%s', database '%s': %s", key, d_fname, d_dbName, e.what()); + catch (const std::exception& e) { + vinfolog("Error while looking up key '%s' from LMDB file '%s', database '%s': %s", key, d_fname, d_dbName, e.what()); } return false; } @@ -115,8 +115,8 @@ bool LMDBKVStore::keyExists(const std::string& key) return false; } } - catch(const std::exception& e) { - warnlog("Error while looking up key '%s' from LMDB file '%s', database '%s': %s", key, d_fname, d_dbName, e.what()); + catch (const std::exception& e) { + vinfolog("Error while looking up key '%s' from LMDB file '%s', database '%s': %s", key, d_fname, d_dbName, e.what()); } return false; } @@ -163,7 +163,7 @@ bool LMDBKVStore::getRangeValue(const std::string& key, std::string& value) return false; } } - catch(const std::exception& e) { + catch (const std::exception& e) { vinfolog("Error while looking up a range from LMDB file '%s', database '%s': %s", d_fname, d_dbName, e.what()); } return false; @@ -230,7 +230,7 @@ void CDBKVStore::refreshDBIfNeeded(time_t now) d_nextCheck = now + d_refreshDelay; d_refreshing.clear(); } - catch(...) { + catch (...) { d_refreshing.clear(); throw; } @@ -252,8 +252,8 @@ bool CDBKVStore::getValue(const std::string& key, std::string& value) } } } - catch(const std::exception& e) { - warnlog("Error while looking up key '%s' from CDB file '%s': %s", key, d_fname, e.what()); + catch (const std::exception& e) { + vinfolog("Error while looking up key '%s' from CDB file '%s': %s", key, d_fname, e.what()); } return false; } @@ -276,8 +276,8 @@ bool CDBKVStore::keyExists(const std::string& key) return (*cdb)->keyExists(key); } } - catch(const std::exception& e) { - warnlog("Error while looking up key '%s' from CDB file '%s': %s", key, d_fname, e.what()); + catch (const std::exception& e) { + vinfolog("Error while looking up key '%s' from CDB file '%s': %s", key, d_fname, e.what()); } return false; } diff --git a/pdns/dnsdistdist/dnsdist-lua-bindings-dnscrypt.cc b/pdns/dnsdistdist/dnsdist-lua-bindings-dnscrypt.cc index 72936ca97531..0385550e0af2 100644 --- a/pdns/dnsdistdist/dnsdist-lua-bindings-dnscrypt.cc +++ b/pdns/dnsdistdist/dnsdist-lua-bindings-dnscrypt.cc @@ -121,9 +121,9 @@ void setupLuaBindingsDNSCrypt(LuaContext& luaCtx, bool client) ctx.addNewCertificate(cert, privateKey); } } - catch(const std::exception& e) { - errlog(e.what()); - g_outputBuffer="Error: "+string(e.what())+"\n"; + catch (const std::exception& e) { + errlog("Error generating a DNSCrypt certificate: %s", e.what()); + g_outputBuffer = "Error generating a DNSCrypt certificate: " + string(e.what()) + "\n"; } }); @@ -167,8 +167,8 @@ void setupLuaBindingsDNSCrypt(LuaContext& luaCtx, bool client) } } catch (const std::exception& e) { - errlog(e.what()); - g_outputBuffer = "Error: " + string(e.what()) + "\n"; + errlog("Error generating a DNSCrypt certificate: %s", e.what()); + g_outputBuffer = "Error generating a DNSCrypt certificate: " + string(e.what()) + "\n"; } }); @@ -195,8 +195,8 @@ void setupLuaBindingsDNSCrypt(LuaContext& luaCtx, bool client) g_outputBuffer = "Provider fingerprint is: " + DNSCryptContext::getProviderFingerprint(publicKey) + "\n"; } catch (const std::exception& e) { - errlog(e.what()); - g_outputBuffer = "Error: " + string(e.what()) + "\n"; + errlog("Error generating a DNSCrypt provider key: %s", e.what()); + g_outputBuffer = "Error generating a DNSCrypt provider key: " + string(e.what()) + "\n"; } sodium_memzero(privateKey, sizeof(privateKey)); @@ -219,8 +219,8 @@ void setupLuaBindingsDNSCrypt(LuaContext& luaCtx, bool client) g_outputBuffer = "Provider fingerprint is: " + DNSCryptContext::getProviderFingerprint(publicKey) + "\n"; } catch (const std::exception& e) { - errlog(e.what()); - g_outputBuffer = "Error: " + string(e.what()) + "\n"; + errlog("Error getting a DNSCrypt provider fingerprint: %s", e.what()); + g_outputBuffer = "Error getting a DNSCrypt provider fingerprint: " + string(e.what()) + "\n"; } }); #endif diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index b22da0c39715..7bd9f758556c 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -407,7 +407,7 @@ void IncomingHTTP2Connection::handleIO() } } catch (const std::exception& e) { - infolog("Exception when processing IO for incoming DoH connection from %s: %s", d_ci.remote.toStringWithPort(), e.what()); + vinfolog("Exception when processing IO for incoming DoH connection from %s: %s", d_ci.remote.toStringWithPort(), e.what()); d_connectionDied = true; stopIO(); } diff --git a/pdns/dnsdistdist/dnsdist-nghttp2.cc b/pdns/dnsdistdist/dnsdist-nghttp2.cc index 352e864decd5..163d2df0925e 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2.cc @@ -889,31 +889,31 @@ static void dohClientThread(pdns::channel::Receiver&& receiv if (g_dohStatesDumpRequested > 0) { /* no race here, we took the lock so it can only be increased in the meantime */ --g_dohStatesDumpRequested; - errlog("Dumping the DoH client states, as requested:"); + infolog("Dumping the DoH client states, as requested:"); data.mplexer->runForAllWatchedFDs([](bool isRead, int fd, const FDMultiplexer::funcparam_t& param, struct timeval ttd) { struct timeval lnow; gettimeofday(&lnow, nullptr); if (ttd.tv_sec > 0) { - errlog("- Descriptor %d is in %s state, TTD in %d", fd, (isRead ? "read" : "write"), (ttd.tv_sec - lnow.tv_sec)); + infolog("- Descriptor %d is in %s state, TTD in %d", fd, (isRead ? "read" : "write"), (ttd.tv_sec - lnow.tv_sec)); } else { - errlog("- Descriptor %d is in %s state, no TTD set", fd, (isRead ? "read" : "write")); + infolog("- Descriptor %d is in %s state, no TTD set", fd, (isRead ? "read" : "write")); } if (param.type() == typeid(std::shared_ptr)) { auto conn = boost::any_cast>(param); - errlog(" - %s", conn->toString()); + infolog(" - %s", conn->toString()); } else if (param.type() == typeid(DoHClientThreadData*)) { - errlog(" - Worker thread pipe"); + infolog(" - Worker thread pipe"); } }); - errlog("The DoH client cache has %d active and %d idle outgoing connections cached", t_downstreamDoHConnectionsManager.getActiveCount(), t_downstreamDoHConnectionsManager.getIdleCount()); + infolog("The DoH client cache has %d active and %d idle outgoing connections cached", t_downstreamDoHConnectionsManager.getActiveCount(), t_downstreamDoHConnectionsManager.getIdleCount()); } } } catch (const std::exception& e) { - errlog("Error in outgoing DoH thread: %s", e.what()); + warnlog("Error in outgoing DoH thread: %s", e.what()); } } } diff --git a/pdns/dnsdistdist/dnsdist-secpoll.cc b/pdns/dnsdistdist/dnsdist-secpoll.cc index 7964d1490b0c..3bc9aeb40cc9 100644 --- a/pdns/dnsdistdist/dnsdist-secpoll.cc +++ b/pdns/dnsdistdist/dnsdist-secpoll.cc @@ -211,10 +211,10 @@ void doSecPoll(const std::string& suffix) int securityStatus = std::stoi(split.first); std::string securityMessage = split.second; - if(securityStatus == 1 && !g_secPollDone) { - warnlog("Polled security status of version %s at startup, no known issues reported: %s", std::string(VERSION), securityMessage); + if (securityStatus == 1 && !g_secPollDone) { + infolog("Polled security status of version %s at startup, no known issues reported: %s", std::string(VERSION), securityMessage); } - if(securityStatus == 2) { + if (securityStatus == 2) { errlog("PowerDNS DNSDist Security Update Recommended: %s", securityMessage); } else if(securityStatus == 3) { @@ -225,7 +225,7 @@ void doSecPoll(const std::string& suffix) g_secPollDone = true; return; } - catch(const std::exception& e) { + catch (const std::exception& e) { if (releaseVersion) { warnlog("Error while retrieving the security update for version %s: %s", version, e.what()); } diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 8a9f5fef2ae5..128bee4126d5 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -1182,7 +1182,7 @@ static int doh_handler(h2o_handler_t *self, h2o_req_t *req) return 0; } catch (const std::exception& e) { - errlog("DOH Handler function failed with error %s", e.what()); + vinfolog("DOH Handler function failed with error: '%s'", e.what()); return 0; } } @@ -1264,10 +1264,10 @@ static void dnsdistclient(pdns::channel::Receiver&& receiver) processDOHQuery(std::move(dohUnit), false); } catch (const std::exception& e) { - errlog("Error while processing query received over DoH: %s", e.what()); + vinfolog("Error while processing query received over DoH: %s", e.what()); } catch (...) { - errlog("Unspecified error while processing query received over DoH"); + vinfolog("Unspecified error while processing query received over DoH"); } } } @@ -1298,7 +1298,7 @@ static void on_dnsdist(h2o_socket_t *listener, const char *err) dohUnit = std::move(*tmp); } catch (const std::exception& e) { - errlog("Error reading a DOH internal response: %s", e.what()); + warnlog("Error reading a DOH internal response: %s", e.what()); return; } diff --git a/pdns/tcpiohandler.cc b/pdns/tcpiohandler.cc index d0c82b69c95d..a5d00ed73ba8 100644 --- a/pdns/tcpiohandler.cc +++ b/pdns/tcpiohandler.cc @@ -1309,7 +1309,7 @@ class GnuTLSConnection: public TLSConnection else if (res == GNUTLS_E_AGAIN) { return IOState::NeedWrite; } - warnlog("Warning, non-fatal error while writing to TLS connection: %s", gnutls_strerror(res)); + vinfolog("Warning, non-fatal error while writing to TLS connection: %s", gnutls_strerror(res)); } } while (pos < toWrite); @@ -1345,7 +1345,7 @@ class GnuTLSConnection: public TLSConnection else if (res == GNUTLS_E_AGAIN) { return IOState::NeedRead; } - warnlog("Warning, non-fatal error while writing to TLS connection: %s", gnutls_strerror(res)); + vinfolog("Warning, non-fatal error while writing to TLS connection: %s", gnutls_strerror(res)); } } while (pos < toRead); From a3b9a6a749d8b37b879c880eff9e907cc5b060d5 Mon Sep 17 00:00:00 2001 From: phonedph1 <20867105+phonedph1@users.noreply.github.com> Date: Thu, 28 Sep 2023 08:34:47 -0600 Subject: [PATCH 758/909] Update tuning.rst --- pdns/dnsdistdist/docs/reference/tuning.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdistdist/docs/reference/tuning.rst b/pdns/dnsdistdist/docs/reference/tuning.rst index d00b14feb073..756dc8cb898c 100644 --- a/pdns/dnsdistdist/docs/reference/tuning.rst +++ b/pdns/dnsdistdist/docs/reference/tuning.rst @@ -163,13 +163,13 @@ Tuning related functions .. function:: setTCPRecvTimeout(num) - Set the read timeout on TCP connections from the client, in seconds + Set the read timeout on TCP connections from the client, in seconds. Defaults to 2 :param int num: .. function:: setTCPSendTimeout(num) - Set the write timeout on TCP connections from the client, in seconds + Set the write timeout on TCP connections from the client, in seconds. Defaults to 2 :param int num: From fb2921fc1d113311b1569588d97519970c7aafcb Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 28 Sep 2023 18:26:03 +0200 Subject: [PATCH 759/909] whitespace error --- pdns/recursordist/rec-zonetocache.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/rec-zonetocache.hh b/pdns/recursordist/rec-zonetocache.hh index 8d946cfd82d3..7243385cc114 100644 --- a/pdns/recursordist/rec-zonetocache.hh +++ b/pdns/recursordist/rec-zonetocache.hh @@ -39,7 +39,7 @@ public: TSIGTriplet d_tt; // Authentication data size_t d_maxReceivedBytes{0}; // Maximum size time_t d_retryOnError{60}; // Retry on error - time_t d_refreshPeriod{static_cast(24 *3600)}; // Time between refetch + time_t d_refreshPeriod{static_cast(24 * 3600)}; // Time between refetch uint32_t d_timeout{20}; // timeout in seconds pdns::ZoneMD::Config d_zonemd{pdns::ZoneMD::Config::Validate}; pdns::ZoneMD::Config d_dnssec{pdns::ZoneMD::Config::Validate}; From 6d43967e44e7ffe047e8eacc060c1873c4d3f3fa Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Fri, 29 Sep 2023 10:09:10 +0200 Subject: [PATCH 760/909] dnsdist kvs docs: fix typo --- .github/actions/spell-check/expect.txt | 1 - pdns/dnsdistdist/docs/reference/kvs.rst | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index fd2ba46eeedf..04155679ef24 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -1140,7 +1140,6 @@ redhat redjack reentrantly refman -refreh refuseds reid reimplementation diff --git a/pdns/dnsdistdist/docs/reference/kvs.rst b/pdns/dnsdistdist/docs/reference/kvs.rst index f39c5c6254ba..4381e6aebb7a 100644 --- a/pdns/dnsdistdist/docs/reference/kvs.rst +++ b/pdns/dnsdistdist/docs/reference/kvs.rst @@ -131,7 +131,7 @@ If the value found in the LMDB database for the key '\\8powerdns\\3com\\0' was ' .. versionadded:: 1.4.0 Return a new KeyValueStore object associated to the corresponding CDB database. The modification time - of the CDB file will be checked every 'refrehDelay' second and the database re-opened if needed. + of the CDB file will be checked every 'refreshDelay' second and the database re-opened if needed. :param string filename: The path to an existing CDB database :param int refreshDelays: The delay in seconds between two checks of the database modification time. 0 means disabled From 8959c0adf0f5be11c2c5dac1b86efe41881e81e1 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 29 Sep 2023 10:31:43 +0200 Subject: [PATCH 761/909] dnsdist: Display whether blocks are eBPF-based in `showDynBlocks()` --- pdns/dnsdist-lua.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index a3a9bf3bdc8d..db21d576a1a6 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -1401,15 +1401,15 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) auto slow = g_dynblockNMG.getCopy(); struct timespec now; gettime(&now); - boost::format fmt("%-24s %8d %8d %-10s %-20s %s\n"); - g_outputBuffer = (fmt % "What" % "Seconds" % "Blocks" % "Warning" % "Action" % "Reason").str(); + boost::format fmt("%-24s %8d %8d %-10s %-20s %-10s %s\n"); + g_outputBuffer = (fmt % "What" % "Seconds" % "Blocks" % "Warning" % "Action" % "eBPF" % "Reason").str(); for (const auto& e : slow) { if (now < e.second.until) { uint64_t counter = e.second.blocks; if (g_defaultBPFFilter && e.second.bpf) { counter += g_defaultBPFFilter->getHits(e.first.getNetwork()); } - g_outputBuffer += (fmt % e.first.toString() % (e.second.until.tv_sec - now.tv_sec) % counter % (e.second.warning ? "true" : "false") % DNSAction::typeToString(e.second.action != DNSAction::Action::None ? e.second.action : g_dynBlockAction) % e.second.reason).str(); + g_outputBuffer += (fmt % e.first.toString() % (e.second.until.tv_sec - now.tv_sec) % counter % (e.second.warning ? "true" : "false") % DNSAction::typeToString(e.second.action != DNSAction::Action::None ? e.second.action : g_dynBlockAction) % (g_defaultBPFFilter && e.second.bpf ? "*" : "") % e.second.reason).str(); } } auto slow2 = g_dynblockSMT.getCopy(); @@ -1418,7 +1418,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) string dom("empty"); if (!node.d_value.domain.empty()) dom = node.d_value.domain.toString(); - g_outputBuffer += (fmt % dom % (node.d_value.until.tv_sec - now.tv_sec) % node.d_value.blocks % (node.d_value.warning ? "true" : "false") % DNSAction::typeToString(node.d_value.action != DNSAction::Action::None ? node.d_value.action : g_dynBlockAction) % node.d_value.reason).str(); + g_outputBuffer += (fmt % dom % (node.d_value.until.tv_sec - now.tv_sec) % node.d_value.blocks % (node.d_value.warning ? "true" : "false") % DNSAction::typeToString(node.d_value.action != DNSAction::Action::None ? node.d_value.action : g_dynBlockAction) % "" % node.d_value.reason).str(); } }); }); From c7306f1464596b9bc6b4d3325d26b1d9d997b3c5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 29 Sep 2023 10:32:30 +0200 Subject: [PATCH 762/909] dnsdist: Log whether newly inserted dynamic blocks are eBPF-based --- pdns/dnsdistdist/dnsdist-dynblocks.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-dynblocks.cc b/pdns/dnsdistdist/dnsdist-dynblocks.cc index 9b7bee8ae3bd..928aff7f9b4a 100644 --- a/pdns/dnsdistdist/dnsdist-dynblocks.cc +++ b/pdns/dnsdistdist/dnsdist-dynblocks.cc @@ -261,7 +261,7 @@ void DynBlockRulesGroup::addOrRefreshBlock(boost::optional Date: Fri, 29 Sep 2023 10:33:29 +0200 Subject: [PATCH 763/909] dnsdist: Document that `add*DynBlocks()` methods are legacy ones --- pdns/dnsdistdist/docs/advanced/ebpf.rst | 25 +++++++++--- pdns/dnsdistdist/docs/guides/dynblocks.rst | 44 +++++++++++++++------- pdns/dnsdistdist/docs/reference/config.rst | 1 + pdns/dnsdistdist/docs/reference/ebpf.rst | 1 + 4 files changed, 52 insertions(+), 19 deletions(-) diff --git a/pdns/dnsdistdist/docs/advanced/ebpf.rst b/pdns/dnsdistdist/docs/advanced/ebpf.rst index 6d8f9c2a20d8..e50dfbf47258 100644 --- a/pdns/dnsdistdist/docs/advanced/ebpf.rst +++ b/pdns/dnsdistdist/docs/advanced/ebpf.rst @@ -59,8 +59,27 @@ Finally, it's also possible to attach it to specific binds at runtime:: > bd = getBind(0) > bd:attachFilter(bpf) -:program:`dnsdist` also supports adding dynamic, expiring blocks to a BPF filter:: +:program:`dnsdist` also supports adding dynamic, expiring blocks to a BPF filter: +.. code-block:: lua + + bpf = newBPFFilter({ipv4MaxItems=1024, ipv6MaxItems=1024, qnamesMaxItems=1024}) + setDefaultBPFFilter(bpf) + local dbr = dynBlockRulesGroup() + dbr:setQueryRate(20, 10, "Exceeded query rate", 60) + + function maintenance() + dbr:apply() + end + +This will dynamically block all hosts that exceeded 20 queries/s as measured over the past 10 seconds, and the dynamic block will last for 60 seconds. + +Since 1.6.0, the default BPF filter set via :func:`setDefaultBPFFilter` will automatically get used when a "drop" dynamic block is inserted via a :ref:`DynBlockRulesGroup`, which provides a better way to combine dynamic blocks with eBPF filtering. +Before that, it was possible to use the :func:`addBPFFilterDynBlocks` method instead: + +.. code-block:: lua + + -- this is a legacy method, please see above for DNSdist >= 1.6.0 bpf = newBPFFilter({ipv4MaxItems=1024, ipv6MaxItems=1024, qnamesMaxItems=1024}) setDefaultBPFFilter(bpf) dbpf = newDynBPFFilter(bpf) @@ -69,16 +88,12 @@ Finally, it's also possible to attach it to specific binds at runtime:: dbpf:purgeExpired() end -This will dynamically block all hosts that exceeded 20 queries/s as measured over the past 10 seconds, and the dynamic block will last for 60 seconds. - The dynamic eBPF blocks and the number of queries they blocked can be seen in the web interface and retrieved from the API. Note however that eBPF dynamic objects need to be registered before they appear in the web interface or the API, using the :func:`registerDynBPFFilter` function:: registerDynBPFFilter(dbpf) They can be unregistered at a later point using the :func:`unregisterDynBPFFilter` function. -Since 1.6.0, the default BPF filter set via :func:`setDefaultBPFFilter` will automatically get used when a "drop" dynamic block is inserted via a :ref:`DynBlockRulesGroup`, which provides a better way to combine dynamic blocks with eBPF filtering. - Requirements ------------ diff --git a/pdns/dnsdistdist/docs/guides/dynblocks.rst b/pdns/dnsdistdist/docs/guides/dynblocks.rst index a8958283c0b0..c987b0c69f5b 100644 --- a/pdns/dnsdistdist/docs/guides/dynblocks.rst +++ b/pdns/dnsdistdist/docs/guides/dynblocks.rst @@ -11,14 +11,28 @@ To set dynamic rules, based on recent traffic, define a function called :func:`m It will get called every second, and from this function you can set rules to block traffic based on statistics. More exactly, the thread handling the :func:`maintenance` function will sleep for one second between each invocation, so if the function takes several seconds to complete it will not be invoked exactly every second. -As an example:: +As an example: + +.. code-block:: lua + + local dbr = dynBlockRulesGroup() + dbr:setQueryRate(20, 10, "Exceeded query rate", 60) function maintenance() - addDynBlocks(exceedQRate(20, 10), "Exceeded query rate", 60) + dbr:apply() end This will dynamically block all hosts that exceeded 20 queries/s as measured over the past 10 seconds, and the dynamic block will last for 60 seconds. +:ref:`DynBlockRulesGroup` is a very efficient way of processing dynamic blocks that was introduced in 1.3.0. Before that, it was possible to use :meth:`addDynBlocks` instead: + +.. code-block:: lua + + -- this is a legacy method, please see above for DNSdist >= 1.3.0 + function maintenance() + addDynBlocks(exceedQRate(20, 10), "Exceeded query rate", 60) + end + Dynamic blocks in force are displayed with :func:`showDynBlocks` and can be cleared with :func:`clearDynBlocks`. They return a table whose key is a :class:`ComboAddress` object, representing the client's source address, and whose value is an integer representing the number of queries matching the corresponding condition (for example the qtype for :func:`exceedQTypeRate`, rcode for :func:`exceedServFails`). @@ -40,18 +54,6 @@ Starting with dnsdist 1.3.0, a new :ref:`dynBlockRulesGroup` function can be use designed to make the processing of multiple rate-limiting rules faster by walking the query and response buffers only once for each invocation, instead of once per existing `exceed*()` invocation. -For example, instead of having something like: - -.. code-block:: lua - - function maintenance() - addDynBlocks(exceedQRate(30, 10), "Exceeded query rate", 60) - addDynBlocks(exceedNXDOMAINs(20, 10), "Exceeded NXD rate", 60) - addDynBlocks(exceedServFails(20, 10), "Exceeded ServFail rate", 60) - addDynBlocks(exceedQTypeRate(DNSQType.ANY, 5, 10), "Exceeded ANY rate", 60) - addDynBlocks(exceedRespByterate(1000000, 10), "Exceeded resp BW rate", 60) - end - The new syntax would be: .. code-block:: lua @@ -67,6 +69,20 @@ The new syntax would be: dbr:apply() end +Before 1.3.0 the legacy syntax was: + +.. code-block:: lua + + function maintenance() + -- this example is using legacy methods, please see above for DNSdist >= 1.3.0 + addDynBlocks(exceedQRate(30, 10), "Exceeded query rate", 60) + addDynBlocks(exceedNXDOMAINs(20, 10), "Exceeded NXD rate", 60) + addDynBlocks(exceedServFails(20, 10), "Exceeded ServFail rate", 60) + addDynBlocks(exceedQTypeRate(DNSQType.ANY, 5, 10), "Exceeded ANY rate", 60) + addDynBlocks(exceedRespByterate(1000000, 10), "Exceeded resp BW rate", 60) + end + + The old syntax would walk the query buffer 2 times and the response one 3 times, while the new syntax does it only once for each. It also reuse the same internal table to keep track of the source IPs, reducing the CPU usage. diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 1b1743664654..cca41b76f00b 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -1382,6 +1382,7 @@ Dynamic Blocks Block a set of addresses with ``message`` for (optionally) a number of seconds. The default number of seconds to block for is 10. + Since 1.3.0, the use of a :ref:`DynBlockRulesGroup` is a much more efficient way of doing the same thing. :param addresses: set of Addresses as returned by an exceed function :param string message: The message to show next to the blocks diff --git a/pdns/dnsdistdist/docs/reference/ebpf.rst b/pdns/dnsdistdist/docs/reference/ebpf.rst index 99e508a8ff0a..6e5902f46f13 100644 --- a/pdns/dnsdistdist/docs/reference/ebpf.rst +++ b/pdns/dnsdistdist/docs/reference/ebpf.rst @@ -7,6 +7,7 @@ These are all the functions, objects and methods related to the :doc:`../advance This is the eBPF equivalent of :func:`addDynBlocks`, blocking a set of addresses for (optionally) a number of seconds, using an eBPF dynamic filter. The default number of seconds to block for is 10. + Since 1.6.0, the use of a :ref:`DynBlockRulesGroup` is a much more efficient way of doing the same thing. :param addresses: set of Addresses as returned by an :ref:`exceed function ` :param DynBPFFilter dynbpf: The dynamic eBPF filter to use From 6ea5cfefa8beed53c97b033f6301142a6ccb1f36 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Fri, 29 Sep 2023 05:07:33 -0400 Subject: [PATCH 764/909] spelling: below Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> --- docs/lua-records/reference/dnsresourcerecord.rst | 2 +- pdns/dnsdistdist/docs/rules-actions.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/lua-records/reference/dnsresourcerecord.rst b/docs/lua-records/reference/dnsresourcerecord.rst index dba9428cb663..a0810e444de0 100644 --- a/docs/lua-records/reference/dnsresourcerecord.rst +++ b/docs/lua-records/reference/dnsresourcerecord.rst @@ -24,7 +24,7 @@ Functions and methods of a ``DNSResourceRecord`` :param int domainId: The optional domain ID of the zone the record belongs to :param int auth: ? - .. todo complete LUA example bellow + .. todo complete LUA example below .. code-block:: lua name = newDN("www.example.org.") diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index 2dae14279294..9d5d6a46b896 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -962,7 +962,7 @@ The following actions exist. Removes given type(s) records from the response. Beware you can accidentally turn the answer into a NODATA response without a SOA record in the additional section in which case you may want to use :func:`NegativeAndSOAAction` to generate an answer, - see example bellow. + see example below. Subsequent rules are processed after this action. .. code-block:: Lua From f0eeb9b93f4c6cc4b610e7b54544b5f4aa35f763 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Fri, 29 Sep 2023 05:10:14 -0400 Subject: [PATCH 765/909] spelling: fine-grained Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> --- docs/changelog/4.2.rst | 2 +- pdns/recursordist/docs/changelog/4.1.rst | 2 +- pdns/recursordist/docs/changelog/4.9.rst | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/changelog/4.2.rst b/docs/changelog/4.2.rst index 731c8adf2c97..f15ebf31bb13 100644 --- a/docs/changelog/4.2.rst +++ b/docs/changelog/4.2.rst @@ -175,7 +175,7 @@ Changelogs for 4.2.x Compared to the last release candidate, one more bug has been fixed. - The LMDB backend is incomplete in this version. Slaving zones works, loading zones with pdnsutil works, but more fine grained edits (using edit-zone, or the REST API) fail. We hope to fix this soon in a 4.2.x release. + The LMDB backend is incomplete in this version. Slaving zones works, loading zones with pdnsutil works, but more fine-grained edits (using edit-zone, or the REST API) fail. We hope to fix this soon in a 4.2.x release. For an overview of features new since 4.1.x, please see `the 4.2.0 announcement blog post `__. diff --git a/pdns/recursordist/docs/changelog/4.1.rst b/pdns/recursordist/docs/changelog/4.1.rst index a547be8ec493..92d1b6a6f706 100644 --- a/pdns/recursordist/docs/changelog/4.1.rst +++ b/pdns/recursordist/docs/changelog/4.1.rst @@ -695,7 +695,7 @@ See :doc:`EOL Statements <../appendices/EOL>`. The full release notes can be read `on the blog `__. - This is a major release containing significant speedups (both in throughput and latency), enhanced capabilities and a highly conformant and robust DNSSEC validation implementation that is ready for heavy production use. In addition, our EDNS Client Subnet implementation now scales effortlessly to networks needing very fine grained scopes (as used by some ‘country sized’ service providers). + This is a major release containing significant speedups (both in throughput and latency), enhanced capabilities and a highly conformant and robust DNSSEC validation implementation that is ready for heavy production use. In addition, our EDNS Client Subnet implementation now scales effortlessly to networks needing very fine-grained scopes (as used by some ‘country sized’ service providers). - Improved DNSSEC support, - Improved documentation, diff --git a/pdns/recursordist/docs/changelog/4.9.rst b/pdns/recursordist/docs/changelog/4.9.rst index e0c7fc956b38..c33375c6e6eb 100644 --- a/pdns/recursordist/docs/changelog/4.9.rst +++ b/pdns/recursordist/docs/changelog/4.9.rst @@ -197,7 +197,7 @@ Changelogs for 4.9.X :tags: Improvements :pullreq: 12709 - More fine grained capping of packet cache TTL. + More fine-grained capping of packet cache TTL. .. change:: :tags: Bug Fixes From e5481242ef39033c6783386c155c7de331e71feb Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Fri, 29 Sep 2023 05:13:41 -0400 Subject: [PATCH 766/909] spelling: mac os x Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> --- docs/changelog/pre-4.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/changelog/pre-4.0.rst b/docs/changelog/pre-4.0.rst index d552634c210b..3a73eb4ddd73 100644 --- a/docs/changelog/pre-4.0.rst +++ b/docs/changelog/pre-4.0.rst @@ -5822,7 +5822,7 @@ Remaining issues Version 2.0 Release Candidate 1 ------------------------------- -The MacOS X release! A very experimental OS X 10.2 build has been added. +The Mac OS X release! A very experimental OS X 10.2 build has been added. Furthermore, the Windows version is now in line with Unix with respect to capabilities. The ODBC backend now has the code to function as both a master and a slave. From 112aaaa4e47fe3cbe42373e3e1ebba1482e153a0 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Fri, 29 Sep 2023 05:08:59 -0400 Subject: [PATCH 767/909] spelling: macos Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> --- docs/changelog/4.7.rst | 2 +- pdns/dnsdistdist/docs/changelog.rst | 2 +- pdns/recursordist/docs/changelog/4.6.rst | 2 +- pdns/recursordist/docs/changelog/4.8.rst | 2 +- pdns/recursordist/docs/getting-started.rst | 4 ++-- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/changelog/4.7.rst b/docs/changelog/4.7.rst index 341f0e18e35f..818e6e24d268 100644 --- a/docs/changelog/4.7.rst +++ b/docs/changelog/4.7.rst @@ -258,7 +258,7 @@ Changelogs for 4.7.x :tags: Improvements :pullreq: 12029 - clang14 has reached MacOS + clang14 has reached macOS .. change:: :tags: Improvements diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index 79778a8ae24d..949cfce92baf 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -2574,7 +2574,7 @@ Changelog :tags: Bug Fixes :pullreq: 9925 - Appease clang++ 12 ASAN on MacOS + Appease clang++ 12 ASAN on macOS .. change:: :tags: Improvements diff --git a/pdns/recursordist/docs/changelog/4.6.rst b/pdns/recursordist/docs/changelog/4.6.rst index 4372face88d1..30b9bc41dc4f 100644 --- a/pdns/recursordist/docs/changelog/4.6.rst +++ b/pdns/recursordist/docs/changelog/4.6.rst @@ -468,7 +468,7 @@ Changelogs for 4.6.X :pullreq: 10634 :tickets: 10631 - Move MacOS to kqueue event handler and assorted compile fixes. + Move macOS to kqueue event handler and assorted compile fixes. .. change:: :tags: Bug Fixes diff --git a/pdns/recursordist/docs/changelog/4.8.rst b/pdns/recursordist/docs/changelog/4.8.rst index a56030368355..4a2b20af91a8 100644 --- a/pdns/recursordist/docs/changelog/4.8.rst +++ b/pdns/recursordist/docs/changelog/4.8.rst @@ -472,7 +472,7 @@ Changelogs for 4.8.X :pullreq: 11857 :tickets: 11855 - Set ``rec_control_LDFLAGS``, needed for MacOS or any platforms where libcrypto is not in default lib path. + Set ``rec_control_LDFLAGS``, needed for macOS or any platforms where libcrypto is not in default lib path. .. change:: :tags: Improvements diff --git a/pdns/recursordist/docs/getting-started.rst b/pdns/recursordist/docs/getting-started.rst index 9a31549963cb..2e16bab51f3e 100644 --- a/pdns/recursordist/docs/getting-started.rst +++ b/pdns/recursordist/docs/getting-started.rst @@ -31,9 +31,9 @@ OpenBSD On OpenBSD, :program:`Recursor` is available through the `OpenBSD ports system `_. Run ``pkg_add powerdns-recursor`` as root to install. -MacOS +macOS ^^^^^ -On MacOS :program:`Recursor` is available through `brew `_. +On macOS :program:`Recursor` is available through `brew `_. Run ``brew install pdnsrec`` to install. Compiling From Source From 104099d4c82c8b5ad702d2f9c78f09fb138bf9d1 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Thu, 31 Aug 2023 11:54:03 -0400 Subject: [PATCH 768/909] Upgrade check-spelling to v0.0.22 Refresh metadata based on https://github.com/check-spelling/spell-check-this/tree/b968ca32e0e5961a85c7fe3e9431f81553c3f434/.github/actions/spelling --- .../actions/spell-check/candidate.patterns | 188 ++++++++++++++---- .github/actions/spell-check/expect.txt | 74 +------ .../spell-check/line_forbidden.patterns | 73 ++++++- .github/actions/spell-check/patterns.txt | 11 +- .github/actions/spell-check/reject.txt | 1 + .github/workflows/spelling3.yml | 26 ++- 6 files changed, 250 insertions(+), 123 deletions(-) diff --git a/.github/actions/spell-check/candidate.patterns b/.github/actions/spell-check/candidate.patterns index 5dcfee8b08e3..bf9dce0b1220 100644 --- a/.github/actions/spell-check/candidate.patterns +++ b/.github/actions/spell-check/candidate.patterns @@ -1,23 +1,36 @@ # marker to ignore all code on line ^.*/\* #no-spell-check-line \*/.*$ -# marker for ignoring a comment to the end of the line -// #no-spell-check.*$ +# marker to ignore all code on line +^.*\bno-spell-check(?:-line|)(?:\s.*|)$ + +# https://cspell.org/configuration/document-settings/ +# cspell inline +^.*\b[Cc][Ss][Pp][Ee][Ll]{2}:\s*[Dd][Ii][Ss][Aa][Bb][Ll][Ee]-[Ll][Ii][Nn][Ee]\b # patch hunk comments ^\@\@ -\d+(?:,\d+|) \+\d+(?:,\d+|) \@\@ .* # git index header -index [0-9a-z]{7,40}\.\.[0-9a-z]{7,40} +index (?:[0-9a-z]{7,40},|)[0-9a-z]{7,40}\.\.[0-9a-z]{7,40} + +# file permissions +['"`\s][-bcdLlpsw](?:[-r][-w][-Ssx]){2}[-r][-w][-SsTtx]\+?['"`\s] + +# css url wrappings +#\burl\([^)]+\) # cid urls (['"])cid:.*?\g{-1} # data url in parens -\(data:[^)]*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\) +\(data:(?:[^) ][^)]*?|)(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,})[^)]*\) # data url in quotes -([`'"])data:.*?(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\g{-1} +([`'"])data:(?:[^ `'"].*?|)(?:[A-Z]{3,}|[A-Z][a-z]{2,}|[a-z]{3,}).*\g{-1} # data url data:[-a-zA-Z=;:/0-9+]*,\S* +# https/http/file urls +#(?:\b(?:https?|ftp|file)://)[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|] + # mailto urls mailto:[-a-zA-Z=;:/?%&0-9+@.]{3,} @@ -35,6 +48,9 @@ magnet:[?=:\w]+ # asciinema \basciinema\.org/a/[0-9a-zA-Z]+ +# asciinema v2 +^\[\d+\.\d+, "[io]", ".*"\]$ + # apple \bdeveloper\.apple\.com/[-\w?=/]+ # Apple music @@ -89,7 +105,7 @@ vpc-\w+ # Google Drive \bdrive\.google\.com/(?:file/d/|open)[-0-9a-zA-Z_?=]* # Google Groups -\bgroups\.google\.com/(?:(?:forum/#!|d/)(?:msg|topics?|searchin)|a)/[^/\s"]+/[-a-zA-Z0-9$]+(?:/[-a-zA-Z0-9]+)* +\bgroups\.google\.com(?:/[a-z]+/(?:#!|)[^/\s"]+)* # Google Maps \bmaps\.google\.com/maps\?[\w&;=]* # Google themes @@ -117,6 +133,8 @@ themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+. (?:\[`?[0-9a-f]+`?\]\(https:/|)/(?:www\.|)github\.com(?:/[^/\s"]+){2,}(?:/[^/\s")]+)(?:[0-9a-f]+(?:[-0-9a-zA-Z/#.]*|)\b|) # GitHub SHAs \bgithub\.com(?:/[^/\s"]+){2}[@#][0-9a-f]+\b +# GitHub SHA refs +\[([0-9a-f]+)\]\(https://(?:www\.|)github.com/[-\w]+/[-\w]+/commit/\g{-1}[0-9a-f]* # GitHub wiki \bgithub\.com/(?:[^/]+/){2}wiki/(?:(?:[^/]+/|)_history|[^/]+(?:/_compare|)/[0-9a-f.]{40,})\b # githubusercontent @@ -128,9 +146,9 @@ themes\.googleusercontent\.com/static/fonts/[^/\s"]+/v\d+/[^.]+. # git.io \bgit\.io/[0-9a-zA-Z]+ # GitHub JSON -"node_id": "[-a-zA-Z=;:/0-9+]*" +"node_id": "[-a-zA-Z=;:/0-9+_]*" # Contributor -\[[^\]]+\]\(https://github\.com/[^/\s"]+\) +\[[^\]]+\]\(https://github\.com/[^/\s"]+/?\) # GHSA GHSA(?:-[0-9a-z]{4}){3} @@ -143,8 +161,8 @@ GHSA(?:-[0-9a-z]{4}){3} # GitLab commits \bgitlab\.[^/\s"]*/(?:[^/\s"]+/){2}commits?/[0-9a-f]+\b -# binanace -accounts.binance.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]* +# binance +accounts\.binance\.com/[a-z/]*oauth/authorize\?[-0-9a-zA-Z&%]* # bitbucket diff \bapi\.bitbucket\.org/\d+\.\d+/repositories/(?:[^/\s"]+/){2}diff(?:stat|)(?:/[^/\s"]+){2}:[0-9a-f]+ @@ -280,9 +298,9 @@ slack://[a-zA-Z0-9?&=]+ \bdropbox\.com/sh?/[^/\s"]+/[-0-9A-Za-z_.%?=&;]+ # ipfs protocol -ipfs://[0-9a-z]* +ipfs://[0-9a-zA-Z]{3,} # ipfs url -/ipfs/[0-9a-z]* +/ipfs/[0-9a-zA-Z]{3,} # w3 \bw3\.org/[-0-9a-zA-Z/#.]+ @@ -308,6 +326,12 @@ ipfs://[0-9a-z]* # Wikipedia \ben\.wikipedia\.org/wiki/[-\w%.#]+ +# Contributors with non-ascii characters in their name +Hoffst[^[:ascii:]]+tte +Gri[^[:ascii:]] +Lundstr[^[:ascii:]]+m +Joaqu[^[:ascii:]]n + # gitweb [^"\s]+/gitweb/\S+;h=[0-9a-f]+ @@ -359,14 +383,22 @@ ipfs://[0-9a-z]* # tinyurl \btinyurl\.com/\w+ +# codepen +\bcodepen\.io/[\w/]+ + +# registry.npmjs.org +\bregistry\.npmjs\.org/(?:@[^/"']+/|)[^/"']+/-/[-\w@.]+ + # getopts \bgetopts\s+(?:"[^"]+"|'[^']+') # ANSI color codes -(?:\\(?:u00|x)1b|\x1b)\[\d+(?:;\d+|)m +(?:\\(?:u00|x)1[Bb]|\x1b|\\u\{1[Bb]\})\[\d+(?:;\d+|)m # URL escaped characters \%[0-9A-F][A-F] +# lower URL escaped characters +\%[0-9a-f][a-f](?=[a-z]{2,}) # IPv6 \b(?:[0-9a-fA-F]{0,4}:){3,7}[0-9a-fA-F]{0,4}\b # c99 hex digits (not the full format, just one I've seen) @@ -376,7 +408,7 @@ ipfs://[0-9a-z]* # sha sha\d+:[0-9]*[a-f]{3,}[0-9a-f]* # sha-... -- uses a fancy capture -(['"]|")[0-9a-f]{40,}\g{-1} +(\\?['"]|")[0-9a-f]{40,}\g{-1} # hex runs \b[0-9a-fA-F]{16,}\b # hex in url queries @@ -391,18 +423,21 @@ sha\d+:[0-9]*[a-f]{3,}[0-9a-f]* # Well known gpg keys .well-known/openpgpkey/[\w./]+ +# pki +-----BEGIN.*-----END + # uuid: \b[0-9a-fA-F]{8}-(?:[0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}\b # hex digits including css/html color classes: -(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|u\d+)\b +(?:[\\0][xX]|\\u|[uU]\+|#x?|\%23)[0-9_a-fA-FgGrR]*?[a-fA-FgGrR]{2,}[0-9_a-fA-FgGrR]*(?:[uUlL]{0,3}|[iu]\d+)\b # integrity -integrity="sha\d+-[-a-zA-Z=;:/0-9+]{40,}" +integrity=(['"])(?:\s*sha\d+-[-a-zA-Z=;:/0-9+]{40,})+\g{-1} # https://www.gnu.org/software/groff/manual/groff.html # man troff content \\f[BCIPR] -# ' -\\\(aq +# '/" +\\\([ad]q # .desktop mime types ^MimeTypes?=.*$ @@ -411,21 +446,33 @@ integrity="sha\d+-[-a-zA-Z=;:/0-9+]{40,}" # Localized .desktop content Name\[[^\]]+\]=.* -# IServiceProvider -#\bI(?=(?:[A-Z][a-z]{2,})+\b) +# IServiceProvider / isAThing +#\b(?:I|isA)(?=(?:[A-Z][a-z]{2,})+\b) # crypt -"\$2[ayb]\$.{56}" +(['"])\$2[ayb]\$.{56}\g{-1} # scrypt / argon \$(?:scrypt|argon\d+[di]*)\$\S+ +# go.sum +#\bh1:\S+ + +# scala modules +("[^"]+"\s*%%?\s*){2,3}"[^"]+" + # Input to GitHub JSON -content: "[-a-zA-Z=;:/0-9+]*=" +content: (['"])[-a-zA-Z=;:/0-9+]*=\g{-1} -# Python stringprefix / binaryprefix +# This does not cover multiline strings, if your repository has them, +# you'll want to remove the `(?=.*?")` suffix. +# The `(?=.*?")` suffix should limit the false positives rate +# printf +%(?:(?:(?:hh?|ll?|[jzt])?[diuoxn]|l?[cs]|L?[fega]|p)(?=[a-z]{2,})|(?:X|L?[FEGA]|p)(?=[a-zA-Z]{2,}))(?=[_a-zA-Z]+\b)(?!%)(?=.*?['"]) + +# Python string prefix / binary prefix # Note that there's a high false positive rate, remove the `?=` and search for the regex to see if the matches seem like reasonable strings -(?|m([|!/@#,;']).*?\g{-1}) + +# perl qr regex +(?|\(.*?\)|([|!/@#,;']).*?\g{-1}) # Go regular expressions regexp?\.MustCompile\(`[^`]*`\) +# regex choice +\(\?:[^)]+\|[^)]+\) + +# proto +^\s*(\w+)\s\g{-1} = + # sed regular expressions sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2} +# node packages +(["'])\@[^/'" ]+/[^/'" ]+\g{-1} + # go install go install(?:\s+[a-z]+\.[-@\w/.]+)+ @@ -462,19 +525,47 @@ go install(?:\s+[a-z]+\.[-@\w/.]+)+ -[0-9a-f]{10}-\w{5}\s # posthog secrets -posthog\.init\((['"])phc_[^"',]+\g{-1}, +([`'"])phc_[^"',]+\g{-1} # xcode # xcodeproject scenes -(?:Controller|ID|id)="\w{3}-\w{2}-\w{3}" +(?:Controller|destination|ID|id)="\w{3}-\w{2}-\w{3}" # xcode api botches customObjectInstantitationMethod +# configure flags +.* \| --\w{2,}.*?(?=\w+\s\w+) + # font awesome classes \.fa-[-a-z0-9]+ +# bearer auth +(['"])Bear[e][r] .*?\g{-1} + +# basic auth +(['"])Basic [-a-zA-Z=;:/0-9+]{3,}\g{-1} + +# base64 encoded content +([`'"])[-a-zA-Z=;:/0-9+]+==\g{-1} +# base64 encoded content in xml/sgml +>[-a-zA-Z=;:/0-9+]+== 0.0.22) +\\\w{2,}\{ + +# eslint +"varsIgnorePattern": ".+" + +# Windows short paths +[/\\][^/\\]{5,6}~\d{1,2}[/\\] + +# in a version of check-spelling after @0.0.21 printf markers won't be automatically consumed +# printf markers +(?v# (?:(?<=[A-Z]{2})V|(?<=[a-z]{2}|[A-Z]{2})v)\d+(?:\b|(?=[a-zA-Z_])) -# Compiler flags (Scala) -(?:^|[\t ,>"'`=(])-J-[DPWXY](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,}) -# Compiler flags -#(?:^|[\t ,"'`=(])-[DPWXYLlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,}) + +# Compiler flags (Unix, Java/Scala) +# Use if you have things like `-Pdocker` and want to treat them as `docker` +#(?:^|[\t ,>"'`=(])-(?:(?:J-|)[DPWXY]|[Llf])(?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,}) + +# Compiler flags (Windows / PowerShell) +# This is a subset of the more general compiler flags pattern. +# It avoids matching `-Path` to prevent it from being treated as `ath` +#(?:^|[\t ,"'`=(])-(?:[DPL](?=[A-Z]{2,})|[WXYlf](?=[A-Z]{2,}|[A-Z][a-z]|[a-z]{2,})) # Compiler flags (linker) ,-B + # curl arguments \b(?:\\n|)curl(?:\s+-[a-zA-Z]{1,2}\b)*(?:\s+-[a-zA-Z]{3,})(?:\s+-[a-zA-Z]+)* # set arguments diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index fd2ba46eeedf..84780bfea211 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -1,6 +1,5 @@ aaaarecord aaldering -abi aborttransaction Abraitis ACLTo @@ -26,7 +25,6 @@ alexa algoroll allocs Altpeter -amd Anderton anewid anid @@ -53,8 +51,6 @@ Ascio Asenov ASEP Ashish -asnum -aspx associateddomain asyncresolve Atlassian @@ -175,7 +171,6 @@ cds Cegetel Cerb certusage -CFLAGS CGNAT changeme changetype @@ -191,13 +186,13 @@ Cloos closesocket clusions cmouse -cmsg cmsghdr -cname +cmsgs cnamechainresolution CNAMEd CNAMEDNS cnamerecord +cnames cnf cnn cockroachlabs @@ -215,12 +210,10 @@ conaxis configfile configname configsetting -configurability confs conntrack Conntracking Consolas -constexpr controllen controlsocket coprocess @@ -231,7 +224,6 @@ corpit costypetrisor coverity cppcheck -createdb createslavedomain Cremers criteo @@ -266,7 +258,6 @@ dbfile dblfilename dbpf dbr -DBX dcobject ddns deactivatedomainkey @@ -279,7 +270,6 @@ defpol defttl Dehaine DENIC -deref descclassname descname Dessel @@ -299,7 +289,6 @@ dilinger Dimitrios Directi Disqus -distro djbdns dlerror dlg @@ -321,7 +310,6 @@ dnsdomain dnsext dnsgram dnskey -dnsmessage dnsname dnsnameset dnsop @@ -348,9 +336,7 @@ dnszone Dobrawy docdefault docnamecachelookup -documentclass documentwrapper -dofile Dohmen domaininfo domainmetadata @@ -386,7 +372,6 @@ ech econds ECSDA ecswho -EDE editline edns ednsbufsiz @@ -398,7 +383,6 @@ edu ejones Ekkelenkamp elgoog -Emph Enden ent envoutput @@ -421,7 +405,6 @@ ezdns Faerch failedservers farsightsec -fcgi fcontext fedoraproject feedents @@ -436,7 +419,6 @@ firewalled firewalls fixednow Florus -fontname footerbgcolor footertextcolor forfun @@ -463,7 +445,6 @@ gaba gacogne gatech Gavarret -gcc gdpr Geijn genindex @@ -482,7 +463,6 @@ getcarbonhostname getdomaininfo getdomainkeys getdomainmetadata -gethostname getifaddrs getlocaladdress getn @@ -490,7 +470,6 @@ getrandom getregisteredname gettag gettime -gettimeofday gettsigkey Geuze GFm @@ -522,7 +501,6 @@ gsql gsqlite gss gssapi -gsub gtld guilabel Gyselinck @@ -559,7 +537,6 @@ Houtworm howto hpecorp hpiers -hpp htbp htmlescape htmlhelp @@ -568,17 +545,14 @@ httpdomain hubert iana icann -ico ict idprotect -idx iers ietf ifportup ifurlextup ifurlup ihsinme -illumos Imhard incbin includeboilerplate @@ -602,11 +576,11 @@ ipencrypt ipfilter IPSECKEY iputils +irc isane ismaster isoc -isp -ispell +ISPs isql ixfr ixfrdist @@ -622,7 +596,6 @@ Jelte Jermar Jeroen jessie -Joaqu jonathaneen Jong Jorn @@ -642,7 +615,6 @@ Kerkhof KEYBITS keyblock keydir -keyfile keyname keypair keypairgen @@ -704,7 +676,6 @@ letterpaper libatomic libcrypto libcryptopp -libcurl libdecaf libdir libedit @@ -779,7 +750,6 @@ malcrafted mallocs malware Mamane -manpages mapasync Mapbox mariadb @@ -815,7 +785,6 @@ Milas Mimimization minbody mindex -MINFO minipatch Mischan mjt @@ -861,7 +830,6 @@ mysqld myuser mywebapp namedroppers -nameserver nameserving naptr Nauck @@ -898,7 +866,6 @@ noaction noad noall nocookie -NODELAY noedns noerrors NOLOCK @@ -912,7 +879,6 @@ noout noping noport norve -nosniff nostrip NOSUBDIR nosync @@ -950,7 +916,6 @@ obidos objectclass Obser obspm -odbc odbcbackend odbcinst Oddy @@ -966,6 +931,7 @@ opendbx openpgpkey openports opensc +opensuse openwall Opmeer OPNUM @@ -992,8 +958,6 @@ packethandler papersize paramater PARAMKEYWORDS -passthrough -passthru PATC patchlevels pathconfig @@ -1023,7 +987,6 @@ pgmysql pgmysqlbackend pgp pgpsql -pgsql phishing phonedph pickclosest @@ -1071,9 +1034,7 @@ PRId primetime princ prioritization -privatekey privs -progid protobuf protozero providername @@ -1084,7 +1045,6 @@ pseudonymize pseudorecord pthread ptrrecord -ptrs Publieke publishdomainkey pullreq @@ -1097,7 +1057,6 @@ qlen Qlim qname qperq -qps QPSIP qpslimits QRate @@ -1161,7 +1120,7 @@ removedomainkey replacerrset requery resolv -respawn +respawned respawning respout respsizes @@ -1170,6 +1129,7 @@ retransfering reuseds reuseport RFCs +rhel Rietz rightsidebar Rijsdijk @@ -1181,13 +1141,11 @@ rocommunity Roel Rosmalen roundrobin -RPATH rping rpms rpz rpzstatistics rrcontent -rrd rrdata rrdtool rrname @@ -1250,7 +1208,6 @@ shnya showdetails showflags Shukla -sid sidebarbgcolor sidebarbtncolor sidebarbutton @@ -1267,7 +1224,6 @@ Signingpiper signpipe signttl signzone -sigs singlethreaded Sipek siphash @@ -1282,8 +1238,6 @@ smn Smurthwaite Snarked sndbuf -snmp -snmpd snprintf soa soadata @@ -1317,7 +1271,6 @@ srandom srcname SRecord Srule -srv sshfp ssi SSQ @@ -1342,12 +1295,10 @@ Storesund stou strcasestr stringmatch -strpos stubquery stubresolver Stussy stutiredboy -subdomain subkey submitters subnetmask @@ -1390,7 +1341,6 @@ tds teeaction Telenet testsdir -textcolor Tful thel thelog @@ -1418,7 +1368,6 @@ toctree todos toint tokenuser -tolower Tolstov Toosarani Toshifumi @@ -1429,7 +1378,6 @@ trusteer trx trxid TSAN -tsc tsig tsigalgo tsigkey @@ -1446,7 +1394,6 @@ Tushuizen Tuxis TVJRU tylerneylon -typedefs typenames ualberta udpqueryresponse @@ -1457,7 +1404,6 @@ UIDs Uisms unauth unbreak -uncached unescaping unfresh unhash @@ -1480,10 +1426,8 @@ upgradeable upperalpha upperroman urandom -usec usecase userbase -userspace uwaterloo Valentei Valentini @@ -1532,7 +1476,6 @@ Wielicki Wijk Wijnand Wijngaards -wikipedia wil wildcarded Willcott @@ -1543,7 +1486,7 @@ wirelength Wisiol wmem Wojas -workaround +workarounds Worldnic would've wouter @@ -1571,7 +1514,6 @@ Yehuda yeswehack Yiu Ylitalo -yml YMMV Yogesh yourcompany diff --git a/.github/actions/spell-check/line_forbidden.patterns b/.github/actions/spell-check/line_forbidden.patterns index 9050d6614c78..df82a713d0ca 100644 --- a/.github/actions/spell-check/line_forbidden.patterns +++ b/.github/actions/spell-check/line_forbidden.patterns @@ -1,4 +1,6 @@ -# reject `m_data` as there's a certain OS which has evil defines that break things if it's used elsewhere +# reject `m_data` as VxWorks defined it and that breaks things if it's used elsewhere +# see [fprime](https://github.com/nasa/fprime/commit/d589f0a25c59ea9a800d851ea84c2f5df02fb529) +# and [Qt](https://github.com/qtproject/qt-solutions/blame/fb7bc42bfcc578ff3fa3b9ca21a41e96eb37c1c7/qtscriptclassic/src/qscriptbuffer_p.h#L46) # \bm_data\b # If you have a framework that uses `it()` for testing and `fit()` for debugging a specific test, @@ -6,40 +8,72 @@ # to use this: #\bfit\( +# s.b. anymore +\bany more[,.] + # s.b. GitHub -\bGithub\b +(? Date: Fri, 29 Sep 2023 11:33:01 +0200 Subject: [PATCH 769/909] rec: more log (level) fixes Found while working on a list --- pdns/recursordist/lua-recursor4.cc | 10 +++++++--- pdns/recursordist/pdns_recursor.cc | 8 ++++---- pdns/recursordist/pubsuffixloader.cc | 2 +- pdns/recursordist/rec-lua-conf.cc | 6 ++---- pdns/recursordist/rec-taskqueue.cc | 18 +++++++++--------- pdns/recursordist/rec-tcp.cc | 2 +- pdns/recursordist/syncres.cc | 20 ++++++++++---------- pdns/unix_utility.cc | 4 ++-- 8 files changed, 36 insertions(+), 34 deletions(-) diff --git a/pdns/recursordist/lua-recursor4.cc b/pdns/recursordist/lua-recursor4.cc index 04c538025cd5..6ba031e9e14a 100644 --- a/pdns/recursordist/lua-recursor4.cc +++ b/pdns/recursordist/lua-recursor4.cc @@ -22,6 +22,7 @@ #include "lua-recursor4.hh" #include #include "logger.hh" +#include "logging.hh" #include "dnsparser.hh" #include "syncres.hh" #include "namespaces.hh" @@ -346,7 +347,8 @@ void RecursorLua4::postPrepareContext() } } catch(std::exception& e) { - g_log <withName("lua")->error(Logr::Error, e.what(), "Error in call to DNSSuffixMatchGroup:add")); } } ); @@ -501,7 +503,8 @@ void RecursorLua4::getFeatures(Features& features) static void warnDrop(const RecursorLua4::DNSQuestion& dq) { if (dq.rcode == -2) { - g_log << Logger::Error << "Returning -2 (pdns.DROP) is not supported anymore, see https://docs.powerdns.com/recursor/lua-scripting/hooks.html#hooksemantics" << endl; + SLOG(g_log << Logger::Error << "Returning -2 (pdns.DROP) is not supported anymore, see https://docs.powerdns.com/recursor/lua-scripting/hooks.html#hooksemantics" << endl, + g_slog->withName("lua")->info(Logr::Error,"Returning -2 (pdns.DROP) is not supported anymore, see https://docs.powerdns.com/recursor/lua-scripting/hooks.html#hooksemantics")); // We *could* set policy here, but that would also mean interfering with rcode and the return code of the hook. // So leave it at the error message. } @@ -744,7 +747,8 @@ bool RecursorLua4::genhook(const luacall_t& func, DNSQuestion& dq, int& ret) con dq.udpAnswer = std::string(reinterpret_cast(p.data()), p.size()); auto cbFunc = d_lw->readVariable>(dq.udpCallback).get_value_or(0); if (!cbFunc) { - g_log << Logger::Error << "Attempted callback for Lua UDP Query/Response which could not be found" << endl; + SLOG(g_log << Logger::Error << "Attempted callback for Lua UDP Query/Response which could not be found" << endl, + g_slog->withName("lua")->info(Logr::Error, "Attempted callback for Lua UDP Query/Response which could not be found")); return false; } bool result = cbFunc(&dq); diff --git a/pdns/recursordist/pdns_recursor.cc b/pdns/recursordist/pdns_recursor.cc index 3eafd3f69c2d..6ecbce1b78ec 100644 --- a/pdns/recursordist/pdns_recursor.cc +++ b/pdns/recursordist/pdns_recursor.cc @@ -1882,7 +1882,7 @@ void startDoResolve(void* arg) // NOLINT(readability-function-cognitive-complexi } catch (const std::exception& e) { SLOG(g_log << Logger::Error << "STL error " << makeLoginfo(comboWriter) << ": " << e.what(), - resolver.d_slog->error(Logr::Error, e.what(), "Exception in resolver context ", "exception", Logging::Loggable("std::exception"))); + resolver.d_slog->error(Logr::Error, e.what(), "Exception in resolver context", "exception", Logging::Loggable("std::exception"))); // Luawrapper nests the exception from Lua, so we unnest it here try { @@ -2624,8 +2624,8 @@ void makeUDPServerSockets(deferredAdd_t& deferredAdds, Logr::log_t log) #endif if (address.sin6.sin6_family == AF_INET6 && setsockopt(socketFd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one)) < 0) { int err = errno; - SLOG(g_log << Logger::Error << "Failed to set IPv6 socket to IPv6 only, continuing anyhow: " << stringerror(err) << endl, - log->error(Logr::Error, "Failed to set IPv6 socket to IPv6 only, continuing anyhow")); + SLOG(g_log << Logger::Warning << "Failed to set IPv6 socket to IPv6 only, continuing anyhow: " << stringerror(err) << endl, + log->error(Logr::Warning, "Failed to set IPv6 socket to IPv6 only, continuing anyhow")); } } if (::arg().mustDo("non-local-bind")) { @@ -2755,7 +2755,7 @@ void distributeAsyncFunction(const string& packet, const pipefunc_t& func) { if (!RecThreadInfo::self().isDistributor()) { SLOG(g_log << Logger::Error << "distributeAsyncFunction() has been called by a worker (" << RecThreadInfo::id() << ")" << endl, - g_slog->info(Logr::Error, "distributeAsyncFunction() has been called by a worker")); // tid will be added + g_slog->withName("runtime")->info(Logr::Error, "distributeAsyncFunction() has been called by a worker")); // tid will be added _exit(1); } diff --git a/pdns/recursordist/pubsuffixloader.cc b/pdns/recursordist/pubsuffixloader.cc index ea8b9908d00f..3d413d66c9a3 100644 --- a/pdns/recursordist/pubsuffixloader.cc +++ b/pdns/recursordist/pubsuffixloader.cc @@ -73,7 +73,7 @@ void initPublicSuffixList(const std::string& file) } catch (const std::exception& e) { SLOG(g_log << Logger::Warning << "Error while loading the Public Suffix List from '" << file << "', falling back to the built-in list: " << e.what() << endl, - g_slog->withName("runtime")->error(Logr::Error, e.what(), "Loaded the Public Suffix List", "file", Logging::Loggable(file))); + g_slog->withName("runtime")->error(Logr::Error, e.what(), "Error while loading the Public Suffix List", "file", Logging::Loggable(file))); } } diff --git a/pdns/recursordist/rec-lua-conf.cc b/pdns/recursordist/rec-lua-conf.cc index ec169e454421..96d12941705d 100644 --- a/pdns/recursordist/rec-lua-conf.cc +++ b/pdns/recursordist/rec-lua-conf.cc @@ -377,13 +377,11 @@ static void rpzPrimary(LuaConfigItems& lci, luaConfigDelayedThreads& delayedThre } catch (const std::exception& e) { SLOG(g_log << Logger::Error << "Problem configuring 'rpzPrimary': " << e.what() << endl, - lci.d_slog->error(Logr::Critical, e.what(), "Exception configuring 'rpzPrimary'", "exception", Logging::Loggable("std::exception"))); - exit(1); // FIXME proper exit code? + lci.d_slog->error(Logr::Error, e.what(), "Exception configuring 'rpzPrimary'", "exception", Logging::Loggable("std::exception"))); } catch (const PDNSException& e) { SLOG(g_log << Logger::Error << "Problem configuring 'rpzPrimary': " << e.reason << endl, - lci.d_slog->error(Logr::Critical, e.reason, "Exception configuring 'rpzPrimary'", Logging::Loggable("PDNSException"))); - exit(1); // FIXME proper exit code? + lci.d_slog->error(Logr::Error, e.reason, "Exception configuring 'rpzPrimary'", Logging::Loggable("PDNSException"))); } delayedThreads.rpzPrimaryThreads.emplace_back(primaries, defpol, defpolOverrideLocal, maxTTL, zoneIdx, tt, maxReceivedXFRMBytes, localAddress, axfrTimeout, refresh, sr, dumpFile); diff --git a/pdns/recursordist/rec-taskqueue.cc b/pdns/recursordist/rec-taskqueue.cc index 9997991455b4..b5dba064dfa4 100644 --- a/pdns/recursordist/rec-taskqueue.cc +++ b/pdns/recursordist/rec-taskqueue.cc @@ -134,23 +134,23 @@ static void resolveInternal(const struct timeval& now, bool logErrors, const pdn log->info(Logr::Debug, "done", "rcode", Logging::Loggable(res), "records", Logging::Loggable(ret.size())); } catch (const std::exception& e) { - log->error(Logr::Error, msg, e.what()); + log->error(Logr::Warning, msg, e.what()); } catch (const PDNSException& e) { - log->error(Logr::Error, msg, e.reason); + log->error(Logr::Warning, msg, e.reason); } catch (const ImmediateServFailException& e) { if (logErrors) { - log->error(Logr::Error, msg, e.reason); + log->error(Logr::Warning, msg, e.reason); } } catch (const PolicyHitException& e) { if (logErrors) { - log->error(Logr::Notice, msg, "PolicyHit"); + log->error(Logr::Warning, msg, "PolicyHit"); } } catch (...) { - log->error(Logr::Error, msg, "Unexpectec exception"); + log->error(Logr::Warning, msg, "Unexpectec exception"); } if (exceptionOccurred) { if (task.d_refreshMode) { @@ -195,14 +195,14 @@ static void tryDoT(const struct timeval& now, bool logErrors, const pdns::Resolv log->info(Logr::Debug, "done", "ok", Logging::Loggable(tryOK)); } catch (const std::exception& e) { - log->error(Logr::Error, msg, e.what()); + log->error(Logr::Warning, msg, e.what()); } catch (const PDNSException& e) { - log->error(Logr::Error, msg, e.reason); + log->error(Logr::Warning, msg, e.reason); } catch (const ImmediateServFailException& e) { if (logErrors) { - log->error(Logr::Error, msg, e.reason); + log->error(Logr::Warning, msg, e.reason); } } catch (const PolicyHitException& e) { @@ -211,7 +211,7 @@ static void tryDoT(const struct timeval& now, bool logErrors, const pdns::Resolv } } catch (...) { - log->error(Logr::Error, msg, "Unexpected exception"); + log->error(Logr::Warning, msg, "Unexpected exception"); } if (exceptionOccurred) { ++s_resolve_tasks.exceptions; diff --git a/pdns/recursordist/rec-tcp.cc b/pdns/recursordist/rec-tcp.cc index ca3c3b3e3687..7d1a8bb3d103 100644 --- a/pdns/recursordist/rec-tcp.cc +++ b/pdns/recursordist/rec-tcp.cc @@ -1114,7 +1114,7 @@ void makeTCPServerSockets(deferredAdd_t& deferredAdds, std::set& tcpSockets if (address.sin6.sin6_family == AF_INET6 && setsockopt(socketFd, IPPROTO_IPV6, IPV6_V6ONLY, &tmp, sizeof(tmp)) < 0) { int err = errno; SLOG(g_log << Logger::Error << "Failed to set IPv6 socket to IPv6 only, continuing anyhow: " << stringerror(err) << endl, - log->error(Logr::Error, err, "Failed to set IPv6 socket to IPv6 only, continuing anyhow")); + log->error(Logr::Warning, err, "Failed to set IPv6 socket to IPv6 only, continuing anyhow")); } #ifdef TCP_DEFER_ACCEPT diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 8e8819fb7c26..253058ecacd9 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -5897,28 +5897,28 @@ int directResolve(const DNSName& qname, const QType qtype, const QClass qclass, res = sr.beginResolve(qname, qtype, qclass, ret, 0); } catch (const PDNSException& e) { - SLOG(g_log << Logger::Error << "Failed to resolve " << qname << ", got pdns exception: " << e.reason << endl, - log->error(Logr::Error, e.reason, msg, "exception", Logging::Loggable("PDNSException"))); + SLOG(g_log << Logger::Warning << "Failed to resolve " << qname << ", got pdns exception: " << e.reason << endl, + log->error(Logr::Warning, e.reason, msg, "exception", Logging::Loggable("PDNSException"))); ret.clear(); } catch (const ImmediateServFailException& e) { - SLOG(g_log << Logger::Error << "Failed to resolve " << qname << ", got ImmediateServFailException: " << e.reason << endl, - log->error(Logr::Error, e.reason, msg, "exception", Logging::Loggable("ImmediateServFailException"))); + SLOG(g_log << Logger::Warning << "Failed to resolve " << qname << ", got ImmediateServFailException: " << e.reason << endl, + log->error(Logr::Warning, e.reason, msg, "exception", Logging::Loggable("ImmediateServFailException"))); ret.clear(); } catch (const PolicyHitException& e) { - SLOG(g_log << Logger::Error << "Failed to resolve " << qname << ", got a policy hit" << endl, - log->info(Logr::Error, msg, "exception", Logging::Loggable("PolicyHitException"))); + SLOG(g_log << Logger::Warning << "Failed to resolve " << qname << ", got a policy hit" << endl, + log->info(Logr::Warning, msg, "exception", Logging::Loggable("PolicyHitException"))); ret.clear(); } catch (const std::exception& e) { - SLOG(g_log << Logger::Error << "Failed to resolve " << qname << ", got STL error: " << e.what() << endl, - log->error(Logr::Error, e.what(), msg, "exception", Logging::Loggable("std::exception"))); + SLOG(g_log << Logger::Warning << "Failed to resolve " << qname << ", got STL error: " << e.what() << endl, + log->error(Logr::Warning, e.what(), msg, "exception", Logging::Loggable("std::exception"))); ret.clear(); } catch (...) { - SLOG(g_log << Logger::Error << "Failed to resolve " << qname << ", got an exception" << endl, - log->info(Logr::Error, msg)); + SLOG(g_log << Logger::Warning << "Failed to resolve " << qname << ", got an exception" << endl, + log->info(Logr::Warning, msg)); ret.clear(); } diff --git a/pdns/unix_utility.cc b/pdns/unix_utility.cc index 2fb2d00e07ca..b6b169aa17a9 100644 --- a/pdns/unix_utility.cc +++ b/pdns/unix_utility.cc @@ -165,7 +165,7 @@ void Utility::dropGroupPrivs( uid_t uid, gid_t gid ) if (initgroups(pw->pw_name, gid)<0) { int err = errno; SLOG(g_log<withName("runtime")->error(Logr::Critical, err, "Unable to drop supplementary groups")); + g_slog->withName("runtime")->error(Logr::Critical, err, "Unable to set supplementary groups")); exit(1); } } @@ -180,7 +180,7 @@ void Utility::dropUserPrivs( uid_t uid ) if(setuid(uid)<0) { int err = errno; SLOG(g_log<withName("runtime")->error(Logr::Error, err, "Unable to set effective user id", "uid", Logging::Loggable(uid))); + g_slog->withName("runtime")->error(Logr::Critical, err, "Unable to set effective user id", "uid", Logging::Loggable(uid))); exit(1); } else { From 9774c1880a91f524785f4629cdf547f258336ee6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 29 Sep 2023 11:41:06 +0200 Subject: [PATCH 770/909] Fix typoe and ws --- pdns/recursordist/lua-recursor4.cc | 2 +- pdns/recursordist/rec-taskqueue.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pdns/recursordist/lua-recursor4.cc b/pdns/recursordist/lua-recursor4.cc index 6ba031e9e14a..a22f54d6bf39 100644 --- a/pdns/recursordist/lua-recursor4.cc +++ b/pdns/recursordist/lua-recursor4.cc @@ -504,7 +504,7 @@ static void warnDrop(const RecursorLua4::DNSQuestion& dq) { if (dq.rcode == -2) { SLOG(g_log << Logger::Error << "Returning -2 (pdns.DROP) is not supported anymore, see https://docs.powerdns.com/recursor/lua-scripting/hooks.html#hooksemantics" << endl, - g_slog->withName("lua")->info(Logr::Error,"Returning -2 (pdns.DROP) is not supported anymore, see https://docs.powerdns.com/recursor/lua-scripting/hooks.html#hooksemantics")); + g_slog->withName("lua")->info(Logr::Error, "Returning -2 (pdns.DROP) is not supported anymore, see https://docs.powerdns.com/recursor/lua-scripting/hooks.html#hooksemantics")); // We *could* set policy here, but that would also mean interfering with rcode and the return code of the hook. // So leave it at the error message. } diff --git a/pdns/recursordist/rec-taskqueue.cc b/pdns/recursordist/rec-taskqueue.cc index b5dba064dfa4..a520e827c735 100644 --- a/pdns/recursordist/rec-taskqueue.cc +++ b/pdns/recursordist/rec-taskqueue.cc @@ -150,7 +150,7 @@ static void resolveInternal(const struct timeval& now, bool logErrors, const pdn } } catch (...) { - log->error(Logr::Warning, msg, "Unexpectec exception"); + log->error(Logr::Warning, msg, "Unexpected exception"); } if (exceptionOccurred) { if (task.d_refreshMode) { From a754b6e59525c8d94a6c0328b98de5e1a48d023f Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Fri, 29 Sep 2023 05:50:10 -0400 Subject: [PATCH 771/909] Remove test-auth --- build-scripts/test-auth | 147 ---------------------------------------- 1 file changed, 147 deletions(-) delete mode 100755 build-scripts/test-auth diff --git a/build-scripts/test-auth b/build-scripts/test-auth deleted file mode 100755 index 6812dd716584..000000000000 --- a/build-scripts/test-auth +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/sh - -set -x -context='' -# poor mans option parsing -if [ -n "$1" ]; then - if [ "$1" != "odbc" ]; then - echo "invalid argument" - exit 1 - fi - context=odbc - if [ -n "$2" ]; then - echo "too many arguments" - exit 1 - fi -fi - -export PDNS=/usr/sbin/pdns_server -export PDNS2=$PDNS -export SDIG=/usr/bin/sdig -export NSEC3DIG=/usr/bin/nsec3dig -export NOTIFY=/usr/bin/pdns_notify -export SAXFR=/usr/bin/saxfr -export ZONE2SQL=/usr/bin/zone2sql -export ZONE2JSON=/usr/bin/zone2json -export PDNSUTIL=/usr/bin/pdnsutil -export PDNSCONTROL=/usr/bin/pdns_control - -export GEM_HOME=${PWD}/gems -mkdir -p $GEM_HOME -export PATH="${GEM_HOME}/bin:$PATH" - -if [ -z "$context" ]; then - cd modules/remotebackend - ruby -S bundle install - cd ../../ -fi - -MODULES="" - -for dir in /usr/lib/x86_64-linux-gnu/pdns /usr/lib64/pdns; do - if [ -d $dir ]; then - MODULES=$dir - break - fi -done -[ -z $MODULES ] && echo "No module directory found" >&2 && exit 1 - -# Symlink the modules on the system -cd regression-tests/modules -for backend in *.so; do - ln -sf $MODULES/$backend $backend -done - -cd .. - -EXITCODE=0 - -if [ -z "$context" ]; then - export geoipregion=oc geoipregionip=1.2.3.4 - ./start-test-stop 5300 bind-both || EXITCODE=1 - ./start-test-stop 5300 bind-dnssec-both || EXITCODE=1 - - # No PKCS#11 in packages - #SETUP_SOFTHSM=y ./start-test-stop 5300 bind-dnssec-pkcs11 || EXITCODE=1 - ./start-test-stop 5300 bind-dnssec-nsec3-both || EXITCODE=1 - ./start-test-stop 5300 bind-dnssec-nsec3-optout-both || EXITCODE=1 - ./start-test-stop 5300 bind-dnssec-nsec3-narrow || EXITCODE=1 - ./start-test-stop 5300 bind-hybrid-nsec3 || EXITCODE=1 - - # Adding extra IPs to docker containers in not supported :( - #./start-test-stop 5300 geoipbackend || EXITCODE=1 - #./start-test-stop 5300 geoipbackend-nsec3-narrow || EXITCODE=1 - - ./start-test-stop 5300 gmysql-nodnssec-both || EXITCODE=1 - ./start-test-stop 5300 gmysql-both || EXITCODE=1 - ./start-test-stop 5300 gmysql-nsec3-both || EXITCODE=1 - ./start-test-stop 5300 gmysql-nsec3-optout-both || EXITCODE=1 - ./start-test-stop 5300 gmysql-nsec3-narrow || EXITCODE=1 - - ./start-test-stop 5300 gpgsql-nodnssec-both || EXITCODE=1 - ./start-test-stop 5300 gpgsql-both || EXITCODE=1 - ./start-test-stop 5300 gpgsql-nsec3-both || EXITCODE=1 - ./start-test-stop 5300 gpgsql-nsec3-optout-both || EXITCODE=1 - ./start-test-stop 5300 gpgsql-nsec3-narrow || EXITCODE=1 - - ./start-test-stop 5300 gsqlite3-nodnssec-both || EXITCODE=1 - ./start-test-stop 5300 gsqlite3-both || EXITCODE=1 - ./start-test-stop 5300 gsqlite3-nsec3-both || EXITCODE=1 - ./start-test-stop 5300 gsqlite3-nsec3-optout-both || EXITCODE=1 - ./start-test-stop 5300 gsqlite3-nsec3-narrow || EXITCODE=1 - - timeout 120s ./start-test-stop 5300 remotebackend-pipe || EXITCODE=1 - timeout 120s ./start-test-stop 5300 remotebackend-pipe-dnssec || EXITCODE=1 - timeout 120s ./start-test-stop 5300 remotebackend-unix || EXITCODE=1 - timeout 120s ./start-test-stop 5300 remotebackend-unix-dnssec || EXITCODE=1 - timeout 120s ./start-test-stop 5300 remotebackend-http || EXITCODE=1 - timeout 120s ./start-test-stop 5300 remotebackend-http-dnssec || EXITCODE=1 - - timeout 120s ./start-test-stop 5300 lua2 - timeout 120s ./start-test-stop 5300 lua2-dnssec - - # No 0MQ in the PowerDNS packages - #timeout 120s ./start-test-stop 5300 remotebackend-zeromq || EXITCODE=1 - #timeout 120s ./start-test-stop 5300 remotebackend-zeromq-dnssec || EXITCODE=1 - - ./start-test-stop 5300 tinydns || EXITCODE=1 - - cd ../regression-tests.nobackend/ - - ./runtests || EXITCODE=1 -elif [ "$context" = "odbc" ]; then - cat > ~/.odbc.ini << __EOF__ -[pdns-sqlite3-1] -Driver = SQLite3 -Database = $(pwd)/pdns.sqlite3 - -[pdns-sqlite3-2] -Driver = SQLite3 -Database = $(pwd)/pdns.sqlite32 - -[pdns-mssql] -Driver=FreeTDS -Trace=No -Server=pdns-odbc-regress-sql-1.database.windows.net -Port=1433 -Database=pdns -TDS_Version=7.1 -ClientCharset=UTF-8 -__EOF__ - - set +x - . ~/.mssql-credentials - set -x - export GODBC_SQLITE3_DSN=pdns-sqlite3-1 - timeout 120s ./start-test-stop 5300 godbc_sqlite3-nodnssec || EXITCODE=1 - export GODBC_MSSQL_DSN=pdns-mssql - export GODBC_MSSQL_USERNAME - export GODBC_MSSQL_PASSWORD - timeout 3600s ./start-test-stop 5300 godbc_mssql-nodnssec || EXITCODE=1 - timeout 3600s ./start-test-stop 5300 godbc_mssql || EXITCODE=1 - timeout 3600s ./start-test-stop 5300 godbc_mssql-nsec3 || EXITCODE=1 - timeout 3600s ./start-test-stop 5300 godbc_mssql-nsec3-optout || EXITCODE=1 - timeout 3600s ./start-test-stop 5300 godbc_mssql-nsec3-narrow || EXITCODE=1 -fi - -exit $EXITCODE From ba2ff172b74d583705d7e198aea041b6cc6bf0ce Mon Sep 17 00:00:00 2001 From: Jacob Bunk Nielsen Date: Fri, 29 Sep 2023 11:51:10 +0200 Subject: [PATCH 772/909] Consistent formatting of open-tcp-connections --- docs/performance.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/performance.rst b/docs/performance.rst index 759c59951647..b25a684e903f 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -229,7 +229,7 @@ Number of entries in the metadata cache .. _stat-open-tcp-connections: open-tcp-connections -~~~~~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^^^^^ Number of currently open TCP connections .. _stat-overload-drops: From 29ae011fbee8cddb67a1f160bb7d5f8449caea7e Mon Sep 17 00:00:00 2001 From: Jacob Bunk Nielsen Date: Fri, 29 Sep 2023 11:51:40 +0200 Subject: [PATCH 773/909] Document send and receive latency metrics --- docs/performance.rst | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/docs/performance.rst b/docs/performance.rst index b25a684e903f..d27307883397 100644 --- a/docs/performance.rst +++ b/docs/performance.rst @@ -286,6 +286,12 @@ rd-queries ^^^^^^^^^^ Number of packets sent by clients requesting recursion (regardless of if we'll be providing them with recursion). +.. _stat-receive-latency: + +receive-latency +^^^^^^^^^^^^^^^ +Average number of microseconds needed to receive a query + .. _stat-recursing-answers: recursing-answers @@ -394,6 +400,12 @@ timedout-packets ^^^^^^^^^^^^^^^^ Amount of packets that were dropped because they had to wait too long internally +.. _stat-send-latency: + +send-latency +^^^^^^^^^^^^ +Average number of microseconds needed to send the answer + .. _stat-udp-answers-bytes: udp-answers-bytes From b3bd55e0feee0a2b2a56a22783621d6958fc10ad Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Wed, 22 Mar 2023 01:19:45 -0400 Subject: [PATCH 774/909] Remove remote 3.3 warning --- docs/backends/remote.rst | 3 --- 1 file changed, 3 deletions(-) diff --git a/docs/backends/remote.rst b/docs/backends/remote.rst index 1f1a7145f82e..7588684c59f0 100644 --- a/docs/backends/remote.rst +++ b/docs/backends/remote.rst @@ -19,9 +19,6 @@ connector. Important notices ----------------- -Please do not use remotebackend shipped before version 3.3. This version -has severe bug that can crash the entire process. - There is a breaking change on v4.0 and later. Before version 4.0, the DNS names passed in queries were without trailing dot, after version 4.0 the DNS names are sent with trailing dot. F.ex. example.org is now sent From 2b8de4d5c2f0d8360ef0bd6b4e33183acd1e0a87 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 29 Sep 2023 15:52:10 +0200 Subject: [PATCH 775/909] dnsdist: Fix eBPF metrics in the internal web server We used to only display eBPF dynamic blocks for the Dynamic BPF registered via `registerDynBPFFilter()`, which does not play well with the new DynBlockRulesGroup approach. This commit fixes it by making exporting / displaying metric for the default BPF filter (`setDefaultBPFFilter`) as well. --- pdns/dnsdist-web.cc | 68 +++++++++++++++++-------- pdns/dnsdistdist/docs/advanced/ebpf.rst | 1 + pdns/dnsdistdist/html/local.js | 4 +- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index 50379859725c..58053aa045c4 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -964,33 +964,42 @@ static void handleJSONStats(const YaHTTP::Request& req, YaHTTP::Response& resp) auto nmg = g_dynblockNMG.getLocal(); struct timespec now; gettime(&now); - for (const auto& e: *nmg) { - if(now < e.second.until ) { - Json::object thing{ - {"reason", e.second.reason}, - {"seconds", (double)(e.second.until.tv_sec - now.tv_sec)}, - {"blocks", (double)e.second.blocks}, - {"action", DNSAction::typeToString(e.second.action != DNSAction::Action::None ? e.second.action : g_dynBlockAction) }, - {"warning", e.second.warning } - }; - obj.emplace(e.first.toString(), thing); + for (const auto& entry: *nmg) { + if (!(now < entry.second.until)) { + continue; + } + uint64_t counter = entry.second.blocks; + if (entry.second.bpf && g_defaultBPFFilter) { + counter += g_defaultBPFFilter->getHits(entry.first.getNetwork()); } + Json::object thing{ + {"reason", entry.second.reason}, + {"seconds", static_cast(entry.second.until.tv_sec - now.tv_sec)}, + {"blocks", static_cast(counter)}, + {"action", DNSAction::typeToString(entry.second.action != DNSAction::Action::None ? entry.second.action : g_dynBlockAction)}, + {"warning", entry.second.warning}, + {"ebpf", entry.second.bpf} + }; + obj.emplace(entry.first.toString(), thing); } auto smt = g_dynblockSMT.getLocal(); smt->visit([&now,&obj](const SuffixMatchTree& node) { - if(now (node.d_value.until.tv_sec - now.tv_sec)}, + {"blocks", static_cast(node.d_value.blocks)}, + {"action", DNSAction::typeToString(node.d_value.action != DNSAction::Action::None ? node.d_value.action : g_dynBlockAction)}, + {"ebpf", node.d_value.bpf} + }; + obj.emplace(dom, thing); }); #endif /* DISABLE_DYNBLOCKS */ Json my_json = obj; @@ -1013,6 +1022,23 @@ static void handleJSONStats(const YaHTTP::Request& req, YaHTTP::Response& resp) obj.emplace(std::get<0>(entry).toString(), thing ); } } + if (g_defaultBPFFilter) { + auto nmg = g_dynblockNMG.getLocal(); + for (const auto& entry: *nmg) { + if (!(now < entry.second.until) || !entry.second.bpf) { + continue; + } + uint64_t counter = entry.second.blocks + g_defaultBPFFilter->getHits(entry.first.getNetwork()); + Json::object thing{ + {"reason", entry.second.reason}, + {"seconds", static_cast(entry.second.until.tv_sec - now.tv_sec)}, + {"blocks", static_cast(counter)}, + {"action", DNSAction::typeToString(entry.second.action != DNSAction::Action::None ? entry.second.action : g_dynBlockAction)}, + {"warning", entry.second.warning}, + }; + obj.emplace(entry.first.toString(), thing); + } + } #endif /* HAVE_EBPF */ Json my_json = obj; resp.body = my_json.dump(); diff --git a/pdns/dnsdistdist/docs/advanced/ebpf.rst b/pdns/dnsdistdist/docs/advanced/ebpf.rst index e50dfbf47258..2905b95e96c9 100644 --- a/pdns/dnsdistdist/docs/advanced/ebpf.rst +++ b/pdns/dnsdistdist/docs/advanced/ebpf.rst @@ -93,6 +93,7 @@ The dynamic eBPF blocks and the number of queries they blocked can be seen in th registerDynBPFFilter(dbpf) They can be unregistered at a later point using the :func:`unregisterDynBPFFilter` function. +Since 1.8.2, the metrics for the BPF filter registered via :func:`setDefaultBPFFilter` are exported as well. Requirements ------------ diff --git a/pdns/dnsdistdist/html/local.js b/pdns/dnsdistdist/html/local.js index 81c1b061faae..cefb0a4d9650 100644 --- a/pdns/dnsdistdist/html/local.js +++ b/pdns/dnsdistdist/html/local.js @@ -237,10 +237,10 @@ $(document).ready(function() { $.ajax({ url: 'jsonstat?command=dynblocklist', type: 'GET', dataType: 'json', jsonp: false, success: function(data) { - var bouw=''; + var bouw='
        Dyn blocked netmaskSecondsBlocksReason
        '; var gotsome=false; $.each(data, function(a,b) { - bouw=bouw+(""); + bouw=bouw+(""); gotsome=true; }); From f57b74a69cf3b235ac22b38deb77ff3b09aba27b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 29 Sep 2023 17:13:18 +0200 Subject: [PATCH 776/909] dnsdist: Skip our BADVERS regression test on broken Python versions See https://github.com/PowerDNS/pdns/pull/12912 for the longer explanation. --- regression-tests.dnsdist/test_RulesActions.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/regression-tests.dnsdist/test_RulesActions.py b/regression-tests.dnsdist/test_RulesActions.py index 14702acd012d..d3f0ebb9d381 100644 --- a/regression-tests.dnsdist/test_RulesActions.py +++ b/regression-tests.dnsdist/test_RulesActions.py @@ -2,6 +2,7 @@ import base64 from datetime import datetime, timedelta import os +import sys import time import unittest import dns @@ -1196,6 +1197,9 @@ def testBadVers(self): Advanced: A question with ECS version larger than 0 yields BADVERS """ + if sys.version_info >= (3, 11) and sys.version_info < (3, 12): + raise unittest.SkipTest("Test skipped, see https://github.com/PowerDNS/pdns/pull/12912") + name = 'ednsversionrule.advanced.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN', use_edns=1) From 22cf0cf5ed02490a7cf32c346615b9b7022e92cf Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Mon, 2 Oct 2023 17:03:44 +0200 Subject: [PATCH 777/909] auth-4.8.3: changelog and secpoll --- docs/changelog/4.8.rst | 28 ++++++++++++++++++++++++++++ docs/secpoll.zone | 3 ++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/docs/changelog/4.8.rst b/docs/changelog/4.8.rst index 37f772e6bd64..f78374738c9e 100644 --- a/docs/changelog/4.8.rst +++ b/docs/changelog/4.8.rst @@ -1,6 +1,34 @@ Changelogs for 4.8.x ==================== +.. changelog:: + :version: 4.8.3 + :released: 5th of October 2023 + + This is release 4.8.3 of the Authoritative Server. + + Please review the :doc:`Upgrade Notes <../upgrading>` before upgrading from versions < 4.8.x. + + This release contains one new feature (``default-catalog-zone``), one bugfix (in ixfrdist), and a workaround for a bug in the MySQL client libraries. + + .. change:: + :tags: Improvements + :pullreq: 13271 + + smysql: stop explicitly setting MYSQL_OPT_RECONNECT to 0 + + .. change:: + :tags: New Features + :pullreq: 13240 + + add default-catalog-zone setting + + .. change:: + :tags: Bug Fixes + :pullreq: 13316 + + ixfrdist: set AA=1 on SOA responses + .. changelog:: :version: 4.8.2 :released: 7th of September 2023 diff --git a/docs/secpoll.zone b/docs/secpoll.zone index e815725a20a8..4c5730563ad4 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023091802 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023100501 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -123,6 +123,7 @@ auth-4.8.0-beta1.security-status 60 IN TXT "2 Unsupported auth-4.8.0.security-status 60 IN TXT "1 OK" auth-4.8.1.security-status 60 IN TXT "1 OK" auth-4.8.2.security-status 60 IN TXT "1 OK" +auth-4.8.3.security-status 60 IN TXT "1 OK" ; Auth Debian auth-3.4.1-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2015-02/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-03/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-04/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-05/" From 1935bc62f985b4b60c6924806f1a3bfcc23fad7b Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 3 Oct 2023 09:13:33 +0200 Subject: [PATCH 778/909] update sphinxcontrib-api hash, add a comment --- docs/requirements.in | 2 +- docs/requirements.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/requirements.in b/docs/requirements.in index 20140c66a122..273a5e69ae3a 100644 --- a/docs/requirements.in +++ b/docs/requirements.in @@ -1,4 +1,4 @@ -# To generate requirements.txt, run: +# To generate requirements.txt, install pip-tools and run: # pip-compile --generate-hashes requirements.in Sphinx>=1.5.0,!=1.8.0,<2.0 diff --git a/docs/requirements.txt b/docs/requirements.txt index 7a4f05bf1819..4f6b8a24c3be 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -306,7 +306,7 @@ sphinxcontrib-httpdomain==1.8.1 \ --hash=sha256:6c2dfe6ca282d75f66df333869bb0ce7331c01b475db6809ff9d107b7cdfe04b # via sphinxcontrib-openapi sphinxcontrib-openapi @ https://github.com/PowerDNS/sphinxcontrib-openapi/archive/refs/heads/use-jsondomain-pdns-py3.10-noscm.zip \ - --hash=sha256:7314b6a453d8c397d45a284255adbb55b7ba464f5f2ace32da4d08941ed76b2d + --hash=sha256:ad6659a5e86e4899386d249f1eae18a459175a92da0dd851ce20f8b8ff6569b0 # via -r requirements.in sphinxcontrib-serializinghtml==1.1.5 \ --hash=sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd \ From ee33b77e98abe0f225151ea763775e21d1ee5a54 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 26 Sep 2023 11:27:12 +0200 Subject: [PATCH 779/909] dnsdist: Fix timeouts on incoming DoH connections with nghttp2 --- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 27 ++++---------------------- pdns/dnsdistdist/dnsdist-nghttp2-in.hh | 1 - 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 7bd9f758556c..0302d536fee8 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -951,23 +951,7 @@ int IncomingHTTP2Connection::on_stream_close_callback(nghttp2_session* session, { auto* conn = static_cast(user_data); - if (error_code == 0) { - return 0; - } - - auto stream = conn->d_currentStreams.find(stream_id); - if (stream == conn->d_currentStreams.end()) { - /* we don't care, then */ - return 0; - } - - struct timeval now - { - }; - gettimeofday(&now, nullptr); - auto request = std::move(stream->second); - conn->d_currentStreams.erase(stream->first); - + conn->d_currentStreams.erase(stream_id); return 0; } @@ -1167,11 +1151,6 @@ void IncomingHTTP2Connection::handleWritableIOCallback([[maybe_unused]] int desc conn->writeToSocket(true); } -bool IncomingHTTP2Connection::isIdle() const -{ - return getConcurrentStreamsCount() == 0; -} - void IncomingHTTP2Connection::stopIO() { d_ioState->reset(); @@ -1217,7 +1196,9 @@ void IncomingHTTP2Connection::updateIO(IOState newState, const FDMultiplexer::ca gettimeofday(&now, nullptr); if (newState == IOState::NeedRead) { - if (isIdle()) { + /* use the idle TTL if the handshake has been completed (and proxy protocol payload received, if any), + and we have processed at least one query, otherwise we use the shorter read TTL */ + if ((d_state == State::waitingForQuery || d_state == State::idle) && (d_queriesCount > 0 || d_currentQueriesCount)) { ttd = getIdleClientReadTTD(now); } else { diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh index a648a5027b3f..020e1c26e312 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.hh +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.hh @@ -86,7 +86,6 @@ private: std::unique_ptr getDOHUnit(uint32_t streamID) override; void stopIO(); - bool isIdle() const; uint32_t getConcurrentStreamsCount() const; void updateIO(IOState newState, const FDMultiplexer::callbackfunc_t& callback); void handleIOError(); From 0bf2607803e827ffd0638c28f34809d0a12cbbb5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 2 Oct 2023 19:58:43 +0200 Subject: [PATCH 780/909] dnsdist: Apply suggestion from Charles-Henri's code review (thanks!) --- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 0302d536fee8..432e9f22c94d 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -1198,7 +1198,7 @@ void IncomingHTTP2Connection::updateIO(IOState newState, const FDMultiplexer::ca if (newState == IOState::NeedRead) { /* use the idle TTL if the handshake has been completed (and proxy protocol payload received, if any), and we have processed at least one query, otherwise we use the shorter read TTL */ - if ((d_state == State::waitingForQuery || d_state == State::idle) && (d_queriesCount > 0 || d_currentQueriesCount)) { + if ((d_state == State::waitingForQuery || d_state == State::idle) && (d_queriesCount > 0 || d_currentQueriesCount > 0)) { ttd = getIdleClientReadTTD(now); } else { From 645d66cf33addb641643cd9dc3cfe3cb5e427710 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Tue, 26 Sep 2023 14:40:37 +0200 Subject: [PATCH 781/909] Cleanup remote backend --- modules/remotebackend/httpconnector.cc | 59 ++-- modules/remotebackend/pipeconnector.cc | 74 +++-- modules/remotebackend/remotebackend.cc | 272 ++++++++++-------- modules/remotebackend/remotebackend.hh | 75 ++--- .../remotebackend/test-remotebackend-http.cc | 4 +- .../remotebackend/test-remotebackend-json.cc | 4 +- .../remotebackend/test-remotebackend-keys.hh | 3 + .../remotebackend/test-remotebackend-pipe.cc | 4 +- .../remotebackend/test-remotebackend-post.cc | 4 +- .../remotebackend/test-remotebackend-unix.cc | 4 +- .../test-remotebackend-zeromq.cc | 4 +- modules/remotebackend/test-remotebackend.cc | 36 ++- modules/remotebackend/unixconnector.cc | 62 ++-- modules/remotebackend/zmqconnector.cc | 21 +- 14 files changed, 357 insertions(+), 269 deletions(-) diff --git a/modules/remotebackend/httpconnector.cc b/modules/remotebackend/httpconnector.cc index 2c21d85c095f..015f3008aa91 100644 --- a/modules/remotebackend/httpconnector.cc +++ b/modules/remotebackend/httpconnector.cc @@ -80,16 +80,17 @@ HTTPConnector::HTTPConnector(std::map options) : } } -HTTPConnector::~HTTPConnector() {} +HTTPConnector::~HTTPConnector() = default; void HTTPConnector::addUrlComponent(const Json& parameters, const string& element, std::stringstream& ss) { std::string sparam; - if (parameters[element] != Json()) + if (parameters[element] != Json()) { ss << "/" << YaHTTP::Utility::encodeURL(asString(parameters[element]), false); + } } -std::string HTTPConnector::buildMemberListArgs(std::string prefix, const Json& args) +std::string HTTPConnector::buildMemberListArgs(const std::string& prefix, const Json& args) { std::stringstream stream; @@ -101,7 +102,7 @@ std::string HTTPConnector::buildMemberListArgs(std::string prefix, const Json& a stream << prefix << "[" << YaHTTP::Utility::encodeURL(pair.first, false) << "]="; } else { - stream << prefix << "[" << YaHTTP::Utility::encodeURL(pair.first, false) << "]=" << YaHTTP::Utility::encodeURL(this->asString(pair.second), false); + stream << prefix << "[" << YaHTTP::Utility::encodeURL(pair.first, false) << "]=" << YaHTTP::Utility::encodeURL(HTTPConnector::asString(pair.second), false); } stream << "&"; } @@ -173,7 +174,7 @@ void HTTPConnector::restful_requestbuilder(const std::string& method, const Json else if (method == "createSlaveDomain") { addUrlComponent(parameters, "ip", ss); addUrlComponent(parameters, "domain", ss); - if (parameters["account"].is_null() == false && parameters["account"].is_string()) { + if (!parameters["account"].is_null() && parameters["account"].is_string()) { req.POST()["account"] = parameters["account"].string_value(); } req.preparePost(); @@ -316,7 +317,8 @@ void HTTPConnector::post_requestbuilder(const Json& input, YaHTTP::Request& req) req.body = out; } else { - std::stringstream url, content; + std::stringstream url; + std::stringstream content; // call url/method.suffix url << d_url << "/" << input["method"].string_value() << d_url_suffix; req.setup("POST", url.str()); @@ -329,7 +331,9 @@ void HTTPConnector::post_requestbuilder(const Json& input, YaHTTP::Request& req) int HTTPConnector::send_message(const Json& input) { - int rv, ec, fd; + int rv = 0; + int ec = 0; + int fd = 0; std::vector members; std::string method; @@ -338,10 +342,12 @@ int HTTPConnector::send_message(const Json& input) // perform request YaHTTP::Request req; - if (d_post) + if (d_post) { post_requestbuilder(input, req); - else + } + else { restful_requestbuilder(input["method"].string_value(), input["parameters"], req); + } rv = -1; req.headers["connection"] = "Keep-Alive"; // see if we can streamline requests (not needed, strictly speaking) @@ -366,13 +372,18 @@ int HTTPConnector::send_message(const Json& input) } } - if (rv == 1) + if (rv == 1) { return rv; + } this->d_socket.reset(); // connect using tcp - struct addrinfo *gAddr, *gAddrPtr, hints; + struct addrinfo* gAddr = nullptr; + struct addrinfo* gAddrPtr = nullptr; + struct addrinfo hints + { + }; std::string sPort = std::to_string(d_port); memset(&hints, 0, sizeof hints); hints.ai_family = AF_UNSPEC; @@ -383,7 +394,7 @@ int HTTPConnector::send_message(const Json& input) // try to connect to each address. gAddrPtr = gAddr; - while (gAddrPtr) { + while (gAddrPtr != nullptr) { try { d_socket = std::make_unique(gAddrPtr->ai_family, gAddrPtr->ai_socktype, gAddrPtr->ai_protocol); d_addr.setSockaddr(gAddrPtr->ai_addr, gAddrPtr->ai_addrlen); @@ -399,8 +410,9 @@ int HTTPConnector::send_message(const Json& input) g_log << Logger::Error << "While writing to HTTP endpoint " << d_addr.toStringWithPort() << ": exception caught" << std::endl; } - if (rv > -1) + if (rv > -1) { break; + } d_socket.reset(); gAddrPtr = gAddrPtr->ai_next; } @@ -418,27 +430,31 @@ int HTTPConnector::recv_message(Json& output) YaHTTP::AsyncResponseLoader arl; YaHTTP::Response resp; - if (d_socket == nullptr) + if (d_socket == nullptr) { return -1; // cannot receive :( + } char buffer[4096]; int rd = -1; - time_t t0; + time_t t0 = 0; arl.initialize(&resp); try { - t0 = time((time_t*)NULL); - while (arl.ready() == false && (labs(time((time_t*)NULL) - t0) <= timeout)) { + t0 = time((time_t*)nullptr); + while (!arl.ready() && (labs(time((time_t*)nullptr) - t0) <= timeout)) { rd = d_socket->readWithTimeout(buffer, sizeof(buffer), timeout); - if (rd == 0) + if (rd == 0) { throw NetworkError("EOF while reading"); - if (rd < 0) + } + if (rd < 0) { throw NetworkError(std::string(strerror(rd))); + } arl.feed(std::string(buffer, rd)); } // timeout occurred. - if (arl.ready() == false) + if (!arl.ready()) { throw NetworkError("timeout"); + } } catch (NetworkError& ne) { d_socket.reset(); @@ -459,8 +475,9 @@ int HTTPConnector::recv_message(Json& output) int rv = -1; std::string err; output = Json::parse(resp.body, err); - if (output != nullptr) + if (output != nullptr) { return resp.body.size(); + } g_log << Logger::Error << "Cannot parse JSON reply: " << err << endl; return rv; diff --git a/modules/remotebackend/pipeconnector.cc b/modules/remotebackend/pipeconnector.cc index e6f3a5da8e2a..cc90a441978f 100644 --- a/modules/remotebackend/pipeconnector.cc +++ b/modules/remotebackend/pipeconnector.cc @@ -45,17 +45,18 @@ PipeConnector::PipeConnector(std::map optionsMap) : PipeConnector::~PipeConnector() { - int status; + int status = 0; // just in case... - if (d_pid == -1) + if (d_pid == -1) { return; + } - if (!waitpid(d_pid, &status, WNOHANG)) { + if (waitpid(d_pid, &status, WNOHANG) == 0) { kill(d_pid, 9); waitpid(d_pid, &status, 0); } - if (d_fd1[1]) { + if (d_fd1[1] != 0) { close(d_fd1[1]); } } @@ -63,39 +64,46 @@ PipeConnector::~PipeConnector() void PipeConnector::launch() { // no relaunch - if (d_pid > 0 && checkStatus()) + if (d_pid > 0 && checkStatus()) { return; + } std::vector v; split(v, command, boost::is_any_of(" ")); std::vector argv(v.size() + 1); - argv[v.size()] = 0; + argv[v.size()] = nullptr; - for (size_t n = 0; n < v.size(); n++) + for (size_t n = 0; n < v.size(); n++) { argv[n] = v[n].c_str(); + } signal(SIGPIPE, SIG_IGN); - if (access(argv[0], X_OK)) // check before fork so we can throw + if (access(argv[0], X_OK) != 0) { // check before fork so we can throw throw PDNSException("Command '" + string(argv[0]) + "' cannot be executed: " + stringerror()); + } - if (pipe(d_fd1) < 0 || pipe(d_fd2) < 0) + if (pipe(d_fd1) < 0 || pipe(d_fd2) < 0) { throw PDNSException("Unable to open pipe for coprocess: " + string(strerror(errno))); + } - if ((d_pid = fork()) < 0) + if ((d_pid = fork()) < 0) { throw PDNSException("Unable to fork for coprocess: " + stringerror()); - else if (d_pid > 0) { // parent speaking + } + if (d_pid > 0) { // parent speaking close(d_fd1[0]); setCloseOnExec(d_fd1[1]); close(d_fd2[1]); setCloseOnExec(d_fd2[0]); - if (!(d_fp = std::unique_ptr(fdopen(d_fd2[0], "r"), fclose))) + if (!(d_fp = std::unique_ptr(fdopen(d_fd2[0], "r"), fclose))) { throw PDNSException("Unable to associate a file pointer with pipe: " + stringerror()); - if (d_timeout) - setbuf(d_fp.get(), 0); // no buffering please, confuses poll + } + if (d_timeout != 0) { + setbuf(d_fp.get(), nullptr); // no buffering please, confuses poll + } } - else if (!d_pid) { // child + else if (d_pid == 0) { // child signal(SIGCHLD, SIG_DFL); // silence a warning from perl close(d_fd1[1]); close(d_fd2[0]); @@ -112,8 +120,9 @@ void PipeConnector::launch() // stdin & stdout are now connected, fire up our coprocess! - if (execv(argv[0], const_cast(argv.data())) < 0) // now what + if (execv(argv[0], const_cast(argv.data())) < 0) { // now what exit(123); + } /* not a lot we can do here. We shouldn't return because that will leave a forked process around. no way to log this either - only thing we can do is make sure that our parent catches this soonest! */ @@ -127,7 +136,7 @@ void PipeConnector::launch() this->send(msg); msg = nullptr; - if (this->recv(msg) == false) { + if (!this->recv(msg)) { g_log << Logger::Error << "Failed to initialize coprocess" << std::endl; } } @@ -140,13 +149,14 @@ int PipeConnector::send_message(const Json& input) line.append(1, '\n'); unsigned int sent = 0; - int bytes; + int bytes = 0; // writen routine - socket may not accept al data in one go while (sent < line.size()) { bytes = write(d_fd1[1], line.c_str() + sent, line.length() - sent); - if (bytes < 0) + if (bytes < 0) { throw PDNSException("Writing to coprocess failed: " + std::string(strerror(errno))); + } sent += bytes; } @@ -162,33 +172,38 @@ int PipeConnector::recv_message(Json& output) while (1) { receive.clear(); - if (d_timeout) { + if (d_timeout != 0) { int ret = waitForData(fileno(d_fp.get()), 0, d_timeout * 1000); - if (ret < 0) + if (ret < 0) { throw PDNSException("Error waiting on data from coprocess: " + stringerror()); - if (!ret) + } + if (ret == 0) { throw PDNSException("Timeout waiting for data from coprocess"); + } } - if (!stringfgets(d_fp.get(), receive)) + if (!stringfgets(d_fp.get(), receive)) { throw PDNSException("Child closed pipe"); + } s_output.append(receive); // see if it can be parsed output = Json::parse(s_output, err); - if (output != nullptr) + if (output != nullptr) { return s_output.size(); + } } return 0; } -bool PipeConnector::checkStatus() +bool PipeConnector::checkStatus() const { - int status; + int status = 0; int ret = waitpid(d_pid, &status, WNOHANG); - if (ret < 0) + if (ret < 0) { throw PDNSException("Unable to ascertain status of coprocess " + std::to_string(d_pid) + " from " + std::to_string(getpid()) + ": " + string(strerror(errno))); - else if (ret) { + } + if (ret != 0) { if (WIFEXITED(status)) { int exitStatus = WEXITSTATUS(status); throw PDNSException("Coprocess exited with code " + std::to_string(exitStatus)); @@ -197,8 +212,9 @@ bool PipeConnector::checkStatus() int sig = WTERMSIG(status); string reason = "CoProcess died on receiving signal " + std::to_string(sig); #ifdef WCOREDUMP - if (WCOREDUMP(status)) + if (WCOREDUMP(status)) { reason += ". Dumped core"; + } #endif throw PDNSException(reason); diff --git a/modules/remotebackend/remotebackend.cc b/modules/remotebackend/remotebackend.cc index 19e1ec99a60e..8fa086ab6b4c 100644 --- a/modules/remotebackend/remotebackend.cc +++ b/modules/remotebackend/remotebackend.cc @@ -49,7 +49,7 @@ bool Connector::recv(Json& value) if (value["result"] == Json()) { throw PDNSException("No 'result' field in response from remote process"); } - else if (value["result"].is_bool() && boolFromJson(value, "result", false) == false) { + if (value["result"].is_bool() && !boolFromJson(value, "result", false)) { retval = false; } for (const auto& message : value["log"].array_items()) { @@ -78,13 +78,11 @@ RemoteBackend::RemoteBackend(const std::string& suffix) this->d_connstr = getArg("connection-string"); this->d_dnssec = mustDo("dnssec"); - this->d_index = -1; - this->d_trxid = 0; build(); } -RemoteBackend::~RemoteBackend() {} +RemoteBackend::~RemoteBackend() = default; bool RemoteBackend::send(Json& value) { @@ -131,10 +129,11 @@ int RemoteBackend::build() std::map options; // connstr is of format "type:options" - size_t pos; - pos = d_connstr.find_first_of(":"); - if (pos == std::string::npos) + size_t pos = 0; + pos = d_connstr.find_first_of(':'); + if (pos == std::string::npos) { throw PDNSException("Invalid connection string: malformed"); + } type = d_connstr.substr(0, pos); opts = d_connstr.substr(pos + 1); @@ -144,10 +143,12 @@ int RemoteBackend::build() // find out some options and parse them while we're at it for (const auto& opt : parts) { - std::string key, val; + std::string key; + std::string val; // make sure there is something else than air in the option... - if (opt.find_first_not_of(" ") == std::string::npos) + if (opt.find_first_not_of(" ") == std::string::npos) { continue; + } // split it on '='. if not found, we treat it as "yes" pos = opt.find_first_of("="); @@ -193,14 +194,15 @@ int RemoteBackend::build() */ void RemoteBackend::lookup(const QType& qtype, const DNSName& qdomain, int zoneId, DNSPacket* pkt_p) { - if (d_index != -1) + if (d_index != -1) { throw PDNSException("Attempt to lookup while one running"); + } string localIP = "0.0.0.0"; string remoteIP = "0.0.0.0"; string realRemote = "0.0.0.0/0"; - if (pkt_p) { + if (pkt_p != nullptr) { localIP = pkt_p->getLocal().toString(); realRemote = pkt_p->getRealRemote().toString(); remoteIP = pkt_p->getInnerRemote().toString(); @@ -210,30 +212,34 @@ void RemoteBackend::lookup(const QType& qtype, const DNSName& qdomain, int zoneI {"method", "lookup"}, {"parameters", Json::object{{"qtype", qtype.toString()}, {"qname", qdomain.toString()}, {"remote", remoteIP}, {"local", localIP}, {"real-remote", realRemote}, {"zone-id", zoneId}}}}; - if (this->send(query) == false || this->recv(d_result) == false) { + if (!this->send(query) || !this->recv(d_result)) { return; } // OK. we have result parameters in result. do not process empty result. - if (d_result["result"].is_array() == false || d_result["result"].array_items().size() < 1) + if (!d_result["result"].is_array() || d_result["result"].array_items().empty()) { return; + } d_index = 0; } bool RemoteBackend::list(const DNSName& target, int domain_id, bool include_disabled) { - if (d_index != -1) + if (d_index != -1) { throw PDNSException("Attempt to lookup while one running"); + } Json query = Json::object{ {"method", "list"}, {"parameters", Json::object{{"zonename", target.toString()}, {"domain_id", domain_id}, {"include_disabled", include_disabled}}}}; - if (this->send(query) == false || this->recv(d_result) == false) + if (!this->send(query) || !this->recv(d_result)) { return false; - if (d_result["result"].is_array() == false || d_result["result"].array_items().size() < 1) + } + if (!d_result["result"].is_array() || d_result["result"].array_items().empty()) { return false; + } d_index = 0; return true; @@ -241,8 +247,9 @@ bool RemoteBackend::list(const DNSName& target, int domain_id, bool include_disa bool RemoteBackend::get(DNSResourceRecord& rr) { - if (d_index == -1) + if (d_index == -1) { return false; + } rr.qtype = stringFromJson(d_result["result"][d_index], "qtype"); rr.qname = DNSName(stringFromJson(d_result["result"][d_index], "qname")); @@ -250,10 +257,12 @@ bool RemoteBackend::get(DNSResourceRecord& rr) rr.content = stringFromJson(d_result["result"][d_index], "content"); rr.ttl = d_result["result"][d_index]["ttl"].int_value(); rr.domain_id = intFromJson(d_result["result"][d_index], "domain_id", -1); - if (d_dnssec) - rr.auth = intFromJson(d_result["result"][d_index], "auth", 1); - else - rr.auth = 1; + if (d_dnssec) { + rr.auth = (intFromJson(d_result["result"][d_index], "auth", 1) != 0); + } + else { + rr.auth = true; + } rr.scopeMask = d_result["result"][d_index]["scopeMask"].int_value(); d_index++; @@ -268,24 +277,28 @@ bool RemoteBackend::get(DNSResourceRecord& rr) bool RemoteBackend::getBeforeAndAfterNamesAbsolute(uint32_t id, const DNSName& qname, DNSName& unhashed, DNSName& before, DNSName& after) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "getBeforeAndAfterNamesAbsolute"}, {"parameters", Json::object{{"id", Json(static_cast(id))}, {"qname", qname.toString()}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return false; + } unhashed = DNSName(stringFromJson(answer["result"], "unhashed")); before.clear(); after.clear(); - if (answer["result"]["before"] != Json()) + if (answer["result"]["before"] != Json()) { before = DNSName(stringFromJson(answer["result"], "before")); - if (answer["result"]["after"] != Json()) + } + if (answer["result"]["after"] != Json()) { after = DNSName(stringFromJson(answer["result"], "after")); + } return true; } @@ -296,20 +309,23 @@ bool RemoteBackend::getAllDomainMetadata(const DNSName& name, std::mapsend(query) == false) + if (!this->send(query)) { return false; + } meta.clear(); Json answer; // not mandatory to implement - if (this->recv(answer) == false) + if (!this->recv(answer)) { return true; + } for (const auto& pair : answer["result"].object_items()) { if (pair.second.is_array()) { - for (const auto& val : pair.second.array_items()) + for (const auto& val : pair.second.array_items()) { meta[pair.first].push_back(asString(val)); + } } else { meta[pair.first].push_back(asString(pair.second)); @@ -325,19 +341,22 @@ bool RemoteBackend::getDomainMetadata(const DNSName& name, const std::string& ki {"method", "getDomainMetadata"}, {"parameters", Json::object{{"name", name.toString()}, {"kind", kind}}}}; - if (this->send(query) == false) + if (!this->send(query)) { return false; + } meta.clear(); Json answer; // not mandatory to implement - if (this->recv(answer) == false) + if (!this->recv(answer)) { return true; + } if (answer["result"].is_array()) { - for (const auto& row : answer["result"].array_items()) + for (const auto& row : answer["result"].array_items()) { meta.push_back(row.string_value()); + } } else if (answer["result"].is_string()) { meta.push_back(answer["result"].string_value()); @@ -353,8 +372,9 @@ bool RemoteBackend::setDomainMetadata(const DNSName& name, const std::string& ki {"parameters", Json::object{{"name", name.toString()}, {"kind", kind}, {"value", meta}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return false; + } return boolFromJson(answer, "result", false); } @@ -362,16 +382,18 @@ bool RemoteBackend::setDomainMetadata(const DNSName& name, const std::string& ki bool RemoteBackend::getDomainKeys(const DNSName& name, std::vector& keys) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "getDomainKeys"}, {"parameters", Json::object{{"name", name.toString()}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return false; + } keys.clear(); @@ -391,33 +413,33 @@ bool RemoteBackend::getDomainKeys(const DNSName& name, std::vector(id)}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - - return true; + return this->send(query) && this->recv(answer); } bool RemoteBackend::addDomainKey(const DNSName& name, const KeyData& key, int64_t& id) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "addDomainKey"}, {"parameters", Json::object{{"name", name.toString()}, {"key", Json::object{{"flags", static_cast(key.flags)}, {"active", key.active}, {"published", key.published}, {"content", key.content}}}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return false; + } id = answer["result"].int_value(); return id >= 0; @@ -426,69 +448,61 @@ bool RemoteBackend::addDomainKey(const DNSName& name, const KeyData& key, int64_ bool RemoteBackend::activateDomainKey(const DNSName& name, unsigned int id) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "activateDomainKey"}, {"parameters", Json::object{{"name", name.toString()}, {"id", static_cast(id)}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - - return true; + return this->send(query) && this->recv(answer); } bool RemoteBackend::deactivateDomainKey(const DNSName& name, unsigned int id) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "deactivateDomainKey"}, {"parameters", Json::object{{"name", name.toString()}, {"id", static_cast(id)}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - - return true; + return this->send(query) && this->recv(answer); } bool RemoteBackend::publishDomainKey(const DNSName& name, unsigned int id) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "publishDomainKey"}, {"parameters", Json::object{{"name", name.toString()}, {"id", static_cast(id)}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - - return true; + return this->send(query) && this->recv(answer); } bool RemoteBackend::unpublishDomainKey(const DNSName& name, unsigned int id) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "unpublishDomainKey"}, {"parameters", Json::object{{"name", name.toString()}, {"id", static_cast(id)}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - - return true; + return this->send(query) && this->recv(answer); } bool RemoteBackend::doesDNSSEC() @@ -499,16 +513,18 @@ bool RemoteBackend::doesDNSSEC() bool RemoteBackend::getTSIGKey(const DNSName& name, DNSName& algorithm, std::string& content) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "getTSIGKey"}, {"parameters", Json::object{{"name", name.toString()}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return false; + } algorithm = DNSName(stringFromJson(answer["result"], "algorithm")); content = stringFromJson(answer["result"], "content"); @@ -519,48 +535,46 @@ bool RemoteBackend::getTSIGKey(const DNSName& name, DNSName& algorithm, std::str bool RemoteBackend::setTSIGKey(const DNSName& name, const DNSName& algorithm, const std::string& content) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "setTSIGKey"}, {"parameters", Json::object{{"name", name.toString()}, {"algorithm", algorithm.toString()}, {"content", content}}}}; Json answer; - if (connector->send(query) == false || connector->recv(answer) == false) - return false; - - return true; + return connector->send(query) && connector->recv(answer); } bool RemoteBackend::deleteTSIGKey(const DNSName& name) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "deleteTSIGKey"}, {"parameters", Json::object{{"name", name.toString()}}}}; Json answer; - if (connector->send(query) == false || connector->recv(answer) == false) - return false; - - return true; + return connector->send(query) && connector->recv(answer); } bool RemoteBackend::getTSIGKeys(std::vector& keys) { // no point doing dnssec if it's not supported - if (d_dnssec == false) + if (!d_dnssec) { return false; + } Json query = Json::object{ {"method", "getTSIGKeys"}, {"parameters", Json::object{}}}; Json answer; - if (connector->send(query) == false || connector->recv(answer) == false) + if (!connector->send(query) || !connector->recv(answer)) { return false; + } for (const auto& jsonKey : answer["result"].array_items()) { struct TSIGKey key; @@ -577,14 +591,15 @@ void RemoteBackend::parseDomainInfo(const Json& obj, DomainInfo& di) { di.id = intFromJson(obj, "id", -1); di.zone = DNSName(stringFromJson(obj, "zone")); - for (const auto& master : obj["masters"].array_items()) - di.masters.push_back(ComboAddress(master.string_value(), 53)); + for (const auto& master : obj["masters"].array_items()) { + di.masters.emplace_back(master.string_value(), 53); + } di.notified_serial = static_cast(doubleFromJson(obj, "notified_serial", 0)); di.serial = static_cast(obj["serial"].number_value()); di.last_check = static_cast(obj["last_check"].number_value()); - string kind = ""; + string kind; if (obj["kind"].is_string()) { kind = stringFromJson(obj, "kind"); } @@ -602,15 +617,18 @@ void RemoteBackend::parseDomainInfo(const Json& obj, DomainInfo& di) bool RemoteBackend::getDomainInfo(const DNSName& domain, DomainInfo& di, bool /* getSerial */) { - if (domain.empty()) + if (domain.empty()) { return false; + } + Json query = Json::object{ {"method", "getDomainInfo"}, {"parameters", Json::object{{"name", domain.toString()}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return false; + } this->parseDomainInfo(answer["result"], di); return true; @@ -623,7 +641,7 @@ void RemoteBackend::setNotified(uint32_t id, uint32_t serial) {"parameters", Json::object{{"id", static_cast(id)}, {"serial", static_cast(serial)}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) { + if (!this->send(query) || !this->recv(answer)) { g_log << Logger::Error << kBackendId << " Failed to execute RPC for RemoteBackend::setNotified(" << id << "," << serial << ")" << endl; } } @@ -646,11 +664,12 @@ bool RemoteBackend::superMasterBackend(const string& ip, const DNSName& domain, {"method", "superMasterBackend"}, {"parameters", Json::object{{"ip", ip}, {"domain", domain.toString()}, {"nsset", rrset}}}}; - *ddb = 0; + *ddb = nullptr; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return false; + } // we are the backend *ddb = this; @@ -676,9 +695,7 @@ bool RemoteBackend::createSlaveDomain(const string& ip, const DNSName& domain, c }}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - return true; + return this->send(query) && this->recv(answer); } bool RemoteBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const QType& qtype, const vector& rrset) @@ -699,10 +716,7 @@ bool RemoteBackend::replaceRRSet(uint32_t domain_id, const DNSName& qname, const {"parameters", Json::object{{"domain_id", static_cast(domain_id)}, {"qname", qname.toString()}, {"qtype", qtype.toString()}, {"trxid", static_cast(d_trxid)}, {"rrset", json_rrset}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - - return true; + return this->send(query) && this->recv(answer); } bool RemoteBackend::feedRecord(const DNSResourceRecord& rr, const DNSName& ordername, bool /* ordernameIsNSEC3 */) @@ -715,19 +729,18 @@ bool RemoteBackend::feedRecord(const DNSResourceRecord& rr, const DNSName& order }}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - return true; // XXX FIXME this API should not return 'true' I think -ahu + return this->send(query) && this->recv(answer); // XXX FIXME this API should not return 'true' I think -ahu } bool RemoteBackend::feedEnts(int domain_id, map& nonterm) { Json::array nts; - for (const auto& t : nonterm) + for (const auto& t : nonterm) { nts.push_back(Json::object{ {"nonterm", t.first.toString()}, {"auth", t.second}}); + } Json query = Json::object{ {"method", "feedEnts"}, @@ -735,19 +748,18 @@ bool RemoteBackend::feedEnts(int domain_id, map& nonterm) }; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - return true; + return this->send(query) && this->recv(answer); } bool RemoteBackend::feedEnts3(int domain_id, const DNSName& domain, map& nonterm, const NSEC3PARAMRecordContent& ns3prc, bool narrow) { Json::array nts; - for (const auto& t : nonterm) + for (const auto& t : nonterm) { nts.push_back(Json::object{ {"nonterm", t.first.toString()}, {"auth", t.second}}); + } Json query = Json::object{ {"method", "feedEnts3"}, @@ -755,30 +767,30 @@ bool RemoteBackend::feedEnts3(int domain_id, const DNSName& domain, mapsend(query) == false || this->recv(answer) == false) - return false; - return true; + return this->send(query) && this->recv(answer); } bool RemoteBackend::startTransaction(const DNSName& domain, int domain_id) { - this->d_trxid = time((time_t*)NULL); + this->d_trxid = time((time_t*)nullptr); Json query = Json::object{ {"method", "startTransaction"}, {"parameters", Json::object{{"domain", domain.toString()}, {"domain_id", domain_id}, {"trxid", static_cast(d_trxid)}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) { + if (!this->send(query) || !this->recv(answer)) { d_trxid = -1; return false; } return true; } + bool RemoteBackend::commitTransaction() { - if (d_trxid == -1) + if (d_trxid == -1) { return false; + } Json query = Json::object{ {"method", "commitTransaction"}, @@ -786,15 +798,14 @@ bool RemoteBackend::commitTransaction() d_trxid = -1; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - return true; + return this->send(query) && this->recv(answer); } bool RemoteBackend::abortTransaction() { - if (d_trxid == -1) + if (d_trxid == -1) { return false; + } Json query = Json::object{ {"method", "abortTransaction"}, @@ -802,9 +813,7 @@ bool RemoteBackend::abortTransaction() d_trxid = -1; Json answer; - if (this->send(query) == false || this->recv(answer) == false) - return false; - return true; + return this->send(query) && this->recv(answer); } string RemoteBackend::directBackendCmd(const string& querystr) @@ -814,8 +823,9 @@ string RemoteBackend::directBackendCmd(const string& querystr) {"parameters", Json::object{{"query", querystr}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return "backend command failed"; + } return asString(answer["result"]); } @@ -827,11 +837,13 @@ bool RemoteBackend::searchRecords(const string& pattern, int maxResults, vector< {"parameters", Json::object{{"pattern", pattern}, {"maxResults", maxResults}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return false; + } - if (answer["result"].is_array() == false) + if (!answer["result"].is_array()) { return false; + } for (const auto& row : answer["result"].array_items()) { DNSResourceRecord rr; @@ -841,10 +853,12 @@ bool RemoteBackend::searchRecords(const string& pattern, int maxResults, vector< rr.content = stringFromJson(row, "content"); rr.ttl = row["ttl"].int_value(); rr.domain_id = intFromJson(row, "domain_id", -1); - if (d_dnssec) - rr.auth = intFromJson(row, "auth", 1); - else + if (d_dnssec) { + rr.auth = (intFromJson(row, "auth", 1) != 0); + } + else { rr.auth = 1; + } rr.scopeMask = row["scopeMask"].int_value(); result.push_back(rr); } @@ -865,11 +879,13 @@ void RemoteBackend::getAllDomains(vector* domains, bool /* getSerial {"parameters", Json::object{{"include_disabled", include_disabled}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return; + } - if (answer["result"].is_array() == false) + if (!answer["result"].is_array()) { return; + } for (const auto& row : answer["result"].array_items()) { DomainInfo di; @@ -886,11 +902,13 @@ void RemoteBackend::getUpdatedMasters(vector& domains, std::unordere }; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return; + } - if (answer["result"].is_array() == false) + if (!answer["result"].is_array()) { return; + } for (const auto& row : answer["result"].array_items()) { DomainInfo di; @@ -907,11 +925,13 @@ void RemoteBackend::getUnfreshSlaveInfos(vector* domains) }; Json answer; - if (this->send(query) == false || this->recv(answer) == false) + if (!this->send(query) || !this->recv(answer)) { return; + } - if (answer["result"].is_array() == false) + if (!answer["result"].is_array()) { return; + } for (const auto& row : answer["result"].array_items()) { DomainInfo di; @@ -927,7 +947,7 @@ void RemoteBackend::setStale(uint32_t domain_id) {"parameters", Json::object{{"id", static_cast(domain_id)}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) { + if (!this->send(query) || !this->recv(answer)) { g_log << Logger::Error << kBackendId << " Failed to execute RPC for RemoteBackend::setStale(" << domain_id << ")" << endl; } } @@ -939,7 +959,7 @@ void RemoteBackend::setFresh(uint32_t domain_id) {"parameters", Json::object{{"id", static_cast(domain_id)}}}}; Json answer; - if (this->send(query) == false || this->recv(answer) == false) { + if (!this->send(query) || !this->recv(answer)) { g_log << Logger::Error << kBackendId << " Failed to execute RPC for RemoteBackend::setFresh(" << domain_id << ")" << endl; } } @@ -951,7 +971,7 @@ DNSBackend* RemoteBackend::maker() } catch (...) { g_log << Logger::Error << kBackendId << " Unable to instantiate a remotebackend!" << endl; - return 0; + return nullptr; }; } diff --git a/modules/remotebackend/remotebackend.hh b/modules/remotebackend/remotebackend.hh index 078594e7f329..23c7be638a0c 100644 --- a/modules/remotebackend/remotebackend.hh +++ b/modules/remotebackend/remotebackend.hh @@ -51,21 +51,24 @@ using json11::Json; class Connector { public: - virtual ~Connector(){}; + virtual ~Connector() = default; bool send(Json& value); bool recv(Json& value); virtual int send_message(const Json& input) = 0; virtual int recv_message(Json& output) = 0; protected: - string asString(const Json& value) + static string asString(const Json& value) { - if (value.is_number()) + if (value.is_number()) { return std::to_string(value.int_value()); - if (value.is_bool()) + } + if (value.is_bool()) { return (value.bool_value() ? "1" : "0"); - if (value.is_string()) + } + if (value.is_string()) { return value.string_value(); + } throw JsonException("Json value not convertible to String"); }; }; @@ -75,9 +78,9 @@ class UnixsocketConnector : public Connector { public: UnixsocketConnector(std::map options); - virtual ~UnixsocketConnector(); - virtual int send_message(const Json& input); - virtual int recv_message(Json& output); + ~UnixsocketConnector() override; + int send_message(const Json& input) override; + int recv_message(Json& output) override; private: ssize_t read(std::string& data); @@ -94,10 +97,10 @@ class HTTPConnector : public Connector { public: HTTPConnector(std::map options); - ~HTTPConnector(); + ~HTTPConnector() override; - virtual int send_message(const Json& input); - virtual int recv_message(Json& output); + int send_message(const Json& input) override; + int recv_message(Json& output) override; private: std::string d_url; @@ -108,8 +111,8 @@ private: bool d_post_json; void restful_requestbuilder(const std::string& method, const Json& parameters, YaHTTP::Request& req); void post_requestbuilder(const Json& input, YaHTTP::Request& req); - void addUrlComponent(const Json& parameters, const string& element, std::stringstream& ss); - std::string buildMemberListArgs(std::string prefix, const Json& args); + static void addUrlComponent(const Json& parameters, const string& element, std::stringstream& ss); + static std::string buildMemberListArgs(const std::string& prefix, const Json& args); std::unique_ptr d_socket; ComboAddress d_addr; std::string d_host; @@ -121,9 +124,9 @@ class ZeroMQConnector : public Connector { public: ZeroMQConnector(std::map options); - virtual ~ZeroMQConnector(); - virtual int send_message(const Json& input); - virtual int recv_message(Json& output); + ~ZeroMQConnector() override; + int send_message(const Json& input) override; + int recv_message(Json& output) override; private: void connect(); @@ -140,19 +143,19 @@ class PipeConnector : public Connector { public: PipeConnector(std::map options); - ~PipeConnector(); + ~PipeConnector() override; - virtual int send_message(const Json& input); - virtual int recv_message(Json& output); + int send_message(const Json& input) override; + int recv_message(Json& output) override; private: void launch(); - bool checkStatus(); + [[nodiscard]] bool checkStatus() const; std::string command; std::map options; - int d_fd1[2], d_fd2[2]; + int d_fd1[2]{}, d_fd2[2]{}; int d_pid; int d_timeout; std::unique_ptr d_fp{nullptr, fclose}; @@ -162,7 +165,7 @@ class RemoteBackend : public DNSBackend { public: RemoteBackend(const std::string& suffix = ""); - ~RemoteBackend(); + ~RemoteBackend() override; void lookup(const QType& qtype, const DNSName& qdomain, int zoneId = -1, DNSPacket* pkt_p = nullptr) override; bool get(DNSResourceRecord& rr) override; @@ -211,35 +214,41 @@ private: std::unique_ptr connector; bool d_dnssec; Json d_result; - int d_index; - int64_t d_trxid; + int d_index{-1}; + int64_t d_trxid{0}; std::string d_connstr; bool send(Json& value); bool recv(Json& value); - void makeErrorAndThrow(Json& value); + static void makeErrorAndThrow(Json& value); - string asString(const Json& value) + static string asString(const Json& value) { - if (value.is_number()) + if (value.is_number()) { return std::to_string(value.int_value()); - if (value.is_bool()) + } + if (value.is_bool()) { return (value.bool_value() ? "1" : "0"); - if (value.is_string()) + } + if (value.is_string()) { return value.string_value(); + } throw JsonException("Json value not convertible to String"); }; - bool asBool(const Json& value) + static bool asBool(const Json& value) { - if (value.is_bool()) + if (value.is_bool()) { return value.bool_value(); + } try { string val = asString(value); - if (val == "0") + if (val == "0") { return false; - if (val == "1") + } + if (val == "1") { return true; + } } catch (const JsonException&) { }; diff --git a/modules/remotebackend/test-remotebackend-http.cc b/modules/remotebackend/test-remotebackend-http.cc index bcfb51e7c5fb..824db562037c 100644 --- a/modules/remotebackend/test-remotebackend-http.cc +++ b/modules/remotebackend/test-remotebackend-http.cc @@ -67,7 +67,7 @@ struct RemotebackendSetup { RemotebackendSetup() { - be = 0; + be = nullptr; try { // setup minimum arguments ::arg().set("module-dir") = "./.libs"; @@ -82,7 +82,7 @@ struct RemotebackendSetup BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason); }; } - ~RemotebackendSetup() {} + ~RemotebackendSetup() = default; }; BOOST_GLOBAL_FIXTURE(RemotebackendSetup); diff --git a/modules/remotebackend/test-remotebackend-json.cc b/modules/remotebackend/test-remotebackend-json.cc index 266b73aca61c..48d023ed8299 100644 --- a/modules/remotebackend/test-remotebackend-json.cc +++ b/modules/remotebackend/test-remotebackend-json.cc @@ -66,7 +66,7 @@ struct RemotebackendSetup { RemotebackendSetup() { - be = 0; + be = nullptr; try { // setup minimum arguments ::arg().set("module-dir") = "./.libs"; @@ -81,7 +81,7 @@ struct RemotebackendSetup BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason); }; } - ~RemotebackendSetup() {} + ~RemotebackendSetup() = default; }; BOOST_GLOBAL_FIXTURE(RemotebackendSetup); diff --git a/modules/remotebackend/test-remotebackend-keys.hh b/modules/remotebackend/test-remotebackend-keys.hh index 807bdd8609e9..ac501b57086f 100644 --- a/modules/remotebackend/test-remotebackend-keys.hh +++ b/modules/remotebackend/test-remotebackend-keys.hh @@ -19,6 +19,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include +#include + DNSBackend::KeyData k1 = {std::string("Private-key-format: v1.2\nAlgorithm: 5 (RSASHA1)\nModulus: qpe9fxlN4dBT38cLPWtqljZhcJjbqRprj9XsYmf2/uFu4kA5sHYrlQY7H9lpzGJPRfOAfxShBpKs1AVaVInfJQ==\nPublicExponent: AQAB\nPrivateExponent: Ad3YogzXvVDLsWuAfioY571QlolbdTbzVlhLEMLD6dSRx+xcZgw6c27ak2HAH00iSKTvqK3AyeaK8Eqy/oJ5QQ==\nPrime1: wo8LZrdU2y0xLGCeLhwziQDDtTMi18NEIwlx8tUPnhs=\nPrime2: 4HcuFqgo7NOiXFvN+V2PT+QaIt2+oi6D2m8/qtTDS78=\nExponent1: GUdCoPbi9JM7l1t6Ud1iKMPLqchaF5SMTs0UXAuous8=\nExponent2: nzgKqimX9f1corTAEw0pddrwKyEtcu8ZuhzFhZCsAxM=\nCoefficient: YGNxbulf5GTNiIu0oNKmAF0khNtx9layjOPEI0R4/RY="), 1, 257, true, true}; DNSBackend::KeyData k2 = {std::string("Private-key-format: v1.2\nAlgorithm: 5 (RSASHA1)\nModulus: tY2TAMgL/whZdSbn2aci4wcMqohO24KQAaq5RlTRwQ33M8FYdW5fZ3DMdMsSLQUkjGnKJPKEdN3Qd4Z5b18f+w==\nPublicExponent: AQAB\nPrivateExponent: BB6xibPNPrBV0PUp3CQq0OdFpk9v9EZ2NiBFrA7osG5mGIZICqgOx/zlHiHKmX4OLmL28oU7jPKgogeuONXJQQ==\nPrime1: yjxe/iHQ4IBWpvCmuGqhxApWF+DY9LADIP7bM3Ejf3M=\nPrime2: 5dGWTyYEQRBVK74q1a64iXgaNuYm1pbClvvZ6ccCq1k=\nExponent1: TwM5RebmWeAqerzJFoIqw5IaQugJO8hM4KZR9A4/BTs=\nExponent2: bpV2HSmu3Fvuj7jWxbFoDIXlH0uJnrI2eg4/4hSnvSk=\nCoefficient: e2uDDWN2zXwYa2P6VQBWQ4mR1ZZjFEtO/+YqOJZun1Y="), 2, 256, true, true}; diff --git a/modules/remotebackend/test-remotebackend-pipe.cc b/modules/remotebackend/test-remotebackend-pipe.cc index e293a48ad8bc..6ad872c28127 100644 --- a/modules/remotebackend/test-remotebackend-pipe.cc +++ b/modules/remotebackend/test-remotebackend-pipe.cc @@ -66,7 +66,7 @@ struct RemotebackendSetup { RemotebackendSetup() { - be = 0; + be = nullptr; try { // setup minimum arguments ::arg().set("module-dir") = "./.libs"; @@ -85,7 +85,7 @@ struct RemotebackendSetup BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason); }; } - ~RemotebackendSetup() {} + ~RemotebackendSetup() = default; }; BOOST_GLOBAL_FIXTURE(RemotebackendSetup); diff --git a/modules/remotebackend/test-remotebackend-post.cc b/modules/remotebackend/test-remotebackend-post.cc index 10e5e09932fb..fe129623f16c 100644 --- a/modules/remotebackend/test-remotebackend-post.cc +++ b/modules/remotebackend/test-remotebackend-post.cc @@ -66,7 +66,7 @@ struct RemotebackendSetup { RemotebackendSetup() { - be = 0; + be = nullptr; try { // setup minimum arguments ::arg().set("module-dir") = "./.libs"; @@ -81,7 +81,7 @@ struct RemotebackendSetup BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason); }; } - ~RemotebackendSetup() {} + ~RemotebackendSetup() = default; }; BOOST_GLOBAL_FIXTURE(RemotebackendSetup); diff --git a/modules/remotebackend/test-remotebackend-unix.cc b/modules/remotebackend/test-remotebackend-unix.cc index 5ccdf1aef621..fd2c1b15a6aa 100644 --- a/modules/remotebackend/test-remotebackend-unix.cc +++ b/modules/remotebackend/test-remotebackend-unix.cc @@ -66,7 +66,7 @@ struct RemotebackendSetup { RemotebackendSetup() { - be = 0; + be = nullptr; try { // setup minimum arguments ::arg().set("module-dir") = "./.libs"; @@ -85,7 +85,7 @@ struct RemotebackendSetup BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason); }; } - ~RemotebackendSetup() {} + ~RemotebackendSetup() = default; }; BOOST_GLOBAL_FIXTURE(RemotebackendSetup); diff --git a/modules/remotebackend/test-remotebackend-zeromq.cc b/modules/remotebackend/test-remotebackend-zeromq.cc index dc346b7035a1..bccf0768372d 100644 --- a/modules/remotebackend/test-remotebackend-zeromq.cc +++ b/modules/remotebackend/test-remotebackend-zeromq.cc @@ -68,7 +68,7 @@ struct RemotebackendSetup { RemotebackendSetup() { - be = 0; + be = nullptr; try { // setup minimum arguments ::arg().set("module-dir") = "./.libs"; @@ -87,7 +87,7 @@ struct RemotebackendSetup BOOST_TEST_MESSAGE("Cannot start remotebackend: " << ex.reason); }; } - ~RemotebackendSetup() {} + ~RemotebackendSetup() = default; }; BOOST_GLOBAL_FIXTURE(RemotebackendSetup); diff --git a/modules/remotebackend/test-remotebackend.cc b/modules/remotebackend/test-remotebackend.cc index 443713cc8d64..e4a43208bf9d 100644 --- a/modules/remotebackend/test-remotebackend.cc +++ b/modules/remotebackend/test-remotebackend.cc @@ -75,8 +75,9 @@ BOOST_AUTO_TEST_CASE(test_method_list) BOOST_TEST_MESSAGE("Testing list method"); be->list(DNSName("unit.test."), -1); - while (be->get(rr)) + while (be->get(rr)) { record_count++; + } BOOST_CHECK_EQUAL(record_count, 5); // number of records our test domain has } @@ -90,7 +91,7 @@ BOOST_AUTO_TEST_CASE(test_method_doesDNSSEC) BOOST_AUTO_TEST_CASE(test_method_setDomainMetadata) { std::vector meta; - meta.push_back("VALUE"); + meta.emplace_back("VALUE"); BOOST_TEST_MESSAGE("Testing setDomainMetadata method"); BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."), "TEST", meta)); } @@ -102,8 +103,9 @@ BOOST_AUTO_TEST_CASE(test_method_alsoNotifies) BOOST_TEST_MESSAGE("Testing alsoNotifies method"); be->alsoNotifies(DNSName("unit.test."), &alsoNotifies); BOOST_CHECK_EQUAL(alsoNotifies.size(), 1); - if (alsoNotifies.size() > 0) + if (!alsoNotifies.empty()) { BOOST_CHECK_EQUAL(alsoNotifies.count("192.0.2.1"), 1); + } BOOST_CHECK(be->setDomainMetadata(DNSName("unit.test."), "ALSO-NOTIFY", std::vector())); } @@ -115,8 +117,9 @@ BOOST_AUTO_TEST_CASE(test_method_getDomainMetadata) BOOST_CHECK_EQUAL(meta.size(), 1); // in case we got more than one value, which would be unexpected // but not fatal - if (meta.size() > 0) + if (!meta.empty()) { BOOST_CHECK_EQUAL(meta[0], "VALUE"); + } } BOOST_AUTO_TEST_CASE(test_method_getAllDomainMetadata) @@ -127,14 +130,15 @@ BOOST_AUTO_TEST_CASE(test_method_getAllDomainMetadata) BOOST_CHECK_EQUAL(meta.size(), 1); // in case we got more than one value, which would be unexpected // but not fatal - if (meta.size() > 0) + if (!meta.empty()) { BOOST_CHECK_EQUAL(meta["TEST"][0], "VALUE"); + } } BOOST_AUTO_TEST_CASE(test_method_addDomainKey) { BOOST_TEST_MESSAGE("Testing addDomainKey method"); - int64_t id; + int64_t id = 0; be->addDomainKey(DNSName("unit.test."), k1, id); BOOST_CHECK_EQUAL(id, 1); be->addDomainKey(DNSName("unit.test."), k2, id); @@ -182,7 +186,9 @@ BOOST_AUTO_TEST_CASE(test_method_removeDomainKey) BOOST_AUTO_TEST_CASE(test_method_getBeforeAndAfterNamesAbsolute) { - DNSName unhashed, before, after; + DNSName unhashed; + DNSName before; + DNSName after; BOOST_TEST_MESSAGE("Testing getBeforeAndAfterNamesAbsolute method"); be->getBeforeAndAfterNamesAbsolute(-1, DNSName("middle.unit.test."), unhashed, before, after); @@ -193,7 +199,8 @@ BOOST_AUTO_TEST_CASE(test_method_getBeforeAndAfterNamesAbsolute) BOOST_AUTO_TEST_CASE(test_method_setTSIGKey) { - std::string algorithm, content; + std::string algorithm; + std::string content; BOOST_TEST_MESSAGE("Testing setTSIGKey method"); BOOST_CHECK_MESSAGE(be->setTSIGKey(DNSName("unit.test."), DNSName("hmac-md5."), "kp4/24gyYsEzbuTVJRUMoqGFmN3LYgVDzJ/3oRSP7ys="), "did not return true"); } @@ -210,7 +217,8 @@ BOOST_AUTO_TEST_CASE(test_method_getTSIGKey) BOOST_AUTO_TEST_CASE(test_method_deleteTSIGKey) { - std::string algorithm, content; + std::string algorithm; + std::string content; BOOST_TEST_MESSAGE("Testing deleteTSIGKey method"); BOOST_CHECK_MESSAGE(be->deleteTSIGKey(DNSName("unit.test.")), "did not return true"); } @@ -220,8 +228,8 @@ BOOST_AUTO_TEST_CASE(test_method_getTSIGKeys) std::vector keys; BOOST_TEST_MESSAGE("Testing getTSIGKeys method"); be->getTSIGKeys(keys); - BOOST_CHECK(keys.size() > 0); - if (keys.size() > 0) { + BOOST_CHECK(!keys.empty()); + if (!keys.empty()) { BOOST_CHECK_EQUAL(keys[0].name.toString(), "test."); BOOST_CHECK_EQUAL(keys[0].algorithm.toString(), "NULL."); BOOST_CHECK_EQUAL(keys[0].key, "NULL"); @@ -268,7 +276,7 @@ BOOST_AUTO_TEST_CASE(test_method_superMasterBackend) { DNSResourceRecord rr; std::vector nsset; - DNSBackend* dbd; + DNSBackend* dbd = nullptr; BOOST_TEST_MESSAGE("Testing superMasterBackend method"); rr.qname = DNSName("example.com."); @@ -284,7 +292,7 @@ BOOST_AUTO_TEST_CASE(test_method_superMasterBackend) rr.content = "ns2.example.com."; nsset.push_back(rr); - BOOST_CHECK(be->superMasterBackend("10.0.0.1", DNSName("example.com."), nsset, NULL, NULL, &dbd)); + BOOST_CHECK(be->superMasterBackend("10.0.0.1", DNSName("example.com."), nsset, nullptr, nullptr, &dbd)); // let's see what we got BOOST_CHECK_EQUAL(dbd, be); @@ -376,7 +384,7 @@ BOOST_AUTO_TEST_CASE(test_method_getUpdatedMasters) be->getUpdatedMasters(result, catalogs, hashes); - BOOST_REQUIRE(result.size() > 0); + BOOST_REQUIRE(!result.empty()); di = result.at(0); BOOST_CHECK_EQUAL(di.zone.toString(), "master.test."); diff --git a/modules/remotebackend/unixconnector.cc b/modules/remotebackend/unixconnector.cc index 9fd071528bf6..82447c617264 100644 --- a/modules/remotebackend/unixconnector.cc +++ b/modules/remotebackend/unixconnector.cc @@ -62,42 +62,52 @@ int UnixsocketConnector::send_message(const Json& input) { auto data = input.dump() + "\n"; int rv = this->write(data); - if (rv == -1) + if (rv == -1) { return -1; + } return rv; } int UnixsocketConnector::recv_message(Json& output) { - int rv; - std::string s_output, err; - - struct timeval t0, t; - - gettimeofday(&t0, NULL); + int rv = 0; + std::string s_output; + std::string err; + + struct timeval t0 + { + }; + struct timeval t + { + }; + + gettimeofday(&t0, nullptr); memcpy(&t, &t0, sizeof(t0)); s_output = ""; while ((t.tv_sec - t0.tv_sec) * 1000 + (t.tv_usec - t0.tv_usec) / 1000 < this->timeout) { int avail = waitForData(this->fd, 0, this->timeout * 500); // use half the timeout as poll timeout - if (avail < 0) // poll error + if (avail < 0) { // poll error return -1; + } if (avail == 0) { // timeout - gettimeofday(&t, NULL); + gettimeofday(&t, nullptr); continue; } rv = this->read(s_output); - if (rv == -1) + if (rv == -1) { return -1; + } if (rv > 0) { // see if it can be parsed output = Json::parse(s_output, err); - if (output != nullptr) + if (output != nullptr) { return s_output.size(); + } } - gettimeofday(&t, NULL); + gettimeofday(&t, nullptr); } close(fd); @@ -107,17 +117,19 @@ int UnixsocketConnector::recv_message(Json& output) ssize_t UnixsocketConnector::read(std::string& data) { - ssize_t nread; + ssize_t nread = 0; char buf[1500] = {0}; reconnect(); - if (!connected) + if (!connected) { return -1; + } nread = ::read(this->fd, buf, sizeof buf); // just try again later... - if (nread == -1 && errno == EAGAIN) + if (nread == -1 && errno == EAGAIN) { return 0; + } if (nread == -1 || nread == 0) { connected = false; @@ -134,8 +146,9 @@ ssize_t UnixsocketConnector::write(const std::string& data) size_t pos = 0; reconnect(); - if (!connected) + if (!connected) { return -1; + } while (pos < data.size()) { ssize_t written = ::write(fd, &data.at(pos), data.size() - pos); @@ -144,20 +157,21 @@ ssize_t UnixsocketConnector::write(const std::string& data) close(fd); return -1; } - else { - pos = pos + static_cast(written); - } + pos = pos + static_cast(written); } return pos; } void UnixsocketConnector::reconnect() { - struct sockaddr_un sock; - int rv; + struct sockaddr_un sock + { + }; + int rv = 0; - if (connected) + if (connected) { return; // no point reconnecting if connected... + } connected = true; g_log << Logger::Info << "Reconnecting to backend" << std::endl; @@ -169,7 +183,7 @@ void UnixsocketConnector::reconnect() return; } - if (makeUNsockaddr(path, &sock)) { + if (makeUNsockaddr(path, &sock) != 0) { g_log << Logger::Error << "Unable to create UNIX domain socket: Path '" << path << "' is not a valid UNIX socket path." << std::endl; return; } @@ -192,7 +206,7 @@ void UnixsocketConnector::reconnect() this->send(msg); msg = nullptr; - if (this->recv(msg) == false) { + if (!this->recv(msg)) { g_log << Logger::Warning << "Failed to initialize backend" << std::endl; close(fd); this->connected = false; diff --git a/modules/remotebackend/zmqconnector.cc b/modules/remotebackend/zmqconnector.cc index 86544eda209c..cce0f3a5ea41 100644 --- a/modules/remotebackend/zmqconnector.cc +++ b/modules/remotebackend/zmqconnector.cc @@ -59,13 +59,13 @@ ZeroMQConnector::ZeroMQConnector(std::map options) : this->send(msg); msg = nullptr; - if (this->recv(msg) == false) { + if (!this->recv(msg)) { g_log << Logger::Error << "Failed to initialize zeromq" << std::endl; throw PDNSException("Failed to initialize zeromq"); } }; -ZeroMQConnector::~ZeroMQConnector() {} +ZeroMQConnector::~ZeroMQConnector() = default; int ZeroMQConnector::send_message(const Json& input) { @@ -88,8 +88,9 @@ int ZeroMQConnector::send_message(const Json& input) // message was not sent g_log << Logger::Error << "Cannot send to " << this->d_endpoint << ": " << zmq_strerror(errno) << std::endl; } - else + else { return line.size(); + } } } } @@ -120,7 +121,7 @@ int ZeroMQConnector::recv_message(Json& output) // we have an event if ((item.revents & ZMQ_POLLIN) == ZMQ_POLLIN) { string data; - size_t msg_size; + size_t msg_size = 0; zmq_msg_init(&message); // read something if (zmq_msg_recv(&message, this->d_sock.get(), ZMQ_NOBLOCK) > 0) { @@ -129,18 +130,18 @@ int ZeroMQConnector::recv_message(Json& output) data.assign(reinterpret_cast(zmq_msg_data(&message)), msg_size); zmq_msg_close(&message); output = Json::parse(data, err); - if (output != nullptr) + if (output != nullptr) { rv = msg_size; - else + } + else { g_log << Logger::Error << "Cannot parse JSON reply from " << this->d_endpoint << ": " << err << endl; + } break; } - else if (errno == EAGAIN) { + if (errno == EAGAIN) { continue; // try again } } - else { - break; - } + break; } } } From 1592789438ad354e8c9a9e0848ebac754cb925ae Mon Sep 17 00:00:00 2001 From: Ewoud Kohl van Wijngaarden Date: Tue, 3 Oct 2023 17:13:21 +0200 Subject: [PATCH 782/909] Match the lmdb-filename example with the default The default config places it in /var/lib, which is a more logical place for a DB. --- docs/backends/lmdb.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/backends/lmdb.rst b/docs/backends/lmdb.rst index 03ef9623cd0d..178dcf738cd2 100644 --- a/docs/backends/lmdb.rst +++ b/docs/backends/lmdb.rst @@ -32,7 +32,7 @@ Settings ``lmdb-filename`` ^^^^^^^^^^^^^^^^^ -Path to the LMDB file (e.g. */var/spool/powerdns/pdns.lmdb*) +Path to the LMDB file (e.g. */var/lib/powerdns/pdns.lmdb*) .. warning:: On systemd systems, From d0a8b2d9f86bf0948831cf08ebf9e8531687eae1 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 3 Oct 2023 15:18:28 +0200 Subject: [PATCH 783/909] Import clang-tidy-diff.py --- .github/scripts/clang-tidy-diff.py | 279 +++++++++++++++++++++++++++++ 1 file changed, 279 insertions(+) create mode 100755 .github/scripts/clang-tidy-diff.py diff --git a/.github/scripts/clang-tidy-diff.py b/.github/scripts/clang-tidy-diff.py new file mode 100755 index 000000000000..396a201b667e --- /dev/null +++ b/.github/scripts/clang-tidy-diff.py @@ -0,0 +1,279 @@ +#!/usr/bin/env python3 +# +#===- clang-tidy-diff.py - ClangTidy Diff Checker -----------*- python -*--===# +# +# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +# See https://llvm.org/LICENSE.txt for license information. +# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +# +#===-----------------------------------------------------------------------===# + +r""" +ClangTidy Diff Checker +====================== + +This script reads input from a unified diff, runs clang-tidy on all changed +files and outputs clang-tidy warnings in changed lines only. This is useful to +detect clang-tidy regressions in the lines touched by a specific patch. +Example usage for git/svn users: + + git diff -U0 HEAD^ | clang-tidy-diff.py -p1 + svn diff --diff-cmd=diff -x-U0 | \ + clang-tidy-diff.py -fix -checks=-*,modernize-use-override + +""" + +import argparse +import glob +import json +import multiprocessing +import os +import re +import shutil +import subprocess +import sys +import tempfile +import threading +import traceback + +try: + import yaml +except ImportError: + yaml = None + +is_py2 = sys.version[0] == '2' + +if is_py2: + import Queue as queue +else: + import queue as queue + + +def run_tidy(task_queue, lock, timeout): + watchdog = None + while True: + command = task_queue.get() + try: + proc = subprocess.Popen(command, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + + if timeout is not None: + watchdog = threading.Timer(timeout, proc.kill) + watchdog.start() + + stdout, stderr = proc.communicate() + + with lock: + sys.stdout.write(stdout.decode('utf-8') + '\n') + sys.stdout.flush() + if stderr: + sys.stderr.write(stderr.decode('utf-8') + '\n') + sys.stderr.flush() + except Exception as e: + with lock: + sys.stderr.write('Failed: ' + str(e) + ': '.join(command) + '\n') + finally: + with lock: + if not (timeout is None or watchdog is None): + if not watchdog.is_alive(): + sys.stderr.write('Terminated by timeout: ' + + ' '.join(command) + '\n') + watchdog.cancel() + task_queue.task_done() + + +def start_workers(max_tasks, tidy_caller, task_queue, lock, timeout): + for _ in range(max_tasks): + t = threading.Thread(target=tidy_caller, args=(task_queue, lock, timeout)) + t.daemon = True + t.start() + + +def merge_replacement_files(tmpdir, mergefile): + """Merge all replacement files in a directory into a single file""" + # The fixes suggested by clang-tidy >= 4.0.0 are given under + # the top level key 'Diagnostics' in the output yaml files + mergekey = "Diagnostics" + merged = [] + for replacefile in glob.iglob(os.path.join(tmpdir, '*.yaml')): + content = yaml.safe_load(open(replacefile, 'r')) + if not content: + continue # Skip empty files. + merged.extend(content.get(mergekey, [])) + + if merged: + # MainSourceFile: The key is required by the definition inside + # include/clang/Tooling/ReplacementsYaml.h, but the value + # is actually never used inside clang-apply-replacements, + # so we set it to '' here. + output = {'MainSourceFile': '', mergekey: merged} + with open(mergefile, 'w') as out: + yaml.safe_dump(output, out) + else: + # Empty the file: + open(mergefile, 'w').close() + + +def main(): + parser = argparse.ArgumentParser(description= + 'Run clang-tidy against changed files, and ' + 'output diagnostics only for modified ' + 'lines.') + parser.add_argument('-clang-tidy-binary', metavar='PATH', + default='clang-tidy', + help='path to clang-tidy binary') + parser.add_argument('-p', metavar='NUM', default=0, + help='strip the smallest prefix containing P slashes') + parser.add_argument('-regex', metavar='PATTERN', default=None, + help='custom pattern selecting file paths to check ' + '(case sensitive, overrides -iregex)') + parser.add_argument('-iregex', metavar='PATTERN', default= + r'.*\.(cpp|cc|c\+\+|cxx|c|cl|h|hpp|m|mm|inc)', + help='custom pattern selecting file paths to check ' + '(case insensitive, overridden by -regex)') + parser.add_argument('-j', type=int, default=1, + help='number of tidy instances to be run in parallel.') + parser.add_argument('-timeout', type=int, default=None, + help='timeout per each file in seconds.') + parser.add_argument('-fix', action='store_true', default=False, + help='apply suggested fixes') + parser.add_argument('-checks', + help='checks filter, when not specified, use clang-tidy ' + 'default', + default='') + parser.add_argument('-use-color', action='store_true', + help='Use colors in output') + parser.add_argument('-path', dest='build_path', + help='Path used to read a compile command database.') + if yaml: + parser.add_argument('-export-fixes', metavar='FILE', dest='export_fixes', + help='Create a yaml file to store suggested fixes in, ' + 'which can be applied with clang-apply-replacements.') + parser.add_argument('-extra-arg', dest='extra_arg', + action='append', default=[], + help='Additional argument to append to the compiler ' + 'command line.') + parser.add_argument('-extra-arg-before', dest='extra_arg_before', + action='append', default=[], + help='Additional argument to prepend to the compiler ' + 'command line.') + parser.add_argument('-quiet', action='store_true', default=False, + help='Run clang-tidy in quiet mode') + parser.add_argument('-load', dest='plugins', + action='append', default=[], + help='Load the specified plugin in clang-tidy.') + + clang_tidy_args = [] + argv = sys.argv[1:] + if '--' in argv: + clang_tidy_args.extend(argv[argv.index('--'):]) + argv = argv[:argv.index('--')] + + args = parser.parse_args(argv) + + # Extract changed lines for each file. + filename = None + lines_by_file = {} + for line in sys.stdin: + match = re.search('^\+\+\+\ \"?(.*?/){%s}([^ \t\n\"]*)' % args.p, line) + if match: + filename = match.group(2) + if filename is None: + continue + + if args.regex is not None: + if not re.match('^%s$' % args.regex, filename): + continue + else: + if not re.match('^%s$' % args.iregex, filename, re.IGNORECASE): + continue + + match = re.search('^@@.*\+(\d+)(,(\d+))?', line) + if match: + start_line = int(match.group(1)) + line_count = 1 + if match.group(3): + line_count = int(match.group(3)) + if line_count == 0: + continue + end_line = start_line + line_count - 1 + lines_by_file.setdefault(filename, []).append([start_line, end_line]) + + if not any(lines_by_file): + print("No relevant changes found.") + sys.exit(0) + + max_task_count = args.j + if max_task_count == 0: + max_task_count = multiprocessing.cpu_count() + max_task_count = min(len(lines_by_file), max_task_count) + + tmpdir = None + if yaml and args.export_fixes: + tmpdir = tempfile.mkdtemp() + + # Tasks for clang-tidy. + task_queue = queue.Queue(max_task_count) + # A lock for console output. + lock = threading.Lock() + + # Run a pool of clang-tidy workers. + start_workers(max_task_count, run_tidy, task_queue, lock, args.timeout) + + # Form the common args list. + common_clang_tidy_args = [] + if args.fix: + common_clang_tidy_args.append('-fix') + if args.checks != '': + common_clang_tidy_args.append('-checks=' + args.checks) + if args.quiet: + common_clang_tidy_args.append('-quiet') + if args.build_path is not None: + common_clang_tidy_args.append('-p=%s' % args.build_path) + if args.use_color: + common_clang_tidy_args.append('--use-color') + for arg in args.extra_arg: + common_clang_tidy_args.append('-extra-arg=%s' % arg) + for arg in args.extra_arg_before: + common_clang_tidy_args.append('-extra-arg-before=%s' % arg) + for plugin in args.plugins: + common_clang_tidy_args.append('-load=%s' % plugin) + + for name in lines_by_file: + line_filter_json = json.dumps( + [{"name": name, "lines": lines_by_file[name]}], + separators=(',', ':')) + + # Run clang-tidy on files containing changes. + command = [args.clang_tidy_binary] + command.append('-line-filter=' + line_filter_json) + if yaml and args.export_fixes: + # Get a temporary file. We immediately close the handle so clang-tidy can + # overwrite it. + (handle, tmp_name) = tempfile.mkstemp(suffix='.yaml', dir=tmpdir) + os.close(handle) + command.append('-export-fixes=' + tmp_name) + command.extend(common_clang_tidy_args) + command.append(name) + command.extend(clang_tidy_args) + + task_queue.put(command) + + # Wait for all threads to be done. + task_queue.join() + + if yaml and args.export_fixes: + print('Writing fixes to ' + args.export_fixes + ' ...') + try: + merge_replacement_files(tmpdir, args.export_fixes) + except: + sys.stderr.write('Error exporting fixes.\n') + traceback.print_exc() + + if tmpdir: + shutil.rmtree(tmpdir) + + +if __name__ == '__main__': + main() From ae3b2b09b2374c64197a86fc4812993ad2ffd9ed Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 3 Oct 2023 15:46:24 +0200 Subject: [PATCH 784/909] clang-tidy-diff.py: clang-tidy only supports filename in filter-line, not paths --- .github/scripts/clang-tidy-diff.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/scripts/clang-tidy-diff.py b/.github/scripts/clang-tidy-diff.py index 396a201b667e..1d93fd226c95 100755 --- a/.github/scripts/clang-tidy-diff.py +++ b/.github/scripts/clang-tidy-diff.py @@ -36,6 +36,8 @@ import threading import traceback +from pathlib import Path + try: import yaml except ImportError: @@ -242,7 +244,8 @@ def main(): for name in lines_by_file: line_filter_json = json.dumps( - [{"name": name, "lines": lines_by_file[name]}], + # clang-tidy only supports filenames in -line-filter, not paths + [{"name": Path(name).name, "lines": lines_by_file[name]}], separators=(',', ':')) # Run clang-tidy on files containing changes. From 16fa78918dfd6fcdb28708d942dec9523838ceb7 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 2 Oct 2023 10:48:18 +0200 Subject: [PATCH 785/909] build-and-test-all: Fix clang-tidy now that we build in dist dirs --- .github/scripts/helpers.py | 27 ++++++++++ ...normalize_paths_in_compilation_database.py | 37 ++++++++++++++ .github/workflows/build-and-test-all.yml | 51 ++++++++++++++----- 3 files changed, 103 insertions(+), 12 deletions(-) create mode 100644 .github/scripts/normalize_paths_in_compilation_database.py diff --git a/.github/scripts/helpers.py b/.github/scripts/helpers.py index cc170d1eed5c..36969c8060f3 100644 --- a/.github/scripts/helpers.py +++ b/.github/scripts/helpers.py @@ -1,7 +1,9 @@ """Helpers for dealing with git, compilation databases, etc.""" +import pathlib import json import os +import sys import git import yaml @@ -46,3 +48,28 @@ def index_compdb(file_contents): filename = os.path.join(item["directory"], item["file"]) result.add(filename) return result + +def normalize_dist_dir(version, distPath): + """Map the path of a source file from inside the dist directory + to its path in the git repository.""" + # get rid of the distdir path, to get file paths as they are in the repository + repositoryPath = pathlib.Path(get_repo_root()).resolve() + distPath = pathlib.Path(distPath).resolve() + if f'pdns-{version}' in distPath.parts: + # authoritative or tool + authPath = repositoryPath.joinpath(f'pdns-{version}').resolve() + relativeToAuth = distPath.relative_to(authPath) + return str(repositoryPath.joinpath(relativeToAuth)) + + if f'pdns-recursor-{version}' in distPath.parts: + recPath = repositoryPath.joinpath('pdns', 'recursordist', f'pdns-recursor-{version}').resolve() + relativeToRec = distPath.relative_to(recPath) + return str(repositoryPath.joinpath('pdns', 'recursordist', relativeToRec).resolve()) + + if f'dnsdist-{version}' in distPath.parts: + dnsdistPath = repositoryPath.joinpath('pdns', 'dnsdistdist', f'dnsdist-{version}').resolve() + relativeToDist = distPath.relative_to(dnsdistPath) + return str(repositoryPath.joinpath('pdns', 'dnsdistdist', relativeToDist).resolve()) + + print(f'Unable to map {distPath}', file=sys.stderr) + return str(distPath) diff --git a/.github/scripts/normalize_paths_in_compilation_database.py b/.github/scripts/normalize_paths_in_compilation_database.py new file mode 100644 index 000000000000..f5645fb3905b --- /dev/null +++ b/.github/scripts/normalize_paths_in_compilation_database.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 + +import argparse +import os + +import json + +import helpers + +def create_argument_parser(): + """Create command-line argument parser.""" + parser = argparse.ArgumentParser( + description="Normalize paths in compilation database" + ) + parser.add_argument( + "--version", + type=str, + required=True, + help="Version number of the current build", + ) + parser.add_argument('database') + return parser.parse_args() + +if __name__ == "__main__": + """Start the script.""" + args = create_argument_parser() + + compDB = helpers.load_compdb(args.database) + for entry in compDB: + for key in ['file', 'directory']: + if key in entry: + entry[key] = helpers.normalize_dist_dir(args.version, entry[key]) + + with open(args.database + '.temp', 'w', encoding='utf-8') as outputFile: + json.dump(compDB, outputFile, ensure_ascii=False, indent=2) + + os.rename(args.database + '.temp', args.database) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index bd7d62b248ec..3b80c182b573 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -62,12 +62,19 @@ jobs: working-directory: . - run: inv ci-auth-configure - run: inv ci-auth-make-bear # This runs under pdns-$BUILDER_VERSION/pdns/ - - run: ln -s ../clang-tidy.full .clang-tidy + - name: Normalize paths in compilation DB + working-directory: . + run: python3 .github/scripts/normalize_paths_in_compilation_database.py --version $BUILDER_VERSION pdns-$BUILDER_VERSION/pdns/compile_commands.json + - name: Copy the compilation DB + working-directory: . + run: cp pdns-$BUILDER_VERSION/pdns/compile_commands.json . + - run: ln -s .clang-tidy.full .clang-tidy + working-directory: . - name: Run clang-tidy - working-directory: ./pdns-${{ env.BUILDER_VERSION }}/pdns - run: git diff -U0 HEAD^..HEAD | python3 ../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p2 -export-fixes clang-tidy-auth.yml + working-directory: . + run: git diff -U0 HEAD^..HEAD | python3 .github/scripts/git-filter.py | python3 .github/scripts/clang-tidy-diff.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p1 -export-fixes clang-tidy-auth.yml - name: Print clang-tidy fixes YAML - working-directory: ./pdns-${{ env.BUILDER_VERSION }}/pdns + working-directory: . shell: bash run: | if [ -f clang-tidy-auth.yml ]; then @@ -75,12 +82,12 @@ jobs: fi - name: Result annotations id: clang-tidy-annotations + working-directory: . shell: bash - working-directory: ./pdns-${{ env.BUILDER_VERSION }}/pdns run: | if [ -f clang-tidy-auth.yml ]; then set +e - python3 ../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-auth.yml + python3 .github/scripts/clang-tidy.py --fixes-file clang-tidy-auth.yml echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-auth-install-remotebackend-test-deps @@ -143,10 +150,19 @@ jobs: working-directory: ./pdns/recursordist/ - run: inv ci-rec-configure - run: inv ci-rec-make-bear - - run: ln -s ../../../.clang-tidy.full .clang-tidy + - name: Normalize paths in compilation DB + working-directory: . + run: python3 .github/scripts/normalize_paths_in_compilation_database.py --version $BUILDER_VERSION ./pdns/recursordist/pdns-recursor-$BUILDER_VERSION/compile_commands.json + - name: Copy compilation DB + working-directory: . + run: cp ./pdns/recursordist/pdns-recursor-$BUILDER_VERSION/compile_commands.json . + - run: ln -s .clang-tidy.full .clang-tidy + working-directory: . - name: Run clang-tidy - run: git diff -U0 HEAD^..HEAD | python3 ../../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-rec.yml + working-directory: . + run: git diff -U0 HEAD^..HEAD | python3 .github/scripts/git-filter.py | python3 .github/scripts/clang-tidy-diff.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p1 -export-fixes clang-tidy-rec.yml - name: Print clang-tidy fixes YAML + working-directory: . shell: bash run: | if [ -f clang-tidy-rec.yml ]; then @@ -154,11 +170,12 @@ jobs: fi - name: Result annotations id: clang-tidy-annotations + working-directory: . shell: bash run: | if [ -f clang-tidy-rec.yml ]; then set +e - python ../../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-rec.yml + python .github/scripts/clang-tidy.py --fixes-file clang-tidy-rec.yml echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-rec-run-unit-tests @@ -223,10 +240,19 @@ jobs: working-directory: ./pdns/dnsdistdist/ - run: inv ci-dnsdist-configure ${{ matrix.features }} - run: inv ci-dnsdist-make-bear - - run: ln -s ../../../.clang-tidy.full .clang-tidy + - name: Normalize paths in compilation DB + working-directory: . + run: python3 .github/scripts/normalize_paths_in_compilation_database.py --version $BUILDER_VERSION ./pdns/dnsdistdist/dnsdist-$BUILDER_VERSION/compile_commands.json + - name: Copy compilation DB + run: cp ./pdns/dnsdistdist/dnsdist-$BUILDER_VERSION/compile_commands.json compile_commands.json + working-directory: . + - run: ln -s .clang-tidy.full .clang-tidy + working-directory: . - name: Run clang-tidy - run: git diff -U0 HEAD^..HEAD | python3 ../../../.github/scripts/git-filter.py | python3 /usr/bin/clang-tidy-diff-${CLANG_VERSION}.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p3 -export-fixes clang-tidy-dnsdist.yml + working-directory: . + run: git diff -U0 HEAD^..HEAD | python3 .github/scripts/git-filter.py | python3 .github/scripts/clang-tidy-diff.py -clang-tidy-binary /usr/bin/clang-tidy-${CLANG_VERSION} -extra-arg=-ferror-limit=0 -p1 -export-fixes clang-tidy-dnsdist.yml - name: Print clang-tidy fixes YAML + working-directory: . shell: bash run: | if [ -f clang-tidy-dnsdist.yml ]; then @@ -234,11 +260,12 @@ jobs: fi - name: Result annotations id: clang-tidy-annotations + working-directory: . shell: bash run: | if [ -f clang-tidy-dnsdist.yml ]; then set +e - python ../../../.github/scripts/clang-tidy.py --fixes-file clang-tidy-dnsdist.yml + python .github/scripts/clang-tidy.py --fixes-file clang-tidy-dnsdist.yml echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-dnsdist-run-unit-tests From 02e9744fd616227e023be94c320c9fc5bebb32d0 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 3 Oct 2023 15:48:10 +0200 Subject: [PATCH 786/909] git-filter.py: Document that we cannot normalize here --- .github/scripts/git-filter.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/scripts/git-filter.py b/.github/scripts/git-filter.py index 14033eb38eda..d776cc550222 100755 --- a/.github/scripts/git-filter.py +++ b/.github/scripts/git-filter.py @@ -16,6 +16,10 @@ def main(): """Start the script.""" + # It might be tempting to normalize the paths here instead of + # rewriting the compilation database, but then clang-tidy + # loses the depth of files in the repository, outputing for + # example "credentials.cc" instead of "pdns/credentials.cc" compdb = helpers.load_compdb("compile_commands.json") compdb = helpers.index_compdb(compdb) From a59f52421be74bfc67f4f40a3010ac4ed9f66b6f Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 3 Oct 2023 16:26:30 +0200 Subject: [PATCH 787/909] git-filter: We no longer need to check for non pdns/ paths --- .github/scripts/git-filter.py | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/.github/scripts/git-filter.py b/.github/scripts/git-filter.py index d776cc550222..aa05904f0a5e 100755 --- a/.github/scripts/git-filter.py +++ b/.github/scripts/git-filter.py @@ -32,25 +32,6 @@ def main(): for patch in patch_set: path = os.path.join(root, patch.path) if path in compdb: - if not patch.path.startswith(pdns_path): - # If the file being diffed is not under the pdns/ directory, we - # need to reconstruct its filename in the patch adding extra - # paths that clang-tidy-diff will get rid of: this way - # clang-tidy can work with the correct file path. - # - # Example with a source file under modules/: - # patch.path = modules/foo/foo.cc - # path = /home/user/workspace/pdns/modules/foo/foo.cc - # cwd = /home/user/workspace/pdns/pdns/ - # relpath = ../modules/foo/foo.cc - # - # Then the patch filenames would be: - # patch.source_file = a/pdns/../modules/foo/foo.cc - # patch.target_file = b/pdns/../modules/foo/foo.cc - relpath = os.path.relpath(path, cwd) - if patch.source_file is not None: - patch.source_file = os.path.join("a", "pdns", relpath) - patch.target_file = os.path.join("b", "pdns", relpath) print(patch) else: msg = f"Skipping {path}: it is not in the compilation db" From 9a67feab168b35f2d5c7bc324ea0ff6aa29971b9 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 3 Oct 2023 15:47:04 +0200 Subject: [PATCH 788/909] clang-tidy.py: We need to output relative paths in annotations --- .github/scripts/clang-tidy.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/.github/scripts/clang-tidy.py b/.github/scripts/clang-tidy.py index 856be887f67c..4fafc03e168c 100755 --- a/.github/scripts/clang-tidy.py +++ b/.github/scripts/clang-tidy.py @@ -33,6 +33,7 @@ def main(): """Start the script.""" args = create_argument_parser() + repo_root_dir = Path(helpers.get_repo_root()) fixes_path = Path(args.fixes_file) compdb_filename = os.path.join(fixes_path.parent, "compile_commands.json") compdb = helpers.load_compdb(compdb_filename) @@ -67,14 +68,6 @@ def main(): else os.path.join(directory, filename) ) - if full_filename not in compdb: - print( - f"Skipping `{full_filename}`" - " because it is not found" - " in the compilation database" - ) - continue - try: file_contents = helpers.load_file(full_filename) except OSError: @@ -85,16 +78,17 @@ def main(): line = helpers.get_line_from_offset(file_contents, offset) + relative_filename = Path(full_filename).resolve().relative_to(repo_root_dir) annotation = "".join( [ - f"::warning file={full_filename},line={line}", + f"::warning file={relative_filename},line={line}", f"::{message} ({name} - Level={level})", ] ) print(annotation) # User-friendly printout - print(f"{level}: {full_filename}:{line}: {message} ({name})") + print(f"{level}: {relative_filename}:{line}: {message} ({name})") have_warnings = True From a6d98578316a34667baa8698cd6045aa3c22ec4b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 6 Oct 2023 09:21:26 +0200 Subject: [PATCH 789/909] dnsdist: Display the rule name, if any, in the web interface MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As suggested by Sébastien Riccio. --- pdns/dnsdist-web.cc | 1 + pdns/dnsdistdist/html/local.js | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/pdns/dnsdist-web.cc b/pdns/dnsdist-web.cc index 8477b765bba2..69f543621e50 100644 --- a/pdns/dnsdist-web.cc +++ b/pdns/dnsdist-web.cc @@ -1263,6 +1263,7 @@ static void handleStats(const YaHTTP::Request& req, YaHTTP::Response& resp) {"id", num++}, {"creationOrder", (double)a.d_creationOrder}, {"uuid", boost::uuids::to_string(a.d_id)}, + {"name", a.d_name}, {"matches", (double)a.d_rule->d_matches}, {"rule", a.d_rule->toString()}, {"action", a.d_action->toString()}, diff --git a/pdns/dnsdistdist/html/local.js b/pdns/dnsdistdist/html/local.js index cefb0a4d9650..1db6999dbaa0 100644 --- a/pdns/dnsdistdist/html/local.js +++ b/pdns/dnsdistdist/html/local.js @@ -204,10 +204,10 @@ $(document).ready(function() { bouw = bouw + "
        Dyn blocked netmaskSecondsBlockseBPFReason
        "+a+""+b.seconds+""+b.blocks+""+b.reason+"
        "+a+""+b.seconds+""+b.blocks+""+b.ebpf+""+b.reason+"
        "; $("#downstreams").html(bouw); - bouw=''; + bouw='
        #RuleActionMatches
        '; if(data["rules"].length) { $.each(data["rules"], function(a,b) { - bouw = bouw + (""); + bouw = bouw + (""); bouw = bouw + (""); }); } @@ -216,10 +216,10 @@ $(document).ready(function() { bouw = bouw + "
        #NameRuleActionMatches
        "+b["id"]+""+b["rule"]+""+b["action"]+"
        "+b["id"]+""+b["name"]+""+b["rule"]+""+b["action"]+""+b["matches"]+"
        "; $("#rules").html(bouw); - bouw=''; + bouw='
        #Response RuleActionMatches
        '; if(data["response-rules"].length) { $.each(data["response-rules"], function(a,b) { - bouw = bouw + (""); + bouw = bouw + (""); bouw = bouw + (""); }); } From 9d89cf23b63d7a1a679e7aa53991c10cf0a60866 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 6 Oct 2023 12:14:26 +0200 Subject: [PATCH 790/909] BUILDING-PACKAGES: Document how to build packages --- BUILDING-PACKAGES.md | 95 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 BUILDING-PACKAGES.md diff --git a/BUILDING-PACKAGES.md b/BUILDING-PACKAGES.md new file mode 100644 index 000000000000..5a56d89bfa2c --- /dev/null +++ b/BUILDING-PACKAGES.md @@ -0,0 +1,95 @@ +Building packages +================= + +PowerDNS uses the pdns-builder tool to generate packages for its products. The actual workflow can be found in the [builder-support](https://github.com/PowerDNS/pdns/tree/master/builder-support) directory of the git repository. +The [build-tags.yml](https://github.com/PowerDNS/pdns/blob/master/.github/workflows/build-tags.yml) workflow automatically builds packages when a tag is pushed, so there is no need to trigger a manual build for releases, and actually doing so would be worse from a provenance point of view where full automation is always better. + +Building packages on your own computer +-------------------------------------- + +1. Clone our git repo (`git clone https://github.com/PowerDNS/pdns.git`) +2. Check out the version you want, it can be a git tag like dnsdist-1.8.1, a git commit ID or branch +3. Update submodules (`git submodule update --init --recursive`) +4. Execute `builder/build.sh` to see what arguments it supports +5. Then run `builder/build.sh` with the arguments you want (for example, `builder/build.sh -m recursor ubuntu-bionic`) + +Building packages from GitHub actions +------------------------------------- + +You can build packages from your own fork of the PowerDNS repository. Go to the [PowerDNS/pdns](https://github.com/PowerDNS/pdns) repository and click on `Fork` at the top right of the screen. When asked if you would like to only copy the master branch, say no, as otherwise you will not be able to build packages from tagged releases. If you have already done so and have not done any modification to your fork, the easiest way is to delete and recreate it. + +On your fork, go to the `Actions` tab. You will be greeted by a message stating `Workflows aren’t being run on this forked repository`. You can click `I understand my workflows, go ahead and enable them`. + +Please be aware that by default some of the workflows are executed once every day, and enabling them will consume billing time our of your GitHub actions quota, although at the moment GitHub disables these by default: `This scheduled workflow is disabled because scheduled workflows are disabled by default in forks`. + +On the left side, click on `Trigger specific package build`. + +Locate the `Run workflow` dropdown item on the top right side of the screen, inside the blue region stating `This workflow has a workflow_dispatch event trigger.` It will open a menu with several options: +- `Branch`: you can keep `master` here, unless you need to build for an operating system which is not in the list, in which case you will have to create a new branch and add the required file for this OS. See `Adding a new OS` below. +- `Product to build`: select the product you want to build packages for, for example `dnsdist` +- `OSes to build for, space separated`: keep one or more OSes you want to build packages for, for example `ubuntu-focal` +- `git ref to checkout`: the exact version you want to build. It can be the name of branch, a git tag or a git commit ID. Most likely you will be willing to build from a tagged release, like `dnsdist-1.8.1`. +- `is this a release build?`: Keep `NO` + +Click `Run workflow` to start the build. + +If you reload the page, you should now see your build in progress as a `Trigger specific package build` workflow run. It will take some time to finish, but you can look at the progress by clicking on it. + +Once it's done, you can retrieve the generated package in the list of artifacts on the `Summary` page of the workflow run, by clicking on the `Summary` link on the top right of the screen. + +Adding a new OS to the list +--------------------------- + +Adding a new OS is usually easy, provided that it does not differ too much from an existing one. For example, to add support for Debian Bookworm (already present in the current repository), one had to: + +Copy the existing instructions for Debian Buster: +``` +cp builder-support/dockerfiles/Dockerfile.target.debian-buster builder-support/dockerfiles/Dockerfile.target.debian-bookworm +``` + +In the new `builder-support/dockerfiles/Dockerfile.target.debian-bookworm` file, replace every occurence of `debian-buster` by `debian-bookworm`, and of `debian:buster` by `debian:bookworm` + +Create symbolic links for the amd64 and arm64 versions: +``` +ln -s builder-support/dockerfiles/Dockerfile.target.debian-bookworm builder-support/dockerfiles/Dockerfile.target.debian-bookworm-amd64 +ln -s builder-support/dockerfiles/Dockerfile.target.debian-bookworm builder-support/dockerfiles/Dockerfile.target.debian-bookworm-arm64 +``` + +Then add the new target to the list of OSes in the `.github/workflows/builder-dispatch.yml` workflow file: +``` +default: >- + el-7 + el-8 + el-9 + debian-buster + debian-bullseye + debian-bookworm + ubuntu-focal + ubuntu-jammy +``` + +If release packages should be automatically built for this new target, then `.github/workflows/build-packages.yml` has to be updated as well: +`` +``` +default: >- + el-7 + el-8 + el-9 + debian-buster + debian-bullseye + debian-bookworm + ubuntu-focal + ubuntu-jammy +``` + +Not forgetting to update the list of hashes later in the same file: +``` +pkghashes-el-7: ${{ steps.pkghashes.outputs.pkghashes-el-7 }} +pkghashes-el-8: ${{ steps.pkghashes.outputs.pkghashes-el-8 }} +pkghashes-el-9: ${{ steps.pkghashes.outputs.pkghashes-el-9 }} +pkghashes-debian-buster: ${{ steps.pkghashes.outputs.pkghashes-debian-buster }} +pkghashes-debian-bullseye: ${{ steps.pkghashes.outputs.pkghashes-debian-bullseye }} +pkghashes-debian-bookworm: ${{ steps.pkghashes.outputs.pkghashes-debian-bookworm }} +pkghashes-ubuntu-focal: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-focal }} +pkghashes-ubuntu-jammy: ${{ steps.pkghashes.outputs.pkghashes-ubuntu-jammy }} +``` From 7d6458b7e094206c0a2db9c969e88961bc9db729 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 6 Oct 2023 13:05:39 +0200 Subject: [PATCH 791/909] Netmask: Normalize subnet masks coming from a string Until now we only normalized too large masks when constructed from a `ComboAddress` object and a separate mask, but not from a string. --- pdns/iputils.hh | 8 ++++---- pdns/test-iputils_hh.cc | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/pdns/iputils.hh b/pdns/iputils.hh index 459167e97bab..1aa0a0b5186b 100644 --- a/pdns/iputils.hh +++ b/pdns/iputils.hh @@ -483,22 +483,22 @@ public: Netmask(const ComboAddress& network, uint8_t bits=0xff): d_network(network) { d_network.sin4.sin_port = 0; - setBits(network.isIPv4() ? std::min(bits, static_cast(32)) : std::min(bits, static_cast(128))); + setBits(bits); } Netmask(const sockaddr_in* network, uint8_t bits = 0xff): d_network(network) { d_network.sin4.sin_port = 0; - setBits(std::min(bits, static_cast(32))); + setBits(bits); } Netmask(const sockaddr_in6* network, uint8_t bits = 0xff): d_network(network) { d_network.sin4.sin_port = 0; - setBits(std::min(bits, static_cast(128))); + setBits(bits); } void setBits(uint8_t value) { - d_bits = value; + d_bits = d_network.isIPv4() ? std::min(value, static_cast(32U)) : std::min(value, static_cast(128U)); if (d_bits < 32) { d_mask = ~(0xFFFFFFFF >> d_bits); diff --git a/pdns/test-iputils_hh.cc b/pdns/test-iputils_hh.cc index a299fed6e8a4..da21868b06f7 100644 --- a/pdns/test-iputils_hh.cc +++ b/pdns/test-iputils_hh.cc @@ -264,6 +264,24 @@ BOOST_AUTO_TEST_CASE(test_Netmask) { BOOST_CHECK(all < empty); BOOST_CHECK(empty > full); BOOST_CHECK(full < empty); + + /* invalid (too large) mask */ + { + Netmask invalidMaskV4("192.0.2.1/33"); + BOOST_CHECK_EQUAL(invalidMaskV4.getBits(), 32U); + BOOST_CHECK(invalidMaskV4.getNetwork() == ComboAddress("192.0.2.1")); + Netmask invalidMaskV6("fe80::92fb:a6ff:fe4a:51da/129"); + BOOST_CHECK_EQUAL(invalidMaskV6.getBits(), 128U); + BOOST_CHECK(invalidMaskV6.getNetwork() == ComboAddress("fe80::92fb:a6ff:fe4a:51da")); + } + { + Netmask invalidMaskV4(ComboAddress("192.0.2.1"), 33); + BOOST_CHECK_EQUAL(invalidMaskV4.getBits(), 32U); + BOOST_CHECK(invalidMaskV4.getNetwork() == ComboAddress("192.0.2.1")); + Netmask invalidMaskV6(ComboAddress("fe80::92fb:a6ff:fe4a:51da"), 129); + BOOST_CHECK_EQUAL(invalidMaskV6.getBits(), 128U); + BOOST_CHECK(invalidMaskV6.getNetwork() == ComboAddress("fe80::92fb:a6ff:fe4a:51da")); + } } static std::string NMGOutputToSorted(const std::string& str) From d74dda8a89ef593396f25521cce123f27c90c015 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 6 Oct 2023 15:57:28 +0200 Subject: [PATCH 792/909] Update BUILDING-PACKAGES.md as suggested by Peter (thanks!) Co-authored-by: Peter van Dijk --- BUILDING-PACKAGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILDING-PACKAGES.md b/BUILDING-PACKAGES.md index 5a56d89bfa2c..4662e3a70200 100644 --- a/BUILDING-PACKAGES.md +++ b/BUILDING-PACKAGES.md @@ -25,7 +25,7 @@ Please be aware that by default some of the workflows are executed once every da On the left side, click on `Trigger specific package build`. Locate the `Run workflow` dropdown item on the top right side of the screen, inside the blue region stating `This workflow has a workflow_dispatch event trigger.` It will open a menu with several options: -- `Branch`: you can keep `master` here, unless you need to build for an operating system which is not in the list, in which case you will have to create a new branch and add the required file for this OS. See `Adding a new OS` below. +- `Branch`: you can keep `master` here, unless you need to build for an operating system which is not in the list, in which case you will have to create a new branch and add the required file(s) for this OS. See `Adding a new OS` below. - `Product to build`: select the product you want to build packages for, for example `dnsdist` - `OSes to build for, space separated`: keep one or more OSes you want to build packages for, for example `ubuntu-focal` - `git ref to checkout`: the exact version you want to build. It can be the name of branch, a git tag or a git commit ID. Most likely you will be willing to build from a tagged release, like `dnsdist-1.8.1`. From a85c9834623a9661edcd78c58bfde8089daa31e9 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 6 Oct 2023 16:13:39 +0200 Subject: [PATCH 793/909] BUILDING-PACKAGES: Use a supported OS as example Co-authored-by: Peter van Dijk --- BUILDING-PACKAGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BUILDING-PACKAGES.md b/BUILDING-PACKAGES.md index 4662e3a70200..7da089d8158f 100644 --- a/BUILDING-PACKAGES.md +++ b/BUILDING-PACKAGES.md @@ -11,7 +11,7 @@ Building packages on your own computer 2. Check out the version you want, it can be a git tag like dnsdist-1.8.1, a git commit ID or branch 3. Update submodules (`git submodule update --init --recursive`) 4. Execute `builder/build.sh` to see what arguments it supports -5. Then run `builder/build.sh` with the arguments you want (for example, `builder/build.sh -m recursor ubuntu-bionic`) +5. Then run `builder/build.sh` with the arguments you want (for example, `builder/build.sh -m recursor debian-bookworm`) Building packages from GitHub actions ------------------------------------- From 6b845683ebb8605bed3591164e736e11c8bc24de Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 6 Oct 2023 16:14:23 +0200 Subject: [PATCH 794/909] BUILDING-PACKAGES: Mention that `pdns-builder` requires a working Docker local daemon Co-authored-by: Peter van Dijk --- BUILDING-PACKAGES.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/BUILDING-PACKAGES.md b/BUILDING-PACKAGES.md index 7da089d8158f..0df59bdd90c3 100644 --- a/BUILDING-PACKAGES.md +++ b/BUILDING-PACKAGES.md @@ -7,6 +7,8 @@ The [build-tags.yml](https://github.com/PowerDNS/pdns/blob/master/.github/workfl Building packages on your own computer -------------------------------------- +This requires a working Docker installation. + 1. Clone our git repo (`git clone https://github.com/PowerDNS/pdns.git`) 2. Check out the version you want, it can be a git tag like dnsdist-1.8.1, a git commit ID or branch 3. Update submodules (`git submodule update --init --recursive`) From 6d21517a9013baf0cf762ecd0590d8cf4452cbc4 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 9 Oct 2023 11:10:17 +0200 Subject: [PATCH 795/909] dnsdist: Apply Otto's suggestions to the EDE code and docs --- pdns/dnsdistdist/dnsdist-edns.cc | 6 +++--- pdns/dnsdistdist/docs/rules-actions.rst | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-edns.cc b/pdns/dnsdistdist/dnsdist-edns.cc index a5aba4aae96b..1131bf29bc66 100644 --- a/pdns/dnsdistdist/dnsdist-edns.cc +++ b/pdns/dnsdistdist/dnsdist-edns.cc @@ -34,7 +34,7 @@ std::pair, std::optional> getExtendedDNSErr int res = locateEDNSOptRR(packet, &optStart, &optLen, &last); if (res != 0) { - return std::make_pair(std::nullopt, std::nullopt); + return {std::nullopt, std::nullopt}; } size_t optContentStart = 0; @@ -43,7 +43,7 @@ std::pair, std::optional> getExtendedDNSErr std::optional extraText{std::nullopt}; /* we need at least 2 bytes after the option length (info-code) */ if (!isEDNSOptionInOpt(packet, optStart, optLen, EDNSOptionCode::EXTENDEDERROR, &optContentStart, &optContentLen) || optContentLen < sizeof(infoCode)) { - return std::make_pair(std::nullopt, std::nullopt); + return {std::nullopt, std::nullopt}; } memcpy(&infoCode, &packet.at(optContentStart), sizeof(infoCode)); infoCode = ntohs(infoCode); @@ -53,6 +53,6 @@ std::pair, std::optional> getExtendedDNSErr extraText->resize(optContentLen - sizeof(infoCode)); memcpy(extraText->data(), &packet.at(optContentStart + sizeof(infoCode)), optContentLen - sizeof(infoCode)); } - return std::make_pair(infoCode, std::move(extraText)); + return {infoCode, std::move(extraText)}; } } diff --git a/pdns/dnsdistdist/docs/rules-actions.rst b/pdns/dnsdistdist/docs/rules-actions.rst index 19c4ed51b4ae..db85036754e4 100644 --- a/pdns/dnsdistdist/docs/rules-actions.rst +++ b/pdns/dnsdistdist/docs/rules-actions.rst @@ -1441,7 +1441,7 @@ The following actions exist. * ``serverID=""``: str - Set the Server Identity field. * ``ipEncryptKey=""``: str - A key, that can be generated via the :func:`makeIPCipherKey` function, to encrypt the IP address of the requestor for anonymization purposes. The encryption is done using ipcrypt for IPv4 and a 128-bit AES ECB operation for IPv6. * ``exportTags=""``: str - The comma-separated list of keys of internal tags to export into the ``tags`` Protocol Buffer field, as "key:value" strings. Note that a tag with an empty value will be exported as "", not ":". An empty string means that no internal tag will be exported. The special value ``*`` means that all tags will be exported. - * ``exportExtendedErrorsToMeta=""``: str - Export Extended DNS Errors present in the DNS response, if any, into the specified ``tags`` Protocol Buffer field. The EDE info code will be exported as an integer value, and the EDE extra text, if present, as a string value. + * ``exportExtendedErrorsToMeta=""``: str - Export Extended DNS Errors present in the DNS response, if any, into the ``meta`` Protocol Buffer field using the specified ``key``. The EDE info code will be exported as an integer value, and the EDE extra text, if present, as a string value. .. function:: SetAdditionalProxyProtocolValueAction(type, value) From e23cdb01deacb45c2bfb87d52346463d74cd51d7 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 9 Oct 2023 11:15:50 +0200 Subject: [PATCH 796/909] Mention removal of sysvinit script in 4.9.x changelog. Fixes #13343 --- pdns/recursordist/docs/changelog/4.9.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/docs/changelog/4.9.rst b/pdns/recursordist/docs/changelog/4.9.rst index e0c7fc956b38..ff8d11e35193 100644 --- a/pdns/recursordist/docs/changelog/4.9.rst +++ b/pdns/recursordist/docs/changelog/4.9.rst @@ -210,7 +210,7 @@ Changelogs for 4.9.X :tags: Improvements :pullreq: 10072,12716 - Update Debian packaging for Recursor (Chris Hofstaedtler). + Update Debian packaging for Recursor, including removal of sysv init script (Chris Hofstaedtler). .. change:: :tags: Improvements From a985c6a731664e4c95fe4c5a5a0b3792546525fb Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 14 Sep 2023 14:59:29 +0200 Subject: [PATCH 797/909] Update the code coverage m4 to support modern options, hook it up --- configure.ac | 1 + m4/pdns_enable_coverage.m4 | 19 +++++++++++++++++-- pdns/dnsdistdist/configure.ac | 1 + pdns/dnsdistdist/m4/pdns_enable_coverage.m4 | 1 + pdns/recursordist/configure.ac | 1 + pdns/recursordist/m4/pdns_enable_coverage.m4 | 1 + 6 files changed, 22 insertions(+), 2 deletions(-) create mode 120000 pdns/dnsdistdist/m4/pdns_enable_coverage.m4 create mode 120000 pdns/recursordist/m4/pdns_enable_coverage.m4 diff --git a/configure.ac b/configure.ac index 8f6fde4604a1..348127854d4e 100644 --- a/configure.ac +++ b/configure.ac @@ -130,6 +130,7 @@ PDNS_ENABLE_UNIT_TESTS PDNS_ENABLE_BACKEND_UNIT_TESTS PDNS_ENABLE_REPRODUCIBLE PDNS_ENABLE_FUZZ_TARGETS +PDNS_ENABLE_COVERAGE PDNS_WITH_SQLITE3 diff --git a/m4/pdns_enable_coverage.m4 b/m4/pdns_enable_coverage.m4 index 17846ffa1690..9e06468bc9ee 100644 --- a/m4/pdns_enable_coverage.m4 +++ b/m4/pdns_enable_coverage.m4 @@ -7,9 +7,24 @@ AC_DEFUN([PDNS_ENABLE_COVERAGE], [ [enable_coverage=no] ) AC_MSG_RESULT([$enable_coverage]) - AS_IF([test "x$enable_coverage" != "xno"], [ + + AS_IF([test "x$enable_coverage" = "xclang"], [ + dnl let's see if the clang++ specific format is supported, + dnl as it has a much lower overhead and is more accurate, + dnl see https://clang.llvm.org/docs/SourceBasedCodeCoverage.html + gl_COMPILER_OPTION_IF([-fprofile-instr-generate -fcoverage-mapping], [ + CFLAGS="$CFLAGS -DCOVERAGE -DCLANG_COVERAGE -fprofile-instr-generate -fcoverage-mapping" + CXXFLAGS="$CXXFLAGS -DCOVERAGE -DCLANG_COVERAGE -fprofile-instr-generate -fcoverage-mapping" + ], [ + AC_MSG_ERROR([$CXX does not support gathering coverage data in the clang format]) + ]) + ]) + + AS_IF([test "x$enable_coverage" = "xyes"], [ gl_COMPILER_OPTION_IF([-fprofile-arcs -ftest-coverage], [ - CXXFLAGS="$CXXFLAGS -U_FORTIFY_SOURCE -g -O0 -fprofile-arcs -ftest-coverage" + CFLAGS="$CFLAGS -DCOVERAGE --coverage" + CXXFLAGS="$CXXFLAGS -DCOVERAGE --coverage" + LDFLAGS="$LDFLAGS --coverage" ], [ AC_MSG_ERROR([$CXX does not support gathering coverage data]) ]) diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index feeeba3a1287..e30075c25c00 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -131,6 +131,7 @@ PDNS_INIT_AUTO_VARS PDNS_ENABLE_SANITIZERS PDNS_ENABLE_LTO +PDNS_ENABLE_COVERAGE PDNS_CHECK_PYTHON_VENV diff --git a/pdns/dnsdistdist/m4/pdns_enable_coverage.m4 b/pdns/dnsdistdist/m4/pdns_enable_coverage.m4 new file mode 120000 index 000000000000..9af5272b6af4 --- /dev/null +++ b/pdns/dnsdistdist/m4/pdns_enable_coverage.m4 @@ -0,0 +1 @@ +../../../m4/pdns_enable_coverage.m4 \ No newline at end of file diff --git a/pdns/recursordist/configure.ac b/pdns/recursordist/configure.ac index 231f3ae7a264..f1f1a504c616 100644 --- a/pdns/recursordist/configure.ac +++ b/pdns/recursordist/configure.ac @@ -66,6 +66,7 @@ AS_IF([test -n "$pdns_context_library"], [AC_MSG_RESULT([$pdns_context_library]) PDNS_ENABLE_UNIT_TESTS PDNS_ENABLE_REPRODUCIBLE +PDNS_ENABLE_COVERAGE PDNS_WITH_LUA([mandatory]) AS_IF([test "x$LUAPC" = "xluajit"], [ diff --git a/pdns/recursordist/m4/pdns_enable_coverage.m4 b/pdns/recursordist/m4/pdns_enable_coverage.m4 new file mode 120000 index 000000000000..9af5272b6af4 --- /dev/null +++ b/pdns/recursordist/m4/pdns_enable_coverage.m4 @@ -0,0 +1 @@ +../../../m4/pdns_enable_coverage.m4 \ No newline at end of file From 460a6daa8b951833ad9f4a8338079a1393b4b952 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 14 Sep 2023 15:01:56 +0200 Subject: [PATCH 798/909] auth: Properly record coverage data when exiting --- pdns/Makefile.am | 1 + pdns/auth-main.cc | 15 +++++++++++++++ pdns/coverage.cc | 48 +++++++++++++++++++++++++++++++++++++++++++++++ pdns/coverage.hh | 27 ++++++++++++++++++++++++++ 4 files changed, 91 insertions(+) create mode 100644 pdns/coverage.cc create mode 100644 pdns/coverage.hh diff --git a/pdns/Makefile.am b/pdns/Makefile.am index b22bcfdc3cc8..75e0fa213f22 100644 --- a/pdns/Makefile.am +++ b/pdns/Makefile.am @@ -211,6 +211,7 @@ pdns_server_SOURCES = \ circular_buffer.hh \ comment.hh \ communicator.cc communicator.hh \ + coverage.cc coverage.hh \ credentials.cc credentials.hh \ dbdnsseckeeper.cc \ digests.hh \ diff --git a/pdns/auth-main.cc b/pdns/auth-main.cc index e3d4b39b097f..559e1f29c358 100644 --- a/pdns/auth-main.cc +++ b/pdns/auth-main.cc @@ -53,6 +53,7 @@ #endif #include "auth-main.hh" +#include "coverage.hh" #include "secpoll-auth.hh" #include "dynhandler.hh" #include "dnsseckeeper.hh" @@ -1183,6 +1184,14 @@ static void tbhandler(int num) } #endif +#ifdef COVERAGE +static void sigTermHandler([[maybe_unused]] int signal) +{ + pdns::coverage::dumpCoverageData(); + _exit(EXIT_SUCCESS); +} +#endif /* COVERAGE */ + //! The main function of pdns, the pdns process int main(int argc, char** argv) { @@ -1282,6 +1291,12 @@ int main(int argc, char** argv) cerr << "Um, we did get here!" << endl; } +#ifdef COVERAGE + if (!::arg().mustDo("guardian") && !::arg().mustDo("daemon")) { + signal(SIGTERM, sigTermHandler); + } +#endif + // we really need to do work - either standalone or as an instance #if defined(__GLIBC__) && !defined(__UCLIBC__) diff --git a/pdns/coverage.cc b/pdns/coverage.cc new file mode 100644 index 000000000000..71fcda4b0749 --- /dev/null +++ b/pdns/coverage.cc @@ -0,0 +1,48 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#include "config.h" +#include "coverage.hh" + +#ifdef COVERAGE +extern "C" +{ + //NOLINTNEXTLINE(bugprone-reserved-identifier): not ours + void __gcov_dump(void); +#ifdef CLANG_COVERAGE + //NOLINTNEXTLINE(bugprone-reserved-identifier): not ours + int __llvm_profile_write_file(void); +#endif /* CLANG_COVERAGE */ +} +#endif /* COVERAGE */ + +namespace pdns::coverage +{ +void dumpCoverageData() +{ +#ifdef COVERAGE + __gcov_dump(); +#ifdef CLANG_COVERAGE + __llvm_profile_write_file(); +#endif /* CLANG_COVERAGE */ +#endif /* COVERAGE */ +} +} diff --git a/pdns/coverage.hh b/pdns/coverage.hh new file mode 100644 index 000000000000..960f28c8ddbe --- /dev/null +++ b/pdns/coverage.hh @@ -0,0 +1,27 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +namespace pdns::coverage +{ +void dumpCoverageData(); +} From b335696564f4d893c68f8241bedd96ea8bfa2959 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 14 Sep 2023 15:03:08 +0200 Subject: [PATCH 799/909] dnsdist: Properly record clang coverage data when exiting --- pdns/dnsdist-lua.cc | 12 ++---------- pdns/dnsdist.cc | 9 +++------ pdns/dnsdistdist/Makefile.am | 1 + pdns/dnsdistdist/coverage.cc | 1 + pdns/dnsdistdist/coverage.hh | 1 + 5 files changed, 8 insertions(+), 16 deletions(-) create mode 120000 pdns/dnsdistdist/coverage.cc create mode 120000 pdns/dnsdistdist/coverage.hh diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 1896cce32dd6..902ccf64ac0c 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -57,6 +57,7 @@ #include "dnsdist-web.hh" #include "base64.hh" +#include "coverage.hh" #include "doh.hh" #include "dolog.hh" #include "sodcrypto.hh" @@ -282,13 +283,6 @@ static void LuaThread(const std::string& code) } } -#ifdef COVERAGE -extern "C" -{ - void __gcov_dump(void); -} -#endif - static bool checkConfigurationTime(const std::string& name) { if (!g_configurationDone) { @@ -866,9 +860,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) g_tlslocals.clear(); g_rings.clear(); #endif /* 0 */ -#ifdef COVERAGE - __gcov_dump(); -#endif + pdns::coverage::dumpCoverageData(); _exit(0); }); diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index cde7fd061bd2..7d6e5bac60be 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -68,6 +68,7 @@ #include "base64.hh" #include "capabilities.hh" +#include "coverage.hh" #include "delaypipe.hh" #include "doh.hh" #include "dolog.hh" @@ -2395,11 +2396,6 @@ static void usage() } #ifdef COVERAGE -extern "C" -{ - void __gcov_dump(void); -} - static void cleanupLuaObjects() { /* when our coverage mode is enabled, we need to make @@ -2410,13 +2406,14 @@ static void cleanupLuaObjects() g_selfansweredrespruleactions.setState({}); g_dstates.setState({}); g_policy.setState(ServerPolicy()); + g_pools.setState({}); clearWebHandlers(); } static void sigTermHandler(int) { cleanupLuaObjects(); - __gcov_dump(); + pdns::coverage::dumpCoverageData(); _exit(EXIT_SUCCESS); } #else /* COVERAGE */ diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index e845dcd5bb0e..db92cc87305d 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -139,6 +139,7 @@ dnsdist_SOURCES = \ channel.cc channel.hh \ circular_buffer.hh \ connection-management.hh \ + coverage.cc coverage.hh \ credentials.cc credentials.hh \ dns.cc dns.hh \ dns_random.hh \ diff --git a/pdns/dnsdistdist/coverage.cc b/pdns/dnsdistdist/coverage.cc new file mode 120000 index 000000000000..5b8a2c82f47f --- /dev/null +++ b/pdns/dnsdistdist/coverage.cc @@ -0,0 +1 @@ +../coverage.cc \ No newline at end of file diff --git a/pdns/dnsdistdist/coverage.hh b/pdns/dnsdistdist/coverage.hh new file mode 120000 index 000000000000..da12b36c7269 --- /dev/null +++ b/pdns/dnsdistdist/coverage.hh @@ -0,0 +1 @@ +../coverage.hh \ No newline at end of file From 3810b63d83e7132cafe6fc88a7ba0015fb219903 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 14 Sep 2023 15:05:43 +0200 Subject: [PATCH 800/909] rec: Properly record coverage data when exiting --- pdns/recursordist/Makefile.am | 1 + pdns/recursordist/coverage.cc | 1 + pdns/recursordist/coverage.hh | 1 + pdns/recursordist/rec_channel_rec.cc | 7 ++++++- 4 files changed, 9 insertions(+), 1 deletion(-) create mode 120000 pdns/recursordist/coverage.cc create mode 120000 pdns/recursordist/coverage.hh diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index f75a0962d35b..8c482ab8fca6 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -114,6 +114,7 @@ pdns_recursor_SOURCES = \ channel.cc channel.hh \ circular_buffer.hh \ comment.hh \ + coverage.cc coverage.hh \ credentials.cc credentials.hh \ dns.hh dns.cc \ dns_random.hh \ diff --git a/pdns/recursordist/coverage.cc b/pdns/recursordist/coverage.cc new file mode 120000 index 000000000000..5b8a2c82f47f --- /dev/null +++ b/pdns/recursordist/coverage.cc @@ -0,0 +1 @@ +../coverage.cc \ No newline at end of file diff --git a/pdns/recursordist/coverage.hh b/pdns/recursordist/coverage.hh new file mode 120000 index 000000000000..da12b36c7269 --- /dev/null +++ b/pdns/recursordist/coverage.hh @@ -0,0 +1 @@ +../coverage.hh \ No newline at end of file diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index 2373e5f80269..bbff8289a24d 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -28,6 +28,7 @@ #include "rec-lua-conf.hh" #include "aggressive_nsec.hh" +#include "coverage.hh" #include "validate-recursor.hh" #include "filterpo.hh" @@ -1586,8 +1587,12 @@ void doExitGeneric(bool nicely) g_log << Logger::Error << "Exiting on user request" << endl; g_rcc.~RecursorControlChannel(); - if (!g_pidfname.empty()) + if (!g_pidfname.empty()) { unlink(g_pidfname.c_str()); // we can at least try.. + } + + pdns::coverage::dumpCoverageData(); + if (nicely) { RecursorControlChannel::stop = true; } From 628a1dec1befdb7bc34053b5baf72e2d220e39f9 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 14 Sep 2023 15:06:13 +0200 Subject: [PATCH 801/909] build-and-test-all: Generate code coverage data from CI --- .../scripts/normalize_paths_in_coverage.py | 53 +++++++++ .github/workflows/build-and-test-all.yml | 101 ++++++++++++++++++ tasks.py | 33 +++++- 3 files changed, 184 insertions(+), 3 deletions(-) create mode 100755 .github/scripts/normalize_paths_in_coverage.py diff --git a/.github/scripts/normalize_paths_in_coverage.py b/.github/scripts/normalize_paths_in_coverage.py new file mode 100755 index 000000000000..be0a80b12205 --- /dev/null +++ b/.github/scripts/normalize_paths_in_coverage.py @@ -0,0 +1,53 @@ +#!/usr/bin/env python + +import os +import sys + +if __name__ == '__main__': + repositoryRoot = os.path.realpath(sys.argv[1]) + version = sys.argv[2] + inputFile = sys.argv[3] + outputFile = sys.argv[4] + with open(inputFile, mode='r') as inputFilePtr: + with open(outputFile, mode='w') as outputFilePtr: + for line in inputFilePtr: + if not line.startswith('SF:'): + outputFilePtr.write(line) + continue + + parts = line.split(':') + if len(parts) != 2: + outputFilePtr.write(line) + continue + + source_file = parts[1].rstrip() + # get rid of symbolic links + target = os.path.realpath(source_file) + + # get rid of the distdir path, to get file paths as they are in the repository + if f'pdns-{version}' in target: + # authoritative or tool + authPath = os.path.join(repositoryRoot, f'pdns-{version}') + relativeToAuth = os.path.relpath(target, authPath) + target = relativeToAuth + elif f'pdns-recursor-{version}' in target: + recPath = os.path.join(repositoryRoot, 'pdns', 'recursordist', f'pdns-recursor-{version}') + relativeToRec = os.path.relpath(target, recPath) + target = os.path.join('pdns', 'recursordist', relativeToRec) + elif f'dnsdist-{version}' in target: + distPath = os.path.join(repositoryRoot, 'pdns', 'dnsdistdist', f'dnsdist-{version}') + relativeToDist = os.path.relpath(target, distPath) + target = os.path.join('pdns', 'dnsdistdist', relativeToDist) + else: + print(f'Ignoring {target} that we could not map to a distdir', file=sys.stderr) + continue + + # we need to propery map symbolic links + fullPath = os.path.join(repositoryRoot, target) + if os.path.islink(fullPath): + # get the link target + realPath = os.path.realpath(fullPath) + # and make it relative again + target = os.path.relpath(realPath, repositoryRoot) + + outputFilePtr.write(f"SF:{target}\n") diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index bd7d62b248ec..6e25bc0d127d 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -15,6 +15,8 @@ env: # github.workspace variable points to the Runner home folder. Container home folder defined below. REPO_HOME: '/__w/pdns/pdns' BUILDER_VERSION: '0.0.0-git1' + COVERAGE: yes + LLVM_PROFILE_FILE: "/tmp/code-%p.profraw" jobs: build-auth: @@ -85,6 +87,15 @@ jobs: fi - run: inv ci-auth-install-remotebackend-test-deps - run: inv ci-auth-run-unit-tests + - run: inv generate-coverage-info ./testrunner $GITHUB_WORKSPACE + working-directory: ./pdns-${{ env.BUILDER_VERSION }}/pdns + - name: Coveralls Parallel auth unit + uses: coverallsapp/github-action@v2 + with: + flag-name: auth-unit-${{ matrix.sanitizers }} + path-to-lcov: $GITHUB_WORKSPACE/coverage.lcov + parallel: true + allow-empty: true - run: inv ci-make-install - run: ccache -s - name: Store the binaries @@ -162,6 +173,16 @@ jobs: echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-rec-run-unit-tests + - run: inv generate-coverage-info ./testrunner $GITHUB_WORKSPACE + if: ${{ matrix.sanitizers != 'tsan' }} + - name: Coveralls Parallel rec unit + if: ${{ matrix.sanitizers != 'tsan' }} + uses: coverallsapp/github-action@v2 + with: + flag-name: rec-unit-${{ matrix.sanitizers }} + path-to-lcov: $GITHUB_WORKSPACE/coverage.lcov + parallel: true + allow-empty: true - run: inv ci-make-install - run: ccache -s - name: Store the binaries @@ -242,6 +263,16 @@ jobs: echo "failed=$?" >> $GITHUB_OUTPUT fi - run: inv ci-dnsdist-run-unit-tests + - run: inv generate-coverage-info ./testrunner $GITHUB_WORKSPACE + if: ${{ matrix.sanitizers != 'tsan' }} + - name: Coveralls Parallel dnsdist unit + if: ${{ matrix.sanitizers != 'tsan' }} + uses: coverallsapp/github-action@v2 + with: + flag-name: dnsdist-unit-${{ matrix.features }}-${{ matrix.sanitizers }} + path-to-lcov: $GITHUB_WORKSPACE/coverage.lcov + parallel: true + allow-empty: true - run: inv ci-make-install - run: ccache -s - name: Store the binaries @@ -301,6 +332,14 @@ jobs: - run: inv install-clang-runtime - run: inv install-auth-test-deps -b ${{ matrix.backend }} - run: inv test-api auth -b ${{ matrix.backend }} + - run: inv generate-coverage-info /opt/pdns-auth/sbin/pdns_server $GITHUB_WORKSPACE + - name: Coveralls Parallel auth API ${{ matrix.backend }} + uses: coverallsapp/github-action@v2 + with: + flag-name: auth-api-${{ matrix.backend }} + path-to-lcov: $GITHUB_WORKSPACE/coverage.lcov + parallel: true + allow-empty: true test-auth-backend: needs: build-auth @@ -413,6 +452,14 @@ jobs: - run: inv install-clang-runtime - run: inv install-auth-test-deps -b ${{ matrix.backend }} - run: inv test-auth-backend -b ${{ matrix.backend }} + - run: inv generate-coverage-info /opt/pdns-auth/sbin/pdns_server $GITHUB_WORKSPACE + - name: Coveralls Parallel auth backend ${{ matrix.backend }} + uses: coverallsapp/github-action@v2 + with: + flag-name: auth-backend-${{ matrix.backend }} + path-to-lcov: $GITHUB_WORKSPACE/coverage.lcov + parallel: true + allow-empty: true test-ixfrdist: needs: build-auth @@ -436,6 +483,14 @@ jobs: - run: inv install-clang-runtime - run: inv install-auth-test-deps - run: inv test-ixfrdist + - run: inv generate-coverage-info /opt/pdns-auth/bin/ixfrdist $GITHUB_WORKSPACE + - name: Coveralls Parallel ixfrdist + uses: coverallsapp/github-action@v2 + with: + flag-name: ixfrdist + path-to-lcov: $GITHUB_WORKSPACE/coverage.lcov + parallel: true + allow-empty: true test-recursor-api: needs: build-recursor @@ -468,6 +523,16 @@ jobs: - run: inv install-clang-runtime - run: inv install-rec-test-deps - run: inv test-api recursor + - run: inv generate-coverage-info /opt/pdns-recursor/sbin/pdns_recursor $GITHUB_WORKSPACE + if: ${{ matrix.sanitizers != 'tsan' }} + - name: Coveralls Parallel recursor API + if: ${{ matrix.sanitizers != 'tsan' }} + uses: coverallsapp/github-action@v2 + with: + flag-name: rec-api + path-to-lcov: $GITHUB_WORKSPACE/coverage.lcov + parallel: true + allow-empty: true test-recursor-regression: needs: build-recursor @@ -501,6 +566,16 @@ jobs: - run: inv install-clang-runtime - run: inv install-rec-test-deps - run: inv test-regression-recursor + - run: inv generate-coverage-info /opt/pdns-recursor/sbin/pdns_recursor $GITHUB_WORKSPACE + if: ${{ matrix.sanitizers != 'tsan' }} + - name: Coveralls Parallel recursor regression + if: ${{ matrix.sanitizers != 'tsan' }} + uses: coverallsapp/github-action@v2 + with: + flag-name: rec-regression + path-to-lcov: $GITHUB_WORKSPACE/coverage.lcov + parallel: true + allow-empty: true test-recursor-bulk: name: 'test rec *mini* bulk' @@ -532,6 +607,16 @@ jobs: - run: inv install-clang-runtime - run: inv install-rec-bulk-deps - run: inv test-bulk-recursor ${{ matrix.threads }} ${{ matrix.mthreads }} ${{ matrix.shards }} + - run: inv generate-coverage-info /opt/pdns-recursor/sbin/pdns_recursor $GITHUB_WORKSPACE + if: ${{ matrix.sanitizers != 'tsan' }} + - name: Coveralls Parallel recursor bulk + if: ${{ matrix.sanitizers != 'tsan' }} + uses: coverallsapp/github-action@v2 + with: + flag-name: rec-regression-bulk + path-to-lcov: $GITHUB_WORKSPACE/coverage.lcov + parallel: true + allow-empty: true test-dnsdist-regression: needs: build-dnsdist @@ -548,6 +633,8 @@ jobs: TSAN_OPTIONS: "halt_on_error=1:intercept_send=0:suppressions=${{ env.REPO_HOME }}/pdns/dnsdistdist/dnsdist-tsan.supp" # IncludeDir tests are disabled because of a weird interaction between TSAN and these tests which ever only happens on GH actions SKIP_INCLUDEDIR_TESTS: yes + SANITIZERS: ${{ matrix.sanitizers }} + COVERAGE: yes options: --sysctl net.ipv6.conf.all.disable_ipv6=0 steps: - uses: actions/checkout@v3 @@ -562,6 +649,16 @@ jobs: - run: inv install-clang-runtime - run: inv install-dnsdist-test-deps - run: inv test-dnsdist + - run: inv generate-coverage-info /opt/dnsdist/bin/dnsdist $GITHUB_WORKSPACE + if: ${{ matrix.sanitizers != 'tsan' }} + - name: Coveralls Parallel dnsdist regression + if: ${{ matrix.sanitizers != 'tsan' }} + uses: coverallsapp/github-action@v2 + with: + flag-name: dnsdist-regression-full-${{ matrix.sanitizers }} + path-to-lcov: $GITHUB_WORKSPACE/coverage.lcov + parallel: true + allow-empty: true swagger-syntax-check: if: ${{ !github.event.schedule || vars.SCHEDULED_JOBS_BUILD_AND_TEST_ALL }} @@ -616,6 +713,10 @@ jobs: if: success() || failure() runs-on: ubuntu-20.04 steps: + - name: Coveralls Parallel Finished + uses: coverallsapp/github-action@v2 + with: + parallel-finished: true - name: Install jq and yq run: "sudo snap install jq yq" - name: Fail job if any of the previous jobs failed diff --git a/tasks.py b/tasks.py index 7d8982198c22..97b73352478f 100644 --- a/tasks.py +++ b/tasks.py @@ -203,6 +203,28 @@ def install_auth_build_deps(c): c.sudo('apt-get install -y --no-install-recommends ' + ' '.join(all_build_deps + git_build_deps + auth_build_deps)) install_libdecaf(c, 'pdns-auth') +def is_coverage_enabled(): + sanitizers = os.getenv('SANITIZERS') + if sanitizers: + sanitizers = sanitizers.split('+') + if 'tsan' in sanitizers: + return False + return os.getenv('COVERAGE') == 'yes' + +@task +def install_coverage_deps(c): + if is_coverage_enabled(): + c.sudo(f'apt-get install -y --no-install-recommends llvm-{clang_version}') + +@task +def generate_coverage_info(c, binary, outputDir): + if is_coverage_enabled(): + version = os.getenv('BUILDER_VERSION') + c.run(f'llvm-profdata-{clang_version} merge -sparse -o {outputDir}/temp.profdata /tmp/code-*.profraw') + c.run(f'llvm-cov-{clang_version} export --format=lcov --ignore-filename-regex=\'^/usr/\' -instr-profile={outputDir}/temp.profdata -object {binary} > {outputDir}/coverage.lcov') + c.run(f'{outputDir}/.github/scripts/normalize_paths_in_coverage.py {outputDir} {version} {outputDir}/coverage.lcov {outputDir}/normalized_coverage.lcov') + c.run(f'mv {outputDir}/normalized_coverage.lcov {outputDir}/coverage.lcov') + def setup_authbind(c): c.sudo('touch /etc/authbind/byport/53') c.sudo('chmod 755 /etc/authbind/byport/53') @@ -395,6 +417,7 @@ def ci_auth_configure(c): fuzz_targets = os.getenv('FUZZING_TARGETS') fuzz_targets = '--enable-fuzz-targets' if fuzz_targets == 'yes' else '' + coverage = '--enable-coverage=clang' if is_coverage_enabled() else '' modules = " ".join([ "bind", @@ -425,6 +448,7 @@ def ci_auth_configure(c): sanitizers, unittests, fuzz_targets, + coverage, ]) res = c.run(configure_cmd, warn=True) if res.exited != 0: @@ -438,6 +462,7 @@ def ci_rec_configure(c): unittests = os.getenv('UNIT_TESTS') unittests = '--enable-unit-tests' if unittests == 'yes' else '' + coverage = '--enable-coverage=clang' if is_coverage_enabled() else '' configure_cmd = " ".join([ get_base_configure_cmd(), @@ -449,6 +474,7 @@ def ci_rec_configure(c): "--enable-dns-over-tls", sanitizers, unittests, + coverage, ]) res = c.run(configure_cmd, warn=True) if res.exited != 0: @@ -523,8 +549,9 @@ def ci_dnsdist_configure(c, features): unittests = ' --enable-unit-tests' if os.getenv('UNIT_TESTS') == 'yes' else '' fuzztargets = '--enable-fuzz-targets' if os.getenv('FUZZING_TARGETS') == 'yes' else '' sanitizers = ' '.join('--enable-'+x for x in os.getenv('SANITIZERS').split('+')) if os.getenv('SANITIZERS') != '' else '' - cflags = '-O1 -Werror=vla -Werror=shadow -Wformat=2 -Werror=format-security -Werror=string-plus-int' - cxxflags = cflags + ' -Wp,-D_GLIBCXX_ASSERTIONS ' + additional_flags + coverage = '--enable-coverage=clang' if is_coverage_enabled() else '' + cflags = get_cflags() + cxxflags = " ".join([get_cxxflags(), additional_flags]) res = c.run(f'''CFLAGS="%s" \ CXXFLAGS="%s" \ AR=llvm-ar-{clang_version} \ @@ -536,7 +563,7 @@ def ci_dnsdist_configure(c, features): --enable-fortify-source=auto \ --enable-auto-var-init=pattern \ --enable-lto=thin \ - --prefix=/opt/dnsdist %s %s %s %s''' % (cflags, cxxflags, features_set, sanitizers, unittests, fuzztargets), warn=True) + --prefix=/opt/dnsdist %s %s %s %s %s''' % (cflags, cxxflags, features_set, sanitizers, unittests, fuzztargets, coverage), warn=True) if res.exited != 0: c.run('cat config.log') raise UnexpectedExit(res) From 5b7a7b0f969c2934ff4ccf7bbf36cb9f8c3b231f Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 14 Sep 2023 16:13:05 +0200 Subject: [PATCH 802/909] Add Code Coverage documentation --- CODE_COVERAGE.md | 77 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 CODE_COVERAGE.md diff --git a/CODE_COVERAGE.md b/CODE_COVERAGE.md new file mode 100644 index 000000000000..555cdffc5457 --- /dev/null +++ b/CODE_COVERAGE.md @@ -0,0 +1,77 @@ +Code Coverage +------------- + +PowerDNS uses [coveralls](https://coveralls.io/) to generate code coverage reports from our Continuous Integration tests. The resulting analysis can then be consulted [online](https://coveralls.io/github/PowerDNS/pdns), and gives hindsight into which parts of the code are automatically tested. + +Code coverage is generated during our Continuous Integration tests, for every pull requests and pushs. In addition to the dashboard on coveralls's website, a summary is posted on pull requests. + +# Technical Details + +## DebugInfo vs Source-based Code Coverage + +There are two main ways of generating code coverage: `GCOV` and `source-based`. + +### GCOV + +The `GCOV` approach, supported by both `g++` and `clang++`, is enabled by passing the `--coverage` flag (equivalent to `-ftest-coverage -fprofile-arcs`) to the compiler and linker. It operates on debugging information (`DebugInfo`), usually [DWARF](https://dwarfstd.org/), generated by the compiler, and also used by debuggers. +This approach generates `.gcno` files during the compilation, which are stored along the object files, and `.gcda` files at runtime when the final program is executed. + +* There are as many `.gcno` and `.gcda` files as object files, which may be a lot. +* Every invocation of a program updates the `.gcda` files corresponding to the code that has been executed. It will append to existing `.gcda` files, but only process can update a given file so parallel execution will result in corrupted data. +* Writing to each `.gcda` might take a while for large programs, and has been known to slow down execution quite a lot. +* Accurate reporting of lines and branches may be problematic when optimizations are enabled, so it is advised to disable optimizations to get useful analysis. +* Note that the `.gcda` files produced by `clang++` are not fully compatible with the `g++` ones, and with the existing tools, but [`llvm-cov gcov`](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) can produce `.gcov` files that should be compatible. A symptom of this incompatiblity looks like this: + +``` +Processing pdns/ednssubnet.gcda +__w/pdns/pdns/pdns/ednssubnet.gcno:version '408', prefer 'B02' +``` + +### Sourced Based + +`clang++` supports [source-based coverage](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html), which operates on `AST` and preprocessor information directly. This is enabled by passing `-fprofile-instr-generate -fcoverage-mapping` to the compiler and leads to `.profraw` files being produced when the binary is executed. +The `.profraw` file(s) can be merged by [`llvm-profdata merge`](https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge) into a `.profdata` file which can then be used by [`llvm-cov show`](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show) to generate HTML and text reports, or by [`llvm-cov export`](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-export) to export `LCOV` data that is compatible with other tools. + +* Source-based coverage can generate accurate data with optimizations enabled, and has a much lower overhead that `GCOV`. +* The path and exact name of the `.profraw` files generated when a program is executed can be controlled via the `LLVM_PROFILE_FILE` environment variable, which supports [patterns](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html#running-the-instrumented-program) like `%p`, which expands to the process ID. That allows running several programs in parallel, each program generating its own file at the end. + +## Implementation + +We use `clang++`'s source-based coverage method in our CI, as it allows running our regression tests in parallel with several workers. It is enabled by passing the `--enable-coverage=clang` flag during `configure` for all products. +The code coverage generation is done as part of the (build-and-test-all.yml)[https://github.com/PowerDNS/pdns/blob/master/.github/workflows/build-and-test-all.yml] workflow. + +Since we have a `monorepo` for three products which share the same code-base, the process is a bit tricky: + +* We use coveralls's `parallel` feature, which allows us to generate partial reports from several steps of our CI process, then merge them during the `collect` phase and upload the resulting `LCOV` file to coveralls. +* After executing our tests, the `generate_coverage_info` method in [`tasks.py`](https://github.com/PowerDNS/pdns/blob/master/tasks.py) merges the `.profraw` files that have been generated every time a binary has been executed into a single `.profdata` file via [`llvm-profdata merge`](https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge). We enable the `sparse` mode to get a smaller `.profdata` file, since we do not do Profile-Guided Optimization (PGO). +* It then generates a `.lcov` file from the `.profdata` via [`llvm-cov export`](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-export), telling it to ignore reports for files under `/usr` in the process (via the `-ignore-filename-regex` parameter). +* We then normalize the paths of the source files to prevent duplicates for files that are used by more than one product, and to account for the fact that our CI actually compiles from a `distdir`. This is handled by a Python script, [.github/scripts/normalize_paths_in_coverage.py](https://github.com/PowerDNS/pdns/blob/master/.github/scripts/normalize_paths_in_coverage.py) that parses the `LCOV` data and updates the paths. +* We call [Coveralls's github action](https://github.com/coverallsapp/github-action) to upload the resulting `LCOV` data for this step. +* After all steps have completed, we call that action again to let it know that our workflow is finished and the data can be consolidated. + +One important thing to remember is that the content is only written into a `.profraw` file is the program terminates correctly, calling `exit` handlers, and if the `__llvm_profile_write_file()` function is called. Our code base has a wrapper around that, `pdns::coverage::dumpCoverageData()`. +This is especially important for us because our products often terminates by calling `_exit()`, bypassing the `exit` handlers, to avoid issues with the destruction order of global objects. + +## Generating Coverage Outside Of the CI + +It is possible to generate a code coverage report without going through the CI, for example to test the coverage of a new feature in a given product. + +### Source-based Coverage With clang++ + +* Run the `configure` script with the `--enable-coverage=clang` option, setting the `CC` and `CXX` environment variables to use the `clang` compiler: `CC=clang CXX=clang++ ./configure --enable-coverage=clang` +* Compile the product as usual with: `make` +* Run the test(s) that are expected to cover the new feature, via `./testrunner` or `make check` for the unit tests, and the instructions of the corresponding `regression-tests*` directory for the regression tests. It is advised to set the `LLVM_PROFILE_FILE` environment variable in such a way that an invocation of the product do not override the results from the previous invocation. For example setting `LLVM_PROFILE_FILE="/tmp/code-%p.profraw"` will result in each invocation writing a new file into the `/tmp` directory, replacing `%p` with the process ID. +* Merge the resulting `*.profraw` file into a single `code.profdata` file by running `llvm-profdata merge -sparse -o /tmp/code.profdata /tmp/code-*.profraw` +* Generate a HTML report into the `/tmp/html-report` directory by running `llvm-cov show --instr-profile /tmp/code.profdata -format html -output-dir /tmp/html-report -object ` + +### GCOV + +* Run the `configure` script with the `--enable-coverage` option, using either `g++` or `clang++`: `./configure --enable-coverage` +* Compile as usual with: `make`. This will generate `.gcno` files along with the usual `.o` object files and the final binaries. +* Run the test(s) that are expected to cover the new feature, via `./testrunner` or `make check` for the unit tests, and the instructions of the corresponding `regression-tests*` directory for the regression tests. Note that the regression should not be run in parallel, as it would corrupt the `.gcna` files that will be generated in the process. For dnsdist, that means running `pytest` without the `--dist=loadfile -n auto` options. +* Generate a HTML report using `gcovr`, or `gcov` then `lcov` + +# Remaining Tasks + +The way our code coverage report is generated does not currently handle very well the multiple tools that are generated during the authoritative server build, and end up in the `pdns-tools` package. Consequently the coverage report for these tools, and the related code parts, is not accurate. +It is likely possible to pass several `--object ` options to `llvm-cov` when processing the `.profdata` file. From 02c535f4ff5c52800675fb9e753d80ca3e1dfc7d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 22 Sep 2023 12:03:53 +0200 Subject: [PATCH 803/909] Code coverage: Apply Fred's suggestions (thanks!) --- CODE_COVERAGE.md | 6 +++--- pdns/coverage.cc | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CODE_COVERAGE.md b/CODE_COVERAGE.md index 555cdffc5457..4b1a471f5b18 100644 --- a/CODE_COVERAGE.md +++ b/CODE_COVERAGE.md @@ -1,9 +1,9 @@ Code Coverage ------------- -PowerDNS uses [coveralls](https://coveralls.io/) to generate code coverage reports from our Continuous Integration tests. The resulting analysis can then be consulted [online](https://coveralls.io/github/PowerDNS/pdns), and gives hindsight into which parts of the code are automatically tested. +PowerDNS uses [coveralls](https://coveralls.io/) to generate code coverage reports from our Continuous Integration tests. The resulting analysis can then be consulted [online](https://coveralls.io/github/PowerDNS/pdns), and gives insight into which parts of the code are automatically tested. -Code coverage is generated during our Continuous Integration tests, for every pull requests and pushs. In addition to the dashboard on coveralls's website, a summary is posted on pull requests. +Code coverage is generated during our Continuous Integration tests, for every pull request. In addition to the dashboard on Coveralls' website, a summary is posted on pull requests. # Technical Details @@ -73,5 +73,5 @@ It is possible to generate a code coverage report without going through the CI, # Remaining Tasks -The way our code coverage report is generated does not currently handle very well the multiple tools that are generated during the authoritative server build, and end up in the `pdns-tools` package. Consequently the coverage report for these tools, and the related code parts, is not accurate. +The way our code coverage report is generated does not currently handle the different authoritative server tools (that end up in the `pdns-tools` package) very well. Consequently the coverage report for these tools, and the related code parts, is not accurate. It is likely possible to pass several `--object ` options to `llvm-cov` when processing the `.profdata` file. diff --git a/pdns/coverage.cc b/pdns/coverage.cc index 71fcda4b0749..3cbfa40424eb 100644 --- a/pdns/coverage.cc +++ b/pdns/coverage.cc @@ -25,10 +25,10 @@ #ifdef COVERAGE extern "C" { - //NOLINTNEXTLINE(bugprone-reserved-identifier): not ours + // NOLINTNEXTLINE(bugprone-reserved-identifier): not ours void __gcov_dump(void); #ifdef CLANG_COVERAGE - //NOLINTNEXTLINE(bugprone-reserved-identifier): not ours + // NOLINTNEXTLINE(bugprone-reserved-identifier): not ours int __llvm_profile_write_file(void); #endif /* CLANG_COVERAGE */ } From f2e51268c9ed9f04a37e501e25b69b5ae8a5a764 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 22 Sep 2023 12:05:17 +0200 Subject: [PATCH 804/909] Code coverage: Fix a link --- CODE_COVERAGE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE_COVERAGE.md b/CODE_COVERAGE.md index 4b1a471f5b18..850502e7599d 100644 --- a/CODE_COVERAGE.md +++ b/CODE_COVERAGE.md @@ -38,7 +38,7 @@ The `.profraw` file(s) can be merged by [`llvm-profdata merge`](https://llvm.org ## Implementation We use `clang++`'s source-based coverage method in our CI, as it allows running our regression tests in parallel with several workers. It is enabled by passing the `--enable-coverage=clang` flag during `configure` for all products. -The code coverage generation is done as part of the (build-and-test-all.yml)[https://github.com/PowerDNS/pdns/blob/master/.github/workflows/build-and-test-all.yml] workflow. +The code coverage generation is done as part of the [build-and-test-all.yml](https://github.com/PowerDNS/pdns/blob/master/.github/workflows/build-and-test-all.yml) workflow. Since we have a `monorepo` for three products which share the same code-base, the process is a bit tricky: From e910a9d07994ed79720d903a5a1515bb65fd95bd Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 9 Oct 2023 11:27:44 +0200 Subject: [PATCH 805/909] Code coverage: Fix two typos --- .github/scripts/normalize_paths_in_coverage.py | 2 +- CODE_COVERAGE.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/normalize_paths_in_coverage.py b/.github/scripts/normalize_paths_in_coverage.py index be0a80b12205..802b19ff1e6f 100755 --- a/.github/scripts/normalize_paths_in_coverage.py +++ b/.github/scripts/normalize_paths_in_coverage.py @@ -42,7 +42,7 @@ print(f'Ignoring {target} that we could not map to a distdir', file=sys.stderr) continue - # we need to propery map symbolic links + # we need to properly map symbolic links fullPath = os.path.join(repositoryRoot, target) if os.path.islink(fullPath): # get the link target diff --git a/CODE_COVERAGE.md b/CODE_COVERAGE.md index 850502e7599d..778928b7bca2 100644 --- a/CODE_COVERAGE.md +++ b/CODE_COVERAGE.md @@ -27,7 +27,7 @@ Processing pdns/ednssubnet.gcda __w/pdns/pdns/pdns/ednssubnet.gcno:version '408', prefer 'B02' ``` -### Sourced Based +### Source Based `clang++` supports [source-based coverage](https://clang.llvm.org/docs/SourceBasedCodeCoverage.html), which operates on `AST` and preprocessor information directly. This is enabled by passing `-fprofile-instr-generate -fcoverage-mapping` to the compiler and leads to `.profraw` files being produced when the binary is executed. The `.profraw` file(s) can be merged by [`llvm-profdata merge`](https://llvm.org/docs/CommandGuide/llvm-profdata.html#profdata-merge) into a `.profdata` file which can then be used by [`llvm-cov show`](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-show) to generate HTML and text reports, or by [`llvm-cov export`](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-export) to export `LCOV` data that is compatible with other tools. From 827946b137e13ed95e3bfd2e6c919909337decda Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 9 Oct 2023 11:36:28 +0200 Subject: [PATCH 806/909] coverage: Do not call __gcov_dump() when using source-based coverage It's useless and will do nothing. --- pdns/coverage.cc | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/pdns/coverage.cc b/pdns/coverage.cc index 3cbfa40424eb..c996207ec8d0 100644 --- a/pdns/coverage.cc +++ b/pdns/coverage.cc @@ -25,11 +25,12 @@ #ifdef COVERAGE extern "C" { - // NOLINTNEXTLINE(bugprone-reserved-identifier): not ours - void __gcov_dump(void); #ifdef CLANG_COVERAGE // NOLINTNEXTLINE(bugprone-reserved-identifier): not ours int __llvm_profile_write_file(void); +#else /* CLANG_COVERAGE */ + // NOLINTNEXTLINE(bugprone-reserved-identifier): not ours + void __gcov_dump(void); #endif /* CLANG_COVERAGE */ } #endif /* COVERAGE */ @@ -39,9 +40,10 @@ namespace pdns::coverage void dumpCoverageData() { #ifdef COVERAGE - __gcov_dump(); #ifdef CLANG_COVERAGE __llvm_profile_write_file(); +#else /* CLANG_COVERAGE */ + __gcov_dump(); #endif /* CLANG_COVERAGE */ #endif /* COVERAGE */ } From 555b64d916d74ff0764318c20935853b75ec9960 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Sun, 30 Jul 2023 17:00:10 +0200 Subject: [PATCH 807/909] dnsdist: configurable DoQ and quiche checks --- pdns/dnsdistdist/configure.ac | 17 +++++++++++++ pdns/dnsdistdist/m4/dnsdist_enable_doq.m4 | 14 +++++++++++ pdns/dnsdistdist/m4/pdns_with_quiche.m4 | 29 +++++++++++++++++++++++ 3 files changed, 60 insertions(+) create mode 100644 pdns/dnsdistdist/m4/dnsdist_enable_doq.m4 create mode 100644 pdns/dnsdistdist/m4/pdns_with_quiche.m4 diff --git a/pdns/dnsdistdist/configure.ac b/pdns/dnsdistdist/configure.ac index e30075c25c00..11495c3c7916 100644 --- a/pdns/dnsdistdist/configure.ac +++ b/pdns/dnsdistdist/configure.ac @@ -20,6 +20,7 @@ CFLAGS="-g -O3 -Wall -Wextra -Wshadow -Wno-unused-parameter -fvisibility=hidden CXXFLAGS="-g -O3 -Wall -Wextra -Wshadow -Wno-unused-parameter -Wmissing-declarations -Wredundant-decls -fvisibility=hidden $CXXFLAGS" PDNS_WITH_LIBSODIUM +PDNS_WITH_QUICHE PDNS_CHECK_DNSTAP([auto]) PDNS_CHECK_RAGEL([dnslabeltext.cc], [www.dnsdist.org]) PDNS_WITH_LIBEDIT @@ -80,6 +81,7 @@ DNSDIST_ENABLE_TLS_PROVIDERS PDNS_ENABLE_DNS_OVER_TLS DNSDIST_ENABLE_DNS_OVER_HTTPS +DNSDIST_ENABLE_DNS_OVER_QUIC AS_IF([test "x$enable_dns_over_tls" != "xno" -o "x$enable_dns_over_https" != "xno"], [ PDNS_WITH_LIBSSL @@ -105,6 +107,13 @@ AS_IF([test "x$enable_dns_over_https" != "xno"], [ ]) ]) +AS_IF([test "x$enable_dns_over_quic" != "xno"], [ + AS_IF([test "x$HAVE_QUICHE" != "x1"], [ + AC_MSG_ERROR([DNS over QUIC support requested but quiche was not found]) + ]) +]) + +PDNS_WITH_NGHTTP2 DNSDIST_WITH_CDB PDNS_CHECK_LMDB PDNS_ENABLE_IPCIPHER @@ -218,6 +227,10 @@ AS_IF([test "x$FSTRM_LIBS" != "x"], [AC_MSG_NOTICE([dnstap: yes])], [AC_MSG_NOTICE([dnstap: no])] ) +AS_IF([test "x$QUICHE_LIBS" != "x"], + [AC_MSG_NOTICE([quiche: yes])], + [AC_MSG_NOTICE([quiche: no])] +) AS_IF([test "x$RE2_LIBS" != "x"], [AC_MSG_NOTICE([re2: yes])], [AC_MSG_NOTICE([re2: no])] @@ -234,6 +247,10 @@ AS_IF([test "x$enable_dns_over_https" != "xno"], [AC_MSG_NOTICE([DNS over HTTPS (DoH): yes])], [AC_MSG_NOTICE([DNS over HTTPS (DoH): no])] ) +AS_IF([test "x$enable_dns_over_quic" != "xno"], + [AC_MSG_NOTICE([DNS over QUIC (DoQ): yes])], + [AC_MSG_NOTICE([DNS over QUIC (DoQ): no])] +) AS_IF([test "x$enable_dns_over_tls" != "xno"], [ AS_IF([test "x$GNUTLS_LIBS" != "x"], [AC_MSG_NOTICE([GnuTLS: yes])], diff --git a/pdns/dnsdistdist/m4/dnsdist_enable_doq.m4 b/pdns/dnsdistdist/m4/dnsdist_enable_doq.m4 new file mode 100644 index 000000000000..e0ea5fc6a17d --- /dev/null +++ b/pdns/dnsdistdist/m4/dnsdist_enable_doq.m4 @@ -0,0 +1,14 @@ +AC_DEFUN([DNSDIST_ENABLE_DNS_OVER_QUIC], [ + AC_MSG_CHECKING([whether to enable incoming DNS over QUIC (DoH) support]) + AC_ARG_ENABLE([dns-over-quic], + AS_HELP_STRING([--enable-dns-over-quic], [enable incoming DNS over QUIC (DoQ) support (requires quiche) @<:@default=no@:>@]), + [enable_dns_over_quic=$enableval], + [enable_dns_over_quic=no] + ) + AC_MSG_RESULT([$enable_dns_over_quic]) + AM_CONDITIONAL([HAVE_DNS_OVER_QUIC], [test "x$enable_dns_over_quic" != "xno"]) + + AM_COND_IF([HAVE_DNS_OVER_QUIC], [ + AC_DEFINE([HAVE_DNS_OVER_QUIC], [1], [Define to 1 if you enable DNS over QUIC support]) + ]) +]) diff --git a/pdns/dnsdistdist/m4/pdns_with_quiche.m4 b/pdns/dnsdistdist/m4/pdns_with_quiche.m4 new file mode 100644 index 000000000000..40d94ddb5650 --- /dev/null +++ b/pdns/dnsdistdist/m4/pdns_with_quiche.m4 @@ -0,0 +1,29 @@ +AC_DEFUN([PDNS_WITH_QUICHE], [ + AC_MSG_CHECKING([whether we will be linking in quiche]) + HAVE_QUICHE=0 + AC_ARG_WITH([quiche], + AS_HELP_STRING([--with-quiche],[use quiche @<:@default=auto@:>@]), + [with_quiche=$withval], + [with_quiche=auto], + ) + AC_MSG_RESULT([$with_quiche]) + + AS_IF([test "x$with_quiche" != "xno"], [ + AS_IF([test "x$with_quiche" = "xyes" -o "x$with_quiche" = "xauto"], [ + PKG_CHECK_MODULES([QUICHE], [quiche], [ + [HAVE_QUICHE=1] + AC_DEFINE([HAVE_QUICHE], [1], [Define to 1 if you have quiche]) + save_CFLAGS=$CFLAGS + save_LIBS=$LIBS + CFLAGS="$QUICHE_CFLAGS $CFLAGS" + LIBS="$QUICHE_LIBS $LIBS" + ], [ : ]) + ]) + ]) + AM_CONDITIONAL([HAVE_QUICHE], [test "x$QUICHE_LIBS" != "x"]) + AS_IF([test "x$with_quiche" = "xyes"], [ + AS_IF([test x"$QUICHE_LIBS" = "x"], [ + AC_MSG_ERROR([quiche requested but libraries were not found]) + ]) + ]) +]) From 3efa20402c11aa1d6fb230fa857d654a746f1299 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Wed, 16 Aug 2023 16:03:48 +0200 Subject: [PATCH 808/909] dnsdist: add DoQ protocol definition --- pdns/dnsdist-protocols.cc | 6 ++++-- pdns/dnsdist-protocols.hh | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pdns/dnsdist-protocols.cc b/pdns/dnsdist-protocols.cc index aee63f28eef4..e113925e0695 100644 --- a/pdns/dnsdist-protocols.cc +++ b/pdns/dnsdist-protocols.cc @@ -33,7 +33,8 @@ const std::array Protocol::s_names = "DNSCryptUDP", "DNSCryptTCP", "DoT", - "DoH"}; + "DoH", + "DoQ"}; const std::array Protocol::s_prettyNames = { "Do53 UDP", @@ -41,7 +42,8 @@ const std::array Protocol::s_prettyN "DNSCrypt UDP", "DNSCrypt TCP", "DNS over TLS", - "DNS over HTTPS"}; + "DNS over HTTPS", + "DNS over QUIC"}; Protocol::Protocol(const std::string& s) { diff --git a/pdns/dnsdist-protocols.hh b/pdns/dnsdist-protocols.hh index bd2a4bb8ad1a..bece30095508 100644 --- a/pdns/dnsdist-protocols.hh +++ b/pdns/dnsdist-protocols.hh @@ -37,7 +37,8 @@ public: DNSCryptUDP, DNSCryptTCP, DoT, - DoH + DoH, + DoQ }; Protocol(typeenum protocol = DoUDP) : @@ -61,7 +62,7 @@ public: private: typeenum d_protocol; - static constexpr size_t s_numberOfProtocols = 6; + static constexpr size_t s_numberOfProtocols = 7; static const std::array s_names; static const std::array s_prettyNames; }; From 57a94421f4575f796bae404f84db6413ecc42518 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Mon, 31 Jul 2023 15:39:36 +0200 Subject: [PATCH 809/909] dnsdist: add basic DoQ support --- pdns/dnsdist-console.cc | 2 + pdns/dnsdist-idstate.hh | 3 + pdns/dnsdist-lua.cc | 83 ++ pdns/dnsdist.cc | 20 +- pdns/dnsdist.hh | 8 + pdns/dnsdistdist/Makefile.am | 7 + pdns/dnsdistdist/dnsdist-internal-queries.cc | 6 + pdns/dnsdistdist/docs/reference/config.rst | 26 + pdns/dnsdistdist/doq.cc | 864 +++++++++++++++++++ pdns/dnsdistdist/doq.hh | 132 +++ 10 files changed, 1150 insertions(+), 1 deletion(-) create mode 100644 pdns/dnsdistdist/doq.cc create mode 100644 pdns/dnsdistdist/doq.hh diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index d1a42663d130..a451f31e1ad7 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -470,6 +470,7 @@ const std::vector g_consoleKeywords{ { "addConsoleACL", true, "netmask", "add a netmask to the console ACL" }, { "addDNSCryptBind", true, "\"127.0.0.1:8443\", \"provider name\", \"/path/to/resolver.cert\", \"/path/to/resolver.key\", {reusePort=false, tcpFastOpenQueueSize=0, interface=\"\", cpus={}}", "listen to incoming DNSCrypt queries on 127.0.0.1 port 8443, with a provider name of `provider name`, using a resolver certificate and associated key stored respectively in the `resolver.cert` and `resolver.key` files. The fifth optional parameter is a table of parameters" }, { "addDOHLocal", true, "addr, certFile, keyFile [, urls [, vars]]", "listen to incoming DNS over HTTPS queries on the specified address using the specified certificate and key. The last two parameters are tables" }, + { "addDOQLocal", true, "addr, certFile, keyFile [, vars]", "listen to incoming DNS over QUIC queries on the specified address using the specified certificate and key. The last parameter is a table" }, { "addDynBlocks", true, "addresses, message[, seconds[, action]]", "block the set of addresses with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)" }, { "addDynBlockSMT", true, "names, message[, seconds [, action]]", "block the set of names with message `msg`, for `seconds` seconds (10 by default), applying `action` (default to the one set with `setDynBlocksAction()`)" }, { "addLocal", true, "addr [, {doTCP=true, reusePort=false, tcpFastOpenQueueSize=0, interface=\"\", cpus={}}]", "add `addr` to the list of addresses we listen on" }, @@ -746,6 +747,7 @@ const std::vector g_consoleKeywords{ { "showDNSCryptBinds", true, "", "display the currently configured DNSCrypt binds" }, { "showDOHFrontends", true, "", "list all the available DOH frontends" }, { "showDOHResponseCodes", true, "", "show the HTTP response code statistics for the DoH frontends"}, + { "showDOQFrontends", true, "", "list all the available DOQ frontends" }, { "showDynBlocks", true, "", "show dynamic blocks in force" }, { "showPools", true, "", "show the available pools" }, { "showPoolServerPolicy", true, "pool", "show server selection policy for this pool" }, diff --git a/pdns/dnsdist-idstate.hh b/pdns/dnsdist-idstate.hh index 313e434ea825..ddc69475401d 100644 --- a/pdns/dnsdist-idstate.hh +++ b/pdns/dnsdist-idstate.hh @@ -32,6 +32,7 @@ struct ClientState; struct DOHUnitInterface; +struct DOQUnit; class DNSCryptQuery; class DNSDistPacketCache; @@ -130,9 +131,11 @@ struct InternalQueryState std::unique_ptr d_protoBufData{nullptr}; boost::optional tempFailureTTL{boost::none}; // 8 ClientState* cs{nullptr}; // 8 + std::unique_ptr du; // 8 size_t d_proxyProtocolPayloadSize{0}; // 8 int32_t d_streamID{-1}; // 4 + std::unique_ptr doqu{nullptr}; // 8 uint32_t cacheKey{0}; // 4 uint32_t cacheKeyNoECS{0}; // 4 // DoH-only */ diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 902ccf64ac0c..39a30ba053c3 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2483,6 +2483,89 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) #endif /* HAVE_DNS_OVER_HTTPS */ }); + luaCtx.writeFunction("addDOQLocal", [client](const std::string& addr, boost::optional, LuaArray, LuaArray>>> certFiles, boost::optional>> keyFiles, boost::optional vars) { + if (client) { + return; + } +#ifdef HAVE_DNS_OVER_QUIC + if (!checkConfigurationTime("addDOQLocal")) { + return; + } + setLuaSideEffect(); + + auto frontend = std::make_shared(); + if (!loadTLSCertificateAndKeys("addDOQLocal", frontend->d_tlsConfig.d_certKeyPairs, *certFiles, *keyFiles)) { + return; + } + frontend->d_local = ComboAddress(addr, 853); + + bool reusePort = false; + int tcpFastOpenQueueSize = 0; + int tcpListenQueueSize = 0; + uint64_t maxInFlightQueriesPerConn = 0; + uint64_t tcpMaxConcurrentConnections = 0; + std::string interface; + std::set cpus; + std::vector> additionalAddresses; + + if (vars) { + parseLocalBindVars(vars, reusePort, tcpFastOpenQueueSize, interface, cpus, tcpListenQueueSize, maxInFlightQueriesPerConn, tcpMaxConcurrentConnections); +// getOptionalValue(vars, "idleTimeout", frontend->d_idleTimeout); + + getOptionalValue(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize); + + parseTLSConfig(frontend->d_tlsConfig, "addDOQLocal", vars); + + bool ignoreTLSConfigurationErrors = false; + if (getOptionalValue(vars, "ignoreTLSConfigurationErrors", ignoreTLSConfigurationErrors) > 0 && ignoreTLSConfigurationErrors) { + // we are asked to try to load the certificates so we can return a potential error + // and properly ignore the frontend before actually launching it + try { + std::map ocspResponses = {}; + auto ctx = libssl_init_server_context(frontend->d_tlsConfig, ocspResponses); + } + catch (const std::runtime_error& e) { + errlog("Ignoring DoQ frontend: '%s'", e.what()); + return; + } + } + + checkAllParametersConsumed("addDOQLocal", vars); + } + g_doqlocals.push_back(frontend); + auto cs = std::make_unique(frontend->d_local, false, reusePort, tcpFastOpenQueueSize, interface, cpus); + cs->doqFrontend = frontend; + cs->d_additionalAddresses = std::move(additionalAddresses); + + g_frontends.push_back(std::move(cs)); +#else + throw std::runtime_error("addDOQLocal() called but DNS over QUIC support is not present!"); +#endif + }); + + luaCtx.writeFunction("showDOQFrontends", []() { +#ifdef HAVE_DNS_OVER_QUIC + setLuaNoSideEffect(); + try { + ostringstream ret; + boost::format fmt("%-3d %-20.20s"); + ret << (fmt % "#" % "Address") << endl; + size_t counter = 0; + for (const auto& ctx : g_doqlocals) { + ret << (fmt % counter % ctx->d_local.toStringWithPort()) << endl; + counter++; + } + g_outputBuffer = ret.str(); + } + catch (const std::exception& e) { + g_outputBuffer = e.what(); + throw; + } +#else + g_outputBuffer = "DNS over QUIC support is not present!\n"; +#endif + }); + luaCtx.writeFunction("showDOHFrontends", []() { #ifdef HAVE_DNS_OVER_HTTPS setLuaNoSideEffect(); diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 7d6e5bac60be..d2b7759968b3 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -109,6 +109,7 @@ string g_outputBuffer; std::vector> g_tlslocals; std::vector> g_dohlocals; +std::vector> g_doqlocals; std::vector> g_dnsCryptLocals; shared_ptr g_defaultBPFFilter{nullptr}; @@ -2317,6 +2318,10 @@ static void setUpLocalBind(std::unique_ptr& cstate) else { infolog("Listening on %s", addr.toStringWithPort()); } + } else { + if (cs.doqFrontend != nullptr) { + infolog("Listening on %s for DoQ", addr.toStringWithPort()); + } } }; @@ -2341,6 +2346,9 @@ static void setUpLocalBind(std::unique_ptr& cstate) if (cstate->dohFrontend != nullptr) { cstate->dohFrontend->setup(); } + if (cstate->doqFrontend != nullptr) { + cstate->doqFrontend->setup(); + } cstate->ready = true; } @@ -2728,7 +2736,7 @@ int main(int argc, char** argv) if (!g_cmdLine.locals.empty()) { for (auto it = g_frontends.begin(); it != g_frontends.end(); ) { /* DoH, DoT and DNSCrypt frontends are separate */ - if ((*it)->dohFrontend == nullptr && (*it)->tlsFrontend == nullptr && (*it)->dnscryptCtx == nullptr) { + if ((*it)->dohFrontend == nullptr && (*it)->tlsFrontend == nullptr && (*it)->dnscryptCtx == nullptr && (*it)->doqFrontend == nullptr) { it = g_frontends.erase(it); } else { @@ -2927,6 +2935,16 @@ int main(int argc, char** argv) #endif /* HAVE_DNS_OVER_HTTPS */ continue; } + if (cs->doqFrontend != nullptr) { +#ifdef HAVE_DNS_OVER_QUIC + std::thread t1(doqThread, cs.get()); + if (!cs->cpus.empty()) { + mapThreadToCPUList(t1.native_handle(), cs->cpus); + } + t1.detach(); +#endif /* HAVE_DNS_OVER_QUIC */ + continue; + } if (cs->udpFD >= 0) { #ifdef USE_SINGLE_ACCEPTOR_THREAD udpStates.push_back(cs.get()); diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 694dab3a6cbe..f9455f2d11e6 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once + #include "config.h" #include "ext/luawrapper/include/LuaContext.hpp" @@ -43,6 +44,7 @@ #include "dnsdist-protocols.hh" #include "dnsname.hh" #include "dnsdist-doh-common.hh" +#include "doq.hh" #include "ednsoptions.hh" #include "iputils.hh" #include "misc.hh" @@ -492,6 +494,7 @@ struct ClientState std::shared_ptr dnscryptCtx{nullptr}; std::shared_ptr tlsFrontend{nullptr}; std::shared_ptr dohFrontend{nullptr}; + std::shared_ptr doqFrontend{nullptr}; std::shared_ptr d_filter{nullptr}; size_t d_maxInFlightQueriesPerConn{1}; size_t d_tcpConcurrentConnectionsLimit{0}; @@ -1053,6 +1056,7 @@ extern ComboAddress g_serverControl; // not changed during runtime extern std::vector> g_tlslocals; extern std::vector> g_dohlocals; +extern std::vector> g_doqlocals; extern std::vector> g_frontends; extern bool g_truncateTC; extern bool g_fixupCase; @@ -1099,6 +1103,10 @@ struct LocalHolders void tcpAcceptorThread(std::vector states); +#ifdef HAVE_DNS_OVER_QUIC +void doqThread(ClientState* cs); +#endif /* HAVE_DNS_OVER_QUIC */ + void setLuaNoSideEffect(); // if nothing has been declared, set that there are no side effects void setLuaSideEffect(); // set to report a side effect, cancelling all _no_ side effect calls bool getLuaNoSideEffect(); // set if there were only explicit declarations of _no_ side effect diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index db92cc87305d..411d33800102 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -211,6 +211,7 @@ dnsdist_SOURCES = \ dnstap.cc dnstap.hh \ dnswriter.cc dnswriter.hh \ doh.hh \ + doq.hh \ dolog.hh \ ednscookies.cc ednscookies.hh \ ednsoptions.cc ednsoptions.hh \ @@ -436,6 +437,12 @@ endif endif +if HAVE_DNS_OVER_QUIC + +dnsdist_SOURCES += doq.cc + +endif + if HAVE_NGHTTP2 dnsdist_LDADD += $(NGHTTP2_LDFLAGS) $(NGHTTP2_LIBS) testrunner_LDADD += $(NGHTTP2_LDFLAGS) $(NGHTTP2_LIBS) diff --git a/pdns/dnsdistdist/dnsdist-internal-queries.cc b/pdns/dnsdistdist/dnsdist-internal-queries.cc index ea4c54139709..9f6a3c40d390 100644 --- a/pdns/dnsdistdist/dnsdist-internal-queries.cc +++ b/pdns/dnsdistdist/dnsdist-internal-queries.cc @@ -23,6 +23,7 @@ #include "dnsdist-nghttp2-in.hh" #include "dnsdist-tcp.hh" #include "doh.hh" +#include "doq.hh" std::unique_ptr getUDPCrossProtocolQueryFromDQ(DNSQuestion& dq); @@ -43,6 +44,11 @@ std::unique_ptr getInternalQueryFromDQ(DNSQuestion& dq, bool #endif /* HAVE_LIBH2OEVLOOP */ return getTCPCrossProtocolQueryFromDQ(dq); } +#endif +#ifdef HAVE_DNS_OVER_QUIC + else if (protocol == dnsdist::Protocol::DoQ) { + return getDOQCrossProtocolQueryFromDQ(dq, isResponse); + } #endif else { return getTCPCrossProtocolQueryFromDQ(dq); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index cca41b76f00b..fbb8e73f7764 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -171,6 +171,26 @@ Listen Sockets * ``readAhead``: bool - When the TLS provider is set to OpenSSL, whether we tell the library to read as many input bytes as possible, which leads to better performance by reducing the number of syscalls. Default is true. * ``proxyProtocolOutsideTLS``: bool - When the use of incoming proxy protocol is enabled, whether the payload is prepended after the start of the TLS session (so inside, meaning it is protected by the TLS layer providing encryption and authentication) or not (outside, meaning it is in clear-text). Default is false which means inside. Note that most third-party software like HAproxy expect the proxy protocol payload to be outside, in clear-text. +.. function:: addDOQLocal(address, [certFile(s) [, keyFile(s) [, urls [, options]]]]) + + .. versionadded:: 1.9.0 + + Listen on the specified address and UDP port for incoming DNS over QUIC connections, presenting the specified X.509 certificate. + + :param str address: The IP Address with an optional port to listen on. + The default port is 853. + :param str certFile(s): The path to a X.509 certificate file in PEM format, a list of paths to such files, or a TLSCertificate object. + :param str keyFile(s): The path to the private key file corresponding to the certificate, or a list of paths to such files, whose order should match the certFile(s) ones. Ignored if ``certFile`` contains TLSCertificate objects. + :param table options: A table with key: value pairs with listen options. + + Options: + + * ``reusePort=false``: bool - Set the ``SO_REUSEPORT`` socket option. + * ``interface=""``: str - Set the network interface to use. + * ``cpus={}``: table - Set the CPU affinity for this listener thread, asking the scheduler to run it on a single CPU id, or a set of CPU ids. This parameter is only available if the OS provides the pthread_setaffinity_np() function. + * ``idleTimeout=30``: int - Set the idle timeout, in seconds. + * ``internalPipeBufferSize=0``: int - Set the size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads. Requires support for ``F_SETPIPE_SZ`` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used. The default value is 0, except on Linux where it is 1048576 since 1.6.0. + .. function:: addTLSLocal(address, certFile(s), keyFile(s) [, options]) .. versionchanged:: 1.4.0 @@ -1220,6 +1240,12 @@ Status, Statistics and More Print the HTTP response codes statistics for all available DNS over HTTPS frontends. +.. function:: showDOQFrontends() + + .. versionadded:: 1.9.0 + + Print the list of all available DNS over QUIC frontends. + .. function:: showResponseLatency() Show a plot of the response time latency distribution diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc new file mode 100644 index 000000000000..c8e8bbe04bc5 --- /dev/null +++ b/pdns/dnsdistdist/doq.cc @@ -0,0 +1,864 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "doq.hh" + +#include "dnsdist-tcp.hh" +#include "dolog.hh" +#include "iputils.hh" +#include "misc.hh" +#include "sstuff.hh" +#include "dnsparser.hh" +#include "threadname.hh" +#include "dnsdist-ecs.hh" +#include "dnsdist-proxy-protocol.hh" + + +class DOQServerConfig +{ +public: + DOQServerConfig(std::unique_ptr&& config_, uint32_t internalPipeBufferSize) : + config(std::move(config_)) + { + { + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverBlocking, internalPipeBufferSize); + d_querySender = std::move(sender); + d_queryReceiver = std::move(receiver); + } + { + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverBlocking, internalPipeBufferSize); + d_responseSender = std::move(sender); + d_responseReceiver = std::move(receiver); + } + } + DOQServerConfig(const DOQServerConfig&) = delete; + DOQServerConfig(DOQServerConfig&&) = default; + DOQServerConfig& operator=(const DOQServerConfig&) = delete; + DOQServerConfig& operator=(DOQServerConfig&&) = default; + ~DOQServerConfig() = default; + + LocalHolders holders; + QuicheConfig config; + ClientState* cs{nullptr}; + std::shared_ptr df{nullptr}; + pdns::channel::Sender d_querySender; + pdns::channel::Receiver d_queryReceiver; + pdns::channel::Sender d_responseSender; + pdns::channel::Receiver d_responseReceiver; +}; + +#if 1 +#define DEBUGLOG_ENABLED +#define DEBUGLOG(x) std::cerr< s_connections; + +/* This internal function sends back the object to the main thread to send a reply. + The caller should NOT release or touch the unit after calling this function */ +static void sendDOQUnitToTheMainThread(DOQUnitUniquePtr&& du, const char* description) +{ + if (du->responseSender == nullptr) { + return; + } + try { + if (!du->responseSender->send(std::move(du))) { + vinfolog("Unable to pass a %s to the DoQ worker thread because the pipe is full", description); + } + } catch (const std::exception& e) { + vinfolog("Unable to pass a %s to the DoQ worker thread because we couldn't write to the pipe: %s", description, e.what()); + } +} + +class DOQTCPCrossQuerySender final : public TCPQuerySender +{ +public: + DOQTCPCrossQuerySender() + { + } + + bool active() const override + { + return true; + } + + void handleResponse(const struct timeval& now, TCPResponse&& response) override + { + if (!response.d_idstate.doqu) { + return; + } + + auto du = std::move(response.d_idstate.doqu); + if (du->responseSender == nullptr) { + return; + } + + du->response = std::move(response.d_buffer); + du->ids = std::move(response.d_idstate); + DNSResponse dr(du->ids, du->response, du->downstream); + + dnsheader cleartextDH; + memcpy(&cleartextDH, dr.getHeader(), sizeof(cleartextDH)); + + if (!response.isAsync()) { + + static thread_local LocalStateHolder> localRespRuleActions = g_respruleactions.getLocal(); + static thread_local LocalStateHolder> localCacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal(); + + dr.ids.doqu = std::move(du); + + + if (!processResponse(dr.ids.doqu->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) { + if (dr.ids.doqu) { + + sendDOQUnitToTheMainThread(std::move(dr.ids.doqu), "Response dropped by rules"); + } + return; + } + + if (dr.isAsynchronous()) { + return; + } + + du = std::move(dr.ids.doqu); + } + + if (!du->ids.selfGenerated) { + double udiff = du->ids.queryRealTime.udiff(); + vinfolog("Got answer from %s, relayed to %s (quic), took %f us", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); + + auto backendProtocol = du->downstream->getProtocol(); + if (backendProtocol == dnsdist::Protocol::DoUDP && du->tcp) { + backendProtocol = dnsdist::Protocol::DoTCP; + } + handleResponseSent(du->ids, udiff, du->ids.origRemote, du->downstream->d_config.remote, du->response.size(), cleartextDH, backendProtocol, true); + } + + ++dnsdist::metrics::g_stats.responses; + if (du->ids.cs) { + ++du->ids.cs->responses; + } + + sendDOQUnitToTheMainThread(std::move(du), "cross-protocol response"); + } + + void handleXFRResponse(const struct timeval& now, TCPResponse&& response) override + { + return handleResponse(now, std::move(response)); + } + + void notifyIOError(const struct timeval& now, TCPResponse&& response) override + { + // auto& query = response.d_idstate; + // if (!query.du) { + // return; + // } + + // auto dohUnit = getDUFromIDS(query); + // if (dohUnit->responseSender == nullptr) { + // return; + // } + + // du->ids = std::move(query); + // sendDOQUnitToTheMainThread(std::move(du), "cross-protocol error response"); + } + // void notifyIOError(InternalQueryState&& query, const struct timeval& now) override + // { + // if (!query.doqu) { + // return; + // } + + // if (query.doqu->responseSender == nullptr) { + // return; + // } + + // auto du = std::move(query.doqu); + // du->ids = std::move(query); + // sendDOQUnitToTheMainThread(std::move(du), "cross-protocol error response"); + // } +}; + +class DOQCrossProtocolQuery : public CrossProtocolQuery +{ +public: + DOQCrossProtocolQuery(DOQUnitUniquePtr&& du, bool isResponse) + { + if (isResponse) { + /* happens when a response becomes async */ + query = InternalQuery(std::move(du->response), std::move(du->ids)); + } + else { + /* we need to duplicate the query here because we might need + the existing query later if we get a truncated answer */ + query = InternalQuery(PacketBuffer(du->query), std::move(du->ids)); + } + + /* it might have been moved when we moved du->ids */ + if (du) { + query.d_idstate.doqu = std::move(du); + } + + /* we _could_ remove it from the query buffer and put in query's d_proxyProtocolPayload, + clearing query.d_proxyProtocolPayloadAdded and du->proxyProtocolPayloadSize. + Leave it for now because we know that the onky case where the payload has been + added is when we tried over UDP, got a TC=1 answer and retried over TCP/DoT, + and we know the TCP/DoT code can handle it. */ + query.d_proxyProtocolPayloadAdded = query.d_idstate.doqu->proxyProtocolPayloadSize > 0; + downstream = query.d_idstate.doqu->downstream; + } + + void handleInternalError() + { + sendDOQUnitToTheMainThread(std::move(query.d_idstate.doqu), "DOQ internal error"); + } + + std::shared_ptr getTCPQuerySender() override + { + query.d_idstate.doqu->downstream = downstream; + return s_sender; + } + + DNSQuestion getDQ() override + { + auto& ids = query.d_idstate; + DNSQuestion dq(ids, query.d_buffer); + return dq; + } + + DNSResponse getDR() override + { + auto& ids = query.d_idstate; + DNSResponse dr(ids, query.d_buffer, downstream); + return dr; + } + + DOQUnitUniquePtr&& releaseDU() + { + return std::move(query.d_idstate.doqu); + } + +private: + static std::shared_ptr s_sender; +}; + +std::shared_ptr DOQCrossProtocolQuery::s_sender = std::make_shared(); + +/* Always called from the main DoQ thread */ +static void handleResponse(DOQFrontend& df, Connection& conn, const uint64_t streamID, const PacketBuffer& response) +{ + uint16_t responseSize = static_cast(response.size()); + const uint8_t sizeBytes[] = { static_cast(responseSize / 256), static_cast(responseSize % 256) }; + auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, sizeBytes, sizeof(sizeBytes), false); + if (res == sizeof(sizeBytes)) { + res = quiche_conn_stream_send(conn.d_conn.get(), streamID, response.data(), response.size(), true); + } +} + +void DOQFrontend::setup() +{ + auto config = QuicheConfig(quiche_config_new(QUICHE_PROTOCOL_VERSION), quiche_config_free); + for (const auto& pair : d_tlsConfig.d_certKeyPairs) { + auto res = quiche_config_load_cert_chain_from_pem_file(config.get(), pair.d_cert.c_str()); + if (res != 0) { + throw std::runtime_error("Error loading the server certificate: " + std::to_string(res)); + } + if (pair.d_key) { + res = quiche_config_load_priv_key_from_pem_file(config.get(), pair.d_key->c_str()); + if (res != 0) { + throw std::runtime_error("Error loading the server key: " + std::to_string(res)); + } + } + } + + { + const std::array alpn{'\x03', 'd', 'o', 'q'}; + auto res = quiche_config_set_application_protos(config.get(), + alpn.data(), + alpn.size()); + if (res != 0) { + throw std::runtime_error("Error setting ALPN: " + std::to_string(res)); + } + } + + quiche_config_set_max_idle_timeout(config.get(), 5000); + quiche_config_set_max_recv_udp_payload_size(config.get(), MAX_DATAGRAM_SIZE); + quiche_config_set_max_send_udp_payload_size(config.get(), MAX_DATAGRAM_SIZE); + quiche_config_set_initial_max_data(config.get(), 10000000); + quiche_config_set_initial_max_stream_data_bidi_local(config.get(), 1000000); + quiche_config_set_initial_max_stream_data_bidi_remote(config.get(), 1000000); + quiche_config_set_initial_max_streams_bidi(config.get(), 100); + quiche_config_set_cc_algorithm(config.get(), QUICHE_CC_RENO); + // quiche_config_log_keys(config.get()); + + d_server_config = std::make_shared(std::move(config), d_internalPipeBufferSize); +} + +static std::optional getCID() +{ + // FIXME remplacer par notre truc de random + int rng = open("/dev/urandom", O_RDONLY); + if (rng < 0) { + return std::nullopt; + + } + PacketBuffer buffer; + buffer.resize(LOCAL_CONN_ID_LEN); + auto got = read(rng, buffer.data(), LOCAL_CONN_ID_LEN); + if (got < 0) { + return std::nullopt; + } + + return buffer; +} + +static PacketBuffer mintToken(const PacketBuffer& dcid, const ComboAddress& peer) +{ + // FIXME: really check whether this needs to be authenticated, via HMAC for example + // client recoit un datagram + // challenge avec token + // suffisement d'infos pour binder a la bonne adresse + // filer l'original CID fille par le client. + // -> ne pas garder l'etat + // -> inclure l'info dans le token + // -> voir avec libsodium ? + // -> token plus gros avec HMAC + // -> regarder ce que font les autres implementations de QUIC + const std::array keyword = {'q', 'u', 'i', 'c', 'h', 'e'}; + auto addrBytes = peer.toByteString(); + PacketBuffer token; + token.reserve(keyword.size() + addrBytes.size() + dcid.size()); + token.insert(token.end(), keyword.begin(), keyword.end()); + token.insert(token.end(), addrBytes.begin(), addrBytes.end()); + token.insert(token.end(), dcid.begin(), dcid.end()); + return token; +} + +// returns the original destination ID if the token is valid, nothing otherwise +static std::optional validateToken(const PacketBuffer& token, const PacketBuffer& dcid, const ComboAddress& peer) +{ + const std::array keyword = {'q', 'u', 'i', 'c', 'h', 'e'}; + auto addrBytes = peer.toByteString(); + auto minimumSize = keyword.size() + addrBytes.size(); + if (token.size() <= minimumSize) { + return std::nullopt; + } + if (std::memcmp(&*keyword.begin(), &*token.begin(), keyword.size()) != 0) { + return std::nullopt; + } + if (std::memcmp(&token.at(keyword.size()), &*addrBytes.begin(), addrBytes.size()) != 0) { + return std::nullopt; + } + return PacketBuffer(token.begin() + keyword.size() + addrBytes.size(), token.end()); +} + +static void handleStatelessRetry(Socket& sock, const PacketBuffer& clientConnID, const PacketBuffer& serverConnID, const ComboAddress& peer, uint32_t version) +{ + auto newServerConnID = getCID(); + if (!newServerConnID) { + return; + } + + auto token = mintToken(serverConnID, peer); + + PacketBuffer out(MAX_DATAGRAM_SIZE); + auto written = quiche_retry(clientConnID.data(), clientConnID.size(), + serverConnID.data(), serverConnID.size(), + newServerConnID->data(), newServerConnID->size(), + token.data(), token.size(), + version, + out.data(), out.size()); + + if (written < 0) { + DEBUGLOG("failed to create retry packet " << written); + return; + } + + out.resize(written); + sock.sendTo(std::string(out.begin(), out.end()), peer); +} + +static void handleVersionNegociation(Socket& sock, const PacketBuffer& clientConnID, const PacketBuffer& serverConnID, const ComboAddress& peer) +{ + PacketBuffer out(MAX_DATAGRAM_SIZE); + + auto written = quiche_negotiate_version(clientConnID.data(), clientConnID.size(), + serverConnID.data(), serverConnID.size(), + out.data(), out.size()); + + if (written < 0) { + DEBUGLOG("failed to create vneg packet " << written); + return; + } + sock.sendTo(reinterpret_cast(out.data()), written, peer); +} + +static std::optional> getConnection(const PacketBuffer& id) +{ + auto it = s_connections.find(id); + if (it == s_connections.end()) { + return std::nullopt; + } + return it->second; +} + +static std::optional> createConnection(QuicheConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const PacketBuffer& token, const ComboAddress& local, const ComboAddress& peer) +{ + auto quicheConn = QuicheConnection(quiche_accept(serverSideID.data(), serverSideID.size(), + originalDestinationID.data(), originalDestinationID.size(), + (struct sockaddr*) &local, + local.getSocklen(), + (struct sockaddr*) &peer, + peer.getSocklen(), + config.get()), quiche_conn_free); + auto conn = Connection(peer, std::move(quicheConn)); + auto pair = s_connections.emplace(serverSideID, std::move(conn)); + return pair.first->second; +} + +static void flushEgress(Socket& sock, Connection& conn) { + std::array out; + quiche_send_info send_info; + + while (true) { + auto written = quiche_conn_send(conn.d_conn.get(), out.data(), out.size(), &send_info); + + if (written == QUICHE_ERR_DONE) { + return; + } + + if (written < 0) { + return; + } + + sock.sendTo(reinterpret_cast(out.data()), written, conn.d_peer); + } + + // FIXME: update timers + // -> on peut appeler une fonction quiche pour savoir quand prochain timeout + // -> pas ici ? + // -> fin de loop event quand est le prochain plus petit timeout a venir + // -> relancer le multiplexer pour au plus ce temps la +} + +std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse) +{ + if (!dq.ids.doqu) { + throw std::runtime_error("Trying to create a DoQ cross protocol query without a valid DoQ unit"); + } + + auto du = std::move(dq.ids.doqu); + if (&dq.ids != &du->ids) { + du->ids = std::move(dq.ids); + } + + du->ids.origID = dq.getHeader()->id; + + if (!isResponse) { + if (du->query.data() != dq.getMutableData().data()) { + du->query = std::move(dq.getMutableData()); + } + } + else { + if (du->response.data() != dq.getMutableData().data()) { + du->response = std::move(dq.getMutableData()); + } + } + + return std::make_unique(std::move(du), isResponse); +} + +/* + We are not in the main DoQ thread but in the DoQ 'client' thread. +*/ +static void processDOQQuery(DOQUnitUniquePtr&& unit, bool inMainThread = false) +{ + const auto handleImmediateResponse = [inMainThread](DOQUnitUniquePtr&& du, const char* reason) { + DEBUGLOG("handleImmediateResponse() reason=" << reason); + if (inMainThread) { + auto conn = getConnection(du->serverConnID); + handleResponse(*du->dsc->df, *conn, du->streamID, du->response); + /* so the unique pointer is stored in the InternalState which itself is stored in the unique pointer itself. We likely need + a better design, but for now let's just reset the internal one since we know it is no longer needed. */ + du->ids.doqu.reset(); + } + else { + sendDOQUnitToTheMainThread(std::move(du), reason); + } + }; + + auto& ids = unit->ids; + ids.doqu = std::move(unit); + auto& du = ids.doqu; + uint16_t queryId = 0; + ComboAddress remote; + + try { + { + // if there was no EDNS, we add it with a large buffer size + // so we can use UDP to talk to the backend. + auto dh = const_cast(reinterpret_cast(du->query.data())); + + if (!dh->arcount) { + if (generateOptRR(std::string(), du->query, 4096, 4096, 0, false)) { + dh = const_cast(reinterpret_cast(du->query.data())); // may have reallocated + dh->arcount = htons(1); + du->ids.ednsAdded = true; + } + } + else { + // we leave existing EDNS in place + } + } + + remote = du->ids.origRemote; + DOQServerConfig* dsc = du->dsc; + auto& holders = dsc->holders; + ClientState& cs = *dsc->cs; + + if (du->query.size() < sizeof(dnsheader)) { + // ++dnsdist::metrics::g_stats.nonCompliantQueries; + // ++cs.nonCompliantQueries; + handleImmediateResponse(std::move(du), "DoQ non-compliant query"); + return; + } + + // ++cs.queries; + // ++dnsdist::metrics::g_stats.queries; + du->ids.queryRealTime.start(); + + { + /* don't keep that pointer around, it will be invalidated if the buffer is ever resized */ + struct dnsheader* dh = reinterpret_cast(du->query.data()); + + if (!checkQueryHeaders(dh, cs)) { + // du->status_code = 400; + handleImmediateResponse(std::move(du), "DoQ invalid headers"); + return; + } + + if (dh->qdcount == 0) { + dh->rcode = RCode::NotImp; + dh->qr = true; + du->response = std::move(du->query); + + handleImmediateResponse(std::move(du), "DoQ empty query"); + return; + } + + queryId = ntohs(dh->id); + } + + auto downstream = du->downstream; + du->ids.qname = DNSName(reinterpret_cast(du->query.data()), du->query.size(), sizeof(dnsheader), false, &du->ids.qtype, &du->ids.qclass); + DNSQuestion dq(du->ids, du->query); + const uint16_t* flags = getFlagsFromDNSHeader(dq.getHeader()); + ids.origFlags = *flags; + du->ids.cs = &cs; + + auto result = processQuery(dq, holders, downstream); + if (result == ProcessQueryResult::Drop) { + handleImmediateResponse(std::move(du), "DoQ dropped query"); + return; + } + else if (result == ProcessQueryResult::Asynchronous) { + return; + } + else if (result == ProcessQueryResult::SendAnswer) { + if (du->response.empty()) { + du->response = std::move(du->query); + } + if (du->response.size() >= sizeof(dnsheader)) { + auto dh = reinterpret_cast(du->response.data()); + + handleResponseSent(du->ids.qname, QType(du->ids.qtype), 0., du->ids.origDest, ComboAddress(), du->response.size(), *dh, dnsdist::Protocol::DoQ, dnsdist::Protocol::DoQ, false); + } + handleImmediateResponse(std::move(du), "DoQ self-answered response"); + return; + } + + if (result != ProcessQueryResult::PassToBackend) { + handleImmediateResponse(std::move(du), "DoQ no backend available"); + return; + } + + if (downstream == nullptr) { + handleImmediateResponse(std::move(du), "DoQ no backend available"); + return; + } + + du->downstream = downstream; + + std::string proxyProtocolPayload; + /* we need to do this _before_ creating the cross protocol query because + after that the buffer will have been moved */ + if (downstream->d_config.useProxyProtocol) { + proxyProtocolPayload = getProxyProtocolPayload(dq); + } + + du->ids.origID = htons(queryId); + du->tcp = true; + + /* this moves du->ids, careful! */ + auto cpq = std::make_unique(std::move(du), false); + cpq->query.d_proxyProtocolPayload = std::move(proxyProtocolPayload); + + if (downstream->passCrossProtocolQuery(std::move(cpq))) { + return; + } + else { + if (inMainThread) { + du = cpq->releaseDU(); + handleImmediateResponse(std::move(du), "DoQ internal error"); + } + else { + cpq->handleInternalError(); + } + return; + } + } + catch (const std::exception& e) { + vinfolog("Got an error in DOQ question thread while parsing a query from %s, id %d: %s", remote.toStringWithPort(), queryId, e.what()); + handleImmediateResponse(std::move(du), "DoQ internal error"); + return; + } + + return; +} + +static void flushResponses(pdns::channel::Receiver&& receiver) +{ + setThreadName("dnsdist/doq-responder"); + + for(;;) { + try { + auto tmp = receiver.receive(); + if (!tmp) { + return ; + } + + auto du = std::move(*tmp); + auto conn = getConnection(du->serverConnID); + + handleResponse(*du->dsc->df, *conn, du->streamID, du->response); + + } + catch (const std::exception& e) { + errlog("Error while processing response received over DoQ: %s", e.what()); + } + catch (...) { + errlog("Unspecified error while processing response received over DoQ"); + } + } +} + +static void dnsdistclient(pdns::channel::Receiver&& receiver) +{ + setThreadName("dnsdist/doq-cli"); + + for(;;) { + try { + auto tmp = receiver.receive(); + if (!tmp) { + continue; + } + auto du = std::move(*tmp); + processDOQQuery(std::move(du), false); + } + catch (const std::exception& e) { + errlog("Error while processing query received over DoQ: %s", e.what()); + } + catch (...) { + errlog("Unspecified error while processing query received over DoQ"); + } + } +} + +static void doq_dispatch_query(DOQServerConfig& dsc, PacketBuffer&& query, const ComboAddress& local, const ComboAddress& remote, const PacketBuffer& serverConnID, const uint64_t streamID) +{ + try { + /* we only parse it there as a sanity check, we will parse it again later */ + DNSPacketMangler mangler(reinterpret_cast(query.data()), query.size()); + mangler.skipDomainName(); + mangler.skipBytes(4); + // Should we ensure message id is 0 ? + + auto du = std::make_unique(std::move(query)); + du->dsc = &dsc; + du->ids.origDest = local; + du->ids.origRemote = remote; + du->ids.protocol = dnsdist::Protocol::DoQ; + du->responseSender = &dsc.d_responseSender; + du->serverConnID = serverConnID; + du->streamID = streamID; + + try { + if (!dsc.d_querySender.send(std::move(du))) { + vinfolog("Unable to pass a DoQ query to the DoQ worker thread because the pipe is full"); + } + } + catch (...) { + vinfolog("Unable to pass a DoQ query to the DoQ worker thread because we couldn't write to the pipe: %s", stringerror()); + } + } + catch (const std::exception& e) { + vinfolog("Had error parsing DoQ DNS packet from %s: %s", remote.toStringWithPort(), e.what()); + } +} + +// this is the entrypoint from dnsdist.cc +void doqThread(ClientState* cs) +{ + try { + std::shared_ptr& frontend = cs->doqFrontend; + + frontend->d_server_config->cs = cs; + frontend->d_server_config->df = cs->doqFrontend; + + std::thread dnsdistThread(dnsdistclient, std::move(frontend->d_server_config->d_queryReceiver)); + dnsdistThread.detach(); + std::thread responderThread(flushResponses, std::move(frontend->d_server_config->d_responseReceiver)); + responderThread.detach(); + setThreadName("dnsdist/doq"); + + Socket sock(cs->udpFD); + + PacketBuffer buffer(std::numeric_limits::max()); + + while (true) { + std::string bufferStr; + ComboAddress client; + if (waitForData(sock.getHandle(), 1, 0) > 0) { + sock.recvFrom(bufferStr, client); + + uint32_t version{0}; + uint8_t type; + std::array scid; + size_t scid_len = scid.size(); + std::array dcid; + size_t dcid_len = dcid.size(); + std::array odcid; + size_t odcid_len = odcid.size(); + std::array token; + size_t token_len = token.size(); + + auto res = quiche_header_info(reinterpret_cast(bufferStr.data()), bufferStr.size(), LOCAL_CONN_ID_LEN, + &version, &type, + scid.data(), &scid_len, + dcid.data(), &dcid_len, + token.data(), &token_len); + if (res != 0) { + continue; + } + + // destination connection ID, will have to be sent as original destination connection ID + PacketBuffer serverConnID(dcid.begin(), dcid.begin() + dcid_len); + // source connection ID, will have to be sent as destination connection ID + PacketBuffer clientConnID(scid.begin(), scid.begin() + scid_len); + auto conn = getConnection(serverConnID); + + if (!conn) { + DEBUGLOG("Connection not found"); + if (!quiche_version_is_supported(version)) { + DEBUGLOG("Unsupported version"); + handleVersionNegociation(sock, clientConnID, serverConnID, client); + continue; + } + + if (token_len == 0) { + /* stateless retry */ + DEBUGLOG("No token received"); + handleStatelessRetry(sock, clientConnID, serverConnID, client, version); + continue; + } + + PacketBuffer tokenBuf(token.begin(), token.begin() + token_len); + auto originalDestinationID = validateToken(tokenBuf, serverConnID, client); + if (!originalDestinationID) { + DEBUGLOG("Discarding invalid token"); + continue; + } + + DEBUGLOG("Creating a new connection"); + conn = createConnection(frontend->d_server_config->config, serverConnID, *originalDestinationID, tokenBuf, cs->local, client); + if (!conn) { + continue; + } + } + quiche_recv_info recv_info = { + (struct sockaddr*)&client, + client.getSocklen(), + + (struct sockaddr*)&cs->local, + cs->local.getSocklen(), + }; + + auto done = quiche_conn_recv(conn->get().d_conn.get(), reinterpret_cast(bufferStr.data()), bufferStr.size(), &recv_info); + if (done < 0) { + continue; + } + + if (quiche_conn_is_established(conn->get().d_conn.get())) { + auto readable = std::unique_ptr(quiche_conn_readable(conn->get().d_conn.get()), quiche_stream_iter_free); + + uint64_t streamID = 0; + while (quiche_stream_iter_next(readable.get(), &streamID)) { + bool fin = false; + buffer.resize(std::numeric_limits::max()); + auto received = quiche_conn_stream_recv(conn->get().d_conn.get(), streamID, + buffer.data(), buffer.size(), + &fin); + if (received < 2) { + break; + } + buffer.resize(received); + + if (fin) { + buffer.erase(buffer.begin(), buffer.begin() + 2); + if (buffer.size() >= sizeof(dnsheader)) { + doq_dispatch_query(*(frontend->d_server_config), std::move(buffer), cs->local, client, serverConnID, streamID); + } + } + } + } + else { + DEBUGLOG("Connection not established"); + } + /* FIXME: we should handle closed connections, timeouts */ + // pacing QUIC ? + // quiche_send_info.at Queue avec les paquets a envoyer par date. + } + for (auto& conn : s_connections) { + flushEgress(sock, conn.second); + } + } + + } + catch (const std::exception& e) { + DEBUGLOG("Caught fatal error: " << e.what()); + } +} diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh new file mode 100644 index 000000000000..a145f83842d6 --- /dev/null +++ b/pdns/dnsdistdist/doq.hh @@ -0,0 +1,132 @@ +/* + * This file is part of PowerDNS or dnsdist. + * Copyright -- PowerDNS.COM B.V. and its contributors + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * In addition, for the avoidance of any doubt, permission is granted to + * link this program with OpenSSL and to (re)distribute the binaries + * produced as the result of such linking. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ +#pragma once + +#include +#include "channel.hh" +#include "iputils.hh" +#include "libssl.hh" +#include "noinitvector.hh" +#include "stat_t.hh" +#include "dnsdist-idstate.hh" + +#ifdef HAVE_DNS_OVER_QUIC + +#include + +using QuicheConnection = std::unique_ptr; +using QuicheConfig = std::unique_ptr; + +class Connection +{ +public: + Connection(const ComboAddress& peer, std::unique_ptr&& conn) : + d_peer(peer), d_conn(std::move(conn)) + { + } + Connection(const Connection&) = delete; + Connection(Connection&&) = default; + Connection& operator=(const Connection&) = delete; + Connection& operator=(Connection&&) = default; + ~Connection() = default; + + ComboAddress d_peer; + QuicheConnection d_conn; +}; + +#endif + +struct DOQServerConfig; +struct DownstreamState; + +#ifdef HAVE_DNS_OVER_QUIC + +struct DOQFrontend +{ + DOQFrontend() + { + } + + std::shared_ptr d_server_config{nullptr}; + TLSConfig d_tlsConfig; + ComboAddress d_local; + + void setup(); +#ifdef __linux__ + // On Linux this gives us 128k pending queries (default is 8192 queries), + // which should be enough to deal with huge spikes + uint32_t d_internalPipeBufferSize{1024*1024}; +#else + uint32_t d_internalPipeBufferSize{0}; +#endif +}; + +struct DOQUnit +{ + DOQUnit(PacketBuffer&& q): query(std::move(q)) + { + ids.ednsAdded = false; + } + + DOQUnit(const DOQUnit&) = delete; + DOQUnit& operator=(const DOQUnit&) = delete; + + InternalQueryState ids; + PacketBuffer query; + PacketBuffer response; + std::shared_ptr downstream{nullptr}; + DOQServerConfig* dsc{nullptr}; + pdns::channel::Sender* responseSender{nullptr}; + size_t query_at{0}; + size_t proxyProtocolPayloadSize{0}; + int rsock{-1}; + uint64_t streamID{0}; + PacketBuffer serverConnID; + /* whether the query was re-sent to the backend over + TCP after receiving a truncated answer over UDP */ + bool tcp{false}; + bool truncated{false}; +}; + +using DOQUnitUniquePtr = std::unique_ptr; + +struct CrossProtocolQuery; +struct DNSQuestion; +std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse); + +#else +struct DOQUnit +{ +}; + +struct DOQFrontend +{ + DOQFrontend() + { + } + void setup() + { + + } +}; + +#endif From 3dc49a89c5f2c43508d86aed7dbc6b9868dc7f08 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Thu, 14 Sep 2023 15:59:06 +0200 Subject: [PATCH 810/909] dnsdist: add simple DoQ tests, misc cleanup, removes unnecessary chans/threads --- pdns/dnsdist-lua.cc | 3 - pdns/dnsdistdist/docs/reference/config.rst | 1 - pdns/dnsdistdist/doq.cc | 225 ++++++--------------- pdns/dnsdistdist/doq.hh | 9 - regression-tests.dnsdist/dnsdisttests.py | 32 +++ regression-tests.dnsdist/requirements.txt | 1 + regression-tests.dnsdist/test_DOQ.py | 140 +++++++++++++ 7 files changed, 233 insertions(+), 178 deletions(-) create mode 100644 regression-tests.dnsdist/test_DOQ.py diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 39a30ba053c3..6d39d29e0d5a 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2510,9 +2510,6 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) if (vars) { parseLocalBindVars(vars, reusePort, tcpFastOpenQueueSize, interface, cpus, tcpListenQueueSize, maxInFlightQueriesPerConn, tcpMaxConcurrentConnections); -// getOptionalValue(vars, "idleTimeout", frontend->d_idleTimeout); - - getOptionalValue(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize); parseTLSConfig(frontend->d_tlsConfig, "addDOQLocal", vars); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index fbb8e73f7764..6684b3554a40 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -189,7 +189,6 @@ Listen Sockets * ``interface=""``: str - Set the network interface to use. * ``cpus={}``: table - Set the CPU affinity for this listener thread, asking the scheduler to run it on a single CPU id, or a set of CPU ids. This parameter is only available if the OS provides the pthread_setaffinity_np() function. * ``idleTimeout=30``: int - Set the idle timeout, in seconds. - * ``internalPipeBufferSize=0``: int - Set the size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads. Requires support for ``F_SETPIPE_SZ`` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used. The default value is 0, except on Linux where it is 1048576 since 1.6.0. .. function:: addTLSLocal(address, certFile(s), keyFile(s) [, options]) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index c8e8bbe04bc5..b0e05d6a459b 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -33,22 +33,13 @@ #include "dnsdist-proxy-protocol.hh" +static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description); class DOQServerConfig { public: - DOQServerConfig(std::unique_ptr&& config_, uint32_t internalPipeBufferSize) : + DOQServerConfig(std::unique_ptr&& config_) : config(std::move(config_)) { - { - auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverBlocking, internalPipeBufferSize); - d_querySender = std::move(sender); - d_queryReceiver = std::move(receiver); - } - { - auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverBlocking, internalPipeBufferSize); - d_responseSender = std::move(sender); - d_responseReceiver = std::move(receiver); - } } DOQServerConfig(const DOQServerConfig&) = delete; DOQServerConfig(DOQServerConfig&&) = default; @@ -60,13 +51,9 @@ class DOQServerConfig QuicheConfig config; ClientState* cs{nullptr}; std::shared_ptr df{nullptr}; - pdns::channel::Sender d_querySender; - pdns::channel::Receiver d_queryReceiver; - pdns::channel::Sender d_responseSender; - pdns::channel::Receiver d_responseReceiver; }; -#if 1 +#if 0 #define DEBUGLOG_ENABLED #define DEBUGLOG(x) std::cerr< s_connections; -/* This internal function sends back the object to the main thread to send a reply. - The caller should NOT release or touch the unit after calling this function */ -static void sendDOQUnitToTheMainThread(DOQUnitUniquePtr&& du, const char* description) -{ - if (du->responseSender == nullptr) { - return; - } - try { - if (!du->responseSender->send(std::move(du))) { - vinfolog("Unable to pass a %s to the DoQ worker thread because the pipe is full", description); - } - } catch (const std::exception& e) { - vinfolog("Unable to pass a %s to the DoQ worker thread because we couldn't write to the pipe: %s", description, e.what()); - } -} - class DOQTCPCrossQuerySender final : public TCPQuerySender { public: @@ -114,9 +85,6 @@ class DOQTCPCrossQuerySender final : public TCPQuerySender } auto du = std::move(response.d_idstate.doqu); - if (du->responseSender == nullptr) { - return; - } du->response = std::move(response.d_buffer); du->ids = std::move(response.d_idstate); @@ -136,7 +104,7 @@ class DOQTCPCrossQuerySender final : public TCPQuerySender if (!processResponse(dr.ids.doqu->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) { if (dr.ids.doqu) { - sendDOQUnitToTheMainThread(std::move(dr.ids.doqu), "Response dropped by rules"); + sendBackDOQUnit(std::move(dr.ids.doqu), "Response dropped by rules"); } return; } @@ -164,7 +132,7 @@ class DOQTCPCrossQuerySender final : public TCPQuerySender ++du->ids.cs->responses; } - sendDOQUnitToTheMainThread(std::move(du), "cross-protocol response"); + sendBackDOQUnit(std::move(du), "Cross-protocol response"); } void handleXFRResponse(const struct timeval& now, TCPResponse&& response) override @@ -174,33 +142,7 @@ class DOQTCPCrossQuerySender final : public TCPQuerySender void notifyIOError(const struct timeval& now, TCPResponse&& response) override { - // auto& query = response.d_idstate; - // if (!query.du) { - // return; - // } - - // auto dohUnit = getDUFromIDS(query); - // if (dohUnit->responseSender == nullptr) { - // return; - // } - - // du->ids = std::move(query); - // sendDOQUnitToTheMainThread(std::move(du), "cross-protocol error response"); - } - // void notifyIOError(InternalQueryState&& query, const struct timeval& now) override - // { - // if (!query.doqu) { - // return; - // } - - // if (query.doqu->responseSender == nullptr) { - // return; - // } - - // auto du = std::move(query.doqu); - // du->ids = std::move(query); - // sendDOQUnitToTheMainThread(std::move(du), "cross-protocol error response"); - // } + } }; class DOQCrossProtocolQuery : public CrossProtocolQuery @@ -234,7 +176,7 @@ class DOQCrossProtocolQuery : public CrossProtocolQuery void handleInternalError() { - sendDOQUnitToTheMainThread(std::move(query.d_idstate.doqu), "DOQ internal error"); + sendBackDOQUnit(std::move(query.d_idstate.doqu), "DOQ internal error"); } std::shared_ptr getTCPQuerySender() override @@ -271,11 +213,15 @@ std::shared_ptr DOQCrossProtocolQuery::s_sender = std::m /* Always called from the main DoQ thread */ static void handleResponse(DOQFrontend& df, Connection& conn, const uint64_t streamID, const PacketBuffer& response) { - uint16_t responseSize = static_cast(response.size()); - const uint8_t sizeBytes[] = { static_cast(responseSize / 256), static_cast(responseSize % 256) }; - auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, sizeBytes, sizeof(sizeBytes), false); - if (res == sizeof(sizeBytes)) { - res = quiche_conn_stream_send(conn.d_conn.get(), streamID, response.data(), response.size(), true); + if (response.size() == 0) { + quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, 0x5); + } else { + uint16_t responseSize = static_cast(response.size()); + const uint8_t sizeBytes[] = { static_cast(responseSize / 256), static_cast(responseSize % 256) }; + auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, sizeBytes, sizeof(sizeBytes), false); + if (res == sizeof(sizeBytes)) { + res = quiche_conn_stream_send(conn.d_conn.get(), streamID, response.data(), response.size(), true); + } } } @@ -315,12 +261,12 @@ void DOQFrontend::setup() quiche_config_set_cc_algorithm(config.get(), QUICHE_CC_RENO); // quiche_config_log_keys(config.get()); - d_server_config = std::make_shared(std::move(config), d_internalPipeBufferSize); + d_server_config = std::make_shared(std::move(config)); } static std::optional getCID() { - // FIXME remplacer par notre truc de random + // FIXME replace it int rng = open("/dev/urandom", O_RDONLY); if (rng < 0) { return std::nullopt; @@ -339,15 +285,6 @@ static std::optional getCID() static PacketBuffer mintToken(const PacketBuffer& dcid, const ComboAddress& peer) { // FIXME: really check whether this needs to be authenticated, via HMAC for example - // client recoit un datagram - // challenge avec token - // suffisement d'infos pour binder a la bonne adresse - // filer l'original CID fille par le client. - // -> ne pas garder l'etat - // -> inclure l'info dans le token - // -> voir avec libsodium ? - // -> token plus gros avec HMAC - // -> regarder ce que font les autres implementations de QUIC const std::array keyword = {'q', 'u', 'i', 'c', 'h', 'e'}; auto addrBytes = peer.toByteString(); PacketBuffer token; @@ -426,6 +363,13 @@ static std::optional> getConnection(const Pac return it->second; } +static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description) +{ + DEBUGLOG("Handling back a " << description); + auto conn = getConnection(du->serverConnID); + handleResponse(*du->dsc->df, *conn, du->streamID, du->response); +} + static std::optional> createConnection(QuicheConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const PacketBuffer& token, const ComboAddress& local, const ComboAddress& peer) { auto quicheConn = QuicheConnection(quiche_accept(serverSideID.data(), serverSideID.size(), @@ -459,10 +403,6 @@ static void flushEgress(Socket& sock, Connection& conn) { } // FIXME: update timers - // -> on peut appeler une fonction quiche pour savoir quand prochain timeout - // -> pas ici ? - // -> fin de loop event quand est le prochain plus petit timeout a venir - // -> relancer le multiplexer pour au plus ce temps la } std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse) @@ -495,20 +435,15 @@ std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& /* We are not in the main DoQ thread but in the DoQ 'client' thread. */ -static void processDOQQuery(DOQUnitUniquePtr&& unit, bool inMainThread = false) +static void processDOQQuery(DOQUnitUniquePtr&& unit) { - const auto handleImmediateResponse = [inMainThread](DOQUnitUniquePtr&& du, const char* reason) { + const auto handleImmediateResponse = [](DOQUnitUniquePtr&& du, const char* reason) { DEBUGLOG("handleImmediateResponse() reason=" << reason); - if (inMainThread) { auto conn = getConnection(du->serverConnID); handleResponse(*du->dsc->df, *conn, du->streamID, du->response); /* so the unique pointer is stored in the InternalState which itself is stored in the unique pointer itself. We likely need a better design, but for now let's just reset the internal one since we know it is no longer needed. */ du->ids.doqu.reset(); - } - else { - sendDOQUnitToTheMainThread(std::move(du), reason); - } }; auto& ids = unit->ids; @@ -543,6 +478,11 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit, bool inMainThread = false) if (du->query.size() < sizeof(dnsheader)) { // ++dnsdist::metrics::g_stats.nonCompliantQueries; // ++cs.nonCompliantQueries; + struct dnsheader* dh = reinterpret_cast(du->query.data()); + dh->rcode = RCode::ServFail; + dh->qr = true; + du->response = std::move(du->query); + handleImmediateResponse(std::move(du), "DoQ non-compliant query"); return; } @@ -556,7 +496,10 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit, bool inMainThread = false) struct dnsheader* dh = reinterpret_cast(du->query.data()); if (!checkQueryHeaders(dh, cs)) { - // du->status_code = 400; + dh->rcode = RCode::ServFail; + dh->qr = true; + du->response = std::move(du->query); + handleImmediateResponse(std::move(du), "DoQ invalid headers"); return; } @@ -631,13 +574,8 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit, bool inMainThread = false) return; } else { - if (inMainThread) { - du = cpq->releaseDU(); - handleImmediateResponse(std::move(du), "DoQ internal error"); - } - else { - cpq->handleInternalError(); - } + du = cpq->releaseDU(); + handleImmediateResponse(std::move(du), "DoQ internal error"); return; } } @@ -650,54 +588,6 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit, bool inMainThread = false) return; } -static void flushResponses(pdns::channel::Receiver&& receiver) -{ - setThreadName("dnsdist/doq-responder"); - - for(;;) { - try { - auto tmp = receiver.receive(); - if (!tmp) { - return ; - } - - auto du = std::move(*tmp); - auto conn = getConnection(du->serverConnID); - - handleResponse(*du->dsc->df, *conn, du->streamID, du->response); - - } - catch (const std::exception& e) { - errlog("Error while processing response received over DoQ: %s", e.what()); - } - catch (...) { - errlog("Unspecified error while processing response received over DoQ"); - } - } -} - -static void dnsdistclient(pdns::channel::Receiver&& receiver) -{ - setThreadName("dnsdist/doq-cli"); - - for(;;) { - try { - auto tmp = receiver.receive(); - if (!tmp) { - continue; - } - auto du = std::move(*tmp); - processDOQQuery(std::move(du), false); - } - catch (const std::exception& e) { - errlog("Error while processing query received over DoQ: %s", e.what()); - } - catch (...) { - errlog("Unspecified error while processing query received over DoQ"); - } - } -} - static void doq_dispatch_query(DOQServerConfig& dsc, PacketBuffer&& query, const ComboAddress& local, const ComboAddress& remote, const PacketBuffer& serverConnID, const uint64_t streamID) { try { @@ -712,18 +602,10 @@ static void doq_dispatch_query(DOQServerConfig& dsc, PacketBuffer&& query, const du->ids.origDest = local; du->ids.origRemote = remote; du->ids.protocol = dnsdist::Protocol::DoQ; - du->responseSender = &dsc.d_responseSender; du->serverConnID = serverConnID; du->streamID = streamID; - try { - if (!dsc.d_querySender.send(std::move(du))) { - vinfolog("Unable to pass a DoQ query to the DoQ worker thread because the pipe is full"); - } - } - catch (...) { - vinfolog("Unable to pass a DoQ query to the DoQ worker thread because we couldn't write to the pipe: %s", stringerror()); - } + processDOQQuery(std::move(du)); } catch (const std::exception& e) { vinfolog("Had error parsing DoQ DNS packet from %s: %s", remote.toStringWithPort(), e.what()); @@ -739,10 +621,6 @@ void doqThread(ClientState* cs) frontend->d_server_config->cs = cs; frontend->d_server_config->df = cs->doqFrontend; - std::thread dnsdistThread(dnsdistclient, std::move(frontend->d_server_config->d_queryReceiver)); - dnsdistThread.detach(); - std::thread responderThread(flushResponses, std::move(frontend->d_server_config->d_responseReceiver)); - responderThread.detach(); setThreadName("dnsdist/doq"); Socket sock(cs->udpFD); @@ -838,6 +716,7 @@ void doqThread(ClientState* cs) buffer.resize(received); if (fin) { + // we skip message length, should we verify ? buffer.erase(buffer.begin(), buffer.begin() + 2); if (buffer.size() >= sizeof(dnsheader)) { doq_dispatch_query(*(frontend->d_server_config), std::move(buffer), cs->local, client, serverConnID, streamID); @@ -848,15 +727,31 @@ void doqThread(ClientState* cs) else { DEBUGLOG("Connection not established"); } - /* FIXME: we should handle closed connections, timeouts */ + /* FIXME: we should handle timeouts */ // pacing QUIC ? // quiche_send_info.at Queue avec les paquets a envoyer par date. } - for (auto& conn : s_connections) { - flushEgress(sock, conn.second); + for (auto conn = s_connections.begin(); conn != s_connections.end();) { + quiche_conn_on_timeout(conn->second.d_conn.get()); + + flushEgress(sock, conn->second); + + if (quiche_conn_is_closed(conn->second.d_conn.get())) { +#ifdef DEBUGLOG_ENABLED + quiche_stats stats; + quiche_path_stats path_stats; + + quiche_conn_stats(conn->second.d_conn.get(), &stats); + quiche_conn_path_stats(conn->second.d_conn.get(), 0, &path_stats); + + DEBUGLOG("Connection closed, recv="< downstream{nullptr}; DOQServerConfig* dsc{nullptr}; pdns::channel::Sender* responseSender{nullptr}; - size_t query_at{0}; size_t proxyProtocolPayloadSize{0}; - int rsock{-1}; uint64_t streamID{0}; PacketBuffer serverConnID; /* whether the query was re-sent to the backend over diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 75f12e620221..7925c37cf19f 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -1089,3 +1089,35 @@ def sendDOHWithH2OQueryWrapper(self, query, response, useQueue=True): def sendDOTQueryWrapper(self, query, response, useQueue=True): return self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response, self._caCert, useQueue=useQueue) + + @classmethod + def getDOQConnection(cls, port, servername, caFile=None, source=None, source_port=0): + + manager = dns.quic.SyncQuicManager( + verify_mode=caFile + ) + + return manager.connect(servername, port, source, source_port) + + @classmethod + def sendDOQQuery(cls, port, servername, query, response=None, timeout=2.0, caFile=None, useQueue=True, rawQuery=False, fromQueue=None, toQueue=None, connection=None): + + if response: + if toQueue: + toQueue.put(response, True, timeout) + else: + cls._toResponderQueue.put(response, True, timeout) + + message = dns.query.quic(query, servername, timeout, port, verify=caFile, connection=connection) + + receivedQuery = None + + if useQueue: + if fromQueue: + if not fromQueue.empty(): + receivedQuery = fromQueue.get(True, timeout) + else: + if not cls._fromResponderQueue.empty(): + receivedQuery = cls._fromResponderQueue.get(True, timeout) + + return (receivedQuery, message) diff --git a/regression-tests.dnsdist/requirements.txt b/regression-tests.dnsdist/requirements.txt index 3bc85702d228..4c6b1020bdab 100644 --- a/regression-tests.dnsdist/requirements.txt +++ b/regression-tests.dnsdist/requirements.txt @@ -11,3 +11,4 @@ pycurl>=7.43.0 lmdb>=0.95 cdbx==0.1.2 h2>=4.0.0 +aioquic diff --git a/regression-tests.dnsdist/test_DOQ.py b/regression-tests.dnsdist/test_DOQ.py new file mode 100644 index 000000000000..b2ecea850346 --- /dev/null +++ b/regression-tests.dnsdist/test_DOQ.py @@ -0,0 +1,140 @@ +#!/usr/bin/env python +import dns +import clientsubnetoption + +from dnsdisttests import DNSDistTest +from dnsdisttests import pickAvailablePort + +class TestDOQ(DNSDistTest): + _serverKey = 'server.key' + _serverCert = 'server.chain' + _serverName = '127.0.0.1' + _caCert = 'ca.pem' + _doqServerPort = 8853 + _config_template = """ + newServer{address="127.0.0.1:%d"} + + addAction("drop.doq.tests.powerdns.com.", DropAction()) + addAction("refused.doq.tests.powerdns.com.", RCodeAction(DNSRCode.REFUSED)) + addAction("spoof.doq.tests.powerdns.com.", SpoofAction("1.2.3.4")) + addAction("no-backend.doq.tests.powerdns.com.", PoolAction('this-pool-has-no-backend')) + + addDOQLocal("127.0.0.1:%d", "%s", "%s") + """ + _config_params = ['_testServerPort', '_doqServerPort','_serverCert', '_serverKey'] + _verboseMode = True + + def testDOQSimple(self): + """ + DOQ: Simple query + """ + name = 'simple.doq.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN', use_edns=False) + query.id = 0 + expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096) + expectedQuery.id = 0 + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 3600, + dns.rdataclass.IN, + dns.rdatatype.A, + '127.0.0.1') + response.answer.append(rrset) + (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=response, caFile=self._caCert) + self.assertTrue(receivedQuery) + self.assertTrue(receivedResponse) + receivedQuery.id = expectedQuery.id + self.assertEqual(expectedQuery, receivedQuery) + + def testDOQMultipleStreams(self): + """ + DOQ: Test multiple queries using the same connection + """ + + name = 'simple.doq.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN', use_edns=False) + query.id = 0 + expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096) + expectedQuery.id = 0 + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 3600, + dns.rdataclass.IN, + dns.rdatatype.A, + '127.0.0.1') + response.answer.append(rrset) + + connection = self.getDOQConnection(self._doqServerPort, self._serverName, self._caCert) + + (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=response, connection=connection) + self.assertTrue(receivedQuery) + self.assertTrue(receivedResponse) + receivedQuery.id = expectedQuery.id + self.assertEqual(expectedQuery, receivedQuery) + + (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=response, connection=connection) + self.assertTrue(receivedQuery) + self.assertTrue(receivedResponse) + receivedQuery.id = expectedQuery.id + self.assertEqual(expectedQuery, receivedQuery) + + def testDropped(self): + """ + DOQ: Dropped query + """ + name = 'drop.doq.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + dropped = False + try: + (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) + # dns.quic doesn't seem to report correctly the quic error so the connection timeout + except dns.exception.Timeout : + dropped = True + self.assertTrue(dropped) + + def testRefused(self): + """ + DOQ: Refused + """ + name = 'refused.doq.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + query.id = 0 + query.flags &= ~dns.flags.RD + expectedResponse = dns.message.make_response(query) + expectedResponse.set_rcode(dns.rcode.REFUSED) + + (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) + self.assertEqual(receivedResponse, expectedResponse) + + def testSpoof(self): + """ + DOQ: Spoofed + """ + name = 'spoof.doq.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN') + query.id = 0 + query.flags &= ~dns.flags.RD + expectedResponse = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 3600, + dns.rdataclass.IN, + dns.rdatatype.A, + '1.2.3.4') + expectedResponse.answer.append(rrset) + + (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) + self.assertEqual(receivedResponse, expectedResponse) + + def testDOQNoBackend(self): + """ + DOQ: No backend + """ + name = 'no-backend.doq.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN', use_edns=False) + dropped = False + try: + (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) + except dns.exception.Timeout : + dropped = True + self.assertTrue(dropped) + # dns.quic doesn't seem to report correctly the quic error so the connection timeout From fc281f422b9681976bfeece418b661365c2154fd Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Tue, 19 Sep 2023 18:38:48 +0200 Subject: [PATCH 811/909] doq: don't add EDNS --- pdns/dnsdistdist/doq.cc | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index b0e05d6a459b..d56059273cbb 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -453,22 +453,6 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit) ComboAddress remote; try { - { - // if there was no EDNS, we add it with a large buffer size - // so we can use UDP to talk to the backend. - auto dh = const_cast(reinterpret_cast(du->query.data())); - - if (!dh->arcount) { - if (generateOptRR(std::string(), du->query, 4096, 4096, 0, false)) { - dh = const_cast(reinterpret_cast(du->query.data())); // may have reallocated - dh->arcount = htons(1); - du->ids.ednsAdded = true; - } - } - else { - // we leave existing EDNS in place - } - } remote = du->ids.origRemote; DOQServerConfig* dsc = du->dsc; From 182af582c14eb7b120d9f3b374d5090d07ec86d0 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Tue, 19 Sep 2023 18:51:30 +0200 Subject: [PATCH 812/909] doq: spell checking, formating, comments cleaning --- .github/actions/spell-check/allow.txt | 1 + pdns/dnsdist-idstate.hh | 1 - pdns/dnsdistdist/doq.cc | 61 +++++++++++++-------------- pdns/dnsdistdist/doq.hh | 21 ++++----- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/.github/actions/spell-check/allow.txt b/.github/actions/spell-check/allow.txt index d51b7970d3a8..a902870fb4cb 100644 --- a/.github/actions/spell-check/allow.txt +++ b/.github/actions/spell-check/allow.txt @@ -829,6 +829,7 @@ dontdrop dontinclude dontqueries DONTWAIT +DOQ doquery dosec dotests diff --git a/pdns/dnsdist-idstate.hh b/pdns/dnsdist-idstate.hh index ddc69475401d..63daead60265 100644 --- a/pdns/dnsdist-idstate.hh +++ b/pdns/dnsdist-idstate.hh @@ -131,7 +131,6 @@ struct InternalQueryState std::unique_ptr d_protoBufData{nullptr}; boost::optional tempFailureTTL{boost::none}; // 8 ClientState* cs{nullptr}; // 8 - std::unique_ptr du; // 8 size_t d_proxyProtocolPayloadSize{0}; // 8 int32_t d_streamID{-1}; // 4 diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index d56059273cbb..8d704a17dca2 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -32,7 +32,6 @@ #include "dnsdist-ecs.hh" #include "dnsdist-proxy-protocol.hh" - static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description); class DOQServerConfig { @@ -55,7 +54,7 @@ class DOQServerConfig #if 0 #define DEBUGLOG_ENABLED -#define DEBUGLOG(x) std::cerr<response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) { if (dr.ids.doqu) { @@ -197,7 +195,7 @@ class DOQCrossProtocolQuery : public CrossProtocolQuery auto& ids = query.d_idstate; DNSResponse dr(ids, query.d_buffer, downstream); return dr; - } + } DOQUnitUniquePtr&& releaseDU() { @@ -210,14 +208,14 @@ class DOQCrossProtocolQuery : public CrossProtocolQuery std::shared_ptr DOQCrossProtocolQuery::s_sender = std::make_shared(); -/* Always called from the main DoQ thread */ static void handleResponse(DOQFrontend& df, Connection& conn, const uint64_t streamID, const PacketBuffer& response) { if (response.size() == 0) { quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, 0x5); - } else { + } + else { uint16_t responseSize = static_cast(response.size()); - const uint8_t sizeBytes[] = { static_cast(responseSize / 256), static_cast(responseSize % 256) }; + const uint8_t sizeBytes[] = {static_cast(responseSize / 256), static_cast(responseSize % 256)}; auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, sizeBytes, sizeof(sizeBytes), false); if (res == sizeof(sizeBytes)) { res = quiche_conn_stream_send(conn.d_conn.get(), streamID, response.data(), response.size(), true); @@ -270,7 +268,6 @@ static std::optional getCID() int rng = open("/dev/urandom", O_RDONLY); if (rng < 0) { return std::nullopt; - } PacketBuffer buffer; buffer.resize(LOCAL_CONN_ID_LEN); @@ -374,17 +371,19 @@ static std::optional> createConnection(Quiche { auto quicheConn = QuicheConnection(quiche_accept(serverSideID.data(), serverSideID.size(), originalDestinationID.data(), originalDestinationID.size(), - (struct sockaddr*) &local, + (struct sockaddr*)&local, local.getSocklen(), - (struct sockaddr*) &peer, + (struct sockaddr*)&peer, peer.getSocklen(), - config.get()), quiche_conn_free); + config.get()), + quiche_conn_free); auto conn = Connection(peer, std::move(quicheConn)); - auto pair = s_connections.emplace(serverSideID, std::move(conn)); + auto pair = s_connections.emplace(serverSideID, std::move(conn)); return pair.first->second; } -static void flushEgress(Socket& sock, Connection& conn) { +static void flushEgress(Socket& sock, Connection& conn) +{ std::array out; quiche_send_info send_info; @@ -398,11 +397,9 @@ static void flushEgress(Socket& sock, Connection& conn) { if (written < 0) { return; } - + // FIXME pacing (as send_info.at should tell us when to send the packet) ? sock.sendTo(reinterpret_cast(out.data()), written, conn.d_peer); } - - // FIXME: update timers } std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse) @@ -413,7 +410,7 @@ std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& auto du = std::move(dq.ids.doqu); if (&dq.ids != &du->ids) { - du->ids = std::move(dq.ids); + du->ids = std::move(dq.ids); } du->ids.origID = dq.getHeader()->id; @@ -439,11 +436,9 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit) { const auto handleImmediateResponse = [](DOQUnitUniquePtr&& du, const char* reason) { DEBUGLOG("handleImmediateResponse() reason=" << reason); - auto conn = getConnection(du->serverConnID); - handleResponse(*du->dsc->df, *conn, du->streamID, du->response); - /* so the unique pointer is stored in the InternalState which itself is stored in the unique pointer itself. We likely need - a better design, but for now let's just reset the internal one since we know it is no longer needed. */ - du->ids.doqu.reset(); + auto conn = getConnection(du->serverConnID); + handleResponse(*du->dsc->df, *conn, du->streamID, du->response); + du->ids.doqu.reset(); }; auto& ids = unit->ids; @@ -460,8 +455,8 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit) ClientState& cs = *dsc->cs; if (du->query.size() < sizeof(dnsheader)) { - // ++dnsdist::metrics::g_stats.nonCompliantQueries; - // ++cs.nonCompliantQueries; + ++dnsdist::metrics::g_stats.nonCompliantQueries; + ++cs.nonCompliantQueries; struct dnsheader* dh = reinterpret_cast(du->query.data()); dh->rcode = RCode::ServFail; dh->qr = true; @@ -471,8 +466,8 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit) return; } - // ++cs.queries; - // ++dnsdist::metrics::g_stats.queries; + ++cs.queries; + ++dnsdist::metrics::g_stats.queries; du->ids.queryRealTime.start(); { @@ -528,6 +523,11 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit) return; } + ++dnsdist::metrics::g_stats.responses; + if (du->ids.cs != nullptr) { + ++du->ids.cs->responses; + } + if (result != ProcessQueryResult::PassToBackend) { handleImmediateResponse(std::move(du), "DoQ no backend available"); return; @@ -711,10 +711,8 @@ void doqThread(ClientState* cs) else { DEBUGLOG("Connection not established"); } - /* FIXME: we should handle timeouts */ - // pacing QUIC ? - // quiche_send_info.at Queue avec les paquets a envoyer par date. } + for (auto conn = s_connections.begin(); conn != s_connections.end();) { quiche_conn_on_timeout(conn->second.d_conn.get()); @@ -728,10 +726,11 @@ void doqThread(ClientState* cs) quiche_conn_stats(conn->second.d_conn.get(), &stats); quiche_conn_path_stats(conn->second.d_conn.get(), 0, &path_stats); - DEBUGLOG("Connection closed, recv="<&& config_) : config(std::move(config_)) { @@ -264,16 +264,13 @@ void DOQFrontend::setup() static std::optional getCID() { - // FIXME replace it - int rng = open("/dev/urandom", O_RDONLY); - if (rng < 0) { - return std::nullopt; - } PacketBuffer buffer; + size_t idx = 0; + buffer.resize(LOCAL_CONN_ID_LEN); - auto got = read(rng, buffer.data(), LOCAL_CONN_ID_LEN); - if (got < 0) { - return std::nullopt; + while (idx < LOCAL_CONN_ID_LEN) { + buffer.at(idx) = dnsdist::getRandomValue(std::numeric_limits::max()); + ++idx; } return buffer; @@ -623,8 +620,6 @@ void doqThread(ClientState* cs) size_t scid_len = scid.size(); std::array dcid; size_t dcid_len = dcid.size(); - std::array odcid; - size_t odcid_len = odcid.size(); std::array token; size_t token_len = token.size(); From 57b572596cd940992ed2e38eb31bc35800543b5e Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Thu, 21 Sep 2023 15:14:54 +0200 Subject: [PATCH 815/909] doq: add cache hit test --- regression-tests.dnsdist/test_DOQ.py | 56 ++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/regression-tests.dnsdist/test_DOQ.py b/regression-tests.dnsdist/test_DOQ.py index b2ecea850346..8e9ba3dd78aa 100644 --- a/regression-tests.dnsdist/test_DOQ.py +++ b/regression-tests.dnsdist/test_DOQ.py @@ -138,3 +138,59 @@ def testDOQNoBackend(self): dropped = True self.assertTrue(dropped) # dns.quic doesn't seem to report correctly the quic error so the connection timeout + +class TestDOQWithCache(DNSDistTest): + _serverKey = 'server.key' + _serverCert = 'server.chain' + _serverName = '127.0.0.1' + _caCert = 'ca.pem' + _doqServerPort = 8853 + _config_template = """ + newServer{address="127.0.0.1:%d"} + + addDOQLocal("127.0.0.1:%d", "%s", "%s") + + pc = newPacketCache(100, {maxTTL=86400, minTTL=1}) + getPool(""):setCache(pc) + """ + _config_params = ['_testServerPort', '_doqServerPort','_serverCert', '_serverKey'] + _verboseMode = True + + def testCached(self): + """ + Cache: Served from cache + + dnsdist is configured to cache entries, we are sending several + identical requests and checking that the backend only receive + the first one. + """ + numberOfQueries = 10 + name = 'cached.cache.tests.powerdns.com.' + query = dns.message.make_query(name, 'AAAA', 'IN') + query.id = 0 + response = dns.message.make_response(query) + rrset = dns.rrset.from_text(name, + 3600, + dns.rdataclass.IN, + dns.rdatatype.AAAA, + '::1') + response.answer.append(rrset) + + # first query to fill the cache + (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=response, caFile=self._caCert) + self.assertTrue(receivedQuery) + self.assertTrue(receivedResponse) + receivedQuery.id = query.id + self.assertEqual(query, receivedQuery) + self.assertEqual(receivedResponse, response) + + for _ in range(numberOfQueries): + (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) + self.assertEqual(receivedResponse, response) + + total = 0 + for key in self._responsesCounter: + total += self._responsesCounter[key] + TestDOQWithCache._responsesCounter[key] = 0 + + self.assertEqual(total, 1) From f7d508b5f3cc7848da9d7478cac734c99689902c Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Thu, 21 Sep 2023 16:54:21 +0200 Subject: [PATCH 816/909] doq: handle responses in the main thread --- pdns/dnsdist-lua.cc | 2 + pdns/dnsdistdist/docs/reference/config.rst | 1 + pdns/dnsdistdist/doq.cc | 73 +++++++++++++++++++--- pdns/dnsdistdist/doq.hh | 7 +++ 4 files changed, 74 insertions(+), 9 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 6d39d29e0d5a..e04f3ca20d27 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2511,6 +2511,8 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) if (vars) { parseLocalBindVars(vars, reusePort, tcpFastOpenQueueSize, interface, cpus, tcpListenQueueSize, maxInFlightQueriesPerConn, tcpMaxConcurrentConnections); + getOptionalValue(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize); + parseTLSConfig(frontend->d_tlsConfig, "addDOQLocal", vars); bool ignoreTLSConfigurationErrors = false; diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 6684b3554a40..fbb8e73f7764 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -189,6 +189,7 @@ Listen Sockets * ``interface=""``: str - Set the network interface to use. * ``cpus={}``: table - Set the CPU affinity for this listener thread, asking the scheduler to run it on a single CPU id, or a set of CPU ids. This parameter is only available if the OS provides the pthread_setaffinity_np() function. * ``idleTimeout=30``: int - Set the idle timeout, in seconds. + * ``internalPipeBufferSize=0``: int - Set the size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads. Requires support for ``F_SETPIPE_SZ`` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used. The default value is 0, except on Linux where it is 1048576 since 1.6.0. .. function:: addTLSLocal(address, certFile(s), keyFile(s) [, options]) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 80c1c39359e5..6acc201279d0 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -24,11 +24,11 @@ #include "dnsdist-tcp.hh" #include "dnsdist-random.hh" +#include "dnsparser.hh" #include "dolog.hh" #include "iputils.hh" #include "misc.hh" #include "sstuff.hh" -#include "dnsparser.hh" #include "threadname.hh" #include "dnsdist-ecs.hh" #include "dnsdist-proxy-protocol.hh" @@ -36,9 +36,15 @@ static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description); struct DOQServerConfig { - DOQServerConfig(std::unique_ptr&& config_) : + DOQServerConfig(std::unique_ptr&& config_, uint32_t internalPipeBufferSize) : config(std::move(config_)) { + { + auto [sender, receiver] = pdns::channel::createObjectQueue(pdns::channel::SenderBlockingMode::SenderNonBlocking, pdns::channel::ReceiverBlockingMode::ReceiverNonBlocking, internalPipeBufferSize); + d_responseSender = std::move(sender); + d_responseReceiver = std::move(receiver); + } + } DOQServerConfig(const DOQServerConfig&) = delete; DOQServerConfig(DOQServerConfig&&) = default; @@ -50,6 +56,8 @@ struct DOQServerConfig QuicheConfig config; ClientState* cs{nullptr}; std::shared_ptr df{nullptr}; + pdns::channel::Sender d_responseSender; + pdns::channel::Receiver d_responseReceiver; }; #if 0 @@ -84,6 +92,9 @@ class DOQTCPCrossQuerySender final : public TCPQuerySender } auto du = std::move(response.d_idstate.doqu); + if (du->responseSender == nullptr) { + return; + } du->response = std::move(response.d_buffer); du->ids = std::move(response.d_idstate); @@ -259,7 +270,7 @@ void DOQFrontend::setup() quiche_config_set_cc_algorithm(config.get(), QUICHE_CC_RENO); // quiche_config_log_keys(config.get()); - d_server_config = std::make_shared(std::move(config)); + d_server_config = std::make_shared(std::move(config), d_internalPipeBufferSize); } static std::optional getCID() @@ -359,9 +370,16 @@ static std::optional> getConnection(const Pac static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description) { - DEBUGLOG("Handling back a " << description); - auto conn = getConnection(du->serverConnID); - handleResponse(*du->dsc->df, *conn, du->streamID, du->response); + if (du->responseSender == nullptr) { + return; + } + try { + if (!du->responseSender->send(std::move(du))) { + vinfolog("Unable to pass a %s to the DoQ worker thread because the pipe is full", description); + } + } catch (const std::exception& e) { + vinfolog("Unable to pass a %s to the DoQ worker thread because we couldn't write to the pipe: %s", description, e.what()); + } } static std::optional> createConnection(QuicheConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const PacketBuffer& token, const ComboAddress& local, const ComboAddress& peer) @@ -585,6 +603,7 @@ static void doq_dispatch_query(DOQServerConfig& dsc, PacketBuffer&& query, const du->ids.protocol = dnsdist::Protocol::DoQ; du->serverConnID = serverConnID; du->streamID = streamID; + du->responseSender = &dsc.d_responseSender; processDOQQuery(std::move(du)); } @@ -593,6 +612,30 @@ static void doq_dispatch_query(DOQServerConfig& dsc, PacketBuffer&& query, const } } +static void flushResponses(pdns::channel::Receiver& receiver) +{ + for(;;) { + try { + auto tmp = receiver.receive(); + if (!tmp) { + return ; + } + + auto du = std::move(*tmp); + auto conn = getConnection(du->serverConnID); + + handleResponse(*du->dsc->df, *conn, du->streamID, du->response); + + } + catch (const std::exception& e) { + errlog("Error while processing response received over DoQ: %s", e.what()); + } + catch (...) { + errlog("Unspecified error while processing response received over DoQ"); + } + } +} + // this is the entrypoint from dnsdist.cc void doqThread(ClientState* cs) { @@ -607,11 +650,18 @@ void doqThread(ClientState* cs) Socket sock(cs->udpFD); PacketBuffer buffer(std::numeric_limits::max()); + auto mplexer = std::unique_ptr(FDMultiplexer::getMultiplexerSilent()); + auto responseReceiverFD = frontend->d_server_config->d_responseReceiver.getDescriptor(); + mplexer->addReadFD(sock.getHandle(), [](int, FDMultiplexer::funcparam_t&) {}); + mplexer->addReadFD(responseReceiverFD, [](int, FDMultiplexer::funcparam_t&) {}); while (true) { - std::string bufferStr; - ComboAddress client; - if (waitForData(sock.getHandle(), 1, 0) > 0) { + std::vector readyFDs; + mplexer->getAvailableFDs(readyFDs, 500); + + if (std::find(readyFDs.begin(), readyFDs.end(), sock.getHandle()) != readyFDs.end()) { + std::string bufferStr; + ComboAddress client; sock.recvFrom(bufferStr, client); uint32_t version{0}; @@ -706,6 +756,11 @@ void doqThread(ClientState* cs) else { DEBUGLOG("Connection not established"); } + // } + } + + if (std::find(readyFDs.begin(), readyFDs.end(), responseReceiverFD) != readyFDs.end()) { + flushResponses(frontend->d_server_config->d_responseReceiver); } for (auto conn = s_connections.begin(); conn != s_connections.end();) { diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 8761e04ca85b..a45110411a35 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -71,6 +71,13 @@ struct DOQFrontend ComboAddress d_local; void setup(); +#ifdef __linux__ + // On Linux this gives us 128k pending queries (default is 8192 queries), + // which should be enough to deal with huge spikes + uint32_t d_internalPipeBufferSize{1024*1024}; +#else + uint32_t d_internalPipeBufferSize{0}; +#endif }; struct DOQUnit From 3e5c7a76420d24fc7e2711e47c71d06aa9d1b25a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 20 Sep 2023 13:55:54 +0200 Subject: [PATCH 817/909] build-and-test-all: Build Quiche, and enable DoQ for dnsdist --- .github/workflows/build-and-test-all.yml | 4 ++++ tasks.py | 25 ++++++++++++++++++++++++ 2 files changed, 29 insertions(+) diff --git a/.github/workflows/build-and-test-all.yml b/.github/workflows/build-and-test-all.yml index 6e25bc0d127d..b5eb3772e527 100644 --- a/.github/workflows/build-and-test-all.yml +++ b/.github/workflows/build-and-test-all.yml @@ -236,6 +236,10 @@ jobs: path: ~/.ccache key: dnsdist-${{ matrix.features }}-${{ matrix.sanitizers }}-ccache-${{ steps.get-stamp.outputs.stamp }} restore-keys: dnsdist-${{ matrix.features }}-${{ matrix.sanitizers }}-ccache- + - run: inv ci-install-rust ${{ env.REPO_HOME }} + working-directory: ./pdns/dnsdistdist/ + - run: inv ci-build-and-install-quiche + working-directory: ./pdns/dnsdistdist/ - run: inv ci-autoconf working-directory: ./pdns/dnsdistdist/ - run: inv ci-dnsdist-configure ${{ matrix.features }} diff --git a/tasks.py b/tasks.py index 97b73352478f..8846c3052fb6 100644 --- a/tasks.py +++ b/tasks.py @@ -9,6 +9,8 @@ clang_version = os.getenv('CLANG_VERSION', '13') rust_version = 'rust-1.72.0-x86_64-unknown-linux-gnu' +quiche_version = '0.18.0' +quiche_hash = 'eb242a14c4d801a90b57b6021dd29f7a62099f3a4d7a7ba889e105f8328e6c1f' all_build_deps = [ 'ccache', @@ -490,6 +492,7 @@ def ci_dnsdist_configure(c, features): --enable-dnscrypt \ --enable-dns-over-tls \ --enable-dns-over-https \ + --enable-dns-over-quic \ --enable-systemd \ --prefix=/opt/dnsdist \ --with-gnutls \ @@ -885,6 +888,28 @@ def coverity_upload(c, email, project, tarball): --form description="master build" \ https://scan.coverity.com/builds?project={project}', hide=True) +@task +def ci_build_and_install_quiche(c): + # we have to pass -L because GitHub will do a redirect, sadly + c.run(f'curl -L -o quiche-{quiche_version}.tar.gz https://github.com/cloudflare/quiche/archive/{quiche_version}.tar.gz') + # Line below should echo two spaces between digest and name + c.run(f'echo {quiche_hash}" "quiche-{quiche_version}.tar.gz | sha256sum -c -') + c.run(f'tar xf quiche-{quiche_version}.tar.gz') + with c.cd(f'quiche-{quiche_version}'): + c.run('cargo build --release --no-default-features --features ffi,pkg-config-meta,qlog,boringssl-boring-crate --package quiche') + c.run('ls quiche/include/quiche.h target/release/libquiche.a /usr/include /usr/lib /usr/lib/pkgconfig') + # cannot use c.sudo() inside a cd() context, see https://github.com/pyinvoke/invoke/issues/687 + c.run('sudo install -Dm644 quiche/include/quiche.h /usr/include') + c.run('sudo install -Dm644 target/release/libquiche.a /usr/lib') + c.run("""sudo install -Dm644 /dev/stdin /usr/lib/pkgconfig/quiche.pc < Date: Wed, 20 Sep 2023 15:47:12 +0200 Subject: [PATCH 818/909] build-and-test-all: Disable LTO for now, it does not play well with Quiche --- tasks.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tasks.py b/tasks.py index 8846c3052fb6..c040f84a123a 100644 --- a/tasks.py +++ b/tasks.py @@ -565,7 +565,6 @@ def ci_dnsdist_configure(c, features): --enable-option-checking=fatal \ --enable-fortify-source=auto \ --enable-auto-var-init=pattern \ - --enable-lto=thin \ --prefix=/opt/dnsdist %s %s %s %s %s''' % (cflags, cxxflags, features_set, sanitizers, unittests, fuzztargets, coverage), warn=True) if res.exited != 0: c.run('cat config.log') From b5db7ee8f9cc1480c2dd47a2ecd9fd40122212ec Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 20 Sep 2023 15:49:56 +0200 Subject: [PATCH 819/909] dnsdist: Refactoring of SodiumNonce and friends --- pdns/base64.hh | 2 +- pdns/dnsdist-console.cc | 8 ++--- pdns/sodcrypto.cc | 71 +++++++++++++++++++++++++++++++---------- pdns/sodcrypto.hh | 69 ++++++++++++++------------------------- 4 files changed, 84 insertions(+), 66 deletions(-) diff --git a/pdns/base64.hh b/pdns/base64.hh index a84181db3212..f07814bf1b93 100644 --- a/pdns/base64.hh +++ b/pdns/base64.hh @@ -22,5 +22,5 @@ #pragma once #include -template int B64Decode(const std::string& src, Container& dst); +template int B64Decode(const std::string& strInput, Container& strOutput); std::string Base64Encode (const std::string& src); diff --git a/pdns/dnsdist-console.cc b/pdns/dnsdist-console.cc index a451f31e1ad7..a49a50914759 100644 --- a/pdns/dnsdist-console.cc +++ b/pdns/dnsdist-console.cc @@ -236,8 +236,8 @@ void doClient(ComboAddress server, const std::string& command) SodiumNonce theirs, ours, readingNonce, writingNonce; ours.init(); - writen2(fd.getHandle(), (const char*)ours.value, sizeof(ours.value)); - readn2(fd.getHandle(), (char*)theirs.value, sizeof(theirs.value)); + writen2(fd.getHandle(), ours.value.data(), ours.value.size()); + readn2(fd.getHandle(), theirs.value.data(), theirs.value.size()); readingNonce.merge(ours, theirs); writingNonce.merge(theirs, ours); @@ -868,8 +868,8 @@ static void controlClientThread(ConsoleConnection&& conn) SodiumNonce theirs, ours, readingNonce, writingNonce; ours.init(); - readn2(conn.getFD(), (char*)theirs.value, sizeof(theirs.value)); - writen2(conn.getFD(), (char*)ours.value, sizeof(ours.value)); + readn2(conn.getFD(), theirs.value.data(), theirs.value.size()); + writen2(conn.getFD(), ours.value.data(), ours.value.size()); readingNonce.merge(ours, theirs); writingNonce.merge(theirs, ours); diff --git a/pdns/sodcrypto.cc b/pdns/sodcrypto.cc index b92c6e0e53bb..9e9f91ce203d 100644 --- a/pdns/sodcrypto.cc +++ b/pdns/sodcrypto.cc @@ -20,13 +20,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include +#include + #include "namespaces.hh" #include "noinitvector.hh" #include "misc.hh" #include "base64.hh" #include "sodcrypto.hh" - #ifdef HAVE_LIBSODIUM string newKey() @@ -34,9 +35,10 @@ string newKey() std::string key; key.resize(crypto_secretbox_KEYBYTES); - randombytes_buf(reinterpret_cast(&key.at(0)), key.size()); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + randombytes_buf(reinterpret_cast(key.data()), key.size()); - return "\""+Base64Encode(key)+"\""; + return "\"" + Base64Encode(key) + "\""; } bool sodIsValidKey(const std::string& key) @@ -44,7 +46,7 @@ bool sodIsValidKey(const std::string& key) return key.size() == crypto_secretbox_KEYBYTES; } -std::string sodEncryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce) +std::string sodEncryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce) { if (!sodIsValidKey(key)) { throw std::runtime_error("Invalid encryption key of size " + std::to_string(key.size()) + ", use setKey() to set a valid key"); @@ -52,17 +54,20 @@ std::string sodEncryptSym(const std::string& msg, const std::string& key, Sodium std::string ciphertext; ciphertext.resize(msg.length() + crypto_secretbox_MACBYTES); - crypto_secretbox_easy(reinterpret_cast(&ciphertext.at(0)), - reinterpret_cast(msg.c_str()), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + crypto_secretbox_easy(reinterpret_cast(ciphertext.data()), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(msg.data()), msg.length(), - nonce.value, - reinterpret_cast(key.c_str())); + nonce.value.data(), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(key.data())); nonce.increment(); return ciphertext; } -std::string sodDecryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce) +std::string sodDecryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce) { std::string decrypted; @@ -76,18 +81,54 @@ std::string sodDecryptSym(const std::string& msg, const std::string& key, Sodium decrypted.resize(msg.length() - crypto_secretbox_MACBYTES); - if (crypto_secretbox_open_easy(reinterpret_cast(const_cast(decrypted.data())), - reinterpret_cast(msg.c_str()), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + if (crypto_secretbox_open_easy(reinterpret_cast(decrypted.data()), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(msg.data()), msg.length(), - nonce.value, - reinterpret_cast(key.c_str())) != 0) { + nonce.value.data(), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(key.data())) != 0) { throw std::runtime_error("Could not decrypt message, please check that the key configured with setKey() is correct"); } nonce.increment(); return decrypted; } + +void SodiumNonce::init() +{ + randombytes_buf(value.data(), value.size()); +} + +void SodiumNonce::merge(const SodiumNonce& lower, const SodiumNonce& higher) +{ + constexpr size_t halfSize = std::tuple_size{} / 2; + memcpy(value.data(), lower.value.data(), halfSize); + memcpy(value.data() + halfSize, higher.value.data() + halfSize, halfSize); +} + +void SodiumNonce::increment() +{ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + auto* ptr = reinterpret_cast(value.data()); + uint32_t count = htonl(*ptr); + *ptr = ntohl(++count); +} + #else +void SodiumNonce::init() +{ +} + +void SodiumNonce::merge(const SodiumNonce& lower, const SodiumNonce& higher) +{ +} + +void SodiumNonce::increment() +{ +} + std::string sodEncryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce) { return msg; @@ -109,9 +150,7 @@ bool sodIsValidKey(const std::string& key) #endif - -#include "base64.hh" -#include +#include namespace anonpdns { static char B64Decode1(char cInChar) diff --git a/pdns/sodcrypto.hh b/pdns/sodcrypto.hh index ca35631455de..8538702fc811 100644 --- a/pdns/sodcrypto.hh +++ b/pdns/sodcrypto.hh @@ -21,58 +21,37 @@ */ #pragma once #include "config.h" +#include #include -#include +#include +#include -#include - -#ifndef HAVE_LIBSODIUM -struct SodiumNonce -{ - void init(){}; - void merge(const SodiumNonce& lower, const SodiumNonce& higher) {}; - void increment(){}; - unsigned char value[1]{0}; -}; -#else +#if defined(HAVE_LIBSODIUM) #include +#endif struct SodiumNonce { - SodiumNonce() - { - memset(&value, 0, sizeof(value)); - } - - void init() - { - randombytes_buf(value, sizeof value); - } - - void merge(const SodiumNonce& lower, const SodiumNonce& higher) - { - static const size_t halfSize = (sizeof value) / 2; - memcpy(value, lower.value, halfSize); - memcpy(value + halfSize, higher.value + halfSize, halfSize); - } - - void increment() - { - uint32_t* p = (uint32_t*)value; - uint32_t count=htonl(*p); - *p=ntohl(++count); - } - - string toString() const - { - return string((const char*)value, crypto_secretbox_NONCEBYTES); - } - - unsigned char value[crypto_secretbox_NONCEBYTES]; -}; + SodiumNonce() = default; + SodiumNonce(const SodiumNonce&) = default; + SodiumNonce(SodiumNonce&&) = default; + SodiumNonce& operator=(const SodiumNonce&) = default; + SodiumNonce& operator=(SodiumNonce&&) = default; + ~SodiumNonce() = default; + + void init(); + void merge(const SodiumNonce& lower, const SodiumNonce& higher); + void increment(); + +#if !defined(HAVE_LIBSODIUM) + std::array value{}; +#else + std::array value{}; #endif +}; + std::string newKeypair(); -std::string sodEncryptSym(const std::string& msg, const std::string& key, SodiumNonce&); -std::string sodDecryptSym(const std::string& msg, const std::string& key, SodiumNonce&); +std::string sodEncryptSym(const std::string_view& msg, const std::string& key, SodiumNonce&); +std::string sodDecryptSym(const std::string_view& msg, const std::string& key, SodiumNonce&); std::string newKey(); bool sodIsValidKey(const std::string& key); From fc7c753845599ec8d2921794be4290504008c567 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 20 Sep 2023 16:54:37 +0200 Subject: [PATCH 820/909] dnsdist: Proper retry token generation and validation for DoQ --- pdns/dnsdistdist/doq.cc | 83 +++++++++++++++++++++++++++++------------ pdns/sodcrypto.cc | 31 +++++++++------ pdns/sodcrypto.hh | 6 +-- 3 files changed, 83 insertions(+), 37 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 6acc201279d0..2df6b6a40405 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -32,6 +32,9 @@ #include "threadname.hh" #include "dnsdist-ecs.hh" #include "dnsdist-proxy-protocol.hh" +#include "sodcrypto.hh" + +static std::string s_quicRetryTokenKey = newKey(false); static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description); struct DOQServerConfig @@ -69,7 +72,6 @@ struct DOQServerConfig static constexpr size_t MAX_DATAGRAM_SIZE = 1350; static constexpr size_t LOCAL_CONN_ID_LEN = 16; -static constexpr size_t TOKEN_LEN = 32; /* check if this needs to be authenticated, via HMAC-SHA256, for example, see rfc9000 section 8.1.1 */ static std::map s_connections; @@ -287,35 +289,70 @@ static std::optional getCID() return buffer; } +static constexpr size_t MAX_TOKEN_LEN = std::tuple_size{} /* nonce */ + sizeof(uint64_t) /* TTD */ + 16 /* IPv6 */ + QUICHE_MAX_CONN_ID_LEN; + static PacketBuffer mintToken(const PacketBuffer& dcid, const ComboAddress& peer) { - // FIXME: really check whether this needs to be authenticated, via HMAC for example - const std::array keyword = {'q', 'u', 'i', 'c', 'h', 'e'}; - auto addrBytes = peer.toByteString(); - PacketBuffer token; - token.reserve(keyword.size() + addrBytes.size() + dcid.size()); - token.insert(token.end(), keyword.begin(), keyword.end()); - token.insert(token.end(), addrBytes.begin(), addrBytes.end()); - token.insert(token.end(), dcid.begin(), dcid.end()); - return token; + try { + SodiumNonce nonce; + nonce.init(); + + const auto addrBytes = peer.toByteString(); + // this token will be valid for 60s + const uint64_t ttd = time(nullptr) + 60U; + PacketBuffer plainTextToken; + plainTextToken.reserve(sizeof(ttd) + addrBytes.size() + dcid.size()); + plainTextToken.insert(plainTextToken.end(), reinterpret_cast(&ttd), reinterpret_cast(&ttd) + sizeof(ttd)); + plainTextToken.insert(plainTextToken.end(), addrBytes.begin(), addrBytes.end()); + plainTextToken.insert(plainTextToken.end(), dcid.begin(), dcid.end()); + const auto encryptedToken = sodEncryptSym(std::string_view(reinterpret_cast(plainTextToken.data()), plainTextToken.size()), s_quicRetryTokenKey, nonce, false); + // a bit sad, let's see if we can do better later + auto encryptedTokenPacket = PacketBuffer(encryptedToken.begin(), encryptedToken.end()); + encryptedTokenPacket.insert(encryptedTokenPacket.begin(), nonce.value.begin(), nonce.value.end()); + return encryptedTokenPacket; + } + catch (const std::exception& exp) { + vinfolog("Error while minting DoQ token: %s", exp.what()); + throw; + } } // returns the original destination ID if the token is valid, nothing otherwise static std::optional validateToken(const PacketBuffer& token, const PacketBuffer& dcid, const ComboAddress& peer) { - const std::array keyword = {'q', 'u', 'i', 'c', 'h', 'e'}; - auto addrBytes = peer.toByteString(); - auto minimumSize = keyword.size() + addrBytes.size(); - if (token.size() <= minimumSize) { - return std::nullopt; - } - if (std::memcmp(&*keyword.begin(), &*token.begin(), keyword.size()) != 0) { - return std::nullopt; + try { + SodiumNonce nonce; + auto addrBytes = peer.toByteString(); + const uint64_t now = time(nullptr); + const auto minimumSize = nonce.value.size() + sizeof(now) + addrBytes.size(); + if (token.size() <= minimumSize) { + return std::nullopt; + } + + memcpy(nonce.value.data(), token.data(), nonce.value.size()); + + auto cipher = std::string_view(reinterpret_cast(&token.at(nonce.value.size())), token.size() - nonce.value.size()); + auto plainText = sodDecryptSym(cipher, s_quicRetryTokenKey, nonce, false); + + if (plainText.size() <= sizeof(now) + addrBytes.size()) { + return std::nullopt; + } + + uint64_t ttd{0}; + memcpy(&ttd, plainText.data(), sizeof(ttd)); + if (ttd < now) { + return std::nullopt; + } + + if (std::memcmp(&plainText.at(sizeof(ttd)), &*addrBytes.begin(), addrBytes.size()) != 0) { + return std::nullopt; + } + return PacketBuffer(plainText.begin() + (sizeof(ttd) + addrBytes.size()), plainText.end()); } - if (std::memcmp(&token.at(keyword.size()), &*addrBytes.begin(), addrBytes.size()) != 0) { + catch (const std::exception& exp) { + vinfolog("Error while validating DoQ token: %s", exp.what()); return std::nullopt; } - return PacketBuffer(token.begin() + keyword.size() + addrBytes.size(), token.end()); } static void handleStatelessRetry(Socket& sock, const PacketBuffer& clientConnID, const PacketBuffer& serverConnID, const ComboAddress& peer, uint32_t version) @@ -607,8 +644,8 @@ static void doq_dispatch_query(DOQServerConfig& dsc, PacketBuffer&& query, const processDOQQuery(std::move(du)); } - catch (const std::exception& e) { - vinfolog("Had error parsing DoQ DNS packet from %s: %s", remote.toStringWithPort(), e.what()); + catch (const std::exception& exp) { + vinfolog("Had error parsing DoQ DNS packet from %s: %s", remote.toStringWithPort(), exp.what()); } } @@ -670,7 +707,7 @@ void doqThread(ClientState* cs) size_t scid_len = scid.size(); std::array dcid; size_t dcid_len = dcid.size(); - std::array token; + std::array token; size_t token_len = token.size(); auto res = quiche_header_info(reinterpret_cast(bufferStr.data()), bufferStr.size(), LOCAL_CONN_ID_LEN, diff --git a/pdns/sodcrypto.cc b/pdns/sodcrypto.cc index 9e9f91ce203d..d6e9e7e906e4 100644 --- a/pdns/sodcrypto.cc +++ b/pdns/sodcrypto.cc @@ -30,7 +30,7 @@ #ifdef HAVE_LIBSODIUM -string newKey() +string newKey(bool base64Encoded) { std::string key; key.resize(crypto_secretbox_KEYBYTES); @@ -38,6 +38,9 @@ string newKey() // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) randombytes_buf(reinterpret_cast(key.data()), key.size()); + if (!base64Encoded) { + return key; + } return "\"" + Base64Encode(key) + "\""; } @@ -46,10 +49,10 @@ bool sodIsValidKey(const std::string& key) return key.size() == crypto_secretbox_KEYBYTES; } -std::string sodEncryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce) +std::string sodEncryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce, bool incrementNonce) { if (!sodIsValidKey(key)) { - throw std::runtime_error("Invalid encryption key of size " + std::to_string(key.size()) + ", use setKey() to set a valid key"); + throw std::runtime_error("Invalid encryption key of size " + std::to_string(key.size()) + " (" + std::to_string(crypto_secretbox_KEYBYTES) + " expected), use setKey() to set a valid key"); } std::string ciphertext; @@ -63,11 +66,14 @@ std::string sodEncryptSym(const std::string_view& msg, const std::string& key, S // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) reinterpret_cast(key.data())); - nonce.increment(); + if (incrementNonce) { + nonce.increment(); + } + return ciphertext; } -std::string sodDecryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce) +std::string sodDecryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce, bool incrementNonce) { std::string decrypted; @@ -92,7 +98,10 @@ std::string sodDecryptSym(const std::string_view& msg, const std::string& key, S throw std::runtime_error("Could not decrypt message, please check that the key configured with setKey() is correct"); } - nonce.increment(); + if (incrementNonce) { + nonce.increment(); + } + return decrypted; } @@ -129,16 +138,16 @@ void SodiumNonce::increment() { } -std::string sodEncryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce) +std::string sodEncryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce, bool incrementNonce) { - return msg; + return std::string(msg); } -std::string sodDecryptSym(const std::string& msg, const std::string& key, SodiumNonce& nonce) +std::string sodDecryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce, bool incrementNonce) { - return msg; + return std::string(msg); } -string newKey() +string newKey(bool base64Encoded) { return "\"plaintext\""; } diff --git a/pdns/sodcrypto.hh b/pdns/sodcrypto.hh index 8538702fc811..776248cc99fe 100644 --- a/pdns/sodcrypto.hh +++ b/pdns/sodcrypto.hh @@ -51,7 +51,7 @@ struct SodiumNonce }; std::string newKeypair(); -std::string sodEncryptSym(const std::string_view& msg, const std::string& key, SodiumNonce&); -std::string sodDecryptSym(const std::string_view& msg, const std::string& key, SodiumNonce&); -std::string newKey(); +std::string sodEncryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce, bool incrementNonce = true); +std::string sodDecryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce, bool incrementNonce = true); +std::string newKey(bool base64Encoded = true); bool sodIsValidKey(const std::string& key); From 2ade4784923886e8bf8f97181f73f4e6d21555c6 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 21 Sep 2023 14:55:02 +0200 Subject: [PATCH 821/909] dnsdist: Use the shared library version of Quiche Otherwise we have symbol conflicts with the symbols coming from OpenSSL (DoT, DoH) and BoringSSL (DoQ, via Quiche). This does not happen with a shared library because the symbols from BoringSSL are in the same object than their user, Quiche, so they get picked up first, and are not exported so they do not pollute dnsdist's symbols namespace. --- tasks.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tasks.py b/tasks.py index c040f84a123a..8cec3534715c 100644 --- a/tasks.py +++ b/tasks.py @@ -836,7 +836,7 @@ def test_dnsdist(c): c.run('ls -ald /var /var/agentx /var/agentx/master') c.run('ls -al /var/agentx/master') with c.cd('regression-tests.dnsdist'): - c.run('DNSDISTBIN=/opt/dnsdist/bin/dnsdist ./runtests') + c.run('DNSDISTBIN=/opt/dnsdist/bin/dnsdist LD_LIBRARY_PATH=/opt/dnsdist/lib/ ./runtests') @task def test_regression_recursor(c): @@ -895,17 +895,18 @@ def ci_build_and_install_quiche(c): c.run(f'echo {quiche_hash}" "quiche-{quiche_version}.tar.gz | sha256sum -c -') c.run(f'tar xf quiche-{quiche_version}.tar.gz') with c.cd(f'quiche-{quiche_version}'): - c.run('cargo build --release --no-default-features --features ffi,pkg-config-meta,qlog,boringssl-boring-crate --package quiche') + c.run('cargo build --release --no-default-features --features ffi,boringssl-boring-crate --package quiche') c.run('ls quiche/include/quiche.h target/release/libquiche.a /usr/include /usr/lib /usr/lib/pkgconfig') # cannot use c.sudo() inside a cd() context, see https://github.com/pyinvoke/invoke/issues/687 c.run('sudo install -Dm644 quiche/include/quiche.h /usr/include') - c.run('sudo install -Dm644 target/release/libquiche.a /usr/lib') - c.run("""sudo install -Dm644 /dev/stdin /usr/lib/pkgconfig/quiche.pc < Date: Fri, 22 Sep 2023 10:21:48 +0200 Subject: [PATCH 822/909] dnsdist: Use a random port for the DoQ tests --- regression-tests.dnsdist/test_DOQ.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests.dnsdist/test_DOQ.py b/regression-tests.dnsdist/test_DOQ.py index 8e9ba3dd78aa..6f1635905fe3 100644 --- a/regression-tests.dnsdist/test_DOQ.py +++ b/regression-tests.dnsdist/test_DOQ.py @@ -10,7 +10,7 @@ class TestDOQ(DNSDistTest): _serverCert = 'server.chain' _serverName = '127.0.0.1' _caCert = 'ca.pem' - _doqServerPort = 8853 + _doqServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%d"} From 805b22fedb2b7419665e24be192439181e65795a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 22 Sep 2023 10:22:12 +0200 Subject: [PATCH 823/909] dnsdist: Move internal DoQ structures to doq.cc --- pdns/dnsdistdist/doq.cc | 33 +++++++++++++++++++++++++++++---- pdns/dnsdistdist/doq.hh | 32 ++------------------------------ 2 files changed, 31 insertions(+), 34 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 2df6b6a40405..0617ffcd8627 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -36,6 +36,32 @@ static std::string s_quicRetryTokenKey = newKey(false); +#ifdef HAVE_DNS_OVER_QUIC + +#include + +using QuicheConnection = std::unique_ptr; +using QuicheConfig = std::unique_ptr; + +class Connection +{ +public: + Connection(const ComboAddress& peer, std::unique_ptr&& conn) : + d_peer(peer), d_conn(std::move(conn)) + { + } + Connection(const Connection&) = delete; + Connection(Connection&&) = default; + Connection& operator=(const Connection&) = delete; + Connection& operator=(Connection&&) = default; + ~Connection() = default; + + ComboAddress d_peer; + QuicheConnection d_conn; +}; + +#endif + static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description); struct DOQServerConfig { @@ -94,7 +120,7 @@ class DOQTCPCrossQuerySender final : public TCPQuerySender } auto du = std::move(response.d_idstate.doqu); - if (du->responseSender == nullptr) { + if (du->dsc == nullptr) { return; } @@ -407,11 +433,11 @@ static std::optional> getConnection(const Pac static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description) { - if (du->responseSender == nullptr) { + if (du->dsc == nullptr) { return; } try { - if (!du->responseSender->send(std::move(du))) { + if (!du->dsc->d_responseSender.send(std::move(du))) { vinfolog("Unable to pass a %s to the DoQ worker thread because the pipe is full", description); } } catch (const std::exception& e) { @@ -640,7 +666,6 @@ static void doq_dispatch_query(DOQServerConfig& dsc, PacketBuffer&& query, const du->ids.protocol = dnsdist::Protocol::DoQ; du->serverConnID = serverConnID; du->streamID = streamID; - du->responseSender = &dsc.d_responseSender; processDOQQuery(std::move(du)); } diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index a45110411a35..112fa09751c1 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -29,32 +29,6 @@ #include "stat_t.hh" #include "dnsdist-idstate.hh" -#ifdef HAVE_DNS_OVER_QUIC - -#include - -using QuicheConnection = std::unique_ptr; -using QuicheConfig = std::unique_ptr; - -class Connection -{ -public: - Connection(const ComboAddress& peer, std::unique_ptr&& conn) : - d_peer(peer), d_conn(std::move(conn)) - { - } - Connection(const Connection&) = delete; - Connection(Connection&&) = default; - Connection& operator=(const Connection&) = delete; - Connection& operator=(Connection&&) = default; - ~Connection() = default; - - ComboAddress d_peer; - QuicheConnection d_conn; -}; - -#endif - struct DOQServerConfig; struct DownstreamState; @@ -94,16 +68,14 @@ struct DOQUnit InternalQueryState ids; PacketBuffer query; PacketBuffer response; + PacketBuffer serverConnID; std::shared_ptr downstream{nullptr}; DOQServerConfig* dsc{nullptr}; - pdns::channel::Sender* responseSender{nullptr}; - size_t proxyProtocolPayloadSize{0}; uint64_t streamID{0}; - PacketBuffer serverConnID; + size_t proxyProtocolPayloadSize{0}; /* whether the query was re-sent to the backend over TCP after receiving a truncated answer over UDP */ bool tcp{false}; - bool truncated{false}; }; using DOQUnitUniquePtr = std::unique_ptr; From 357b3faaad68a7763c3a9b33da1912dfc0c1e537 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Fri, 22 Sep 2023 12:17:46 +0200 Subject: [PATCH 824/909] doq: fix formating --- pdns/dnsdistdist/doq.cc | 9 ++++----- pdns/dnsdistdist/doq.hh | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 0617ffcd8627..a1ce4c647837 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -73,7 +73,6 @@ struct DOQServerConfig d_responseSender = std::move(sender); d_responseReceiver = std::move(receiver); } - } DOQServerConfig(const DOQServerConfig&) = delete; DOQServerConfig(DOQServerConfig&&) = default; @@ -440,7 +439,8 @@ static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description) if (!du->dsc->d_responseSender.send(std::move(du))) { vinfolog("Unable to pass a %s to the DoQ worker thread because the pipe is full", description); } - } catch (const std::exception& e) { + } + catch (const std::exception& e) { vinfolog("Unable to pass a %s to the DoQ worker thread because we couldn't write to the pipe: %s", description, e.what()); } } @@ -676,18 +676,17 @@ static void doq_dispatch_query(DOQServerConfig& dsc, PacketBuffer&& query, const static void flushResponses(pdns::channel::Receiver& receiver) { - for(;;) { + for (;;) { try { auto tmp = receiver.receive(); if (!tmp) { - return ; + return; } auto du = std::move(*tmp); auto conn = getConnection(du->serverConnID); handleResponse(*du->dsc->df, *conn, du->streamID, du->response); - } catch (const std::exception& e) { errlog("Error while processing response received over DoQ: %s", e.what()); diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 112fa09751c1..c2ebb685e3a0 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -48,7 +48,7 @@ struct DOQFrontend #ifdef __linux__ // On Linux this gives us 128k pending queries (default is 8192 queries), // which should be enough to deal with huge spikes - uint32_t d_internalPipeBufferSize{1024*1024}; + uint32_t d_internalPipeBufferSize{1024 * 1024}; #else uint32_t d_internalPipeBufferSize{0}; #endif From f0f66c590013840dc95b83a7e8d240c0dcf6ac85 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Fri, 22 Sep 2023 14:23:48 +0200 Subject: [PATCH 825/909] doq: really configure idleTimeout --- pdns/dnsdist-lua.cc | 1 + pdns/dnsdistdist/docs/reference/config.rst | 2 +- pdns/dnsdistdist/doq.cc | 2 +- pdns/dnsdistdist/doq.hh | 1 + 4 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index e04f3ca20d27..eccb9a936351 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2512,6 +2512,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) parseLocalBindVars(vars, reusePort, tcpFastOpenQueueSize, interface, cpus, tcpListenQueueSize, maxInFlightQueriesPerConn, tcpMaxConcurrentConnections); getOptionalValue(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize); + getOptionalValue(vars, "idleTimeout", frontend->d_idleTimeout); parseTLSConfig(frontend->d_tlsConfig, "addDOQLocal", vars); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index fbb8e73f7764..c0a3287f4187 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -188,7 +188,7 @@ Listen Sockets * ``reusePort=false``: bool - Set the ``SO_REUSEPORT`` socket option. * ``interface=""``: str - Set the network interface to use. * ``cpus={}``: table - Set the CPU affinity for this listener thread, asking the scheduler to run it on a single CPU id, or a set of CPU ids. This parameter is only available if the OS provides the pthread_setaffinity_np() function. - * ``idleTimeout=30``: int - Set the idle timeout, in seconds. + * ``idleTimeout=5``: int - Set the idle timeout, in seconds. * ``internalPipeBufferSize=0``: int - Set the size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads. Requires support for ``F_SETPIPE_SZ`` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used. The default value is 0, except on Linux where it is 1048576 since 1.6.0. .. function:: addTLSLocal(address, certFile(s), keyFile(s) [, options]) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index a1ce4c647837..6f6d0496eee1 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -287,7 +287,7 @@ void DOQFrontend::setup() } } - quiche_config_set_max_idle_timeout(config.get(), 5000); + quiche_config_set_max_idle_timeout(config.get(), d_idleTimeout * 1000); quiche_config_set_max_recv_udp_payload_size(config.get(), MAX_DATAGRAM_SIZE); quiche_config_set_max_send_udp_payload_size(config.get(), MAX_DATAGRAM_SIZE); quiche_config_set_initial_max_data(config.get(), 10000000); diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index c2ebb685e3a0..9cd69fe928db 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -52,6 +52,7 @@ struct DOQFrontend #else uint32_t d_internalPipeBufferSize{0}; #endif + uint64_t d_idleTimeout{5}; }; struct DOQUnit From 57fc9c5e061a917f761297c7a16c39ec06cb2514 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Fri, 22 Sep 2023 14:44:15 +0200 Subject: [PATCH 826/909] doq: initialize stateless reset token --- pdns/dnsdistdist/doq.cc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 6f6d0496eee1..160f3e7ae80d 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -261,6 +261,14 @@ static void handleResponse(DOQFrontend& df, Connection& conn, const uint64_t str } } +static void fillRandom(PacketBuffer& buffer, size_t size) +{ + buffer.reserve(size); + while (size > 0) { + buffer.insert(buffer.end(), dnsdist::getRandomValue(std::numeric_limits::max())); + --size; + } +} void DOQFrontend::setup() { auto config = QuicheConfig(quiche_config_new(QUICHE_PROTOCOL_VERSION), quiche_config_free); @@ -295,7 +303,12 @@ void DOQFrontend::setup() quiche_config_set_initial_max_stream_data_bidi_remote(config.get(), 1000000); quiche_config_set_initial_max_streams_bidi(config.get(), 100); quiche_config_set_cc_algorithm(config.get(), QUICHE_CC_RENO); - // quiche_config_log_keys(config.get()); + + { + PacketBuffer resetToken; + fillRandom(resetToken, 16); + quiche_config_set_stateless_reset_token(config.get(), reinterpret_cast(resetToken.data())); + } d_server_config = std::make_shared(std::move(config), d_internalPipeBufferSize); } @@ -303,13 +316,8 @@ void DOQFrontend::setup() static std::optional getCID() { PacketBuffer buffer; - size_t idx = 0; - buffer.resize(LOCAL_CONN_ID_LEN); - while (idx < LOCAL_CONN_ID_LEN) { - buffer.at(idx) = dnsdist::getRandomValue(std::numeric_limits::max()); - ++idx; - } + fillRandom(buffer, LOCAL_CONN_ID_LEN); return buffer; } From afc459f8fcda9d8d2f34d3818327e7d0f2387045 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Fri, 22 Sep 2023 15:37:26 +0200 Subject: [PATCH 827/909] doq: properly configure maxInFlight and max buffered data --- pdns/dnsdist-lua.cc | 4 +++- pdns/dnsdistdist/docs/reference/config.rst | 1 + pdns/dnsdistdist/doq.cc | 18 ++++++++++++++---- pdns/dnsdistdist/doq.hh | 1 + 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index eccb9a936351..c3aa3c52f9d1 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2510,7 +2510,9 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) if (vars) { parseLocalBindVars(vars, reusePort, tcpFastOpenQueueSize, interface, cpus, tcpListenQueueSize, maxInFlightQueriesPerConn, tcpMaxConcurrentConnections); - + if (maxInFlightQueriesPerConn > 0) { + frontend->d_maxInFlight = maxInFlightQueriesPerConn; + } getOptionalValue(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize); getOptionalValue(vars, "idleTimeout", frontend->d_idleTimeout); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index c0a3287f4187..f6ad30578304 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -190,6 +190,7 @@ Listen Sockets * ``cpus={}``: table - Set the CPU affinity for this listener thread, asking the scheduler to run it on a single CPU id, or a set of CPU ids. This parameter is only available if the OS provides the pthread_setaffinity_np() function. * ``idleTimeout=5``: int - Set the idle timeout, in seconds. * ``internalPipeBufferSize=0``: int - Set the size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads. Requires support for ``F_SETPIPE_SZ`` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used. The default value is 0, except on Linux where it is 1048576 since 1.6.0. + * ``maxInFlight=0``: int - Maximum number of in-flight queries. The default is 0, which disables out-of-order processing. .. function:: addTLSLocal(address, certFile(s), keyFile(s) [, options]) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 160f3e7ae80d..e283a754b4bd 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -298,10 +298,20 @@ void DOQFrontend::setup() quiche_config_set_max_idle_timeout(config.get(), d_idleTimeout * 1000); quiche_config_set_max_recv_udp_payload_size(config.get(), MAX_DATAGRAM_SIZE); quiche_config_set_max_send_udp_payload_size(config.get(), MAX_DATAGRAM_SIZE); - quiche_config_set_initial_max_data(config.get(), 10000000); - quiche_config_set_initial_max_stream_data_bidi_local(config.get(), 1000000); - quiche_config_set_initial_max_stream_data_bidi_remote(config.get(), 1000000); - quiche_config_set_initial_max_streams_bidi(config.get(), 100); + + // The number of concurrent remotely-initiated bidirectional streams to be open at any given time + // https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_streams_bidi + // 0 means none will get accepted, that's why we have a default value of 65535 + quiche_config_set_initial_max_streams_bidi(config.get(), d_maxInFlight); + + // The number of bytes of incoming stream data to be buffered for each localy or remotely-initiated bidirectional stream + quiche_config_set_initial_max_stream_data_bidi_local(config.get(), 8192); + quiche_config_set_initial_max_stream_data_bidi_remote(config.get(), 8192); + + // The number of total bytes of incoming stream data to be buffered for the whole connection + // https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_data + quiche_config_set_initial_max_data(config.get(), 8192 * d_maxInFlight); + quiche_config_set_cc_algorithm(config.get(), QUICHE_CC_RENO); { diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 9cd69fe928db..624af04d87f7 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -53,6 +53,7 @@ struct DOQFrontend uint32_t d_internalPipeBufferSize{0}; #endif uint64_t d_idleTimeout{5}; + uint64_t d_maxInFlight{65535}; }; struct DOQUnit From faeb9fd6246e2e39b3deeaedcb1cd77903e04665 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 22 Sep 2023 15:24:52 +0200 Subject: [PATCH 828/909] dnsdist: Small cleanup of m4/pdns_with_quiche.m4 --- pdns/dnsdistdist/Makefile.am | 5 +++-- pdns/dnsdistdist/m4/pdns_with_quiche.m4 | 4 ---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/pdns/dnsdistdist/Makefile.am b/pdns/dnsdistdist/Makefile.am index ad1519cdc527..c59dd4df4c2b 100644 --- a/pdns/dnsdistdist/Makefile.am +++ b/pdns/dnsdistdist/Makefile.am @@ -438,9 +438,10 @@ endif endif if HAVE_DNS_OVER_QUIC - dnsdist_SOURCES += doq.cc - +if HAVE_QUICHE +dnsdist_LDADD += $(QUICHE_LDFLAGS) $(QUICHE_LIBS) +endif endif if HAVE_NGHTTP2 diff --git a/pdns/dnsdistdist/m4/pdns_with_quiche.m4 b/pdns/dnsdistdist/m4/pdns_with_quiche.m4 index 40d94ddb5650..fc1d8d46a5b3 100644 --- a/pdns/dnsdistdist/m4/pdns_with_quiche.m4 +++ b/pdns/dnsdistdist/m4/pdns_with_quiche.m4 @@ -13,10 +13,6 @@ AC_DEFUN([PDNS_WITH_QUICHE], [ PKG_CHECK_MODULES([QUICHE], [quiche], [ [HAVE_QUICHE=1] AC_DEFINE([HAVE_QUICHE], [1], [Define to 1 if you have quiche]) - save_CFLAGS=$CFLAGS - save_LIBS=$LIBS - CFLAGS="$QUICHE_CFLAGS $CFLAGS" - LIBS="$QUICHE_LIBS $LIBS" ], [ : ]) ]) ]) From acde66584880900c03679aba07126459f7f5c3b8 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 22 Sep 2023 15:53:00 +0200 Subject: [PATCH 829/909] dnsdist: Small cleanup in doq.cc and doq.hh --- pdns/dnsdistdist/doq.cc | 40 ++++++++++++++++++++++++++-------------- pdns/dnsdistdist/doq.hh | 14 +++++++++----- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index e283a754b4bd..784c7c03ea1e 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -22,24 +22,24 @@ #include "doq.hh" -#include "dnsdist-tcp.hh" -#include "dnsdist-random.hh" +#ifdef HAVE_DNS_OVER_QUIC +#include + #include "dnsparser.hh" #include "dolog.hh" #include "iputils.hh" #include "misc.hh" +#include "sodcrypto.hh" #include "sstuff.hh" #include "threadname.hh" + #include "dnsdist-ecs.hh" #include "dnsdist-proxy-protocol.hh" -#include "sodcrypto.hh" +#include "dnsdist-tcp.hh" +#include "dnsdist-random.hh" static std::string s_quicRetryTokenKey = newKey(false); -#ifdef HAVE_DNS_OVER_QUIC - -#include - using QuicheConnection = std::unique_ptr; using QuicheConfig = std::unique_ptr; @@ -60,12 +60,10 @@ class Connection QuicheConnection d_conn; }; -#endif - static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description); struct DOQServerConfig { - DOQServerConfig(std::unique_ptr&& config_, uint32_t internalPipeBufferSize) : + DOQServerConfig(QuicheConfig&& config_, uint32_t internalPipeBufferSize) : config(std::move(config_)) { { @@ -88,6 +86,17 @@ struct DOQServerConfig pdns::channel::Receiver d_responseReceiver; }; +/* these might seem useless, but they are needed because + they need to be declared _after_ the definition of DOQServerConfig + so that we can use a unique_ptr in DOQFrontend */ +DOQFrontend::DOQFrontend() +{ +} + +DOQFrontend::~DOQFrontend() +{ +} + #if 0 #define DEBUGLOG_ENABLED #define DEBUGLOG(x) std::cerr << x << std::endl; @@ -95,7 +104,7 @@ struct DOQServerConfig #define DEBUGLOG(x) #endif -static constexpr size_t MAX_DATAGRAM_SIZE = 1350; +static constexpr size_t MAX_DATAGRAM_SIZE = 1200; static constexpr size_t LOCAL_CONN_ID_LEN = 16; static std::map s_connections; @@ -269,6 +278,7 @@ static void fillRandom(PacketBuffer& buffer, size_t size) --size; } } + void DOQFrontend::setup() { auto config = QuicheConfig(quiche_config_new(QUICHE_PROTOCOL_VERSION), quiche_config_free); @@ -286,7 +296,7 @@ void DOQFrontend::setup() } { - const std::array alpn{'\x03', 'd', 'o', 'q'}; + constexpr std::array alpn{'\x03', 'd', 'o', 'q'}; auto res = quiche_config_set_application_protos(config.get(), alpn.data(), alpn.size()); @@ -296,7 +306,7 @@ void DOQFrontend::setup() } quiche_config_set_max_idle_timeout(config.get(), d_idleTimeout * 1000); - quiche_config_set_max_recv_udp_payload_size(config.get(), MAX_DATAGRAM_SIZE); + /* maximum size of an outgoing packet, which means the buffer we pass to quiche_conn_send() should be at least that big */ quiche_config_set_max_send_udp_payload_size(config.get(), MAX_DATAGRAM_SIZE); // The number of concurrent remotely-initiated bidirectional streams to be open at any given time @@ -320,7 +330,7 @@ void DOQFrontend::setup() quiche_config_set_stateless_reset_token(config.get(), reinterpret_cast(resetToken.data())); } - d_server_config = std::make_shared(std::move(config), d_internalPipeBufferSize); + d_server_config = std::make_unique(std::move(config), d_internalPipeBufferSize); } static std::optional getCID() @@ -869,3 +879,5 @@ void doqThread(ClientState* cs) DEBUGLOG("Caught fatal error: " << e.what()); } } + +#endif /* HAVE_DNS_OVER_QUIC */ diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 624af04d87f7..72d276892bf2 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -22,6 +22,8 @@ #pragma once #include + +#include "config.h" #include "channel.hh" #include "iputils.hh" #include "libssl.hh" @@ -36,11 +38,14 @@ struct DownstreamState; struct DOQFrontend { - DOQFrontend() - { - } + DOQFrontend(); + DOQFrontend(const DOQFrontend&) = delete; + DOQFrontend(DOQFrontend&&) = delete; + DOQFrontend& operator=(const DOQFrontend&) = delete; + DOQFrontend& operator=(DOQFrontend&&) = delete; + ~DOQFrontend(); - std::shared_ptr d_server_config{nullptr}; + std::unique_ptr d_server_config{nullptr}; TLSConfig d_tlsConfig; ComboAddress d_local; @@ -61,7 +66,6 @@ struct DOQUnit DOQUnit(PacketBuffer&& q) : query(std::move(q)) { - ids.ednsAdded = false; } DOQUnit(const DOQUnit&) = delete; From 7b7f5513b36c33e60b78265d403397651b282c11 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Fri, 22 Sep 2023 17:01:41 +0200 Subject: [PATCH 830/909] doq: add congestion control algorithm configuration option --- .github/actions/spell-check/allow.txt | 1 + pdns/dnsdist-lua.cc | 12 +++++++++++- pdns/dnsdistdist/docs/reference/config.rst | 1 + pdns/dnsdistdist/doq.cc | 11 ++++++++++- pdns/dnsdistdist/doq.hh | 2 ++ 5 files changed, 25 insertions(+), 2 deletions(-) diff --git a/.github/actions/spell-check/allow.txt b/.github/actions/spell-check/allow.txt index a902870fb4cb..6575c877b885 100644 --- a/.github/actions/spell-check/allow.txt +++ b/.github/actions/spell-check/allow.txt @@ -240,6 +240,7 @@ batchmode baz bbnew bbold +bbr bbsv bccaf bdr diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index c3aa3c52f9d1..2c794ec9b55f 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2515,7 +2515,17 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } getOptionalValue(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize); getOptionalValue(vars, "idleTimeout", frontend->d_idleTimeout); - + { + std::string valueStr; + if (getOptionalValue(vars, "congestionControlAlgo", valueStr) > 0) { + if (DOQFrontend::s_available_cc_algorithms.count(valueStr)) { + frontend->d_ccAlgo = valueStr; + } + else { + warnlog("Ignoring unknown value '%s' for 'congestionControlAlgo' on 'addDOQLocal'", valueStr); + } + } + } parseTLSConfig(frontend->d_tlsConfig, "addDOQLocal", vars); bool ignoreTLSConfigurationErrors = false; diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index f6ad30578304..354f477f00d0 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -191,6 +191,7 @@ Listen Sockets * ``idleTimeout=5``: int - Set the idle timeout, in seconds. * ``internalPipeBufferSize=0``: int - Set the size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads. Requires support for ``F_SETPIPE_SZ`` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used. The default value is 0, except on Linux where it is 1048576 since 1.6.0. * ``maxInFlight=0``: int - Maximum number of in-flight queries. The default is 0, which disables out-of-order processing. + * ``congestionControlAlgo="reno"``: str - The congestion control algorithm to be chosen between ``reno``, ``cubic`` and ``bbr`` .. function:: addTLSLocal(address, certFile(s), keyFile(s) [, options]) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 784c7c03ea1e..ed1548ce7a74 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -40,6 +40,12 @@ static std::string s_quicRetryTokenKey = newKey(false); +std::map DOQFrontend::s_available_cc_algorithms = { + {"reno", QUICHE_CC_RENO}, + {"cubic", QUICHE_CC_CUBIC}, + {"bbr", QUICHE_CC_BBR}, +}; + using QuicheConnection = std::unique_ptr; using QuicheConfig = std::unique_ptr; @@ -322,7 +328,10 @@ void DOQFrontend::setup() // https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_data quiche_config_set_initial_max_data(config.get(), 8192 * d_maxInFlight); - quiche_config_set_cc_algorithm(config.get(), QUICHE_CC_RENO); + auto algo = DOQFrontend::s_available_cc_algorithms.find(d_ccAlgo); + if (algo != DOQFrontend::s_available_cc_algorithms.end()) { + quiche_config_set_cc_algorithm(config.get(), static_cast(algo->second)); + } { PacketBuffer resetToken; diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 72d276892bf2..9d318c9aacfe 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -59,6 +59,8 @@ struct DOQFrontend #endif uint64_t d_idleTimeout{5}; uint64_t d_maxInFlight{65535}; + std::string d_ccAlgo{"reno"}; + static std::map s_available_cc_algorithms; }; struct DOQUnit From 0a6676a4036157eef1b02ef4e0c3d9745872d038 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 25 Sep 2023 12:08:40 +0200 Subject: [PATCH 831/909] dnsdist: Add the DoQ transport protocol to Async tests --- regression-tests.dnsdist/dnsdisttests.py | 11 ++- regression-tests.dnsdist/test_Async.py | 107 ++++++++++++++++++----- regression-tests.dnsdist/test_DOQ.py | 24 ++--- 3 files changed, 105 insertions(+), 37 deletions(-) diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 7925c37cf19f..97f8b72dcbb6 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -1090,17 +1090,20 @@ def sendDOHWithH2OQueryWrapper(self, query, response, useQueue=True): def sendDOTQueryWrapper(self, query, response, useQueue=True): return self.sendDOTQuery(self._tlsServerPort, self._serverName, query, response, self._caCert, useQueue=useQueue) + def sendDOQQueryWrapper(self, query, response, useQueue=True): + return self.sendDOQQuery(self._doqServerPort, query, response=response, caFile=self._caCert, useQueue=useQueue, serverName=self._serverName) + @classmethod - def getDOQConnection(cls, port, servername, caFile=None, source=None, source_port=0): + def getDOQConnection(cls, port, caFile=None, source=None, source_port=0): manager = dns.quic.SyncQuicManager( verify_mode=caFile ) - return manager.connect(servername, port, source, source_port) + return manager.connect('127.0.0.1', port, source, source_port) @classmethod - def sendDOQQuery(cls, port, servername, query, response=None, timeout=2.0, caFile=None, useQueue=True, rawQuery=False, fromQueue=None, toQueue=None, connection=None): + def sendDOQQuery(cls, port, query, response=None, timeout=2.0, caFile=None, useQueue=True, rawQuery=False, fromQueue=None, toQueue=None, connection=None, serverName=None): if response: if toQueue: @@ -1108,7 +1111,7 @@ def sendDOQQuery(cls, port, servername, query, response=None, timeout=2.0, caFil else: cls._toResponderQueue.put(response, True, timeout) - message = dns.query.quic(query, servername, timeout, port, verify=caFile, connection=connection) + message = dns.query.quic(query, '127.0.0.1', timeout, port, verify=caFile, connection=connection, server_hostname=serverName) receivedQuery = None diff --git a/regression-tests.dnsdist/test_Async.py b/regression-tests.dnsdist/test_Async.py index 8856df30f59a..e4b8e41c651e 100644 --- a/regression-tests.dnsdist/test_Async.py +++ b/regression-tests.dnsdist/test_Async.py @@ -95,6 +95,7 @@ class AsyncTests(object): _dohWithH2OServerPort = pickAvailablePort() _dohWithNGHTTP2BaseURL = ("https://%s:%d/" % (_serverName, _dohWithNGHTTP2ServerPort)) _dohWithH2OBaseURL = ("https://%s:%d/" % (_serverName, _dohWithH2OServerPort)) + _doqServerPort = pickAvailablePort() def testPass(self): """ @@ -111,11 +112,14 @@ def testPass(self): '192.0.2.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper", "sendDOQQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) + if method == 'sendDOQQueryWrapper': + # dnspython sets the ID to 0 + receivedResponse.id = response.id self.assertEqual(response, receivedResponse) def testPassCached(self): @@ -133,9 +137,9 @@ def testPassCached(self): '192.0.2.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper", "sendDOQQueryWrapper"): sender = getattr(self, method) - if method != 'sendDOTQueryWrapper' and method != 'sendDOHWithH2OQueryWrapper': + if method != 'sendDOTQueryWrapper' and method != 'sendDOHWithH2OQueryWrapper' and method != 'sendDOQQueryWrapper': # first time to fill the cache # disabled for DoT since it was already filled via TCP (receivedQuery, receivedResponse) = sender(query, response) @@ -146,6 +150,9 @@ def testPassCached(self): # second time from the cache sender = getattr(self, method) (_, receivedResponse) = sender(query, response=None, useQueue=False) + if method == 'sendDOQQueryWrapper': + # dnspython sets the ID to 0 + receivedResponse.id = response.id self.assertEqual(response, receivedResponse) def testTimeoutThenAccept(self): @@ -163,11 +170,14 @@ def testTimeoutThenAccept(self): '192.0.2.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper", "sendDOQQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) + if method == 'sendDOQQueryWrapper': + # dnspython sets the ID to 0 + receivedResponse.id = response.id self.assertEqual(response, receivedResponse) def testAcceptThenTimeout(self): @@ -185,11 +195,14 @@ def testAcceptThenTimeout(self): '192.0.2.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper", "sendDOQQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) + if method == 'sendDOQQueryWrapper': + # dnspython sets the ID to 0 + receivedResponse.id = response.id self.assertEqual(response, receivedResponse) def testAcceptThenRefuse(self): @@ -211,11 +224,14 @@ def testAcceptThenRefuse(self): expectedResponse.flags |= dns.flags.RA expectedResponse.set_rcode(dns.rcode.REFUSED) - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper", "sendDOQQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) + if method == 'sendDOQQueryWrapper': + # dnspython sets the ID to 0 + receivedResponse.id = expectedResponse.id self.assertEqual(expectedResponse, receivedResponse) def testAcceptThenCustom(self): @@ -233,18 +249,20 @@ def testAcceptThenCustom(self): '192.0.2.1') response.answer.append(rrset) - # easier to get the same custom response to everyone, sorry! - expectedQuery = dns.message.make_query('custom.async.tests.powerdns.com.', 'A', 'IN') + expectedQuery = dns.message.make_query(name, 'A', 'IN') expectedQuery.id = query.id expectedResponse = dns.message.make_response(expectedQuery) expectedResponse.flags |= dns.flags.RA expectedResponse.set_rcode(dns.rcode.FORMERR) - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper", "sendDOQQueryWrapper"): sender = getattr(self, method) (receivedQuery, receivedResponse) = sender(query, response) receivedQuery.id = query.id self.assertEqual(query, receivedQuery) + if method == 'sendDOQQueryWrapper': + # dnspython sets the ID to 0 + receivedResponse.id = expectedResponse.id self.assertEqual(expectedResponse, receivedResponse) def testAcceptThenDrop(self): @@ -262,9 +280,14 @@ def testAcceptThenDrop(self): '192.0.2.1') response.answer.append(rrset) - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper", "sendDOQQueryWrapper"): sender = getattr(self, method) - (receivedQuery, receivedResponse) = sender(query, response) + try: + (receivedQuery, receivedResponse) = sender(query, response) + except dns.exception.Timeout: + if not self._fromResponderQueue.empty(): + receivedQuery = self._fromResponderQueue.get(True, 1.0) + receivedResponse = None receivedQuery.id = query.id self.assertEqual(query, receivedQuery) self.assertEqual(receivedResponse, None) @@ -280,10 +303,13 @@ def testRefused(self): expectedResponse.flags |= dns.flags.RA expectedResponse.set_rcode(dns.rcode.REFUSED) - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper", "sendDOQQueryWrapper"): sender = getattr(self, method) (_, receivedResponse) = sender(query, response=None, useQueue=False) self.assertTrue(receivedResponse) + if method == 'sendDOQQueryWrapper': + # dnspython sets the ID to 0 + receivedResponse.id = expectedResponse.id self.assertEqual(expectedResponse, receivedResponse) def testDrop(self): @@ -293,9 +319,12 @@ def testDrop(self): name = 'drop.async.tests.powerdns.com.' query = dns.message.make_query(name, 'A', 'IN') - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper", "sendDOQQueryWrapper"): sender = getattr(self, method) - (_, receivedResponse) = sender(query, response=None, useQueue=False) + try: + (_, receivedResponse) = sender(query, response=None, useQueue=False) + except dns.exception.Timeout: + receivedResponse = None self.assertEqual(receivedResponse, None) def testCustom(self): @@ -309,10 +338,13 @@ def testCustom(self): expectedResponse.flags |= dns.flags.RA expectedResponse.set_rcode(dns.rcode.FORMERR) - for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper"): + for method in ("sendUDPQuery", "sendTCPQuery", "sendDOTQueryWrapper", "sendDOHWithNGHTTP2QueryWrapper", "sendDOHWithH2OQueryWrapper", "sendDOQQueryWrapper"): sender = getattr(self, method) (_, receivedResponse) = sender(query, response=None, useQueue=False) self.assertTrue(receivedResponse) + if method == 'sendDOQQueryWrapper': + # dnspython sets the ID to 0 + receivedResponse.id = expectedResponse.id self.assertEqual(expectedResponse, receivedResponse) def testTruncation(self): @@ -369,6 +401,7 @@ class TestAsyncFFI(DNSDistTest, AsyncTests): addTLSLocal("127.0.0.1:%d", "%s", "%s", { provider="openssl" }) addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="h2o"}) addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="nghttp2"}) + addDOQLocal("127.0.0.1:%d", "%s", "%s") local ffi = require("ffi") local C = ffi.C @@ -380,6 +413,8 @@ class TestAsyncFFI(DNSDistTest, AsyncTests): pc = newPacketCache(100) getPool('cache'):setCache(pc) + local asyncObjectsMap = {} + function gotAsyncResponse(endpointID, message, from) print('Got async response '..message) @@ -390,6 +425,7 @@ class TestAsyncFFI(DNSDistTest, AsyncTests): return end local queryID = tonumber(parts[1]) + local qname = asyncObjectsMap[queryID] if parts[2] == 'accept' then print('accepting') C.dnsdist_ffi_resume_from_async(asyncID, queryID, filteringTagName, #filteringTagName, filteringTagValue, #filteringTagValue, true) @@ -407,7 +443,15 @@ class TestAsyncFFI(DNSDistTest, AsyncTests): end if parts[2] == 'custom' then print('sending a custom response') - local raw = '\\000\\000\\128\\129\\000\\001\\000\\000\\000\\000\\000\\001\\006custom\\005async\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001\\000\\000\\041\\002\\000\\000\\000\\128\\000\\000\\000' + local raw = nil + if qname == string.char(6)..'custom'..string.char(5)..'async'..string.char(5)..'tests'..string.char(8)..'powerdns'..string.char(3)..'com' then + raw = '\\000\\000\\128\\129\\000\\001\\000\\000\\000\\000\\000\\001\\006custom\\005async\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001\\000\\000\\041\\002\\000\\000\\000\\128\\000\\000\\000' + elseif qname == string.char(18)..'accept-then-custom'..string.char(5)..'async'..string.char(5)..'tests'..string.char(8)..'powerdns'..string.char(3)..'com' then + raw = '\\000\\000\\128\\129\\000\\001\\000\\000\\000\\000\\000\\001\\018accept-then-custom\\005async\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001\\000\\000\\041\\002\\000\\000\\000\\128\\000\\000\\000' + elseif qname == string.char(18)..'accept-then-custom'..string.char(8)..'tcp-only'..string.char(5)..'async'..string.char(5)..'tests'..string.char(8)..'powerdns'..string.char(3)..'com' then + raw = '\\000\\000\\128\\129\\000\\001\\000\\000\\000\\000\\000\\001\\018accept-then-custom\\008tcp-only\\005async\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001\\000\\000\\041\\002\\000\\000\\000\\128\\000\\000\\000' + end + C.dnsdist_ffi_set_answer_from_async(asyncID, queryID, raw, #raw) return end @@ -418,6 +462,15 @@ class TestAsyncFFI(DNSDistTest, AsyncTests): listener:addUnixListeningEndpoint('%s', 0, gotAsyncResponse) listener:start() + function getQNameRaw(dq) + local ret_ptr = ffi.new("char *[1]") + local ret_ptr_param = ffi.cast("const char **", ret_ptr) + local ret_size = ffi.new("size_t[1]") + local ret_size_param = ffi.cast("size_t*", ret_size) + C.dnsdist_ffi_dnsquestion_get_qname_raw(dq, ret_ptr_param, ret_size_param) + return ffi.string(ret_ptr[0]) + end + function passQueryToAsyncFilter(dq) print('in passQueryToAsyncFilter') local timeout = 500 -- 500 ms @@ -428,7 +481,9 @@ class TestAsyncFFI(DNSDistTest, AsyncTests): -- we need to take a copy, as we can no longer touch that data after calling set_async local buffer = ffi.string(queryPtr, querySize) - print(C.dnsdist_ffi_dnsquestion_set_async(dq, asyncID, C.dnsdist_ffi_dnsquestion_get_id(dq), timeout)) + asyncObjectsMap[C.dnsdist_ffi_dnsquestion_get_id(dq)] = getQNameRaw(dq) + + C.dnsdist_ffi_dnsquestion_set_async(dq, asyncID, C.dnsdist_ffi_dnsquestion_get_id(dq), timeout) asyncResponderEndpoint:send(buffer) return DNSAction.Allow @@ -444,7 +499,9 @@ class TestAsyncFFI(DNSDistTest, AsyncTests): -- we need to take a copy, as we can no longer touch that data after calling set_async local buffer = ffi.string(responsePtr, responseSize) - print(C.dnsdist_ffi_dnsresponse_set_async(dr, asyncID, C.dnsdist_ffi_dnsquestion_get_id(dr), timeout)) + asyncObjectsMap[C.dnsdist_ffi_dnsquestion_get_id(dr)] = getQNameRaw(dr) + + C.dnsdist_ffi_dnsresponse_set_async(dr, asyncID, C.dnsdist_ffi_dnsquestion_get_id(dr), timeout) asyncResponderEndpoint:send(buffer) return DNSResponseAction.Allow @@ -459,7 +516,7 @@ class TestAsyncFFI(DNSDistTest, AsyncTests): """ _asyncResponderSocketPath = asyncResponderSocketPath _dnsdistSocketPath = dnsdistSocketPath - _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath'] + _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_doqServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath'] _verboseMode = True @unittest.skipIf('SKIP_DOH_TESTS' in os.environ, 'DNS over HTTPS tests are disabled') @@ -471,6 +528,7 @@ class TestAsyncLua(DNSDistTest, AsyncTests): addTLSLocal("127.0.0.1:%d", "%s", "%s", { provider="openssl" }) addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="h2o"}) addDOHLocal("127.0.0.1:%d", "%s", "%s", {"/"}, {library="nghttp2"}) + addDOQLocal("127.0.0.1:%d", "%s", "%s") local filteringTagName = 'filtering' local filteringTagValue = 'pass' @@ -513,8 +571,15 @@ class TestAsyncLua(DNSDistTest, AsyncTests): end if parts[2] == 'custom' then print('sending a custom response') - local raw = '\\000\\000\\128\\129\\000\\001\\000\\000\\000\\000\\000\\001\\006custom\\005async\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001\\000\\000\\041\\002\\000\\000\\000\\128\\000\\000\\000' local dq = asyncObject:getDQ() + local raw + if tostring(dq.qname) == 'custom.async.tests.powerdns.com.' then + raw = '\\000\\000\\128\\129\\000\\001\\000\\000\\000\\000\\000\\001\\006custom\\005async\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001\\000\\000\\041\\002\\000\\000\\000\\128\\000\\000\\000' + elseif tostring(dq.qname) == 'accept-then-custom.async.tests.powerdns.com.' then + raw = '\\000\\000\\128\\129\\000\\001\\000\\000\\000\\000\\000\\001\\018accept-then-custom\\005async\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001\\000\\000\\041\\002\\000\\000\\000\\128\\000\\000\\000' + elseif tostring(dq.qname) == 'accept-then-custom.tcp-only.async.tests.powerdns.com.' then + raw = '\\000\\000\\128\\129\\000\\001\\000\\000\\000\\000\\000\\001\\018accept-then-custom\\008tcp-only\\005async\\005tests\\008powerdns\\003com\\000\\000\\001\\000\\001\\000\\000\\041\\002\\000\\000\\000\\128\\000\\000\\000' + end dq:setContent(raw) asyncObject:resume() return @@ -559,5 +624,5 @@ class TestAsyncLua(DNSDistTest, AsyncTests): """ _asyncResponderSocketPath = asyncResponderSocketPath _dnsdistSocketPath = dnsdistSocketPath - _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath'] + _config_params = ['_testServerPort', '_testServerPort', '_tlsServerPort', '_serverCert', '_serverKey', '_dohWithH2OServerPort', '_serverCert', '_serverKey', '_dohWithNGHTTP2ServerPort', '_serverCert', '_serverKey', '_doqServerPort', '_serverCert', '_serverKey', '_asyncResponderSocketPath', '_dnsdistSocketPath'] _verboseMode = True diff --git a/regression-tests.dnsdist/test_DOQ.py b/regression-tests.dnsdist/test_DOQ.py index 6f1635905fe3..5c5aaae1b641 100644 --- a/regression-tests.dnsdist/test_DOQ.py +++ b/regression-tests.dnsdist/test_DOQ.py @@ -8,7 +8,7 @@ class TestDOQ(DNSDistTest): _serverKey = 'server.key' _serverCert = 'server.chain' - _serverName = '127.0.0.1' + _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' _doqServerPort = pickAvailablePort() _config_template = """ @@ -40,7 +40,7 @@ def testDOQSimple(self): dns.rdatatype.A, '127.0.0.1') response.answer.append(rrset) - (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=response, caFile=self._caCert) + (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=response, caFile=self._caCert, serverName=self._serverName) self.assertTrue(receivedQuery) self.assertTrue(receivedResponse) receivedQuery.id = expectedQuery.id @@ -64,15 +64,15 @@ def testDOQMultipleStreams(self): '127.0.0.1') response.answer.append(rrset) - connection = self.getDOQConnection(self._doqServerPort, self._serverName, self._caCert) + connection = self.getDOQConnection(self._doqServerPort, self._caCert) - (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=response, connection=connection) + (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=response, caFile=self._caCert, serverName=self._serverName, connection=connection) self.assertTrue(receivedQuery) self.assertTrue(receivedResponse) receivedQuery.id = expectedQuery.id self.assertEqual(expectedQuery, receivedQuery) - (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=response, connection=connection) + (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=response, caFile=self._caCert, serverName=self._serverName, connection=connection) self.assertTrue(receivedQuery) self.assertTrue(receivedResponse) receivedQuery.id = expectedQuery.id @@ -86,7 +86,7 @@ def testDropped(self): query = dns.message.make_query(name, 'A', 'IN') dropped = False try: - (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) + (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=None, caFile=self._caCert, useQueue=False, serverName=self._serverName) # dns.quic doesn't seem to report correctly the quic error so the connection timeout except dns.exception.Timeout : dropped = True @@ -103,7 +103,7 @@ def testRefused(self): expectedResponse = dns.message.make_response(query) expectedResponse.set_rcode(dns.rcode.REFUSED) - (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) + (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=None, caFile=self._caCert, useQueue=False, serverName=self._serverName) self.assertEqual(receivedResponse, expectedResponse) def testSpoof(self): @@ -122,7 +122,7 @@ def testSpoof(self): '1.2.3.4') expectedResponse.answer.append(rrset) - (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) + (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=None, caFile=self._caCert, useQueue=False, serverName=self._serverName) self.assertEqual(receivedResponse, expectedResponse) def testDOQNoBackend(self): @@ -133,7 +133,7 @@ def testDOQNoBackend(self): query = dns.message.make_query(name, 'A', 'IN', use_edns=False) dropped = False try: - (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) + (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=None, caFile=self._caCert, useQueue=False, serverName=self._serverName) except dns.exception.Timeout : dropped = True self.assertTrue(dropped) @@ -142,7 +142,7 @@ def testDOQNoBackend(self): class TestDOQWithCache(DNSDistTest): _serverKey = 'server.key' _serverCert = 'server.chain' - _serverName = '127.0.0.1' + _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' _doqServerPort = 8853 _config_template = """ @@ -177,7 +177,7 @@ def testCached(self): response.answer.append(rrset) # first query to fill the cache - (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=response, caFile=self._caCert) + (receivedQuery, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=response, caFile=self._caCert, serverName=self._serverName) self.assertTrue(receivedQuery) self.assertTrue(receivedResponse) receivedQuery.id = query.id @@ -185,7 +185,7 @@ def testCached(self): self.assertEqual(receivedResponse, response) for _ in range(numberOfQueries): - (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, self._serverName, query, response=None, caFile=self._caCert, useQueue=False) + (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=None, caFile=self._caCert, useQueue=False, serverName=self._serverName) self.assertEqual(receivedResponse, response) total = 0 From 1cba32b066297d27f64dc1075434f70762346baf Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 25 Sep 2023 12:09:19 +0200 Subject: [PATCH 832/909] dnsdist: Add an option to log DoQ TLS keying material to a file --- pdns/dnsdist-lua.cc | 1 + pdns/dnsdistdist/docs/reference/config.rst | 3 ++- pdns/dnsdistdist/doq.cc | 14 +++++++++++--- pdns/dnsdistdist/doq.hh | 4 +++- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 2c794ec9b55f..0edf61947b05 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2515,6 +2515,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) } getOptionalValue(vars, "internalPipeBufferSize", frontend->d_internalPipeBufferSize); getOptionalValue(vars, "idleTimeout", frontend->d_idleTimeout); + getOptionalValue(vars, "keyLogFile", frontend->d_keyLogFile); { std::string valueStr; if (getOptionalValue(vars, "congestionControlAlgo", valueStr) > 0) { diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 354f477f00d0..2a68f20e5e12 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -191,7 +191,8 @@ Listen Sockets * ``idleTimeout=5``: int - Set the idle timeout, in seconds. * ``internalPipeBufferSize=0``: int - Set the size in bytes of the internal buffer of the pipes used internally to pass queries and responses between threads. Requires support for ``F_SETPIPE_SZ`` which is present in Linux since 2.6.35. The actual size might be rounded up to a multiple of a page size. 0 means that the OS default size is used. The default value is 0, except on Linux where it is 1048576 since 1.6.0. * ``maxInFlight=0``: int - Maximum number of in-flight queries. The default is 0, which disables out-of-order processing. - * ``congestionControlAlgo="reno"``: str - The congestion control algorithm to be chosen between ``reno``, ``cubic`` and ``bbr`` + * ``congestionControlAlgo="reno"``: str - The congestion control algorithm to be chosen between ``reno``, ``cubic`` and ``bbr``. + * ``keyLogFile``: str - Write the TLS keys in the specified file so that an external program can decrypt TLS exchanges, in the format described in https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. .. function:: addTLSLocal(address, certFile(s), keyFile(s) [, options]) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index ed1548ce7a74..2a16a052a298 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -327,6 +327,9 @@ void DOQFrontend::setup() // The number of total bytes of incoming stream data to be buffered for the whole connection // https://docs.rs/quiche/latest/quiche/struct.Config.html#method.set_initial_max_data quiche_config_set_initial_max_data(config.get(), 8192 * d_maxInFlight); + if (!d_keyLogFile.empty()) { + quiche_config_log_keys(config.get()); + } auto algo = DOQFrontend::s_available_cc_algorithms.find(d_ccAlgo); if (algo != DOQFrontend::s_available_cc_algorithms.end()) { @@ -482,7 +485,7 @@ static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description) } } -static std::optional> createConnection(QuicheConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const PacketBuffer& token, const ComboAddress& local, const ComboAddress& peer) +static std::optional> createConnection(const DOQServerConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const PacketBuffer& token, const ComboAddress& local, const ComboAddress& peer) { auto quicheConn = QuicheConnection(quiche_accept(serverSideID.data(), serverSideID.size(), originalDestinationID.data(), originalDestinationID.size(), @@ -490,8 +493,13 @@ static std::optional> createConnection(Quiche local.getSocklen(), (struct sockaddr*)&peer, peer.getSocklen(), - config.get()), + config.config.get()), quiche_conn_free); + + if (config.df && !config.df->d_keyLogFile.empty()) { + quiche_conn_set_keylog_path(quicheConn.get(), config.df->d_keyLogFile.c_str()); + } + auto conn = Connection(peer, std::move(quicheConn)); auto pair = s_connections.emplace(serverSideID, std::move(conn)); return pair.first->second; @@ -809,7 +817,7 @@ void doqThread(ClientState* cs) } DEBUGLOG("Creating a new connection"); - conn = createConnection(frontend->d_server_config->config, serverConnID, *originalDestinationID, tokenBuf, cs->local, client); + conn = createConnection(*frontend->d_server_config, serverConnID, *originalDestinationID, tokenBuf, cs->local, client); if (!conn) { continue; } diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 9d318c9aacfe..70c69d324f67 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -45,11 +45,13 @@ struct DOQFrontend DOQFrontend& operator=(DOQFrontend&&) = delete; ~DOQFrontend(); + void setup(); + std::unique_ptr d_server_config{nullptr}; TLSConfig d_tlsConfig; ComboAddress d_local; + std::string d_keyLogFile; - void setup(); #ifdef __linux__ // On Linux this gives us 128k pending queries (default is 8192 queries), // which should be enough to deal with huge spikes From 6c66428a6e2f517f8a769d8acb0bf6da69579df7 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 25 Sep 2023 15:37:39 +0200 Subject: [PATCH 833/909] dnsdist: Better handling of short reads/writes in DoQ --- pdns/dnsdistdist/doq.cc | 72 +++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 20 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 2a16a052a298..cdb12919c025 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -64,6 +64,7 @@ class Connection ComboAddress d_peer; QuicheConnection d_conn; + std::unordered_map d_streamBuffers; }; static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description); @@ -261,19 +262,46 @@ class DOQCrossProtocolQuery : public CrossProtocolQuery std::shared_ptr DOQCrossProtocolQuery::s_sender = std::make_shared(); +/* from rfc9250 section-4.3 */ +enum class DOQ_Error_Codes : uint64_t { + DOQ_NO_ERROR = 0, + DOQ_INTERNAL_ERROR = 1, + DOQ_PROTOCOL_ERROR = 2, + DOQ_REQUEST_CANCELLED = 3, + DOQ_EXCESSIVE_LOAD = 4, + DOQ_UNSPECIFIED_ERROR = 5 +}; + static void handleResponse(DOQFrontend& df, Connection& conn, const uint64_t streamID, const PacketBuffer& response) { if (response.size() == 0) { - quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, 0x5); + quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_UNSPECIFIED_ERROR)); + return; } - else { - uint16_t responseSize = static_cast(response.size()); - const uint8_t sizeBytes[] = {static_cast(responseSize / 256), static_cast(responseSize % 256)}; - auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, sizeBytes, sizeof(sizeBytes), false); - if (res == sizeof(sizeBytes)) { - res = quiche_conn_stream_send(conn.d_conn.get(), streamID, response.data(), response.size(), true); + + uint16_t responseSize = static_cast(response.size()); + const std::array sizeBytes = {static_cast(responseSize / 256), static_cast(responseSize % 256)}; + size_t pos = 0; + do { + auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, sizeBytes.data() + pos, sizeBytes.size() - pos, false); + if (res < 0) { + quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_INTERNAL_ERROR)); + return; } + pos += res; } + while (pos < sizeBytes.size()); + + pos = 0; + do { + auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, response.data() + pos, response.size() - pos, true); + if (res < 0) { + quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_INTERNAL_ERROR)); + return; + } + pos += res; + } + while (pos < response.size()); } static void fillRandom(PacketBuffer& buffer, size_t size) @@ -755,7 +783,7 @@ void doqThread(ClientState* cs) Socket sock(cs->udpFD); - PacketBuffer buffer(std::numeric_limits::max()); + PacketBuffer buffer(std::numeric_limits::max()); auto mplexer = std::unique_ptr(FDMultiplexer::getMultiplexerSilent()); auto responseReceiverFD = frontend->d_server_config->d_responseReceiver.getDescriptor(); @@ -840,29 +868,33 @@ void doqThread(ClientState* cs) uint64_t streamID = 0; while (quiche_stream_iter_next(readable.get(), &streamID)) { + auto& streamBuffer = conn->get().d_streamBuffers[streamID]; + auto existingLength = streamBuffer.size(); bool fin = false; - buffer.resize(std::numeric_limits::max()); + streamBuffer.resize(existingLength + 512); auto received = quiche_conn_stream_recv(conn->get().d_conn.get(), streamID, - buffer.data(), buffer.size(), + &streamBuffer.at(existingLength), 512, &fin); - if (received < 2) { - break; - } - buffer.resize(received); - + streamBuffer.resize(existingLength + received); if (fin) { - // we skip message length, should we verify ? - buffer.erase(buffer.begin(), buffer.begin() + 2); - if (buffer.size() >= sizeof(dnsheader)) { - doq_dispatch_query(*(frontend->d_server_config), std::move(buffer), cs->local, client, serverConnID, streamID); + if (streamBuffer.size() < (sizeof(dnsheader) + sizeof(uint16_t))) { + quiche_conn_stream_shutdown(conn->get().d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_PROTOCOL_ERROR)); + break; + } + uint16_t payloadLength = streamBuffer.at(0) * 256 + streamBuffer.at(1); + streamBuffer.erase(streamBuffer.begin(), streamBuffer.begin() + 2); + if (payloadLength != streamBuffer.size()) { + quiche_conn_stream_shutdown(conn->get().d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_PROTOCOL_ERROR)); + break; } + doq_dispatch_query(*(frontend->d_server_config), std::move(streamBuffer), cs->local, client, serverConnID, streamID); + conn->get().d_streamBuffers.erase(streamID); } } } else { DEBUGLOG("Connection not established"); } - // } } if (std::find(readyFDs.begin(), readyFDs.end(), responseReceiverFD) != readyFDs.end()) { From 57f9592c977e0019405a3a1c7fe3513accd2bdef Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 25 Sep 2023 15:40:18 +0200 Subject: [PATCH 834/909] dnsdist: Fix code formatting --- pdns/dnsdistdist/doq.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index cdb12919c025..8e6c3d60ef3d 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -263,7 +263,8 @@ class DOQCrossProtocolQuery : public CrossProtocolQuery std::shared_ptr DOQCrossProtocolQuery::s_sender = std::make_shared(); /* from rfc9250 section-4.3 */ -enum class DOQ_Error_Codes : uint64_t { +enum class DOQ_Error_Codes : uint64_t +{ DOQ_NO_ERROR = 0, DOQ_INTERNAL_ERROR = 1, DOQ_PROTOCOL_ERROR = 2, @@ -289,8 +290,7 @@ static void handleResponse(DOQFrontend& df, Connection& conn, const uint64_t str return; } pos += res; - } - while (pos < sizeBytes.size()); + } while (pos < sizeBytes.size()); pos = 0; do { @@ -300,8 +300,7 @@ static void handleResponse(DOQFrontend& df, Connection& conn, const uint64_t str return; } pos += res; - } - while (pos < response.size()); + } while (pos < response.size()); } static void fillRandom(PacketBuffer& buffer, size_t size) From ec9548d75f733a5763c6af2c380e98cf669644df Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Tue, 26 Sep 2023 10:38:43 +0200 Subject: [PATCH 835/909] doq: rename variable, and update non compliant queries stats --- pdns/dnsdistdist/doq.cc | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 8e6c3d60ef3d..f58c6de940b8 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -87,7 +87,7 @@ struct DOQServerConfig LocalHolders holders; QuicheConfig config; - ClientState* cs{nullptr}; + ClientState* clientState{nullptr}; std::shared_ptr df{nullptr}; pdns::channel::Sender d_responseSender; pdns::channel::Receiver d_responseReceiver; @@ -602,11 +602,11 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit) remote = du->ids.origRemote; DOQServerConfig* dsc = du->dsc; auto& holders = dsc->holders; - ClientState& cs = *dsc->cs; + ClientState& clientState = *dsc->clientState; if (du->query.size() < sizeof(dnsheader)) { ++dnsdist::metrics::g_stats.nonCompliantQueries; - ++cs.nonCompliantQueries; + ++clientState.nonCompliantQueries; struct dnsheader* dh = reinterpret_cast(du->query.data()); dh->rcode = RCode::ServFail; dh->qr = true; @@ -616,7 +616,7 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit) return; } - ++cs.queries; + ++clientState.queries; ++dnsdist::metrics::g_stats.queries; du->ids.queryRealTime.start(); @@ -624,7 +624,7 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit) /* don't keep that pointer around, it will be invalidated if the buffer is ever resized */ struct dnsheader* dh = reinterpret_cast(du->query.data()); - if (!checkQueryHeaders(dh, cs)) { + if (!checkQueryHeaders(dh, clientState)) { dh->rcode = RCode::ServFail; dh->qr = true; du->response = std::move(du->query); @@ -650,7 +650,7 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit) DNSQuestion dq(du->ids, du->query); const uint16_t* flags = getFlagsFromDNSHeader(dq.getHeader()); ids.origFlags = *flags; - du->ids.cs = &cs; + du->ids.cs = &clientState; auto result = processQuery(dq, holders, downstream); if (result == ProcessQueryResult::Drop) { @@ -770,17 +770,17 @@ static void flushResponses(pdns::channel::Receiver& receiver) } // this is the entrypoint from dnsdist.cc -void doqThread(ClientState* cs) +void doqThread(ClientState* clientState) { try { - std::shared_ptr& frontend = cs->doqFrontend; + std::shared_ptr& frontend = clientState->doqFrontend; - frontend->d_server_config->cs = cs; - frontend->d_server_config->df = cs->doqFrontend; + frontend->d_server_config->clientState = clientState; + frontend->d_server_config->df = clientState->doqFrontend; setThreadName("dnsdist/doq"); - Socket sock(cs->udpFD); + Socket sock(clientState->udpFD); PacketBuffer buffer(std::numeric_limits::max()); auto mplexer = std::unique_ptr(FDMultiplexer::getMultiplexerSilent()); @@ -844,7 +844,7 @@ void doqThread(ClientState* cs) } DEBUGLOG("Creating a new connection"); - conn = createConnection(*frontend->d_server_config, serverConnID, *originalDestinationID, tokenBuf, cs->local, client); + conn = createConnection(*frontend->d_server_config, serverConnID, *originalDestinationID, tokenBuf, clientState->local, client); if (!conn) { continue; } @@ -853,8 +853,8 @@ void doqThread(ClientState* cs) (struct sockaddr*)&client, client.getSocklen(), - (struct sockaddr*)&cs->local, - cs->local.getSocklen(), + (struct sockaddr*)&clientState->local, + clientState->local.getSocklen(), }; auto done = quiche_conn_recv(conn->get().d_conn.get(), reinterpret_cast(bufferStr.data()), bufferStr.size(), &recv_info); @@ -876,17 +876,21 @@ void doqThread(ClientState* cs) &fin); streamBuffer.resize(existingLength + received); if (fin) { - if (streamBuffer.size() < (sizeof(dnsheader) + sizeof(uint16_t))) { + if (streamBuffer.size() < (sizeof(uint16_t) + sizeof(dnsheader))) { + ++dnsdist::metrics::g_stats.nonCompliantQueries; + ++clientState->nonCompliantQueries; quiche_conn_stream_shutdown(conn->get().d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_PROTOCOL_ERROR)); break; } uint16_t payloadLength = streamBuffer.at(0) * 256 + streamBuffer.at(1); streamBuffer.erase(streamBuffer.begin(), streamBuffer.begin() + 2); if (payloadLength != streamBuffer.size()) { + ++dnsdist::metrics::g_stats.nonCompliantQueries; + ++clientState->nonCompliantQueries; quiche_conn_stream_shutdown(conn->get().d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_PROTOCOL_ERROR)); break; } - doq_dispatch_query(*(frontend->d_server_config), std::move(streamBuffer), cs->local, client, serverConnID, streamID); + doq_dispatch_query(*(frontend->d_server_config), std::move(streamBuffer), clientState->local, client, serverConnID, streamID); conn->get().d_streamBuffers.erase(streamID); } } From f089d71cee8001beff03d71ccfd278eb57bbd783 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Tue, 26 Sep 2023 10:39:27 +0200 Subject: [PATCH 836/909] doq: add doq-responses-pipe-full metric --- pdns/dnsdistdist/dnsdist-metrics.cc | 1 + pdns/dnsdistdist/dnsdist-metrics.hh | 1 + pdns/dnsdistdist/doq.cc | 1 + regression-tests.dnsdist/test_API.py | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/dnsdist-metrics.cc b/pdns/dnsdistdist/dnsdist-metrics.cc index 268778aef23a..6497a455d338 100644 --- a/pdns/dnsdistdist/dnsdist-metrics.cc +++ b/pdns/dnsdistdist/dnsdist-metrics.cc @@ -141,6 +141,7 @@ Stats::Stats() : {"security-status", &securityStatus}, {"doh-query-pipe-full", &dohQueryPipeFull}, {"doh-response-pipe-full", &dohResponsePipeFull}, + {"doq-response-pipe-full", &doqResponsePipeFull}, {"outgoing-doh-query-pipe-full", &outgoingDoHQueryPipeFull}, {"tcp-query-pipe-full", &tcpQueryPipeFull}, {"tcp-cross-protocol-query-pipe-full", &tcpCrossProtocolQueryPipeFull}, diff --git a/pdns/dnsdistdist/dnsdist-metrics.hh b/pdns/dnsdistdist/dnsdist-metrics.hh index b14cb804ef30..37e75d1865a8 100644 --- a/pdns/dnsdistdist/dnsdist-metrics.hh +++ b/pdns/dnsdistdist/dnsdist-metrics.hh @@ -74,6 +74,7 @@ struct Stats stat_t securityStatus{0}; stat_t dohQueryPipeFull{0}; stat_t dohResponsePipeFull{0}; + stat_t doqResponsePipeFull{0}; stat_t outgoingDoHQueryPipeFull{0}; stat_t proxyProtocolInvalid{0}; stat_t tcpQueryPipeFull{0}; diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index f58c6de940b8..06a432a9dabb 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -504,6 +504,7 @@ static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description) } try { if (!du->dsc->d_responseSender.send(std::move(du))) { + ++dnsdist::metrics::g_stats.doqResponsePipeFull; vinfolog("Unable to pass a %s to the DoQ worker thread because the pipe is full", description); } } diff --git a/regression-tests.dnsdist/test_API.py b/regression-tests.dnsdist/test_API.py index c89322569dc8..d36da2e76e46 100644 --- a/regression-tests.dnsdist/test_API.py +++ b/regression-tests.dnsdist/test_API.py @@ -38,7 +38,7 @@ class APITestsBase(DNSDistTest): 'dyn-block-nmg-size', 'rule-servfail', 'rule-truncated', 'security-status', 'udp-in-csum-errors', 'udp-in-errors', 'udp-noport-errors', 'udp-recvbuf-errors', 'udp-sndbuf-errors', 'udp6-in-errors', 'udp6-recvbuf-errors', 'udp6-sndbuf-errors', 'udp6-noport-errors', 'udp6-in-csum-errors', - 'doh-query-pipe-full', 'doh-response-pipe-full', 'proxy-protocol-invalid', 'tcp-listen-overflows', + 'doh-query-pipe-full', 'doh-response-pipe-full', 'doq-response-pipe-full', 'proxy-protocol-invalid', 'tcp-listen-overflows', 'outgoing-doh-query-pipe-full', 'tcp-query-pipe-full', 'tcp-cross-protocol-query-pipe-full', 'tcp-cross-protocol-response-pipe-full'] _verboseMode = True From df9cb7f3261bd3c340c0526ee6ca82abd0e2759d Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Tue, 26 Sep 2023 11:21:49 +0200 Subject: [PATCH 837/909] doq: add valid/error responses counter and two doq protocol related error counters --- pdns/dnsdist-lua.cc | 6 +++--- pdns/dnsdistdist/doq.cc | 5 ++++- pdns/dnsdistdist/doq.hh | 6 ++++++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 0edf61947b05..22debccbaec9 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2561,11 +2561,11 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) setLuaNoSideEffect(); try { ostringstream ret; - boost::format fmt("%-3d %-20.20s"); - ret << (fmt % "#" % "Address") << endl; + boost::format fmt("%-3d %-20.20s %-15d %-15d %-15d %-15d"); + ret << (fmt % "#" % "Address" % "Bad Version" % "Invalid Token" % "Errors" % "Valid") << endl; size_t counter = 0; for (const auto& ctx : g_doqlocals) { - ret << (fmt % counter % ctx->d_local.toStringWithPort()) << endl; + ret << (fmt % counter % ctx->d_local.toStringWithPort() % ctx->d_doqUnsupportedVersionErrors % ctx->d_doqInvalidTokensReceived % ctx->d_errorResponses % ctx->d_validResponses) << endl; counter++; } g_outputBuffer = ret.str(); diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 06a432a9dabb..8786c55d0f4d 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -276,10 +276,11 @@ enum class DOQ_Error_Codes : uint64_t static void handleResponse(DOQFrontend& df, Connection& conn, const uint64_t streamID, const PacketBuffer& response) { if (response.size() == 0) { + ++df.d_errorResponses; quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_UNSPECIFIED_ERROR)); return; } - + ++df.d_validResponses; uint16_t responseSize = static_cast(response.size()); const std::array sizeBytes = {static_cast(responseSize / 256), static_cast(responseSize % 256)}; size_t pos = 0; @@ -826,6 +827,7 @@ void doqThread(ClientState* clientState) DEBUGLOG("Connection not found"); if (!quiche_version_is_supported(version)) { DEBUGLOG("Unsupported version"); + ++frontend->d_doqUnsupportedVersionErrors; handleVersionNegociation(sock, clientConnID, serverConnID, client); continue; } @@ -840,6 +842,7 @@ void doqThread(ClientState* clientState) PacketBuffer tokenBuf(token.begin(), token.begin() + token_len); auto originalDestinationID = validateToken(tokenBuf, serverConnID, client); if (!originalDestinationID) { + ++frontend->d_doqInvalidTokensReceived; DEBUGLOG("Discarding invalid token"); continue; } diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 70c69d324f67..064838a7bced 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -62,6 +62,12 @@ struct DOQFrontend uint64_t d_idleTimeout{5}; uint64_t d_maxInFlight{65535}; std::string d_ccAlgo{"reno"}; + + pdns::stat_t d_doqUnsupportedVersionErrors{0}; // Unsupported protocol version errors + pdns::stat_t d_doqInvalidTokensReceived{0}; // Discarded received tokens + pdns::stat_t d_validResponses{0}; // Valid responses sent + pdns::stat_t d_errorResponses{0}; // Empty responses (no backend, drops, invalid queries, etc.) + static std::map s_available_cc_algorithms; }; From c64f6dd31459b4235d1aaea57d68f66cc91b87ee Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Tue, 26 Sep 2023 11:59:32 +0200 Subject: [PATCH 838/909] doq: add a bit of documentation and display DoQ support in version() if enabled --- pdns/dnsdist.cc | 3 +++ .../dnsdistdist/docs/guides/dns-over-quic.rst | 23 +++++++++++++++++++ pdns/dnsdistdist/docs/guides/index.rst | 1 + pdns/dnsdistdist/docs/install.rst | 1 + 4 files changed, 28 insertions(+) create mode 100644 pdns/dnsdistdist/docs/guides/dns-over-quic.rst diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index d2b7759968b3..1276f09df4cb 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -2572,6 +2572,9 @@ int main(int argc, char** argv) #ifdef HAVE_CDB cout<<"cdb "; #endif +#ifdef HAVE_DNS_OVER_QUIC + cout<<"dns-over-quic "; +#endif #ifdef HAVE_DNS_OVER_TLS cout<<"dns-over-tls("; #ifdef HAVE_GNUTLS diff --git a/pdns/dnsdistdist/docs/guides/dns-over-quic.rst b/pdns/dnsdistdist/docs/guides/dns-over-quic.rst new file mode 100644 index 000000000000..48fb22dc4e5f --- /dev/null +++ b/pdns/dnsdistdist/docs/guides/dns-over-quic.rst @@ -0,0 +1,23 @@ +DNS-over-QUIC (DoQ) +==================== + +:program:`dnsdist` supports DNS-over-QUIC (DoQ, standardized in RFC 9250) for incoming queries since 1.9.0. +To see if the installation supports this, run ``dnsdist --version``. +If the output shows ``dns-over-quic`` incoming DNS-over-QUIC is supported. + +Incoming +-------- + +Adding a listen port for DNS-over-QUIC can be done with the :func:`addDOQLocal` function, e.g.:: + + addDOQLocal('2001:db8:1:f00::1', '/etc/ssl/certs/example.com.pem', '/etc/ssl/private/example.com.key') + +This will make :program:`dnsdist` listen on [2001:db8:1:f00::1]:853 on UDP, and will use the provided certificate and key to serve incoming TLS connections. + +The fourth parameter, if present, indicates various options. For instance, you can change the congestion control algorithm used. An example is:: + + addDOQLocal('2001:db8:1:f00::1', '/etc/ssl/certs/example.com.pem', '/etc/ssl/private/example.com.key', {congestionControlAlgo="bbr"}) + +A particular attention should be taken to the permissions of the certificate and key files. Many ACME clients used to get and renew certificates, like CertBot, set permissions assuming that services are started as root, which is no longer true for dnsdist as of 1.5.0. For that particular case, making a copy of the necessary files in the /etc/dnsdist directory is advised, using for example CertBot's ``--deploy-hook`` feature to copy the files with the right permissions after a renewal. + +More information about sessions management can also be found in :doc:`../advanced/tls-sessions-management`. diff --git a/pdns/dnsdistdist/docs/guides/index.rst b/pdns/dnsdistdist/docs/guides/index.rst index 7a4f5761a95a..b5b6830508bc 100644 --- a/pdns/dnsdistdist/docs/guides/index.rst +++ b/pdns/dnsdistdist/docs/guides/index.rst @@ -14,6 +14,7 @@ These chapters contain several guides and nuggets of information regarding dnsdi serverselection carbon dns-over-https + dns-over-quic dns-over-tls dnscrypt diff --git a/pdns/dnsdistdist/docs/install.rst b/pdns/dnsdistdist/docs/install.rst index 9d24c03dcbef..5c87e2bbf5c3 100644 --- a/pdns/dnsdistdist/docs/install.rst +++ b/pdns/dnsdistdist/docs/install.rst @@ -58,6 +58,7 @@ dnsdist depends on the following libraries: * `nghttp2 `_ (optional, outgoing DoH support) * `OpenSSL `_ (optional, DoT and DoH support) * `protobuf `_ (optional, not needed as of 1.6.0) +* `quiche `_ (optional, incoming DoQ support) * `re2 `_ (optional) * `TinyCDB ` (optional, CDB support) From db2064457cad579002f6efb4114baf91c005641e Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 27 Sep 2023 11:39:57 +0200 Subject: [PATCH 839/909] builder-support: Build dnsdist with Quiche for DNS over QUIC support Except on el-7 where the `clang` version needed to build the `boring-sys`crate for `Quiche` is too old. --- .../debian/dnsdist/debian-buster/copyright | 24 +++++++++++++++ .../debian/dnsdist/debian-buster/rules | 5 +++- .../dockerfiles/Dockerfile.debbuild-prepare | 6 ++++ .../dockerfiles/Dockerfile.rpmbuild | 10 +++++++ builder-support/helpers/install_quiche.sh | 30 +++++++++++++++++++ builder-support/specs/dnsdist.spec | 24 ++++++++++----- 6 files changed, 91 insertions(+), 8 deletions(-) create mode 100755 builder-support/helpers/install_quiche.sh diff --git a/builder-support/debian/dnsdist/debian-buster/copyright b/builder-support/debian/dnsdist/debian-buster/copyright index 761250f2bf67..5fbb60206907 100644 --- a/builder-support/debian/dnsdist/debian-buster/copyright +++ b/builder-support/debian/dnsdist/debian-buster/copyright @@ -77,6 +77,10 @@ Files: src_js/rickshaw.js Copyright: 2011-2014 by Shutterstock Images, LLC License: Expat +Files: */libdnsdist-quiche.so +Copyright: 2018-2019, Cloudflare, Inc. +License: BSD-2-clause + License: Unlicense This is free and unencumbered software released into the public domain. . @@ -144,6 +148,26 @@ License: Expat OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +License: BSD-2-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + License: BSD-3 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/builder-support/debian/dnsdist/debian-buster/rules b/builder-support/debian/dnsdist/debian-buster/rules index e9a2a8cf1a36..6f96e2697879 100755 --- a/builder-support/debian/dnsdist/debian-buster/rules +++ b/builder-support/debian/dnsdist/debian-buster/rules @@ -49,16 +49,18 @@ override_dh_auto_configure: --libexecdir='$${prefix}/lib' \ --enable-lto=thin \ --enable-dns-over-https \ + --enable-dns-over-quic \ --enable-dns-over-tls \ --enable-dnscrypt \ --enable-dnstap \ + --with-ebpf \ --with-gnutls \ --with-h2o \ --with-net-snmp \ --with-libcap \ --with-libsodium \ + --with-quiche \ --with-re2 \ - --with-ebpf \ --with-service-user='_dnsdist' \ --with-service-group='_dnsdist' \ $(CONFIGURE_ARGS) @@ -68,6 +70,7 @@ override_dh_auto_build-arch: override_dh_install: dh_auto_install + install -Dm644 /usr/lib/libdnsdist-quiche.so debian/dnsdist/usr/lib/libdnsdist-quiche.so ifeq ($(DEB_HOST_ARCH_BITS),32) echo RestrictAddressFamilies is broken on 32bit, removing it from service file perl -ni -e 'print unless /RestrictAddressFamilies/' debian/dnsdist/lib/systemd/system/*.service diff --git a/builder-support/dockerfiles/Dockerfile.debbuild-prepare b/builder-support/dockerfiles/Dockerfile.debbuild-prepare index bf86ab18bd36..64a5d401c5cf 100644 --- a/builder-support/dockerfiles/Dockerfile.debbuild-prepare +++ b/builder-support/dockerfiles/Dockerfile.debbuild-prepare @@ -12,6 +12,12 @@ ADD builder-support/helpers/ /pdns/builder-support/helpers/ RUN /pdns/builder-support/helpers/install_rust.sh @ENDIF +@IF [ -n "$M_dnsdist$M_all" ] +RUN /pdns/builder-support/helpers/install_rust.sh +RUN DEBIAN_FRONTEND=noninteractive apt-get -y install --no-install-recommends git cmake clang +RUN /pdns/builder-support/helpers/install_quiche.sh +@ENDIF + # Used for -p option to only build specific packages ARG BUILDER_PACKAGE_MATCH diff --git a/builder-support/dockerfiles/Dockerfile.rpmbuild b/builder-support/dockerfiles/Dockerfile.rpmbuild index 82334e51f1d2..9ec0f3c4ed3a 100644 --- a/builder-support/dockerfiles/Dockerfile.rpmbuild +++ b/builder-support/dockerfiles/Dockerfile.rpmbuild @@ -19,6 +19,16 @@ ADD builder-support/helpers/ /pdns/builder-support/helpers/ RUN /pdns/builder-support/helpers/install_rust.sh @ENDIF +@IF [ -n "$M_dnsdist$M_all" ] +RUN /pdns/builder-support/helpers/install_rust.sh +# We do not build Quiche (DNS over QUIC support) on el-7 because the clang +# version is too old to build the 'boring-sys' crate needed by Quiche +RUN if ! $(grep -q 'release 7' /etc/redhat-release); then \ + yum install -y git cmake clang; \ + /pdns/builder-support/helpers/install_quiche.sh; \ + fi +@ENDIF + # Used for -p option to only build specific spec files ARG BUILDER_PACKAGE_MATCH diff --git a/builder-support/helpers/install_quiche.sh b/builder-support/helpers/install_quiche.sh new file mode 100755 index 000000000000..1c0b55928380 --- /dev/null +++ b/builder-support/helpers/install_quiche.sh @@ -0,0 +1,30 @@ +#!/bin/sh +set -v +set -e + +readonly QUICHE_VERSION='0.18.0' +readonly QUICHE_TARBALL="${QUICHE_VERSION}.tar.gz" +readonly QUICHE_TARBALL_URL="https://github.com/cloudflare/quiche/archive/${QUICHE_TARBALL}" +readonly QUICHE_TARBALL_HASH='eb242a14c4d801a90b57b6021dd29f7a62099f3a4d7a7ba889e105f8328e6c1f' + +cd /tmp +echo $0: Downloading $QUICHE_TARBALL +curl -L -o "${QUICHE_TARBALL}" "${QUICHE_TARBALL_URL}" +# Line below should echo two spaces between digest and name +echo "${QUICHE_TARBALL_HASH}" "${QUICHE_TARBALL}" | sha256sum -c - +tar xf "${QUICHE_TARBALL}" +cd "quiche-${QUICHE_VERSION}" +RUST_BACKTRACE=1 cargo build --release --no-default-features --features ffi,boringssl-boring-crate --package quiche +install -Dm644 quiche/include/quiche.h /usr/include +install -Dm644 target/release/libquiche.so /usr/lib/libdnsdist-quiche.so +install -Dm644 /dev/stdin /usr/lib/pkgconfig/quiche.pc <= 7 - --with-gnutls \ - --enable-dnstap \ - --with-lua=%{lua_implementation} \ - --with-libcap \ - --with-libsodium \ --enable-dnscrypt \ + --enable-dnstap \ --enable-dns-over-https \ --enable-systemd --with-systemd=%{_unitdir} \ - --with-re2 \ + --with-gnutls \ + --with-libcap \ + --with-libsodium \ + --with-lua=%{lua_implementation} \ --with-net-snmp \ - PKG_CONFIG_PATH=/opt/lib64/pkgconfig + --with-re2 \ +%if 0%{?rhel} >= 8 + --enable-dns-over-quic \ + --with-quiche \ +%endif + PKG_CONFIG_PATH=/usr/lib/pkgconfig:/opt/lib64/pkgconfig %endif make %{?_smp_mflags} @@ -110,6 +114,9 @@ make %{?_smp_mflags} check || (cat test-suite.log && false) %install %make_install install -d %{buildroot}/%{_sysconfdir}/dnsdist +%if 0%{?rhel} >= 8 +install -Dm644 /usr/lib/libdnsdist-quiche.so %{buildroot}/%{_libdir}/libdnsdist-quiche.so +%endif %{__mv} %{buildroot}%{_sysconfdir}/dnsdist/dnsdist.conf-dist %{buildroot}%{_sysconfdir}/dnsdist/dnsdist.conf chmod 0640 %{buildroot}/%{_sysconfdir}/dnsdist/dnsdist.conf @@ -149,6 +156,9 @@ systemctl daemon-reload ||: %{!?_licensedir:%global license %%doc} %doc README.md %{_bindir}/* +%if 0%{?rhel} >= 8 +%{_libdir}/libdnsdist-quiche.so +%endif %{_mandir}/man1/* %dir %{_sysconfdir}/dnsdist %attr(-, root, dnsdist) %config(noreplace) %{_sysconfdir}/%{name}/dnsdist.conf From 4033d4ebfdaae95ac0aea97b9871947de854206b Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 27 Sep 2023 11:40:24 +0200 Subject: [PATCH 840/909] tasks: Remove a left-over debug line --- tasks.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tasks.py b/tasks.py index 8cec3534715c..5e07f0b3f688 100644 --- a/tasks.py +++ b/tasks.py @@ -896,7 +896,6 @@ def ci_build_and_install_quiche(c): c.run(f'tar xf quiche-{quiche_version}.tar.gz') with c.cd(f'quiche-{quiche_version}'): c.run('cargo build --release --no-default-features --features ffi,boringssl-boring-crate --package quiche') - c.run('ls quiche/include/quiche.h target/release/libquiche.a /usr/include /usr/lib /usr/lib/pkgconfig') # cannot use c.sudo() inside a cd() context, see https://github.com/pyinvoke/invoke/issues/687 c.run('sudo install -Dm644 quiche/include/quiche.h /usr/include') c.run('sudo install -Dm644 target/release/libquiche.so /usr/lib') From 358f3993ac14ed3a07975eaa197335e2b10dd59d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 27 Sep 2023 12:17:00 +0200 Subject: [PATCH 841/909] dnsdist: Work around an issue with opaque unique_ptrs on g++ 8 --- pdns/dnsdistdist/doq.hh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 064838a7bced..9f147be4d206 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -47,7 +47,7 @@ struct DOQFrontend void setup(); - std::unique_ptr d_server_config{nullptr}; + std::unique_ptr d_server_config; TLSConfig d_tlsConfig; ComboAddress d_local; std::string d_keyLogFile; From 0250b853a1035e3a4b318d27eb81304314c2ab90 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 28 Sep 2023 01:21:47 +0200 Subject: [PATCH 842/909] dnsdist: Fix the type of DoQ frontends --- pdns/dnsdist.hh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index f9455f2d11e6..5d8cb3e1d3f6 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -569,7 +569,10 @@ struct ClientState { std::string result = udpFD != -1 ? "UDP" : "TCP"; - if (dohFrontend) { + if (doqFrontend) { + result += " (DNS over QUIC)"; + } + else if (dohFrontend) { if (dohFrontend->isHTTPS()) { result += " (DNS over HTTPS)"; } From 7e290c7c3cdcc4759e1169414d22a00c0abca893 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 28 Sep 2023 01:23:27 +0200 Subject: [PATCH 843/909] dnsdist: Move the definition of the DoQ thread to doq.hh --- pdns/dnsdist.hh | 4 ---- pdns/dnsdistdist/doq.hh | 2 ++ 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/pdns/dnsdist.hh b/pdns/dnsdist.hh index 5d8cb3e1d3f6..dfaa3d1e58db 100644 --- a/pdns/dnsdist.hh +++ b/pdns/dnsdist.hh @@ -1106,10 +1106,6 @@ struct LocalHolders void tcpAcceptorThread(std::vector states); -#ifdef HAVE_DNS_OVER_QUIC -void doqThread(ClientState* cs); -#endif /* HAVE_DNS_OVER_QUIC */ - void setLuaNoSideEffect(); // if nothing has been declared, set that there are no side effects void setLuaSideEffect(); // set to report a side effect, cancelling all _no_ side effect calls bool getLuaNoSideEffect(); // set if there were only explicit declarations of _no_ side effect diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 9f147be4d206..80e4552ff889 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -100,6 +100,8 @@ struct CrossProtocolQuery; struct DNSQuestion; std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse); +void doqThread(ClientState* clientState); + #else struct DOQUnit From dd9ebcf6dcba5c71f29b949bad0d8d4d73bc75a0 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 28 Sep 2023 01:25:11 +0200 Subject: [PATCH 844/909] dnsdist: Fix the maximum size of a DoQ retry token --- pdns/dnsdistdist/doq.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 8786c55d0f4d..1ba7a8a638ac 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -382,7 +382,7 @@ static std::optional getCID() return buffer; } -static constexpr size_t MAX_TOKEN_LEN = std::tuple_size{} /* nonce */ + sizeof(uint64_t) /* TTD */ + 16 /* IPv6 */ + QUICHE_MAX_CONN_ID_LEN; +static constexpr size_t MAX_TOKEN_LEN = std::tuple_size{} /* nonce */ + /* MAC */ crypto_secretbox_MACBYTES + sizeof(uint64_t) /* TTD */ + 16 /* IPv6 */ + QUICHE_MAX_CONN_ID_LEN; static PacketBuffer mintToken(const PacketBuffer& dcid, const ComboAddress& peer) { From f016a7d5c3e4e275484bdce428c9f178050a4093 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 28 Sep 2023 01:28:49 +0200 Subject: [PATCH 845/909] dnsdist: Make a separate DoQ connections map per bind --- pdns/dnsdistdist/doq.cc | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 1ba7a8a638ac..a90d90e5e1df 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -85,7 +85,10 @@ struct DOQServerConfig DOQServerConfig& operator=(DOQServerConfig&&) = default; ~DOQServerConfig() = default; + using ConnectionsMap = std::map; + LocalHolders holders; + ConnectionsMap d_connections; QuicheConfig config; ClientState* clientState{nullptr}; std::shared_ptr df{nullptr}; @@ -114,8 +117,6 @@ DOQFrontend::~DOQFrontend() static constexpr size_t MAX_DATAGRAM_SIZE = 1200; static constexpr size_t LOCAL_CONN_ID_LEN = 16; -static std::map s_connections; - class DOQTCPCrossQuerySender final : public TCPQuerySender { public: @@ -489,13 +490,13 @@ static void handleVersionNegociation(Socket& sock, const PacketBuffer& clientCon sock.sendTo(reinterpret_cast(out.data()), written, peer); } -static std::optional> getConnection(const PacketBuffer& id) +static std::optional> getConnection(DOQServerConfig::ConnectionsMap& connMap, const PacketBuffer& connID) { - auto it = s_connections.find(id); - if (it == s_connections.end()) { + auto iter = connMap.find(connID); + if (iter == connMap.end()) { return std::nullopt; } - return it->second; + return iter->second; } static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description) @@ -514,7 +515,7 @@ static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description) } } -static std::optional> createConnection(const DOQServerConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const PacketBuffer& token, const ComboAddress& local, const ComboAddress& peer) +static std::optional> createConnection(DOQServerConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const ComboAddress& local, const ComboAddress& peer) { auto quicheConn = QuicheConnection(quiche_accept(serverSideID.data(), serverSideID.size(), originalDestinationID.data(), originalDestinationID.size(), @@ -530,7 +531,7 @@ static std::optional> createConnection(const } auto conn = Connection(peer, std::move(quicheConn)); - auto pair = s_connections.emplace(serverSideID, std::move(conn)); + auto pair = config.d_connections.emplace(serverSideID, std::move(conn)); return pair.first->second; } @@ -588,7 +589,7 @@ static void processDOQQuery(DOQUnitUniquePtr&& unit) { const auto handleImmediateResponse = [](DOQUnitUniquePtr&& du, const char* reason) { DEBUGLOG("handleImmediateResponse() reason=" << reason); - auto conn = getConnection(du->serverConnID); + auto conn = getConnection(du->dsc->df->d_server_config->d_connections, du->serverConnID); handleResponse(*du->dsc->df, *conn, du->streamID, du->response); du->ids.doqu.reset(); }; @@ -757,10 +758,11 @@ static void flushResponses(pdns::channel::Receiver& receiver) return; } - auto du = std::move(*tmp); - auto conn = getConnection(du->serverConnID); - - handleResponse(*du->dsc->df, *conn, du->streamID, du->response); + auto unit = std::move(*tmp); + auto conn = getConnection(unit->dsc->df->d_server_config->d_connections, unit->serverConnID); + if (conn) { + handleResponse(*unit->dsc->df, *conn, unit->streamID, unit->response); + } } catch (const std::exception& e) { errlog("Error while processing response received over DoQ: %s", e.what()); @@ -821,7 +823,7 @@ void doqThread(ClientState* clientState) PacketBuffer serverConnID(dcid.begin(), dcid.begin() + dcid_len); // source connection ID, will have to be sent as destination connection ID PacketBuffer clientConnID(scid.begin(), scid.begin() + scid_len); - auto conn = getConnection(serverConnID); + auto conn = getConnection(frontend->d_server_config->d_connections, serverConnID); if (!conn) { DEBUGLOG("Connection not found"); @@ -848,7 +850,7 @@ void doqThread(ClientState* clientState) } DEBUGLOG("Creating a new connection"); - conn = createConnection(*frontend->d_server_config, serverConnID, *originalDestinationID, tokenBuf, clientState->local, client); + conn = createConnection(*frontend->d_server_config, serverConnID, *originalDestinationID, clientState->local, client); if (!conn) { continue; } @@ -908,7 +910,7 @@ void doqThread(ClientState* clientState) flushResponses(frontend->d_server_config->d_responseReceiver); } - for (auto conn = s_connections.begin(); conn != s_connections.end();) { + for (auto conn = frontend->d_server_config->d_connections.begin(); conn != frontend->d_server_config->d_connections.end();) { quiche_conn_on_timeout(conn->second.d_conn.get()); flushEgress(sock, conn->second); @@ -923,7 +925,7 @@ void doqThread(ClientState* clientState) DEBUGLOG("Connection closed, recv=" << stats.recv << " sent=" << stats.sent << " lost=" << stats.lost << " rtt=" << path_stats.rtt << "ns cwnd=" << path_stats.cwnd); #endif - conn = s_connections.erase(conn); + conn = frontend->d_server_config->d_connections.erase(conn); } else { ++conn; From f9a9515200b18cf20224ff7617f577f284043765 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 28 Sep 2023 01:29:28 +0200 Subject: [PATCH 846/909] dnsdist: Use a random port in DoQ regression tests --- regression-tests.dnsdist/test_DOQ.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/regression-tests.dnsdist/test_DOQ.py b/regression-tests.dnsdist/test_DOQ.py index 5c5aaae1b641..150838eb339b 100644 --- a/regression-tests.dnsdist/test_DOQ.py +++ b/regression-tests.dnsdist/test_DOQ.py @@ -144,7 +144,7 @@ class TestDOQWithCache(DNSDistTest): _serverCert = 'server.chain' _serverName = 'tls.tests.dnsdist.org' _caCert = 'ca.pem' - _doqServerPort = 8853 + _doqServerPort = pickAvailablePort() _config_template = """ newServer{address="127.0.0.1:%d"} From ef4350f8e4efecf3b054e3d3ff163da91fcffa0c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 28 Sep 2023 01:31:27 +0200 Subject: [PATCH 847/909] dnsdist: Handle cross-protocol I/O errors for DoQ queries --- pdns/dnsdistdist/doq.cc | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index a90d90e5e1df..894a99deda85 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -193,8 +193,21 @@ class DOQTCPCrossQuerySender final : public TCPQuerySender return handleResponse(now, std::move(response)); } - void notifyIOError(const struct timeval& now, TCPResponse&& response) override + void notifyIOError([[maybe_unused]] const struct timeval& now, TCPResponse&& response) override { + if (!response.d_idstate.doqu) { + return; + } + + auto unit = std::move(response.d_idstate.doqu); + if (unit->dsc == nullptr) { + return; + } + + /* this will signal an error */ + unit->response.clear(); + unit->ids = std::move(response.d_idstate); + sendBackDOQUnit(std::move(unit), "Cross-protocol error"); } }; From 3201998f3565cfda288dbbf2b736427284f51fc0 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 28 Sep 2023 01:32:34 +0200 Subject: [PATCH 848/909] dnsdist: Delint doq.cc and doq.hh --- pdns/dnsdistdist/doq.cc | 324 +++++++++++++++++++++------------------- pdns/dnsdistdist/doq.hh | 6 +- pdns/sodcrypto.hh | 1 - 3 files changed, 171 insertions(+), 160 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 894a99deda85..2cf7b724e3d8 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -67,7 +67,8 @@ class Connection std::unordered_map d_streamBuffers; }; -static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description); +static void sendBackDOQUnit(DOQUnitUniquePtr&& unit, const char* description); + struct DOQServerConfig { DOQServerConfig(QuicheConfig&& config_, uint32_t internalPipeBufferSize) : @@ -99,13 +100,8 @@ struct DOQServerConfig /* these might seem useless, but they are needed because they need to be declared _after_ the definition of DOQServerConfig so that we can use a unique_ptr in DOQFrontend */ -DOQFrontend::DOQFrontend() -{ -} - -DOQFrontend::~DOQFrontend() -{ -} +DOQFrontend::DOQFrontend() = default; +DOQFrontend::~DOQFrontend() = default; #if 0 #define DEBUGLOG_ENABLED @@ -120,72 +116,72 @@ static constexpr size_t LOCAL_CONN_ID_LEN = 16; class DOQTCPCrossQuerySender final : public TCPQuerySender { public: - DOQTCPCrossQuerySender() - { - } + DOQTCPCrossQuerySender() = default; - bool active() const override + [[nodiscard]] bool active() const override { return true; } - void handleResponse(const struct timeval& now, TCPResponse&& response) override + void handleResponse([[maybe_unused]] const struct timeval& now, TCPResponse&& response) override { if (!response.d_idstate.doqu) { return; } - auto du = std::move(response.d_idstate.doqu); - if (du->dsc == nullptr) { + auto unit = std::move(response.d_idstate.doqu); + if (unit->dsc == nullptr) { return; } - du->response = std::move(response.d_buffer); - du->ids = std::move(response.d_idstate); - DNSResponse dr(du->ids, du->response, du->downstream); + unit->response = std::move(response.d_buffer); + unit->ids = std::move(response.d_idstate); + DNSResponse dnsResponse(unit->ids, unit->response, unit->downstream); - dnsheader cleartextDH; - memcpy(&cleartextDH, dr.getHeader(), sizeof(cleartextDH)); + dnsheader cleartextDH + { + }; + memcpy(&cleartextDH, dnsResponse.getHeader(), sizeof(cleartextDH)); if (!response.isAsync()) { static thread_local LocalStateHolder> localRespRuleActions = g_respruleactions.getLocal(); static thread_local LocalStateHolder> localCacheInsertedRespRuleActions = g_cacheInsertedRespRuleActions.getLocal(); - dr.ids.doqu = std::move(du); + dnsResponse.ids.doqu = std::move(unit); - if (!processResponse(dr.ids.doqu->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dr, false)) { - if (dr.ids.doqu) { + if (!processResponse(dnsResponse.ids.doqu->response, *localRespRuleActions, *localCacheInsertedRespRuleActions, dnsResponse, false)) { + if (dnsResponse.ids.doqu) { - sendBackDOQUnit(std::move(dr.ids.doqu), "Response dropped by rules"); + sendBackDOQUnit(std::move(dnsResponse.ids.doqu), "Response dropped by rules"); } return; } - if (dr.isAsynchronous()) { + if (dnsResponse.isAsynchronous()) { return; } - du = std::move(dr.ids.doqu); + unit = std::move(dnsResponse.ids.doqu); } - if (!du->ids.selfGenerated) { - double udiff = du->ids.queryRealTime.udiff(); - vinfolog("Got answer from %s, relayed to %s (quic), took %f us", du->downstream->d_config.remote.toStringWithPort(), du->ids.origRemote.toStringWithPort(), udiff); + if (!unit->ids.selfGenerated) { + double udiff = unit->ids.queryRealTime.udiff(); + vinfolog("Got answer from %s, relayed to %s (quic), took %f us", unit->downstream->d_config.remote.toStringWithPort(), unit->ids.origRemote.toStringWithPort(), udiff); - auto backendProtocol = du->downstream->getProtocol(); - if (backendProtocol == dnsdist::Protocol::DoUDP && du->tcp) { + auto backendProtocol = unit->downstream->getProtocol(); + if (backendProtocol == dnsdist::Protocol::DoUDP && unit->tcp) { backendProtocol = dnsdist::Protocol::DoTCP; } - handleResponseSent(du->ids, udiff, du->ids.origRemote, du->downstream->d_config.remote, du->response.size(), cleartextDH, backendProtocol, true); + handleResponseSent(unit->ids, udiff, unit->ids.origRemote, unit->downstream->d_config.remote, unit->response.size(), cleartextDH, backendProtocol, true); } ++dnsdist::metrics::g_stats.responses; - if (du->ids.cs) { - ++du->ids.cs->responses; + if (unit->ids.cs != nullptr) { + ++unit->ids.cs->responses; } - sendBackDOQUnit(std::move(du), "Cross-protocol response"); + sendBackDOQUnit(std::move(unit), "Cross-protocol response"); } void handleXFRResponse(const struct timeval& now, TCPResponse&& response) override @@ -214,25 +210,25 @@ class DOQTCPCrossQuerySender final : public TCPQuerySender class DOQCrossProtocolQuery : public CrossProtocolQuery { public: - DOQCrossProtocolQuery(DOQUnitUniquePtr&& du, bool isResponse) + DOQCrossProtocolQuery(DOQUnitUniquePtr&& unit, bool isResponse) { if (isResponse) { /* happens when a response becomes async */ - query = InternalQuery(std::move(du->response), std::move(du->ids)); + query = InternalQuery(std::move(unit->response), std::move(unit->ids)); } else { /* we need to duplicate the query here because we might need the existing query later if we get a truncated answer */ - query = InternalQuery(PacketBuffer(du->query), std::move(du->ids)); + query = InternalQuery(PacketBuffer(unit->query), std::move(unit->ids)); } - /* it might have been moved when we moved du->ids */ - if (du) { - query.d_idstate.doqu = std::move(du); + /* it might have been moved when we moved unit->ids */ + if (unit) { + query.d_idstate.doqu = std::move(unit); } /* we _could_ remove it from the query buffer and put in query's d_proxyProtocolPayload, - clearing query.d_proxyProtocolPayloadAdded and du->proxyProtocolPayloadSize. + clearing query.d_proxyProtocolPayloadAdded and unit->proxyProtocolPayloadSize. Leave it for now because we know that the onky case where the payload has been added is when we tried over UDP, got a TC=1 answer and retried over TCP/DoT, and we know the TCP/DoT code can handle it. */ @@ -254,15 +250,15 @@ class DOQCrossProtocolQuery : public CrossProtocolQuery DNSQuestion getDQ() override { auto& ids = query.d_idstate; - DNSQuestion dq(ids, query.d_buffer); - return dq; + DNSQuestion dnsQuestion(ids, query.d_buffer); + return dnsQuestion; } DNSResponse getDR() override { auto& ids = query.d_idstate; - DNSResponse dr(ids, query.d_buffer, downstream); - return dr; + DNSResponse dnsResponse(ids, query.d_buffer, downstream); + return dnsResponse; } DOQUnitUniquePtr&& releaseDU() @@ -287,35 +283,35 @@ enum class DOQ_Error_Codes : uint64_t DOQ_UNSPECIFIED_ERROR = 5 }; -static void handleResponse(DOQFrontend& df, Connection& conn, const uint64_t streamID, const PacketBuffer& response) +static void handleResponse(DOQFrontend& frontend, Connection& conn, const uint64_t streamID, const PacketBuffer& response) { - if (response.size() == 0) { - ++df.d_errorResponses; + if (response.empty()) { + ++frontend.d_errorResponses; quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_UNSPECIFIED_ERROR)); return; } - ++df.d_validResponses; - uint16_t responseSize = static_cast(response.size()); + ++frontend.d_validResponses; + auto responseSize = static_cast(response.size()); const std::array sizeBytes = {static_cast(responseSize / 256), static_cast(responseSize % 256)}; size_t pos = 0; - do { - auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, sizeBytes.data() + pos, sizeBytes.size() - pos, false); + while (pos < sizeBytes.size()) { + auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, &sizeBytes.at(pos), sizeBytes.size() - pos, false); if (res < 0) { quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_INTERNAL_ERROR)); return; } pos += res; - } while (pos < sizeBytes.size()); + } pos = 0; - do { - auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, response.data() + pos, response.size() - pos, true); + while (pos < response.size()) { + auto res = quiche_conn_stream_send(conn.d_conn.get(), streamID, &response.at(pos), response.size() - pos, true); if (res < 0) { quiche_conn_stream_shutdown(conn.d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_INTERNAL_ERROR)); return; } pos += res; - } while (pos < response.size()); + } } static void fillRandom(PacketBuffer& buffer, size_t size) @@ -381,7 +377,7 @@ void DOQFrontend::setup() { PacketBuffer resetToken; fillRandom(resetToken, 16); - quiche_config_set_stateless_reset_token(config.get(), reinterpret_cast(resetToken.data())); + quiche_config_set_stateless_reset_token(config.get(), resetToken.data()); } d_server_config = std::make_unique(std::move(config), d_internalPipeBufferSize); @@ -409,9 +405,11 @@ static PacketBuffer mintToken(const PacketBuffer& dcid, const ComboAddress& peer const uint64_t ttd = time(nullptr) + 60U; PacketBuffer plainTextToken; plainTextToken.reserve(sizeof(ttd) + addrBytes.size() + dcid.size()); - plainTextToken.insert(plainTextToken.end(), reinterpret_cast(&ttd), reinterpret_cast(&ttd) + sizeof(ttd)); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast,cppcoreguidelines-pro-bounds-pointer-arithmetic) + plainTextToken.insert(plainTextToken.end(), reinterpret_cast(&ttd), reinterpret_cast(&ttd) + sizeof(ttd)); plainTextToken.insert(plainTextToken.end(), addrBytes.begin(), addrBytes.end()); plainTextToken.insert(plainTextToken.end(), dcid.begin(), dcid.end()); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) const auto encryptedToken = sodEncryptSym(std::string_view(reinterpret_cast(plainTextToken.data()), plainTextToken.size()), s_quicRetryTokenKey, nonce, false); // a bit sad, let's see if we can do better later auto encryptedTokenPacket = PacketBuffer(encryptedToken.begin(), encryptedToken.end()); @@ -425,7 +423,7 @@ static PacketBuffer mintToken(const PacketBuffer& dcid, const ComboAddress& peer } // returns the original destination ID if the token is valid, nothing otherwise -static std::optional validateToken(const PacketBuffer& token, const PacketBuffer& dcid, const ComboAddress& peer) +static std::optional validateToken(const PacketBuffer& token, const ComboAddress& peer) { try { SodiumNonce nonce; @@ -438,6 +436,7 @@ static std::optional validateToken(const PacketBuffer& token, cons memcpy(nonce.value.data(), token.data(), nonce.value.size()); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto cipher = std::string_view(reinterpret_cast(&token.at(nonce.value.size())), token.size() - nonce.value.size()); auto plainText = sodDecryptSym(cipher, s_quicRetryTokenKey, nonce, false); @@ -454,6 +453,7 @@ static std::optional validateToken(const PacketBuffer& token, cons if (std::memcmp(&plainText.at(sizeof(ttd)), &*addrBytes.begin(), addrBytes.size()) != 0) { return std::nullopt; } + // NOLINTNEXTLINE(bugprone-narrowing-conversions,cppcoreguidelines-narrowing-conversions) return PacketBuffer(plainText.begin() + (sizeof(ttd) + addrBytes.size()), plainText.end()); } catch (const std::exception& exp) { @@ -500,6 +500,7 @@ static void handleVersionNegociation(Socket& sock, const PacketBuffer& clientCon DEBUGLOG("failed to create vneg packet " << written); return; } + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) sock.sendTo(reinterpret_cast(out.data()), written, peer); } @@ -512,13 +513,13 @@ static std::optional> getConnection(DOQServer return iter->second; } -static void sendBackDOQUnit(DOQUnitUniquePtr&& du, const char* description) +static void sendBackDOQUnit(DOQUnitUniquePtr&& unit, const char* description) { - if (du->dsc == nullptr) { + if (unit->dsc == nullptr) { return; } try { - if (!du->dsc->d_responseSender.send(std::move(du))) { + if (!unit->dsc->d_responseSender.send(std::move(unit))) { ++dnsdist::metrics::g_stats.doqResponsePipeFull; vinfolog("Unable to pass a %s to the DoQ worker thread because the pipe is full", description); } @@ -532,9 +533,11 @@ static std::optional> createConnection(DOQSer { auto quicheConn = QuicheConnection(quiche_accept(serverSideID.data(), serverSideID.size(), originalDestinationID.data(), originalDestinationID.size(), - (struct sockaddr*)&local, + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(&local), local.getSocklen(), - (struct sockaddr*)&peer, + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(&peer), peer.getSocklen(), config.config.get()), quiche_conn_free); @@ -550,12 +553,11 @@ static std::optional> createConnection(DOQSer static void flushEgress(Socket& sock, Connection& conn) { - std::array out; + std::array out{}; quiche_send_info send_info; while (true) { auto written = quiche_conn_send(conn.d_conn.get(), out.data(), out.size(), &send_info); - if (written == QUICHE_ERR_DONE) { return; } @@ -564,198 +566,201 @@ static void flushEgress(Socket& sock, Connection& conn) return; } // FIXME pacing (as send_info.at should tell us when to send the packet) ? + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) sock.sendTo(reinterpret_cast(out.data()), written, conn.d_peer); } } -std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse) +std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& dnsQuestion, bool isResponse) { - if (!dq.ids.doqu) { + if (!dnsQuestion.ids.doqu) { throw std::runtime_error("Trying to create a DoQ cross protocol query without a valid DoQ unit"); } - auto du = std::move(dq.ids.doqu); - if (&dq.ids != &du->ids) { - du->ids = std::move(dq.ids); + auto unit = std::move(dnsQuestion.ids.doqu); + if (&dnsQuestion.ids != &unit->ids) { + unit->ids = std::move(dnsQuestion.ids); } - du->ids.origID = dq.getHeader()->id; + unit->ids.origID = dnsQuestion.getHeader()->id; if (!isResponse) { - if (du->query.data() != dq.getMutableData().data()) { - du->query = std::move(dq.getMutableData()); + if (unit->query.data() != dnsQuestion.getMutableData().data()) { + unit->query = std::move(dnsQuestion.getMutableData()); } } else { - if (du->response.data() != dq.getMutableData().data()) { - du->response = std::move(dq.getMutableData()); + if (unit->response.data() != dnsQuestion.getMutableData().data()) { + unit->response = std::move(dnsQuestion.getMutableData()); } } - return std::make_unique(std::move(du), isResponse); + return std::make_unique(std::move(unit), isResponse); } /* We are not in the main DoQ thread but in the DoQ 'client' thread. */ -static void processDOQQuery(DOQUnitUniquePtr&& unit) +static void processDOQQuery(DOQUnitUniquePtr&& doqUnit) { - const auto handleImmediateResponse = [](DOQUnitUniquePtr&& du, const char* reason) { + const auto handleImmediateResponse = [](DOQUnitUniquePtr&& unit, [[maybe_unused]] const char* reason) { DEBUGLOG("handleImmediateResponse() reason=" << reason); - auto conn = getConnection(du->dsc->df->d_server_config->d_connections, du->serverConnID); - handleResponse(*du->dsc->df, *conn, du->streamID, du->response); - du->ids.doqu.reset(); + auto conn = getConnection(unit->dsc->df->d_server_config->d_connections, unit->serverConnID); + handleResponse(*unit->dsc->df, *conn, unit->streamID, unit->response); + unit->ids.doqu.reset(); }; - auto& ids = unit->ids; - ids.doqu = std::move(unit); - auto& du = ids.doqu; + auto& ids = doqUnit->ids; + ids.doqu = std::move(doqUnit); + auto& unit = ids.doqu; uint16_t queryId = 0; ComboAddress remote; try { - remote = du->ids.origRemote; - DOQServerConfig* dsc = du->dsc; + remote = unit->ids.origRemote; + DOQServerConfig* dsc = unit->dsc; auto& holders = dsc->holders; ClientState& clientState = *dsc->clientState; - if (du->query.size() < sizeof(dnsheader)) { + if (unit->query.size() < sizeof(dnsheader)) { ++dnsdist::metrics::g_stats.nonCompliantQueries; ++clientState.nonCompliantQueries; - struct dnsheader* dh = reinterpret_cast(du->query.data()); - dh->rcode = RCode::ServFail; - dh->qr = true; - du->response = std::move(du->query); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + auto* dnsHeader = reinterpret_cast(unit->query.data()); + dnsHeader->rcode = RCode::ServFail; + dnsHeader->qr = true; + unit->response = std::move(unit->query); - handleImmediateResponse(std::move(du), "DoQ non-compliant query"); + handleImmediateResponse(std::move(unit), "DoQ non-compliant query"); return; } ++clientState.queries; ++dnsdist::metrics::g_stats.queries; - du->ids.queryRealTime.start(); + unit->ids.queryRealTime.start(); { /* don't keep that pointer around, it will be invalidated if the buffer is ever resized */ - struct dnsheader* dh = reinterpret_cast(du->query.data()); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + auto* dnsHeader = reinterpret_cast(unit->query.data()); - if (!checkQueryHeaders(dh, clientState)) { - dh->rcode = RCode::ServFail; - dh->qr = true; - du->response = std::move(du->query); + if (!checkQueryHeaders(dnsHeader, clientState)) { + dnsHeader->rcode = RCode::ServFail; + dnsHeader->qr = true; + unit->response = std::move(unit->query); - handleImmediateResponse(std::move(du), "DoQ invalid headers"); + handleImmediateResponse(std::move(unit), "DoQ invalid headers"); return; } - if (dh->qdcount == 0) { - dh->rcode = RCode::NotImp; - dh->qr = true; - du->response = std::move(du->query); + if (dnsHeader->qdcount == 0) { + dnsHeader->rcode = RCode::NotImp; + dnsHeader->qr = true; + unit->response = std::move(unit->query); - handleImmediateResponse(std::move(du), "DoQ empty query"); + handleImmediateResponse(std::move(unit), "DoQ empty query"); return; } - queryId = ntohs(dh->id); + queryId = ntohs(dnsHeader->id); } - auto downstream = du->downstream; - du->ids.qname = DNSName(reinterpret_cast(du->query.data()), du->query.size(), sizeof(dnsheader), false, &du->ids.qtype, &du->ids.qclass); - DNSQuestion dq(du->ids, du->query); - const uint16_t* flags = getFlagsFromDNSHeader(dq.getHeader()); + auto downstream = unit->downstream; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + unit->ids.qname = DNSName(reinterpret_cast(unit->query.data()), static_cast(unit->query.size()), sizeof(dnsheader), false, &unit->ids.qtype, &unit->ids.qclass); + DNSQuestion dnsQuestion(unit->ids, unit->query); + const uint16_t* flags = getFlagsFromDNSHeader(dnsQuestion.getHeader()); ids.origFlags = *flags; - du->ids.cs = &clientState; + unit->ids.cs = &clientState; - auto result = processQuery(dq, holders, downstream); + auto result = processQuery(dnsQuestion, holders, downstream); if (result == ProcessQueryResult::Drop) { - handleImmediateResponse(std::move(du), "DoQ dropped query"); + handleImmediateResponse(std::move(unit), "DoQ dropped query"); return; } - else if (result == ProcessQueryResult::Asynchronous) { + if (result == ProcessQueryResult::Asynchronous) { return; } - else if (result == ProcessQueryResult::SendAnswer) { - if (du->response.empty()) { - du->response = std::move(du->query); + if (result == ProcessQueryResult::SendAnswer) { + if (unit->response.empty()) { + unit->response = std::move(unit->query); } - if (du->response.size() >= sizeof(dnsheader)) { - auto dh = reinterpret_cast(du->response.data()); + if (unit->response.size() >= sizeof(dnsheader)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + const auto* dnsHeader = reinterpret_cast(unit->response.data()); - handleResponseSent(du->ids.qname, QType(du->ids.qtype), 0., du->ids.origDest, ComboAddress(), du->response.size(), *dh, dnsdist::Protocol::DoQ, dnsdist::Protocol::DoQ, false); + handleResponseSent(unit->ids.qname, QType(unit->ids.qtype), 0., unit->ids.origDest, ComboAddress(), unit->response.size(), *dnsHeader, dnsdist::Protocol::DoQ, dnsdist::Protocol::DoQ, false); } - handleImmediateResponse(std::move(du), "DoQ self-answered response"); + handleImmediateResponse(std::move(unit), "DoQ self-answered response"); return; } ++dnsdist::metrics::g_stats.responses; - if (du->ids.cs != nullptr) { - ++du->ids.cs->responses; + if (unit->ids.cs != nullptr) { + ++unit->ids.cs->responses; } if (result != ProcessQueryResult::PassToBackend) { - handleImmediateResponse(std::move(du), "DoQ no backend available"); + handleImmediateResponse(std::move(unit), "DoQ no backend available"); return; } if (downstream == nullptr) { - handleImmediateResponse(std::move(du), "DoQ no backend available"); + handleImmediateResponse(std::move(unit), "DoQ no backend available"); return; } - du->downstream = downstream; + unit->downstream = downstream; std::string proxyProtocolPayload; /* we need to do this _before_ creating the cross protocol query because after that the buffer will have been moved */ if (downstream->d_config.useProxyProtocol) { - proxyProtocolPayload = getProxyProtocolPayload(dq); + proxyProtocolPayload = getProxyProtocolPayload(dnsQuestion); } - du->ids.origID = htons(queryId); - du->tcp = true; + unit->ids.origID = htons(queryId); + unit->tcp = true; - /* this moves du->ids, careful! */ - auto cpq = std::make_unique(std::move(du), false); + /* this moves unit->ids, careful! */ + auto cpq = std::make_unique(std::move(unit), false); cpq->query.d_proxyProtocolPayload = std::move(proxyProtocolPayload); if (downstream->passCrossProtocolQuery(std::move(cpq))) { return; } - else { - du = cpq->releaseDU(); - handleImmediateResponse(std::move(du), "DoQ internal error"); - return; - } + // NOLINTNEXTLINE(bugprone-use-after-move): it was only moved if the call succeeded + unit = cpq->releaseDU(); + handleImmediateResponse(std::move(unit), "DoQ internal error"); + return; } catch (const std::exception& e) { vinfolog("Got an error in DOQ question thread while parsing a query from %s, id %d: %s", remote.toStringWithPort(), queryId, e.what()); - handleImmediateResponse(std::move(du), "DoQ internal error"); + handleImmediateResponse(std::move(unit), "DoQ internal error"); return; } - - return; } static void doq_dispatch_query(DOQServerConfig& dsc, PacketBuffer&& query, const ComboAddress& local, const ComboAddress& remote, const PacketBuffer& serverConnID, const uint64_t streamID) { try { /* we only parse it there as a sanity check, we will parse it again later */ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) DNSPacketMangler mangler(reinterpret_cast(query.data()), query.size()); mangler.skipDomainName(); mangler.skipBytes(4); // Should we ensure message id is 0 ? - auto du = std::make_unique(std::move(query)); - du->dsc = &dsc; - du->ids.origDest = local; - du->ids.origRemote = remote; - du->ids.protocol = dnsdist::Protocol::DoQ; - du->serverConnID = serverConnID; - du->streamID = streamID; + auto unit = std::make_unique(std::move(query)); + unit->dsc = &dsc; + unit->ids.origDest = local; + unit->ids.origRemote = remote; + unit->ids.protocol = dnsdist::Protocol::DoQ; + unit->serverConnID = serverConnID; + unit->streamID = streamID; - processDOQQuery(std::move(du)); + processDOQQuery(std::move(unit)); } catch (const std::exception& exp) { vinfolog("Had error parsing DoQ DNS packet from %s: %s", remote.toStringWithPort(), exp.what()); @@ -810,25 +815,28 @@ void doqThread(ClientState* clientState) mplexer->getAvailableFDs(readyFDs, 500); if (std::find(readyFDs.begin(), readyFDs.end(), sock.getHandle()) != readyFDs.end()) { + DEBUGLOG("Received datagram"); std::string bufferStr; ComboAddress client; sock.recvFrom(bufferStr, client); uint32_t version{0}; - uint8_t type; - std::array scid; + uint8_t type{0}; + std::array scid{}; size_t scid_len = scid.size(); - std::array dcid; + std::array dcid{}; size_t dcid_len = dcid.size(); - std::array token; + std::array token{}; size_t token_len = token.size(); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto res = quiche_header_info(reinterpret_cast(bufferStr.data()), bufferStr.size(), LOCAL_CONN_ID_LEN, &version, &type, scid.data(), &scid_len, dcid.data(), &dcid_len, token.data(), &token_len); if (res != 0) { + DEBUGLOG("Error in quiche_header_info: "<d_doqInvalidTokensReceived; DEBUGLOG("Discarding invalid token"); @@ -868,14 +876,17 @@ void doqThread(ClientState* clientState) continue; } } + DEBUGLOG("Connection found"); quiche_recv_info recv_info = { - (struct sockaddr*)&client, + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(&client), client.getSocklen(), - - (struct sockaddr*)&clientState->local, + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(&clientState->local), clientState->local.getSocklen(), }; + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) auto done = quiche_conn_recv(conn->get().d_conn.get(), reinterpret_cast(bufferStr.data()), bufferStr.size(), &recv_info); if (done < 0) { continue; @@ -909,6 +920,7 @@ void doqThread(ClientState* clientState) quiche_conn_stream_shutdown(conn->get().d_conn.get(), streamID, QUICHE_SHUTDOWN_WRITE, static_cast(DOQ_Error_Codes::DOQ_PROTOCOL_ERROR)); break; } + DEBUGLOG("Dispatching query"); doq_dispatch_query(*(frontend->d_server_config), std::move(streamBuffer), clientState->local, client, serverConnID, streamID); conn->get().d_streamBuffers.erase(streamID); } diff --git a/pdns/dnsdistdist/doq.hh b/pdns/dnsdistdist/doq.hh index 80e4552ff889..64d080bfd113 100644 --- a/pdns/dnsdistdist/doq.hh +++ b/pdns/dnsdistdist/doq.hh @@ -73,8 +73,8 @@ struct DOQFrontend struct DOQUnit { - DOQUnit(PacketBuffer&& q) : - query(std::move(q)) + DOQUnit(PacketBuffer&& query_) : + query(std::move(query_)) { } @@ -98,7 +98,7 @@ using DOQUnitUniquePtr = std::unique_ptr; struct CrossProtocolQuery; struct DNSQuestion; -std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& dq, bool isResponse); +std::unique_ptr getDOQCrossProtocolQueryFromDQ(DNSQuestion& dnsQuestion, bool isResponse); void doqThread(ClientState* clientState); diff --git a/pdns/sodcrypto.hh b/pdns/sodcrypto.hh index 776248cc99fe..9f9da5d26b36 100644 --- a/pdns/sodcrypto.hh +++ b/pdns/sodcrypto.hh @@ -50,7 +50,6 @@ struct SodiumNonce #endif }; -std::string newKeypair(); std::string sodEncryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce, bool incrementNonce = true); std::string sodDecryptSym(const std::string_view& msg, const std::string& key, SodiumNonce& nonce, bool incrementNonce = true); std::string newKey(bool base64Encoded = true); From c0e87fe49e608de3e10c4c037a03227327579fb5 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Thu, 28 Sep 2023 01:54:01 +0200 Subject: [PATCH 849/909] dnsdist: Get the final size of an encrypted DoQ token in a cleaner way --- pdns/dnsdistdist/doq.cc | 8 +++----- pdns/sodcrypto.hh | 12 ++++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 2cf7b724e3d8..10f7ea89e153 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -138,9 +138,7 @@ class DOQTCPCrossQuerySender final : public TCPQuerySender unit->ids = std::move(response.d_idstate); DNSResponse dnsResponse(unit->ids, unit->response, unit->downstream); - dnsheader cleartextDH - { - }; + dnsheader cleartextDH{}; memcpy(&cleartextDH, dnsResponse.getHeader(), sizeof(cleartextDH)); if (!response.isAsync()) { @@ -392,7 +390,7 @@ static std::optional getCID() return buffer; } -static constexpr size_t MAX_TOKEN_LEN = std::tuple_size{} /* nonce */ + /* MAC */ crypto_secretbox_MACBYTES + sizeof(uint64_t) /* TTD */ + 16 /* IPv6 */ + QUICHE_MAX_CONN_ID_LEN; +static constexpr size_t MAX_TOKEN_LEN = dnsdist::crypto::authenticated::getEncryptedSize(std::tuple_size{} /* nonce */ + sizeof(uint64_t) /* TTD */ + 16 /* IPv6 */ + QUICHE_MAX_CONN_ID_LEN); static PacketBuffer mintToken(const PacketBuffer& dcid, const ComboAddress& peer) { @@ -836,7 +834,7 @@ void doqThread(ClientState* clientState) dcid.data(), &dcid_len, token.data(), &token_len); if (res != 0) { - DEBUGLOG("Error in quiche_header_info: "< Date: Wed, 27 Sep 2023 14:57:16 +0200 Subject: [PATCH 850/909] doq: make sure connection is properly reset if necessary in the tests --- pdns/dnsdistdist/doq.cc | 1 - regression-tests.dnsdist/dnsdisttests.py | 4 +- regression-tests.dnsdist/doqclient.py | 127 ++++++++++++++++++++++ regression-tests.dnsdist/requirements.txt | 1 + regression-tests.dnsdist/test_Async.py | 6 +- regression-tests.dnsdist/test_DOQ.py | 46 ++++++-- 6 files changed, 173 insertions(+), 12 deletions(-) create mode 100644 regression-tests.dnsdist/doqclient.py diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 10f7ea89e153..f1206bb9a115 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -748,7 +748,6 @@ static void doq_dispatch_query(DOQServerConfig& dsc, PacketBuffer&& query, const DNSPacketMangler mangler(reinterpret_cast(query.data()), query.size()); mangler.skipDomainName(); mangler.skipBytes(4); - // Should we ensure message id is 0 ? auto unit = std::make_unique(std::move(query)); unit->dsc = &dsc; diff --git a/regression-tests.dnsdist/dnsdisttests.py b/regression-tests.dnsdist/dnsdisttests.py index 97f8b72dcbb6..f2e5e31a99dd 100644 --- a/regression-tests.dnsdist/dnsdisttests.py +++ b/regression-tests.dnsdist/dnsdisttests.py @@ -28,6 +28,8 @@ import pycurl from io import BytesIO +from doqclient import quic_query + from eqdnsmessage import AssertEqualDNSMessageMixin from proxyprotocol import ProxyProtocol @@ -1111,7 +1113,7 @@ def sendDOQQuery(cls, port, query, response=None, timeout=2.0, caFile=None, useQ else: cls._toResponderQueue.put(response, True, timeout) - message = dns.query.quic(query, '127.0.0.1', timeout, port, verify=caFile, connection=connection, server_hostname=serverName) + message = quic_query(query, '127.0.0.1', timeout, port, verify=caFile, server_hostname=serverName) receivedQuery = None diff --git a/regression-tests.dnsdist/doqclient.py b/regression-tests.dnsdist/doqclient.py new file mode 100644 index 000000000000..94fa7bdc8e1f --- /dev/null +++ b/regression-tests.dnsdist/doqclient.py @@ -0,0 +1,127 @@ +import asyncio +import pickle +import ssl +import struct +from typing import Any, Optional, cast +import dns +import async_timeout + +from aioquic.quic.configuration import QuicConfiguration +from aioquic.asyncio.client import connect +from aioquic.asyncio.protocol import QuicConnectionProtocol +from aioquic.quic.configuration import QuicConfiguration +from aioquic.quic.events import QuicEvent, StreamDataReceived, StreamReset +from aioquic.quic.logger import QuicFileLogger + +class DnsClientProtocol(QuicConnectionProtocol): + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self._ack_waiter: Any = None + + def pack(self, data): + # serialize query + data = bytes(data) + data = struct.pack("!H", len(data)) + data + return data + + async def query(self, query: dns.message) -> None: + data = self.pack(query.to_wire()) + # send query and wait for answer + stream_id = self._quic.get_next_available_stream_id() + self._quic.send_stream_data(stream_id, data, end_stream=True) + waiter = self._loop.create_future() + self._ack_waiter = waiter + self.transmit() + + return await asyncio.shield(waiter) + + def quic_event_received(self, event: QuicEvent) -> None: + if self._ack_waiter is not None: + if isinstance(event, StreamDataReceived): + length = struct.unpack("!H", bytes(event.data[:2]))[0] + answer = dns.message.from_wire(event.data[2 : 2 + length], ignore_trailing=True) + + waiter = self._ack_waiter + self._ack_waiter = None + waiter.set_result(answer) + if isinstance(event, StreamReset): + waiter = self._ack_waiter + self._ack_waiter = None + waiter.set_result(event) + +class BogusDnsClientProtocol(DnsClientProtocol): + def pack(self, data): + # serialize query + data = bytes(data) + data = struct.pack("!H", len(data) * 2) + data + return data + + +async def async_quic_query( + configuration: QuicConfiguration, + host: str, + port: int, + query: dns.message, + timeout: float, + create_protocol=DnsClientProtocol +) -> None: + print("Connecting to {}:{}".format(host, port)) + async with connect( + host, + port, + configuration=configuration, + create_protocol=create_protocol, + ) as client: + client = cast(DnsClientProtocol, client) + print("Sending DNS query") + try: + async with async_timeout.timeout(timeout): + answer = await client.query(query) + return answer + except asyncio.TimeoutError as e: + return e + +class StreamResetError(Exception): + def __init__(self, error, message="Stream reset by peer"): + self.error = error + super().__init__(message) + +def quic_query(query, host='127.0.0.1', timeout=2, port=853, verify=None, server_hostname=None): + configuration = QuicConfiguration(alpn_protocols=["doq"], is_client=True) + if verify: + configuration.load_verify_locations(verify) + result = asyncio.run( + async_quic_query( + configuration=configuration, + host=host, + port=port, + query=query, + timeout=timeout, + create_protocol=DnsClientProtocol + ) + ) + if (isinstance(result, StreamReset)): + raise StreamResetError(result.error_code) + if (isinstance(result, asyncio.TimeoutError)): + raise TimeoutError() + return result + +def quic_bogus_query(query, host='127.0.0.1', timeout=2, port=853, verify=None, server_hostname=None): + configuration = QuicConfiguration(alpn_protocols=["doq"], is_client=True) + if verify: + configuration.load_verify_locations(verify) + result = asyncio.run( + async_quic_query( + configuration=configuration, + host=host, + port=port, + query=query, + timeout=timeout, + create_protocol=BogusDnsClientProtocol + ) + ) + if (isinstance(result, StreamReset)): + raise StreamResetError(result.error_code) + if (isinstance(result, asyncio.TimeoutError)): + raise TimeoutError() + return result diff --git a/regression-tests.dnsdist/requirements.txt b/regression-tests.dnsdist/requirements.txt index 4c6b1020bdab..13ce6de1840c 100644 --- a/regression-tests.dnsdist/requirements.txt +++ b/regression-tests.dnsdist/requirements.txt @@ -12,3 +12,4 @@ lmdb>=0.95 cdbx==0.1.2 h2>=4.0.0 aioquic +async_timeout diff --git a/regression-tests.dnsdist/test_Async.py b/regression-tests.dnsdist/test_Async.py index e4b8e41c651e..34ebf018c90b 100644 --- a/regression-tests.dnsdist/test_Async.py +++ b/regression-tests.dnsdist/test_Async.py @@ -6,6 +6,8 @@ import threading import unittest import dns +import doqclient + from dnsdisttests import DNSDistTest, pickAvailablePort def AsyncResponder(listenPath, responsePath): @@ -284,7 +286,7 @@ def testAcceptThenDrop(self): sender = getattr(self, method) try: (receivedQuery, receivedResponse) = sender(query, response) - except dns.exception.Timeout: + except doqclient.StreamResetError: if not self._fromResponderQueue.empty(): receivedQuery = self._fromResponderQueue.get(True, 1.0) receivedResponse = None @@ -323,7 +325,7 @@ def testDrop(self): sender = getattr(self, method) try: (_, receivedResponse) = sender(query, response=None, useQueue=False) - except dns.exception.Timeout: + except doqclient.StreamResetError: receivedResponse = None self.assertEqual(receivedResponse, None) diff --git a/regression-tests.dnsdist/test_DOQ.py b/regression-tests.dnsdist/test_DOQ.py index 150838eb339b..9a87b62255fc 100644 --- a/regression-tests.dnsdist/test_DOQ.py +++ b/regression-tests.dnsdist/test_DOQ.py @@ -4,6 +4,38 @@ from dnsdisttests import DNSDistTest from dnsdisttests import pickAvailablePort +from doqclient import quic_bogus_query +import doqclient + +class TestDOQBogus(DNSDistTest): + _serverKey = 'server.key' + _serverCert = 'server.chain' + _serverName = 'tls.tests.dnsdist.org' + _caCert = 'ca.pem' + _doqServerPort = pickAvailablePort() + _config_template = """ + newServer{address="127.0.0.1:%d"} + + addDOQLocal("127.0.0.1:%d", "%s", "%s") + """ + _config_params = ['_testServerPort', '_doqServerPort','_serverCert', '_serverKey'] + _verboseMode = True + + def testDOQBogus(self): + """ + DOQ: Test a bogus query (wrong packed length) + """ + name = 'bogus.doq.tests.powerdns.com.' + query = dns.message.make_query(name, 'A', 'IN', use_edns=False) + query.id = 0 + expectedQuery = dns.message.make_query(name, 'A', 'IN', use_edns=True, payload=4096) + expectedQuery.id = 0 + + try: + message = quic_bogus_query(query, '127.0.0.1', 2.0, self._doqServerPort, verify=self._caCert, server_hostname=self._serverName) + self.assertFalse(True) + except doqclient.StreamResetError as e : + self.assertEqual(e.error, 2); class TestDOQ(DNSDistTest): _serverKey = 'server.key' @@ -87,10 +119,9 @@ def testDropped(self): dropped = False try: (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=None, caFile=self._caCert, useQueue=False, serverName=self._serverName) - # dns.quic doesn't seem to report correctly the quic error so the connection timeout - except dns.exception.Timeout : - dropped = True - self.assertTrue(dropped) + self.assertTrue(False) + except doqclient.StreamResetError as e : + self.assertEqual(e.error, 5); def testRefused(self): """ @@ -134,10 +165,9 @@ def testDOQNoBackend(self): dropped = False try: (_, receivedResponse) = self.sendDOQQuery(self._doqServerPort, query, response=None, caFile=self._caCert, useQueue=False, serverName=self._serverName) - except dns.exception.Timeout : - dropped = True - self.assertTrue(dropped) - # dns.quic doesn't seem to report correctly the quic error so the connection timeout + self.assertTrue(False) + except doqclient.StreamResetError as e : + self.assertEqual(e.error, 5); class TestDOQWithCache(DNSDistTest): _serverKey = 'server.key' From 59b2d7ab6bd9d5700a482880677be0f6c20b87df Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Fri, 29 Sep 2023 13:46:46 +0200 Subject: [PATCH 851/909] doq: make cert and key parameters of addDOQLocal mandatory --- pdns/dnsdist-lua.cc | 4 ++-- pdns/dnsdistdist/docs/reference/config.rst | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 22debccbaec9..de7284c5411f 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2483,7 +2483,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) #endif /* HAVE_DNS_OVER_HTTPS */ }); - luaCtx.writeFunction("addDOQLocal", [client](const std::string& addr, boost::optional, LuaArray, LuaArray>>> certFiles, boost::optional>> keyFiles, boost::optional vars) { + luaCtx.writeFunction("addDOQLocal", [client](const std::string& addr, boost::variant, LuaArray, LuaArray>> certFiles, boost::variant> keyFiles, boost::optional vars) { if (client) { return; } @@ -2494,7 +2494,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) setLuaSideEffect(); auto frontend = std::make_shared(); - if (!loadTLSCertificateAndKeys("addDOQLocal", frontend->d_tlsConfig.d_certKeyPairs, *certFiles, *keyFiles)) { + if (!loadTLSCertificateAndKeys("addDOQLocal", frontend->d_tlsConfig.d_certKeyPairs, certFiles, keyFiles)) { return; } frontend->d_local = ComboAddress(addr, 853); diff --git a/pdns/dnsdistdist/docs/reference/config.rst b/pdns/dnsdistdist/docs/reference/config.rst index 2a68f20e5e12..8e5d4fc599ec 100644 --- a/pdns/dnsdistdist/docs/reference/config.rst +++ b/pdns/dnsdistdist/docs/reference/config.rst @@ -171,7 +171,7 @@ Listen Sockets * ``readAhead``: bool - When the TLS provider is set to OpenSSL, whether we tell the library to read as many input bytes as possible, which leads to better performance by reducing the number of syscalls. Default is true. * ``proxyProtocolOutsideTLS``: bool - When the use of incoming proxy protocol is enabled, whether the payload is prepended after the start of the TLS session (so inside, meaning it is protected by the TLS layer providing encryption and authentication) or not (outside, meaning it is in clear-text). Default is false which means inside. Note that most third-party software like HAproxy expect the proxy protocol payload to be outside, in clear-text. -.. function:: addDOQLocal(address, [certFile(s) [, keyFile(s) [, urls [, options]]]]) +.. function:: addDOQLocal(address, certFile(s), keyFile(s) [, options]) .. versionadded:: 1.9.0 From fe263e5997bb2b5e903346ae94b74e90846ad4c9 Mon Sep 17 00:00:00 2001 From: Charles-Henri Bruyand Date: Fri, 29 Sep 2023 14:45:59 +0200 Subject: [PATCH 852/909] doq: doc fix, thanks Otto --- pdns/dnsdistdist/docs/guides/dns-over-quic.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/guides/dns-over-quic.rst b/pdns/dnsdistdist/docs/guides/dns-over-quic.rst index 48fb22dc4e5f..957c82edbcd5 100644 --- a/pdns/dnsdistdist/docs/guides/dns-over-quic.rst +++ b/pdns/dnsdistdist/docs/guides/dns-over-quic.rst @@ -12,7 +12,7 @@ Adding a listen port for DNS-over-QUIC can be done with the :func:`addDOQLocal` addDOQLocal('2001:db8:1:f00::1', '/etc/ssl/certs/example.com.pem', '/etc/ssl/private/example.com.key') -This will make :program:`dnsdist` listen on [2001:db8:1:f00::1]:853 on UDP, and will use the provided certificate and key to serve incoming TLS connections. +This will make :program:`dnsdist` listen on [2001:db8:1:f00::1]:853 on UDP, and will use the provided certificate and key to serve incoming DoQ connections. The fourth parameter, if present, indicates various options. For instance, you can change the congestion control algorithm used. An example is:: From 4af3e47d464915f4c558e06a6fe5cc44ba5844a7 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 29 Sep 2023 15:16:54 +0200 Subject: [PATCH 853/909] Install quiche lib in proper location for macOS, and teach pkgconfig about it --- builder-support/helpers/install_quiche.sh | 24 +++++++++++++++++++---- pdns/dnsdistdist/Makefile.am | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/builder-support/helpers/install_quiche.sh b/builder-support/helpers/install_quiche.sh index 1c0b55928380..908e949f50ed 100755 --- a/builder-support/helpers/install_quiche.sh +++ b/builder-support/helpers/install_quiche.sh @@ -7,6 +7,17 @@ readonly QUICHE_TARBALL="${QUICHE_VERSION}.tar.gz" readonly QUICHE_TARBALL_URL="https://github.com/cloudflare/quiche/archive/${QUICHE_TARBALL}" readonly QUICHE_TARBALL_HASH='eb242a14c4d801a90b57b6021dd29f7a62099f3a4d7a7ba889e105f8328e6c1f' +INSTALL_PREFIX=/usr +SOEXT=so +if [ $(uname) = Darwin ]; then + if [ $(id -u) = 0 ]; then + echo Do not run as root on macOS + exit 1 + fi + INSTALL_PREFIX="${HOMEBREW_PREFIX}" + SOEXT=dylib +fi + cd /tmp echo $0: Downloading $QUICHE_TARBALL curl -L -o "${QUICHE_TARBALL}" "${QUICHE_TARBALL_URL}" @@ -15,15 +26,20 @@ echo "${QUICHE_TARBALL_HASH}" "${QUICHE_TARBALL}" | sha256sum -c - tar xf "${QUICHE_TARBALL}" cd "quiche-${QUICHE_VERSION}" RUST_BACKTRACE=1 cargo build --release --no-default-features --features ffi,boringssl-boring-crate --package quiche -install -Dm644 quiche/include/quiche.h /usr/include -install -Dm644 target/release/libquiche.so /usr/lib/libdnsdist-quiche.so -install -Dm644 /dev/stdin /usr/lib/pkgconfig/quiche.pc < Date: Fri, 6 Oct 2023 16:57:05 +0200 Subject: [PATCH 854/909] dnsdist: Prevent unaligned access when reading the DNS header in DoQ --- pdns/dns.hh | 30 +++++++++++++++++++--- pdns/dnsdistdist/dnsdist-dnsparser.cc | 28 ++++++++++++++++++++ pdns/dnsdistdist/dnsdist-dnsparser.hh | 6 +++++ pdns/dnsdistdist/doq.cc | 37 +++++++++++++++------------ 4 files changed, 81 insertions(+), 20 deletions(-) diff --git a/pdns/dns.hh b/pdns/dns.hh index 24a02e8a4866..066c7c4381b4 100644 --- a/pdns/dns.hh +++ b/pdns/dns.hh @@ -191,9 +191,14 @@ static_assert(sizeof(dnsheader) == 12, "dnsheader size must be 12"); class dnsheader_aligned { public: + static bool isMemoryAligned(const void* mem) + { + return reinterpret_cast(mem) % sizeof(uint32_t) == 0; // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + } + dnsheader_aligned(const void* mem) { - if (reinterpret_cast(mem) % sizeof(uint32_t) == 0) { // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) + if (isMemoryAligned(mem)) { d_p = reinterpret_cast(mem); // NOLINT(cppcoreguidelines-pro-type-reinterpret-cast) } else { @@ -207,14 +212,31 @@ public: return d_p; } + [[nodiscard]] const dnsheader& operator*() const + { + return *d_p; + } + + [[nodiscard]] const dnsheader* operator->() const + { + return d_p; + } + private: dnsheader d_h{}; - const dnsheader *d_p{}; + const dnsheader* d_p{}; }; -inline uint16_t * getFlagsFromDNSHeader(struct dnsheader * dh) +inline uint16_t* getFlagsFromDNSHeader(dnsheader* dh) +{ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return reinterpret_cast(reinterpret_cast(dh) + sizeof(uint16_t)); +} + +inline const uint16_t * getFlagsFromDNSHeader(const dnsheader* dh) { - return (uint16_t*) (((char *) dh) + sizeof(uint16_t)); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + return reinterpret_cast(reinterpret_cast(dh) + sizeof(uint16_t)); } #define DNS_TYPE_SIZE (2) diff --git a/pdns/dnsdistdist/dnsdist-dnsparser.cc b/pdns/dnsdistdist/dnsdist-dnsparser.cc index 90ce07580516..49f2942b03d4 100644 --- a/pdns/dnsdistdist/dnsdist-dnsparser.cc +++ b/pdns/dnsdistdist/dnsdist-dnsparser.cc @@ -186,4 +186,32 @@ bool changeNameInDNSPacket(PacketBuffer& initialPacket, const DNSName& from, con return true; } +namespace PacketMangling +{ + bool editDNSHeaderFromPacket(PacketBuffer& packet, std::function editFunction) + { + if (packet.size() < sizeof(dnsheader)) { + throw std::runtime_error("Trying to edit the DNS header of a too small packet"); + } + + return editDNSHeaderFromRawPacket(packet.data(), editFunction); + } + + bool editDNSHeaderFromRawPacket(void* packet, std::function editFunction) + { + if (dnsheader_aligned::isMemoryAligned(packet)) { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + auto* header = reinterpret_cast(packet); + return editFunction(*header); + } + + dnsheader header; + memcpy(&header, packet, sizeof(header)); + if (!editFunction(header)) { + return false; + } + memcpy(packet, &header, sizeof(header)); + return true; + } +} } diff --git a/pdns/dnsdistdist/dnsdist-dnsparser.hh b/pdns/dnsdistdist/dnsdist-dnsparser.hh index 91de7acf782f..839f6cd396fe 100644 --- a/pdns/dnsdistdist/dnsdist-dnsparser.hh +++ b/pdns/dnsdistdist/dnsdist-dnsparser.hh @@ -54,4 +54,10 @@ public: * because it could contain pointers that would not be rewritten. */ bool changeNameInDNSPacket(PacketBuffer& initialPacket, const DNSName& from, const DNSName& to); + +namespace PacketMangling +{ + bool editDNSHeaderFromPacket(PacketBuffer& packet, std::function editFunction); + bool editDNSHeaderFromRawPacket(void* packet, std::function editFunction); +} } diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index f1206bb9a115..093eebe35e32 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -34,6 +34,7 @@ #include "threadname.hh" #include "dnsdist-ecs.hh" +#include "dnsdist-dnsparser.hh" #include "dnsdist-proxy-protocol.hh" #include "dnsdist-tcp.hh" #include "dnsdist-random.hh" @@ -624,11 +625,7 @@ static void processDOQQuery(DOQUnitUniquePtr&& doqUnit) if (unit->query.size() < sizeof(dnsheader)) { ++dnsdist::metrics::g_stats.nonCompliantQueries; ++clientState.nonCompliantQueries; - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - auto* dnsHeader = reinterpret_cast(unit->query.data()); - dnsHeader->rcode = RCode::ServFail; - dnsHeader->qr = true; - unit->response = std::move(unit->query); + unit->response.clear(); handleImmediateResponse(std::move(unit), "DoQ non-compliant query"); return; @@ -641,11 +638,14 @@ static void processDOQQuery(DOQUnitUniquePtr&& doqUnit) { /* don't keep that pointer around, it will be invalidated if the buffer is ever resized */ // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - auto* dnsHeader = reinterpret_cast(unit->query.data()); - - if (!checkQueryHeaders(dnsHeader, clientState)) { - dnsHeader->rcode = RCode::ServFail; - dnsHeader->qr = true; + dnsheader_aligned dnsHeader(unit->query.data()); + + if (!checkQueryHeaders(dnsHeader.get(), clientState)) { + dnsdist::PacketMangling::editDNSHeaderFromPacket(unit->query, [](dnsheader& header) { + header.rcode = RCode::ServFail; + header.qr = true; + return true; + }); unit->response = std::move(unit->query); handleImmediateResponse(std::move(unit), "DoQ invalid headers"); @@ -653,8 +653,11 @@ static void processDOQQuery(DOQUnitUniquePtr&& doqUnit) } if (dnsHeader->qdcount == 0) { - dnsHeader->rcode = RCode::NotImp; - dnsHeader->qr = true; + dnsdist::PacketMangling::editDNSHeaderFromPacket(unit->query, [](dnsheader& header) { + header.rcode = RCode::NotImp; + header.qr = true; + return true; + }); unit->response = std::move(unit->query); handleImmediateResponse(std::move(unit), "DoQ empty query"); @@ -668,8 +671,11 @@ static void processDOQQuery(DOQUnitUniquePtr&& doqUnit) // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) unit->ids.qname = DNSName(reinterpret_cast(unit->query.data()), static_cast(unit->query.size()), sizeof(dnsheader), false, &unit->ids.qtype, &unit->ids.qclass); DNSQuestion dnsQuestion(unit->ids, unit->query); - const uint16_t* flags = getFlagsFromDNSHeader(dnsQuestion.getHeader()); - ids.origFlags = *flags; + dnsdist::PacketMangling::editDNSHeaderFromPacket(dnsQuestion.getMutableData(), [&ids](dnsheader& header) { + const uint16_t* flags = getFlagsFromDNSHeader(&header); + ids.origFlags = *flags; + return true; + }); unit->ids.cs = &clientState; auto result = processQuery(dnsQuestion, holders, downstream); @@ -685,8 +691,7 @@ static void processDOQQuery(DOQUnitUniquePtr&& doqUnit) unit->response = std::move(unit->query); } if (unit->response.size() >= sizeof(dnsheader)) { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - const auto* dnsHeader = reinterpret_cast(unit->response.data()); + const dnsheader_aligned dnsHeader(unit->response.data()); handleResponseSent(unit->ids.qname, QType(unit->ids.qtype), 0., unit->ids.origDest, ComboAddress(), unit->response.size(), *dnsHeader, dnsdist::Protocol::DoQ, dnsdist::Protocol::DoQ, false); } From 48d024360321fbebe6c9ce55bb0efe973825a4dc Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 9 Oct 2023 15:07:36 +0200 Subject: [PATCH 855/909] Fix a spuriously failing recursorcache_cc test: reset globals (indirectly) used For SyncRes tests we have a general mechanism setting the globals before the test are run, but the non-syncres tests do not have that, while they still use some globals. In this particular case, the test would fail if the last SyncRes test run before was setting SyncRes::s_locked_ttlperc. While there, pass the time to the prune functions. This avoids potential timing issues for some tests. --- pdns/cachecleaner.hh | 3 +- pdns/recursordist/negcache.cc | 4 +-- pdns/recursordist/negcache.hh | 2 +- pdns/recursordist/rec-main.cc | 12 ++++---- pdns/recursordist/recpacketcache.cc | 4 +-- pdns/recursordist/recpacketcache.hh | 2 +- pdns/recursordist/recursor_cache.cc | 12 ++++++-- pdns/recursordist/recursor_cache.hh | 4 ++- pdns/recursordist/test-negcache_cc.cc | 8 +++--- pdns/recursordist/test-recpacketcache_cc.cc | 27 ++++++++--------- pdns/recursordist/test-recursorcache_cc.cc | 32 +++++++++++++-------- 11 files changed, 64 insertions(+), 46 deletions(-) diff --git a/pdns/cachecleaner.hh b/pdns/cachecleaner.hh index 8373ae6f01c6..fa45ca5736c4 100644 --- a/pdns/cachecleaner.hh +++ b/pdns/cachecleaner.hh @@ -131,9 +131,8 @@ uint64_t pruneLockedCollectionsVector(std::vector& maps) } template -uint64_t pruneMutexCollectionsVector(C& container, std::vector& maps, uint64_t maxCached, uint64_t cacheSize) +uint64_t pruneMutexCollectionsVector(time_t now, C& container, std::vector& maps, uint64_t maxCached, uint64_t cacheSize) { - const time_t now = time(nullptr); uint64_t totErased = 0; uint64_t toTrim = 0; uint64_t lookAt = 0; diff --git a/pdns/recursordist/negcache.cc b/pdns/recursordist/negcache.cc index be67da138bac..af6cd1fa6aa9 100644 --- a/pdns/recursordist/negcache.cc +++ b/pdns/recursordist/negcache.cc @@ -284,10 +284,10 @@ void NegCache::clear() * * \param maxEntries The maximum number of entries that may exist in the cache. */ -void NegCache::prune(size_t maxEntries) +void NegCache::prune(time_t now, size_t maxEntries) { size_t cacheSize = size(); - pruneMutexCollectionsVector(*this, d_maps, maxEntries, cacheSize); + pruneMutexCollectionsVector(now, *this, d_maps, maxEntries, cacheSize); } /*! diff --git a/pdns/recursordist/negcache.hh b/pdns/recursordist/negcache.hh index 1ac2855e31f1..86c3b562f428 100644 --- a/pdns/recursordist/negcache.hh +++ b/pdns/recursordist/negcache.hh @@ -98,7 +98,7 @@ public: bool getRootNXTrust(const DNSName& qname, const struct timeval& now, NegCacheEntry& ne, bool serveStale, bool refresh); size_t count(const DNSName& qname); size_t count(const DNSName& qname, QType qtype); - void prune(size_t maxEntries); + void prune(time_t now, size_t maxEntries); void clear(); size_t doDump(int fd, size_t maxCacheEntries, time_t now = time(nullptr)); size_t wipe(const DNSName& name, bool subtree = false); diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 25e6d7d74c7c..0c9ca1cf8f8a 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2404,18 +2404,18 @@ static void houseKeepingWork(Logr::log_t log) else if (info.isHandler()) { if (g_packetCache) { static PeriodicTask packetCacheTask{"packetCacheTask", 5}; - packetCacheTask.runIfDue(now, []() { - g_packetCache->doPruneTo(g_maxPacketCacheEntries); + packetCacheTask.runIfDue(now, [now]() { + g_packetCache->doPruneTo(now.tv_sec, g_maxPacketCacheEntries); }); } static PeriodicTask recordCachePruneTask{"RecordCachePruneTask", 5}; - recordCachePruneTask.runIfDue(now, []() { - g_recCache->doPrune(g_maxCacheEntries); + recordCachePruneTask.runIfDue(now, [now]() { + g_recCache->doPrune(now.tv_sec, g_maxCacheEntries); }); static PeriodicTask negCachePruneTask{"NegCachePrunteTask", 5}; - negCachePruneTask.runIfDue(now, []() { - g_negCache->prune(g_maxCacheEntries / 8); + negCachePruneTask.runIfDue(now, [now]() { + g_negCache->prune(now.tv_sec, g_maxCacheEntries / 8); }); static PeriodicTask aggrNSECPruneTask{"AggrNSECPruneTask", 5}; diff --git a/pdns/recursordist/recpacketcache.cc b/pdns/recursordist/recpacketcache.cc index 4ae3cb51704e..f19176a14151 100644 --- a/pdns/recursordist/recpacketcache.cc +++ b/pdns/recursordist/recpacketcache.cc @@ -251,10 +251,10 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash, assert(map.getEntriesCount() == shard->d_map.size()); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clib implementation } -void RecursorPacketCache::doPruneTo(size_t maxSize) +void RecursorPacketCache::doPruneTo(time_t now, size_t maxSize) { size_t cacheSize = size(); - pruneMutexCollectionsVector(*this, d_maps, maxSize, cacheSize); + pruneMutexCollectionsVector(now, *this, d_maps, maxSize, cacheSize); } uint64_t RecursorPacketCache::doDump(int file) diff --git a/pdns/recursordist/recpacketcache.hh b/pdns/recursordist/recpacketcache.hh index 22207068a9b4..0e51cea628f0 100644 --- a/pdns/recursordist/recpacketcache.hh +++ b/pdns/recursordist/recpacketcache.hh @@ -83,7 +83,7 @@ public: bool getResponsePacket(unsigned int tag, const std::string& queryPacket, DNSName& qname, uint16_t* qtype, uint16_t* qclass, time_t now, std::string* responsePacket, uint32_t* age, vState* valState, uint32_t* qhash, OptPBData* pbdata, bool tcp); void insertResponsePacket(unsigned int tag, uint32_t qhash, std::string&& query, const DNSName& qname, uint16_t qtype, uint16_t qclass, std::string&& responsePacket, time_t now, uint32_t ttl, const vState& valState, OptPBData&& pbdata, bool tcp); - void doPruneTo(size_t maxSize); + void doPruneTo(time_t now, size_t maxSize); uint64_t doDump(int file); uint64_t doWipePacketCache(const DNSName& name, uint16_t qtype = 0xffff, bool subtree = false); diff --git a/pdns/recursordist/recursor_cache.cc b/pdns/recursordist/recursor_cache.cc index d3e434017eec..12067195c5e8 100644 --- a/pdns/recursordist/recursor_cache.cc +++ b/pdns/recursordist/recursor_cache.cc @@ -54,6 +54,14 @@ uint16_t MemRecursorCache::s_maxServedStaleExtensions; +void MemRecursorCache::resetStaticsForTests() +{ + s_maxServedStaleExtensions = 0; + SyncRes::s_refresh_ttlperc = 0; + SyncRes::s_locked_ttlperc = 0; + SyncRes::s_minimumTTL = 0; +} + MemRecursorCache::MemRecursorCache(size_t mapsCount) : d_maps(mapsCount == 0 ? 1 : mapsCount) { @@ -821,10 +829,10 @@ uint64_t MemRecursorCache::doDump(int fd, size_t maxCacheEntries) return count; } -void MemRecursorCache::doPrune(size_t keep) +void MemRecursorCache::doPrune(time_t now, size_t keep) { size_t cacheSize = size(); - pruneMutexCollectionsVector(*this, d_maps, keep, cacheSize); + pruneMutexCollectionsVector(now, *this, d_maps, keep, cacheSize); } namespace boost diff --git a/pdns/recursordist/recursor_cache.hh b/pdns/recursordist/recursor_cache.hh index 7cc2f0316c05..ccbcad2b507c 100644 --- a/pdns/recursordist/recursor_cache.hh +++ b/pdns/recursordist/recursor_cache.hh @@ -71,7 +71,7 @@ public: void replace(time_t, const DNSName& qname, const QType qt, const vector& content, const vector>& signatures, const std::vector>& authorityRecs, bool auth, const DNSName& authZone, boost::optional ednsmask = boost::none, const OptTag& routingTag = boost::none, vState state = vState::Indeterminate, boost::optional from = boost::none, bool refresh = false, time_t ttl_time = time(nullptr)); - void doPrune(size_t keep); + void doPrune(time_t now, size_t keep); uint64_t doDump(int fd, size_t maxCacheEntries); size_t doWipeCache(const DNSName& name, bool sub, QType qtype = 0xffff); @@ -80,6 +80,8 @@ public: pdns::stat_t cacheHits{0}, cacheMisses{0}; + static void resetStaticsForTests(); + private: struct CacheEntry { diff --git a/pdns/recursordist/test-negcache_cc.cc b/pdns/recursordist/test-negcache_cc.cc index 96172d458faa..be31d1e7afea 100644 --- a/pdns/recursordist/test-negcache_cc.cc +++ b/pdns/recursordist/test-negcache_cc.cc @@ -291,7 +291,7 @@ BOOST_AUTO_TEST_CASE(test_prune) BOOST_CHECK_EQUAL(cache.size(), 400U); - cache.prune(100); + cache.prune(now.tv_sec, 100); BOOST_CHECK_EQUAL(cache.size(), 100U); } @@ -313,7 +313,7 @@ BOOST_AUTO_TEST_CASE(test_prune_many_shards) BOOST_CHECK_EQUAL(cache.size(), 400U); - cache.prune(100); + cache.prune(now.tv_sec, 100); BOOST_CHECK_EQUAL(cache.size(), 100U); } @@ -340,7 +340,7 @@ BOOST_AUTO_TEST_CASE(test_prune_valid_entries) /* power2 has been inserted more recently, so it should be removed last */ - cache.prune(1); + cache.prune(now.tv_sec, 1); BOOST_CHECK_EQUAL(cache.size(), 1U); NegCache::NegCacheEntry got; @@ -362,7 +362,7 @@ BOOST_AUTO_TEST_CASE(test_prune_valid_entries) /* power2 has been updated more recently, so it should be removed last */ - cache.prune(1); + cache.prune(now.tv_sec, 1); BOOST_CHECK_EQUAL(cache.size(), 1U); got = NegCache::NegCacheEntry(); diff --git a/pdns/recursordist/test-recpacketcache_cc.cc b/pdns/recursordist/test-recpacketcache_cc.cc index a3d783b0910d..353407ea276f 100644 --- a/pdns/recursordist/test-recpacketcache_cc.cc +++ b/pdns/recursordist/test-recpacketcache_cc.cc @@ -35,31 +35,32 @@ BOOST_AUTO_TEST_CASE(test_recPacketCacheSimple) string qpacket((const char*)&packet[0], packet.size()); pw.startRecord(qname, QType::A, ttd); - BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, time(nullptr), &fpacket, &age, &qhash), false); - BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &qhash), false); + time_t now = time(nullptr); + BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, now, &fpacket, &age, &qhash), false); + BOOST_CHECK_EQUAL(rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash), false); ARecordContent ar("127.0.0.1"); ar.toPacket(pw); pw.commit(); string rpacket((const char*)&packet[0], packet.size()); - rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, vState::Indeterminate, boost::none, false); + rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), now, ttd, vState::Indeterminate, boost::none, false); BOOST_CHECK_EQUAL(rpc.size(), 1U); - rpc.doPruneTo(0); + rpc.doPruneTo(now, 0); BOOST_CHECK_EQUAL(rpc.size(), 0U); - rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, vState::Indeterminate, boost::none, false); + rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), now, ttd, vState::Indeterminate, boost::none, false); BOOST_CHECK_EQUAL(rpc.size(), 1U); rpc.doWipePacketCache(qname); BOOST_CHECK_EQUAL(rpc.size(), 0U); - rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), time(0), ttd, vState::Indeterminate, boost::none, false); + rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), now, ttd, vState::Indeterminate, boost::none, false); BOOST_CHECK_EQUAL(rpc.size(), 1U); uint32_t qhash2 = 0; - bool found = rpc.getResponsePacket(tag, qpacket, time(nullptr), &fpacket, &age, &qhash2); + bool found = rpc.getResponsePacket(tag, qpacket, now, &fpacket, &age, &qhash2); BOOST_CHECK_EQUAL(found, true); BOOST_CHECK_EQUAL(qhash, qhash2); BOOST_CHECK_EQUAL(fpacket, rpacket); - found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &qhash2); + found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash2); BOOST_CHECK_EQUAL(found, true); BOOST_CHECK_EQUAL(qhash, qhash2); BOOST_CHECK_EQUAL(fpacket, rpacket); @@ -73,9 +74,9 @@ BOOST_AUTO_TEST_CASE(test_recPacketCacheSimple) pw2.getHeader()->id = dns_random_uint16(); qpacket.assign((const char*)&packet[0], packet.size()); - found = rpc.getResponsePacket(tag, qpacket, time(nullptr), &fpacket, &age, &qhash); + found = rpc.getResponsePacket(tag, qpacket, now, &fpacket, &age, &qhash); BOOST_CHECK_EQUAL(found, false); - found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, time(nullptr), &fpacket, &age, &qhash); + found = rpc.getResponsePacket(tag, qpacket, qname, QType::A, QClass::IN, now, &fpacket, &age, &qhash); BOOST_CHECK_EQUAL(found, false); rpc.doWipePacketCache(DNSName("com"), 0xffff, true); @@ -175,7 +176,7 @@ BOOST_AUTO_TEST_CASE(test_recPacketCacheSimplePost2038) rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), future, ttd, vState::Indeterminate, boost::none, false); BOOST_CHECK_EQUAL(rpc.size(), 1U); - rpc.doPruneTo(0); + rpc.doPruneTo(time(nullptr), 0); BOOST_CHECK_EQUAL(rpc.size(), 0U); rpc.insertResponsePacket(tag, qhash, string(qpacket), qname, QType::A, QClass::IN, string(rpacket), future, ttd, vState::Indeterminate, boost::none, false); BOOST_CHECK_EQUAL(rpc.size(), 1U); @@ -280,7 +281,7 @@ BOOST_AUTO_TEST_CASE(test_recPacketCache_Tags) BOOST_CHECK_EQUAL(rpc.size(), 2U); /* remove all responses from the cache */ - rpc.doPruneTo(0); + rpc.doPruneTo(time(nullptr), 0); BOOST_CHECK_EQUAL(rpc.size(), 0U); /* reinsert both */ @@ -393,7 +394,7 @@ BOOST_AUTO_TEST_CASE(test_recPacketCache_TCP) BOOST_CHECK_EQUAL(rpc.size(), 2U); /* remove all responses from the cache */ - rpc.doPruneTo(0); + rpc.doPruneTo(time(nullptr), 0); BOOST_CHECK_EQUAL(rpc.size(), 0U); /* reinsert both */ diff --git a/pdns/recursordist/test-recursorcache_cc.cc b/pdns/recursordist/test-recursorcache_cc.cc index e456d3f11681..71a05440eecb 100644 --- a/pdns/recursordist/test-recursorcache_cc.cc +++ b/pdns/recursordist/test-recursorcache_cc.cc @@ -13,6 +13,7 @@ BOOST_AUTO_TEST_SUITE(recursorcache_cc) static void simple(time_t now) { + MemRecursorCache::resetStaticsForTests(); MemRecursorCache MRC; std::vector records; @@ -387,6 +388,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCacheSimpleDistantFuture) BOOST_AUTO_TEST_CASE(test_RecursorCacheGhost) { + MemRecursorCache::resetStaticsForTests(); MemRecursorCache MRC; std::vector records; @@ -430,6 +432,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCacheReplaceAuthByNonAuthMargin) { // Test #12140: as QM does a best NS lookup and then uses it, incoming infra records should update // cache, otherwise they might expire in-between. + MemRecursorCache::resetStaticsForTests(); MemRecursorCache MRC; std::vector records; @@ -475,6 +478,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCacheReplaceAuthByNonAuthMargin) BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingExpiredEntries) { + MemRecursorCache::resetStaticsForTests(); MemRecursorCache MRC(1); std::vector records; @@ -522,7 +526,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingExpiredEntries) /* we ask that 10 entries remain in the cache, this is larger than the cache size (2), so 1 entry will be looked at as the code rounds up the 10% of entries per shard to look at */ - MRC.doPrune(10); + MRC.doPrune(now, 10); BOOST_CHECK_EQUAL(MRC.size(), 1U); /* the remaining entry should be power2, but to get it @@ -555,7 +559,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingExpiredEntries) /* we ask that 10 entries remain in the cache, this is larger than the cache size (2), so 1 entry will be looked at as the code rounds up the 10% of entries per shard to look at */ - MRC.doPrune(10); + MRC.doPrune(now, 10); BOOST_CHECK_EQUAL(MRC.size(), 1U); /* the remaining entry should be power1, but to get it @@ -569,6 +573,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingExpiredEntries) BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingValidEntries) { + MemRecursorCache::resetStaticsForTests(); MemRecursorCache MRC(1); std::vector records; @@ -615,7 +620,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingValidEntries) /* the one for power2 having been inserted more recently should be removed last */ /* we ask that only entry remains in the cache */ - MRC.doPrune(1); + MRC.doPrune(now, 1); BOOST_CHECK_EQUAL(MRC.size(), 1U); /* the remaining entry should be power2 */ @@ -649,7 +654,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingValidEntries) to the back of the expunge queue, so power2 should be at the front and should this time be removed first */ /* we ask that only entry remains in the cache */ - MRC.doPrune(1); + MRC.doPrune(now, 1); BOOST_CHECK_EQUAL(MRC.size(), 1U); /* the remaining entry should be power1 */ @@ -681,7 +686,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingValidEntries) /* the entry for power1 should have been moved to the back of the expunge queue due to the hit, so power2 should be at the front and should this time be removed first */ /* we ask that only entry remains in the cache */ - MRC.doPrune(1); + MRC.doPrune(now, 1); BOOST_CHECK_EQUAL(MRC.size(), 1U); /* the remaining entry should be power1 */ @@ -691,7 +696,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingValidEntries) /* check that power2 is gone */ BOOST_CHECK_EQUAL(MRC.get(now, power2, QType(dr2.d_type), MemRecursorCache::None, &retrieved, who, boost::none, nullptr), -1); - MRC.doPrune(0); + MRC.doPrune(now, 0); BOOST_CHECK_EQUAL(MRC.size(), 0U); /* add a lot of netmask-specific entries */ @@ -716,7 +721,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingValidEntries) /* remove a bit less than half of them */ size_t keep = 129; - MRC.doPrune(keep); + MRC.doPrune(now, keep); BOOST_CHECK_EQUAL(MRC.size(), keep); BOOST_CHECK_EQUAL(MRC.ecsIndexSize(), 1U); @@ -740,13 +745,14 @@ BOOST_AUTO_TEST_CASE(test_RecursorCache_ExpungingValidEntries) BOOST_CHECK_EQUAL(found, keep); /* remove the rest */ - MRC.doPrune(0); + MRC.doPrune(now, 0); BOOST_CHECK_EQUAL(MRC.size(), 0U); BOOST_CHECK_EQUAL(MRC.ecsIndexSize(), 0U); } BOOST_AUTO_TEST_CASE(test_RecursorCacheECSIndex) { + MemRecursorCache::resetStaticsForTests(); MemRecursorCache MRC(1); const DNSName power("powerdns.com."); @@ -797,7 +803,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCacheECSIndex) BOOST_CHECK_EQUAL(getRR(retrieved.at(0))->getCA().toString(), dr1Content.toString()); /* wipe everything */ - MRC.doPrune(0); + MRC.doPrune(now, 0); BOOST_CHECK_EQUAL(MRC.size(), 0U); BOOST_CHECK_EQUAL(MRC.ecsIndexSize(), 0U); @@ -835,7 +841,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCacheECSIndex) BOOST_CHECK_EQUAL(getRR(retrieved.at(0))->getCA().toString(), dr1Content.toString()); /* wipe everything */ - MRC.doPrune(0); + MRC.doPrune(now, 0); BOOST_CHECK_EQUAL(MRC.size(), 0U); BOOST_CHECK_EQUAL(MRC.ecsIndexSize(), 0U); @@ -870,7 +876,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCacheECSIndex) BOOST_CHECK_EQUAL(MRC.size(), 2U); /* wipe everything */ - MRC.doPrune(0); + MRC.doPrune(now, 0); BOOST_CHECK_EQUAL(MRC.size(), 0U); BOOST_CHECK_EQUAL(MRC.ecsIndexSize(), 0U); @@ -899,13 +905,14 @@ BOOST_AUTO_TEST_CASE(test_RecursorCacheECSIndex) BOOST_CHECK_EQUAL(MRC.ecsIndexSize(), 1U); /* wipe everything */ - MRC.doPrune(0); + MRC.doPrune(now, 0); BOOST_CHECK_EQUAL(MRC.size(), 0U); BOOST_CHECK_EQUAL(MRC.ecsIndexSize(), 0U); } BOOST_AUTO_TEST_CASE(test_RecursorCache_Wipe) { + MemRecursorCache::resetStaticsForTests(); MemRecursorCache MRC; const DNSName power("powerdns.com."); @@ -996,6 +1003,7 @@ BOOST_AUTO_TEST_CASE(test_RecursorCache_Wipe) BOOST_AUTO_TEST_CASE(test_RecursorCacheTagged) { + MemRecursorCache::resetStaticsForTests(); MemRecursorCache MRC; const DNSName authZone("."); From a56b8c0fa33e253433a71b1bc171755b94712d03 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 8 Sep 2023 10:26:50 +0200 Subject: [PATCH 856/909] dnsdist: Fix a few warnings from Coverity Mostly false positives, but also a real issue with `QueryProcessingResult::Empty` which was processed twice for incoming DoH queries with nghttp2. --- pdns/dnsdist-tcp.cc | 5 ++++- pdns/dnsdist.cc | 4 +++- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 7 +++---- pdns/dnsdistdist/dnsdist-tcp-upstream.hh | 2 +- pdns/dnsdistdist/doh.cc | 18 ++++++++++++++---- regression-tests.dnsdist/test_DOH.py | 16 ++++++++++++++++ 6 files changed, 41 insertions(+), 11 deletions(-) diff --git a/pdns/dnsdist-tcp.cc b/pdns/dnsdist-tcp.cc index 7b94e00e5109..3d118508cd3e 100644 --- a/pdns/dnsdist-tcp.cc +++ b/pdns/dnsdist-tcp.cc @@ -677,12 +677,15 @@ IncomingTCPConnectionState::QueryProcessingResult IncomingTCPConnectionState::ha TCPResponse response; dh->rcode = RCode::NotImp; dh->qr = true; + auto queryID = dh->id; + response.d_idstate = std::move(ids); + response.d_idstate.origID = queryID; response.d_idstate.selfGenerated = true; response.d_buffer = std::move(query); d_state = State::idle; ++d_currentQueriesCount; queueResponse(state, now, std::move(response), false); - return QueryProcessingResult::Empty; + return QueryProcessingResult::SelfAnswered; } } diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 7d6e5bac60be..8ceb242346fe 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -1568,9 +1568,11 @@ bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint1 vinfolog("Got query for %s|%s from %s%s, relayed to %s", dq.ids.qname.toLogString(), QType(dq.ids.qtype).toString(), dq.ids.origRemote.toStringWithPort(), (doh ? " (https)" : ""), ds->getNameWithAddr()); + /* make a copy since we cannot touch dq.ids after the move */ + auto proxyProtocolPayloadSize = dq.ids.d_proxyProtocolPayloadSize; auto idOffset = ds->saveState(std::move(dq.ids)); /* set the correct ID */ - memcpy(query.data() + dq.ids.d_proxyProtocolPayloadSize, &idOffset, sizeof(idOffset)); + memcpy(query.data() + proxyProtocolPayloadSize, &idOffset, sizeof(idOffset)); /* you can't touch ids or du after this line, unless the call returned a non-negative value, because it might already have been freed */ diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 432e9f22c94d..7d9c52dd87b4 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -230,7 +230,9 @@ std::unique_ptr IncomingHTTP2Connection::getDOHUnit(uint32_t s void IncomingHTTP2Connection::restoreDOHUnit(std::unique_ptr&& unit) { auto context = std::unique_ptr(dynamic_cast(unit.release())); - d_currentStreams.at(context->d_streamID) = std::move(context->d_query); + if (context) { + d_currentStreams.at(context->d_streamID) = std::move(context->d_query); + } } IncomingHTTP2Connection::IncomingHTTP2Connection(ConnectionInfo&& connectionInfo, TCPClientThreadData& threadData, const struct timeval& now) : @@ -906,9 +908,6 @@ void IncomingHTTP2Connection::handleIncomingQuery(IncomingHTTP2Connection::Pendi case QueryProcessingResult::InvalidHeaders: handleImmediateResponse(400, "DoH invalid headers"); break; - case QueryProcessingResult::Empty: - handleImmediateResponse(200, "DoH empty query", std::move(query.d_buffer)); - break; case QueryProcessingResult::Dropped: handleImmediateResponse(403, "DoH dropped query"); break; diff --git a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh index e3ee319b11a1..4c8c47323880 100644 --- a/pdns/dnsdistdist/dnsdist-tcp-upstream.hh +++ b/pdns/dnsdistdist/dnsdist-tcp-upstream.hh @@ -27,7 +27,7 @@ public: class IncomingTCPConnectionState : public TCPQuerySender, public std::enable_shared_from_this { public: - enum class QueryProcessingResult : uint8_t { Forwarded, TooSmall, InvalidHeaders, Empty, Dropped, SelfAnswered, NoBackend, Asynchronous }; + enum class QueryProcessingResult : uint8_t { Forwarded, TooSmall, InvalidHeaders, Dropped, SelfAnswered, NoBackend, Asynchronous }; enum class ProxyProtocolResult : uint8_t { Reading, Done, Error }; IncomingTCPConnectionState(ConnectionInfo&& ci, TCPClientThreadData& threadData, const struct timeval& now): d_buffer(s_maxPacketCacheEntrySize), d_ci(std::move(ci)), d_handler(d_ci.fd, timeval{g_tcpRecvTimeout,0}, d_ci.cs->tlsFrontend ? d_ci.cs->tlsFrontend->getContext() : (d_ci.cs->dohFrontend ? d_ci.cs->dohFrontend->d_tlsContext.getContext() : nullptr), now.tv_sec), d_connectionStartTime(now), d_ioState(make_unique(*threadData.mplexer, d_ci.fd)), d_threadData(threadData), d_creatorThreadID(std::this_thread::get_id()) diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 128bee4126d5..73cdb86f4fe3 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -606,7 +606,10 @@ class DoHCrossProtocolQuery : public CrossProtocolQuery std::shared_ptr getTCPQuerySender() override { - dynamic_cast(query.d_idstate.du.get())->downstream = downstream; + auto* unit = dynamic_cast(query.d_idstate.du.get()); + if (unit != nullptr) { + unit->downstream = downstream; + } return s_sender; } @@ -812,13 +815,20 @@ static void processDOHQuery(DOHUnitUniquePtr&& unit, bool inMainThread = false) } if (inMainThread) { - // NOLINTNEXTLINE(bugprone-use-after-move): cpq is not altered if the call fails - unit = cpq->releaseDU(); + // cpq is not altered if the call fails but linters are not smart enough to notice that + if (cpq) { + // NOLINTNEXTLINE(bugprone-use-after-move): cpq is not altered if the call fails + unit = cpq->releaseDU(); + } unit->status_code = 502; handleImmediateResponse(std::move(unit), "DoH internal error"); } else { - cpq->handleInternalError(); + // cpq is not altered if the call fails but linters are not smart enough to notice that + if (cpq) { + // NOLINTNEXTLINE(bugprone-use-after-move): cpq is not altered if the call fails + cpq->handleInternalError(); + } } return; } diff --git a/regression-tests.dnsdist/test_DOH.py b/regression-tests.dnsdist/test_DOH.py index f9fce6be567d..81f39e659dbb 100644 --- a/regression-tests.dnsdist/test_DOH.py +++ b/regression-tests.dnsdist/test_DOH.py @@ -253,6 +253,22 @@ def testDOHWithoutQuery(self): rcode = conn.getinfo(pycurl.RESPONSE_CODE) self.assertEqual(rcode, 400) + def testDOHZeroQDCount(self): + """ + DOH: qdcount == 0 + """ + if self._dohLibrary == 'h2o': + raise unittest.SkipTest('h2o tries to parse the qname early, so this check will fail') + name = 'zero-qdcount.doh.tests.powerdns.com.' + query = dns.message.Message() + query.id = 0 + query.flags &= ~dns.flags.RD + expectedResponse = dns.message.make_response(query) + expectedResponse.set_rcode(dns.rcode.NOTIMP) + + (_, receivedResponse) = self.sendDOHQuery(self._dohServerPort, self._serverName, self._dohBaseURL, caFile=self._caCert, query=query, response=None, useQueue=False) + self.assertEqual(receivedResponse, expectedResponse) + def testDOHShortPath(self): """ DOH: Short path in GET query From ebe3da4fbf11de76a0c33c90e355ea0e401b5b01 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Tue, 10 Oct 2023 10:32:03 +0200 Subject: [PATCH 857/909] dnsdist: Prevent a warning about pointer arithmetic use --- pdns/dnsdist.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 8ceb242346fe..8e2eee70c186 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -1572,7 +1572,7 @@ bool assignOutgoingUDPQueryToBackend(std::shared_ptr& ds, uint1 auto proxyProtocolPayloadSize = dq.ids.d_proxyProtocolPayloadSize; auto idOffset = ds->saveState(std::move(dq.ids)); /* set the correct ID */ - memcpy(query.data() + proxyProtocolPayloadSize, &idOffset, sizeof(idOffset)); + memcpy(&query.at(proxyProtocolPayloadSize), &idOffset, sizeof(idOffset)); /* you can't touch ids or du after this line, unless the call returned a non-negative value, because it might already have been freed */ From 115db75920b73f07c356308df1b83ba296850e2a Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 11 Oct 2023 10:41:45 +0200 Subject: [PATCH 858/909] dnsdist: Switch to our fork of h2o to mitigate http2 rapid reset --- builder-support/debian/dnsdist/debian-buster/control | 1 - builder-support/debian/dnsdist/debian-buster/rules | 5 ++--- builder-support/dockerfiles/Dockerfile.debbuild | 6 ++++++ builder-support/dockerfiles/Dockerfile.rpmbuild | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/builder-support/debian/dnsdist/debian-buster/control b/builder-support/debian/dnsdist/debian-buster/control index 624f518e52b0..f42fa0ad13e9 100644 --- a/builder-support/debian/dnsdist/debian-buster/control +++ b/builder-support/debian/dnsdist/debian-buster/control @@ -10,7 +10,6 @@ Build-Depends: debhelper (>= 10), libedit-dev, libfstrm-dev, libgnutls28-dev, - libh2o-evloop-dev, liblmdb-dev, libluajit-5.1-dev [!arm64 !s390x], liblua5.3-dev [arm64 s390x], diff --git a/builder-support/debian/dnsdist/debian-buster/rules b/builder-support/debian/dnsdist/debian-buster/rules index e9a2a8cf1a36..04da6b44e201 100755 --- a/builder-support/debian/dnsdist/debian-buster/rules +++ b/builder-support/debian/dnsdist/debian-buster/rules @@ -36,8 +36,6 @@ override_dh_auto_clean: dh_auto_clean override_dh_auto_configure: - # LIBS has been added because Ubuntu Bionic and Cosmic don't have the fix for https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=908124 pulled in - LIBS='-lwslay' \ ./configure \ --host=$(DEB_HOST_GNU_TYPE) \ --build=$(DEB_BUILD_GNU_TYPE) \ @@ -61,7 +59,8 @@ override_dh_auto_configure: --with-ebpf \ --with-service-user='_dnsdist' \ --with-service-group='_dnsdist' \ - $(CONFIGURE_ARGS) + $(CONFIGURE_ARGS) \ + PKG_CONFIG_PATH=/opt/lib/pkgconfig override_dh_auto_build-arch: dh_auto_build -- V=1 diff --git a/builder-support/dockerfiles/Dockerfile.debbuild b/builder-support/dockerfiles/Dockerfile.debbuild index 46b315d74b0a..29f10e8e27eb 100644 --- a/builder-support/dockerfiles/Dockerfile.debbuild +++ b/builder-support/dockerfiles/Dockerfile.debbuild @@ -16,6 +16,12 @@ RUN mv pdns-recursor*.deb /dist; mv pdns-recursor*.ddeb /dist || true @ENDIF @IF [ -n "$M_dnsdist$M_all" ] +RUN mkdir /libh2o && cd /libh2o && \ + apt-get update && apt-get install -y cmake curl libssl-dev zlib1g-dev && \ + curl -L https://github.com/PowerDNS/h2o/archive/refs/tags/v2.2.6+pdns2.tar.gz | tar xz && \ + CFLAGS='-fPIC' cmake -DWITH_PICOTLS=off -DWITH_BUNDLED_SSL=off -DWITH_MRUBY=off -DCMAKE_INSTALL_PREFIX=/opt ./h2o-2.2.6-pdns2 && \ + make install + RUN builder/helpers/build-debs.sh dnsdist-${BUILDER_VERSION} RUN mv dnsdist*.deb /dist; mv dnsdist*.ddeb /dist || true diff --git a/builder-support/dockerfiles/Dockerfile.rpmbuild b/builder-support/dockerfiles/Dockerfile.rpmbuild index 82334e51f1d2..ee316caa0d1c 100644 --- a/builder-support/dockerfiles/Dockerfile.rpmbuild +++ b/builder-support/dockerfiles/Dockerfile.rpmbuild @@ -52,8 +52,8 @@ RUN touch /var/lib/rpm/* && if $(grep -q 'release 7' /etc/redhat-release); then # this is fine because --allowerasing is only there to deal with libcurl conflicting with libcurl-minimal on some el9 images RUN touch /var/lib/rpm/* && mkdir /libh2o && cd /libh2o && \ yum install -y --allowerasing curl libcurl openssl-devel cmake || yum install -y curl libcurl openssl-devel cmake && \ - curl -L https://github.com/h2o/h2o/archive/v2.2.6.tar.gz | tar xz && \ - CFLAGS='-fPIC' cmake -DWITH_PICOTLS=off -DWITH_BUNDLED_SSL=off -DWITH_MRUBY=off -DCMAKE_INSTALL_PREFIX=/opt ./h2o-2.2.6 && \ + curl -L https://github.com/PowerDNS/h2o/archive/refs/tags/v2.2.6+pdns2.tar.gz | tar xz && \ + CFLAGS='-fPIC' cmake -DWITH_PICOTLS=off -DWITH_BUNDLED_SSL=off -DWITH_MRUBY=off -DCMAKE_INSTALL_PREFIX=/opt ./h2o-2.2.6-pdns2 && \ make install RUN touch /var/lib/rpm/* && if $(grep -q 'release 7' /etc/redhat-release); then \ From 97d18cb451fcac78816604556629278c9ca49d3c Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 11 Oct 2023 12:04:21 +0200 Subject: [PATCH 859/909] builder-support: Use curl's "fail fast with no output at all on server errors" option --- builder-support/dockerfiles/Dockerfile.debbuild | 2 +- builder-support/dockerfiles/Dockerfile.rpmbuild | 2 +- builder-support/helpers/install_rust.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/builder-support/dockerfiles/Dockerfile.debbuild b/builder-support/dockerfiles/Dockerfile.debbuild index 29f10e8e27eb..71d30f6ee8b4 100644 --- a/builder-support/dockerfiles/Dockerfile.debbuild +++ b/builder-support/dockerfiles/Dockerfile.debbuild @@ -18,7 +18,7 @@ RUN mv pdns-recursor*.deb /dist; mv pdns-recursor*.ddeb /dist || true @IF [ -n "$M_dnsdist$M_all" ] RUN mkdir /libh2o && cd /libh2o && \ apt-get update && apt-get install -y cmake curl libssl-dev zlib1g-dev && \ - curl -L https://github.com/PowerDNS/h2o/archive/refs/tags/v2.2.6+pdns2.tar.gz | tar xz && \ + curl -f -L https://github.com/PowerDNS/h2o/archive/refs/tags/v2.2.6+pdns2.tar.gz | tar xz && \ CFLAGS='-fPIC' cmake -DWITH_PICOTLS=off -DWITH_BUNDLED_SSL=off -DWITH_MRUBY=off -DCMAKE_INSTALL_PREFIX=/opt ./h2o-2.2.6-pdns2 && \ make install diff --git a/builder-support/dockerfiles/Dockerfile.rpmbuild b/builder-support/dockerfiles/Dockerfile.rpmbuild index ee316caa0d1c..350bbf42e11d 100644 --- a/builder-support/dockerfiles/Dockerfile.rpmbuild +++ b/builder-support/dockerfiles/Dockerfile.rpmbuild @@ -52,7 +52,7 @@ RUN touch /var/lib/rpm/* && if $(grep -q 'release 7' /etc/redhat-release); then # this is fine because --allowerasing is only there to deal with libcurl conflicting with libcurl-minimal on some el9 images RUN touch /var/lib/rpm/* && mkdir /libh2o && cd /libh2o && \ yum install -y --allowerasing curl libcurl openssl-devel cmake || yum install -y curl libcurl openssl-devel cmake && \ - curl -L https://github.com/PowerDNS/h2o/archive/refs/tags/v2.2.6+pdns2.tar.gz | tar xz && \ + curl -f -L https://github.com/PowerDNS/h2o/archive/refs/tags/v2.2.6+pdns2.tar.gz | tar xz && \ CFLAGS='-fPIC' cmake -DWITH_PICOTLS=off -DWITH_BUNDLED_SSL=off -DWITH_MRUBY=off -DCMAKE_INSTALL_PREFIX=/opt ./h2o-2.2.6-pdns2 && \ make install diff --git a/builder-support/helpers/install_rust.sh b/builder-support/helpers/install_rust.sh index 97a766b63e22..f9e931385659 100755 --- a/builder-support/helpers/install_rust.sh +++ b/builder-support/helpers/install_rust.sh @@ -35,7 +35,7 @@ fi cd /tmp echo $0: Downloading $RUST_TARBALL -curl -o $RUST_TARBALL $SITE/$RUST_TARBALL +curl -f -o $RUST_TARBALL $SITE/$RUST_TARBALL # Line below should echo two spaces between digest and name echo $VALUE" "$RUST_TARBALL | sha256sum -c - tar -zxf $RUST_TARBALL From ad3cd0efd002529a113a0486c7be288c6ebbf488 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 11 Oct 2023 12:20:32 +0200 Subject: [PATCH 860/909] dnsdist: Prepare ChangeLog and secpoll for DNSdist 1.8.2 --- docs/secpoll.zone | 3 ++- pdns/dnsdistdist/docs/changelog.rst | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 4c5730563ad4..549047772a1d 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023100501 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023101100 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -517,4 +517,5 @@ dnsdist-1.8.0-rc2.security-status 60 IN TXT "2 Unsuppor dnsdist-1.8.0-rc3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" dnsdist-1.8.0.security-status 60 IN TXT "1 OK" dnsdist-1.8.1.security-status 60 IN TXT "1 OK" +dnsdist-1.8.2.security-status 60 IN TXT "1 OK" dnsdist-1.9.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release (no known vulnerabilities)" diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index 79778a8ae24d..9c103fbc2deb 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -1,6 +1,22 @@ Changelog ========= +.. changelog:: + :version: 1.8.2 + :released: 11th of October 2023 + + This release fixes the HTTP2 rapid reset attack for the packages we provide. + If you are compiling DNSdist yourself or using the packages provided by your distribution, + please check that the h2o library has been patched to mitigate this vulnerability. + + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.8.x. + + .. change:: + :tags: Bug Fixes, Security + :pullreq: #13349 + + Switch to our fork of h2o to mitigate the HTTP2 rapid reset attack + .. changelog:: :version: 1.9.0-alpha1 :released: 18th of September 2023 From bd18396156eefaa3c259dc8b3dc82ff286d6a992 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 11 Oct 2023 12:58:56 +0200 Subject: [PATCH 861/909] secpoll: All DNSdist packages >= 1.4.0-alpha2 were built against a bad h2o version --- docs/secpoll.zone | 67 ++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 549047772a1d..332bdb72da6b 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023101100 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023101102 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -479,43 +479,44 @@ recursor-4.0.0_beta1-1pdns.jessie.raspbian.security-status 60 IN TXT "3 Upgrade ; dnsdist dnsdist-1.3.3.security-status 60 IN TXT "1 OK" dnsdist-1.4.0-alpha1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.4.0-alpha2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.4.0-beta1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.4.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.4.0-rc2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.4.0-rc3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.4.0-rc4.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.4.0-rc5.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.4.0.security-status 60 IN TXT "1 OK" -dnsdist-1.5.0-alpha1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.5.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.5.0-rc2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.5.0-rc3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.5.0-rc4.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.5.0.security-status 60 IN TXT "1 OK" -dnsdist-1.5.1.security-status 60 IN TXT "1 OK" -dnsdist-1.5.2.security-status 60 IN TXT "1 OK" -dnsdist-1.6.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.6.0-alpha2.security-status 60 IN TXT "3 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.6.0-alpha3.security-status 60 IN TXT "3 Unsupported pre-release (no known vulnerabilities)" +dnsdist-1.4.0-alpha2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.4.0-beta1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.4.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.4.0-rc2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.4.0-rc3.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.4.0-rc4.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.4.0-rc5.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.4.0.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.5.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.5.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.5.0-rc2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.5.0-rc3.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.5.0-rc4.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.5.0.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.5.1.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.5.2.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.6.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.6.0-alpha2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.6.0-alpha3.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" dnsdist-1.6.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release" dnsdist-1.6.0-rc2.security-status 60 IN TXT "3 Unsupported pre-release" -dnsdist-1.6.0.security-status 60 IN TXT "1 OK" -dnsdist-1.6.1.security-status 60 IN TXT "1 OK" +dnsdist-1.6.0.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.6.1.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" dnsdist-1.7.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release" dnsdist-1.7.0-alpha2.security-status 60 IN TXT "3 Unsupported pre-release" dnsdist-1.7.0-beta1.security-status 60 IN TXT "3 Unsupported pre-release" dnsdist-1.7.0-beta2.security-status 60 IN TXT "3 Unsupported pre-release" dnsdist-1.7.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release" -dnsdist-1.7.0.security-status 60 IN TXT "1 OK" -dnsdist-1.7.1.security-status 60 IN TXT "1 OK" -dnsdist-1.7.2.security-status 60 IN TXT "1 OK" -dnsdist-1.7.3.security-status 60 IN TXT "1 OK" -dnsdist-1.7.4.security-status 60 IN TXT "1 OK" -dnsdist-1.8.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.8.0-rc2.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.8.0-rc3.security-status 60 IN TXT "2 Unsupported pre-release (no known vulnerabilities)" -dnsdist-1.8.0.security-status 60 IN TXT "1 OK" -dnsdist-1.8.1.security-status 60 IN TXT "1 OK" +dnsdist-1.7.0.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.7.1.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.7.2.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.7.3.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.7.4.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.7.5.security-status 60 IN TXT "1 OK" +dnsdist-1.8.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.8.0-rc2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.8.0-rc3.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.8.0.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" +dnsdist-1.8.1.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" dnsdist-1.8.2.security-status 60 IN TXT "1 OK" -dnsdist-1.9.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release (no known vulnerabilities)" +dnsdist-1.9.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release (known vulnerabilities)" From ceea1249a445ddc510be8f1832ee419b5f867d90 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 11 Oct 2023 13:02:51 +0200 Subject: [PATCH 862/909] dnsdist: Add a ChangeLog entry for 1.7.5 as well --- pdns/dnsdistdist/docs/changelog.rst | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pdns/dnsdistdist/docs/changelog.rst b/pdns/dnsdistdist/docs/changelog.rst index 9c103fbc2deb..ccdb0ffd0ca3 100644 --- a/pdns/dnsdistdist/docs/changelog.rst +++ b/pdns/dnsdistdist/docs/changelog.rst @@ -17,6 +17,22 @@ Changelog Switch to our fork of h2o to mitigate the HTTP2 rapid reset attack +.. changelog:: + :version: 1.7.5 + :released: 11th of October 2023 + + This release fixes the HTTP2 rapid reset attack for the packages we provide. + If you are compiling DNSdist yourself or using the packages provided by your distribution, + please check that the h2o library has been patched to mitigate this vulnerability. + + Please review the :doc:`Upgrade Guide <../upgrade_guide>` before upgrading from versions < 1.7.x. + + .. change:: + :tags: Bug Fixes, Security + :pullreq: #13351 + + Switch to our fork of h2o to mitigate the HTTP2 rapid reset attack + .. changelog:: :version: 1.9.0-alpha1 :released: 18th of September 2023 From 071706d882e97a1e4bf12a0013d746979ad91b4f Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 11 Oct 2023 13:04:21 +0200 Subject: [PATCH 863/909] secpoll: Make it lear that a vulnerability exists for all pre-releases --- docs/secpoll.zone | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index 332bdb72da6b..a734668c98e6 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023101102 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023101103 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -498,15 +498,15 @@ dnsdist-1.5.2.security-status 60 IN TXT "3 Upgrade dnsdist-1.6.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" dnsdist-1.6.0-alpha2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" dnsdist-1.6.0-alpha3.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" -dnsdist-1.6.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release" -dnsdist-1.6.0-rc2.security-status 60 IN TXT "3 Unsupported pre-release" +dnsdist-1.6.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.6.0-rc2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" dnsdist-1.6.0.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" dnsdist-1.6.1.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" -dnsdist-1.7.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release" -dnsdist-1.7.0-alpha2.security-status 60 IN TXT "3 Unsupported pre-release" -dnsdist-1.7.0-beta1.security-status 60 IN TXT "3 Unsupported pre-release" -dnsdist-1.7.0-beta2.security-status 60 IN TXT "3 Unsupported pre-release" -dnsdist-1.7.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release" +dnsdist-1.7.0-alpha1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.7.0-alpha2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.7.0-beta1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.7.0-beta2.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" +dnsdist-1.7.0-rc1.security-status 60 IN TXT "3 Unsupported pre-release (known vulnerabilities)" dnsdist-1.7.0.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" dnsdist-1.7.1.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" dnsdist-1.7.2.security-status 60 IN TXT "3 Upgrade now, see https://blog.cloudflare.com/technical-breakdown-http2-rapid-reset-ddos-attack/" From 0a69a426536f3455efe97b5bb4f5a7632f94e489 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Wed, 11 Oct 2023 13:07:21 +0200 Subject: [PATCH 864/909] spell-check: Allow 'DDoS' --- .github/actions/spell-check/expect.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 04155679ef24..3b79a21184bd 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -269,6 +269,7 @@ dbr DBX dcobject ddns +ddos deactivatedomainkey debian deboynepollard From 60ba49d38e5ded2df5a367d8acacba8b8ec3d2cc Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 11 Oct 2023 14:22:03 +0200 Subject: [PATCH 865/909] If serving stale, wipe CNAME records from cache when we get a NODATA negative response for them PR #12395 already did that for the NXDOMAIN case. --- pdns/recursordist/syncres.cc | 5 + pdns/recursordist/test-syncres_cc10.cc | 155 +++++++++++++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 129091b5db3a..0f7bb2646de8 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -5049,6 +5049,11 @@ bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, co ne.d_ttd = d_now.tv_sec + lowestTTL; ne.d_orig_ttl = lowestTTL; if (qtype.getCode()) { // prevents us from NXDOMAIN'ing a whole domain + // doCNAMECacheCheck() checks record cache and does not look into negcache. That means that an old record might be found if + // serve-stale is active. Avoid that by explicitly zapping that CNAME record. + if (qtype == QType::CNAME && MemRecursorCache::s_maxServedStaleExtensions > 0) { + g_recCache->doWipeCache(qname, false, qtype); + } g_negCache->add(ne); } diff --git a/pdns/recursordist/test-syncres_cc10.cc b/pdns/recursordist/test-syncres_cc10.cc index 474c8cf8f458..1f8abffba9a5 100644 --- a/pdns/recursordist/test-syncres_cc10.cc +++ b/pdns/recursordist/test-syncres_cc10.cc @@ -1626,6 +1626,161 @@ BOOST_AUTO_TEST_CASE(test_servestale_cname_to_nxdomain) BOOST_CHECK_EQUAL(lookupCount, 3U); } +BOOST_AUTO_TEST_CASE(test_servestale_cname_to_nodata) +{ + std::unique_ptr sr; + initSR(sr); + MemRecursorCache::s_maxServedStaleExtensions = 1440; + NegCache::s_maxServedStaleExtensions = 1440; + + primeHints(); + + const DNSName target("www.powerdns.com."); + const DNSName auth("powerdns.com."); + + std::set downServers; + size_t downCount = 0; + size_t lookupCount = 0; + bool cnameOK = true; + + const int theTTL = 5; + const int negTTL = 60; + + sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &cnameOK, target, auth](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { + /* this will cause issue with qname minimization if we ever implement it */ + if (downServers.find(ip) != downServers.end()) { + downCount++; + return LWResult::Result::Timeout; + } + + if (isRootServer(ip)) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY); + addRecordToLW(res, "a.gtld-servers.net.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL); + addRecordToLW(res, "a.gtld-servers.net.", QType::AAAA, "2001:DB8::1", DNSResourceRecord::ADDITIONAL); + return LWResult::Result::Success; + } + else if (ip == ComboAddress("192.0.2.1:53") || ip == ComboAddress("[2001:DB8::1]:53")) { + setLWResult(res, 0, false, false, true); + addRecordToLW(res, "powerdns.com.", QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, theTTL); + addRecordToLW(res, "powerdns.com.", QType::NS, "pdns-public-ns2.powerdns.com.", DNSResourceRecord::AUTHORITY, theTTL); + addRecordToLW(res, "pdns-public-ns1.powerdns.com.", QType::A, "192.0.2.2", DNSResourceRecord::ADDITIONAL, theTTL); + addRecordToLW(res, "pdns-public-ns1.powerdns.com.", QType::AAAA, "2001:DB8::2", DNSResourceRecord::ADDITIONAL, theTTL); + addRecordToLW(res, "pdns-public-ns2.powerdns.com.", QType::A, "192.0.2.3", DNSResourceRecord::ADDITIONAL, theTTL); + addRecordToLW(res, "pdns-public-ns2.powerdns.com.", QType::AAAA, "2001:DB8::3", DNSResourceRecord::ADDITIONAL, theTTL); + return LWResult::Result::Success; + } + else if (ip == ComboAddress("192.0.2.2:53") || ip == ComboAddress("192.0.2.3:53") || ip == ComboAddress("[2001:DB8::2]:53") || ip == ComboAddress("[2001:DB8::3]:53")) { + if (cnameOK) { + setLWResult(res, 0, true, false, true); + addRecordToLW(res, target, QType::CNAME, "cname.powerdns.com.", DNSResourceRecord::ANSWER, 5); + addRecordToLW(res, DNSName("cname.powerdns.com"), QType::A, "192.0.2.4", DNSResourceRecord::ANSWER, theTTL); + lookupCount++; + return LWResult::Result::Success; + } + else { + setLWResult(res, RCode::NoError, true, false, true); + addRecordToLW(res, auth, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 60", DNSResourceRecord::AUTHORITY, negTTL); + lookupCount++; + return LWResult::Result::Success; + } + } + else { + return LWResult::Result::Timeout; + } + }); + + time_t now = time(nullptr); + + vector ret; + int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + BOOST_REQUIRE_EQUAL(ret.size(), 2U); + BOOST_CHECK(ret[0].d_type == QType::CNAME); + BOOST_CHECK(ret[1].d_type == QType::A); + BOOST_CHECK_EQUAL(ret[0].d_name, target); + BOOST_CHECK_EQUAL(ret[1].d_name, DNSName("cname.powerdns.com")); + BOOST_CHECK_EQUAL(downCount, 0U); + BOOST_CHECK_EQUAL(lookupCount, 2U); + + downServers.insert(ComboAddress("192.0.2.2:53")); + downServers.insert(ComboAddress("192.0.2.3:53")); + downServers.insert(ComboAddress("[2001:DB8::2]:53")); + downServers.insert(ComboAddress("[2001:DB8::3]:53")); + + sr->setNow(timeval{now + theTTL + 1, 0}); + + // record is expired, so serve stale should kick in + ret.clear(); + res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_REQUIRE_EQUAL(ret.size(), 2U); + BOOST_CHECK(ret[0].d_type == QType::CNAME); + BOOST_CHECK(ret[1].d_type == QType::A); + BOOST_CHECK_EQUAL(ret[0].d_name, target); + BOOST_CHECK_EQUAL(ret[1].d_name, DNSName("cname.powerdns.com")); + BOOST_CHECK_EQUAL(downCount, 8U); + BOOST_CHECK_EQUAL(lookupCount, 2U); + + // Again, no lookup as the record is marked stale + ret.clear(); + res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_REQUIRE_EQUAL(ret.size(), 2U); + BOOST_CHECK(ret[0].d_type == QType::CNAME); + BOOST_CHECK(ret[1].d_type == QType::A); + BOOST_CHECK_EQUAL(ret[0].d_name, target); + BOOST_CHECK_EQUAL(ret[1].d_name, DNSName("cname.powerdns.com")); + BOOST_CHECK_EQUAL(downCount, 8U); + BOOST_CHECK_EQUAL(lookupCount, 2U); + + // Again, no lookup as the record is marked stale but as the TTL has passed a task should have been pushed + sr->setNow(timeval{now + 2 * (theTTL + 1), 0}); + ret.clear(); + res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_REQUIRE_EQUAL(ret.size(), 2U); + BOOST_CHECK(ret[0].d_type == QType::CNAME); + BOOST_CHECK(ret[1].d_type == QType::A); + BOOST_CHECK_EQUAL(ret[0].d_name, target); + BOOST_CHECK_EQUAL(ret[1].d_name, DNSName("cname.powerdns.com")); + BOOST_CHECK_EQUAL(downCount, 8U); + BOOST_CHECK_EQUAL(lookupCount, 2U); + + BOOST_REQUIRE_EQUAL(getTaskSize(), 2U); + auto task = taskQueuePop(); + BOOST_CHECK(task.d_qname == target); + BOOST_CHECK_EQUAL(task.d_qtype, QType::CNAME); + task = taskQueuePop(); + BOOST_CHECK(task.d_qname == DNSName("cname.powerdns.com")); + BOOST_CHECK_EQUAL(task.d_qtype, QType::A); + + // Now simulate a succeeding task execution and NoDATA on explicit CNAME result becomes available + cnameOK = false; + sr->setNow(timeval{now + 3 * (theTTL + 1), 0}); + downServers.clear(); + sr->setRefreshAlmostExpired(true); + + ret.clear(); + res = sr->beginResolve(target, QType(QType::CNAME), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_CHECK(ret[0].d_type == QType::SOA); + BOOST_CHECK_EQUAL(ret[0].d_name, auth); + BOOST_CHECK_EQUAL(downCount, 8U); + BOOST_CHECK_EQUAL(lookupCount, 3U); + + // And again, result should come from cache + sr->setRefreshAlmostExpired(false); + ret.clear(); + res = sr->beginResolve(target, QType(QType::CNAME), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); + BOOST_REQUIRE_EQUAL(ret.size(), 1U); + BOOST_CHECK(ret[0].d_type == QType::SOA); + BOOST_CHECK_EQUAL(ret[0].d_name, auth); + BOOST_CHECK_EQUAL(downCount, 8U); + BOOST_CHECK_EQUAL(lookupCount, 3U); +} + BOOST_AUTO_TEST_CASE(test_servestale_immediateservfail) { std::unique_ptr sr; From c88611d664e000e5ccdf143c64c2751591c41ca6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 25 Sep 2023 13:59:44 +0200 Subject: [PATCH 866/909] Make QName Minimization parameters from RFC 9156 settable Also fix a counting ommission --- pdns/recursordist/rec-main.cc | 2 ++ pdns/recursordist/settings/table.py | 26 +++++++++++++++++++++++++- pdns/recursordist/syncres.cc | 15 ++++++++------- pdns/recursordist/syncres.hh | 2 ++ 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 25e6d7d74c7c..fd713a11fd1e 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1687,6 +1687,8 @@ static int initSyncRes(Logr::log_t log) SyncRes::s_ecscachelimitttl = ::arg().asNum("ecs-cache-limit-ttl"); SyncRes::s_qnameminimization = ::arg().mustDo("qname-minimization"); + SyncRes::s_minimize_one_lab = ::arg().asNum("qname-minimize-one-label"); + SyncRes::s_max_minimize_count = ::arg().asNum("qname-max-minimize-count"); SyncRes::s_hardenNXD = SyncRes::HardenNXD::DNSSEC; string value = ::arg()["nothing-below-nxdomain"]; diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index e833fb656406..2a54dc147836 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -1955,10 +1955,34 @@ 'help' : 'Use Query Name Minimization', 'doc' : ''' Enable Query Name Minimization. This implements a relaxed form of Query Name Mimimization as -described in :rfc:`7816`. +described in :rfc:`9156`. ''', 'versionadded': '4.3.0' }, + { + 'name' : 'qname_max_minimize_count', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '10', + 'help' : 'RFC9156 max minimize count', + 'doc' : ''' +``Max minimize count`` parameter, described in :rfc:`9156`. This is the maximum number of iterations +of the Quqey Name Minimization Algorithm. + ''', + 'versionadded': '5.0.0' + }, + { + 'name' : 'qname_minimize_one_label', + 'section' : 'recursor', + 'type' : LType.Uint64, + 'default' : '4', + 'help' : 'RFC9156 minimize one label parameter', + 'doc' : ''' +``Minimize one label`` parameter, described in :rfc:`9156`. +The value for the number of iterations of the Query Name Minimization Algorithm that should only have one label appended. + ''', + 'versionadded': '5.0.0' + }, { 'name' : 'source_address', 'section' : 'outgoing', diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 129091b5db3a..2c779dddcffe 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1596,20 +1596,20 @@ LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& address, bool } /* The parameters from rfc9156. */ -/* maximum number of QNAME minimisation iterations */ -static const unsigned int s_max_minimise_count = 10; -/* number of queries that should only have one label appended */ -static const unsigned int s_minimise_one_lab = 4; +/* maximum number of QNAME minimization iterations */ +unsigned int SyncRes::s_max_minimize_count; // default is 10 +/* number of iterations that should only have one label appended */ +unsigned int SyncRes::s_minimize_one_lab; // default is 4 static unsigned int qmStepLen(unsigned int labels, unsigned int qnamelen, unsigned int i) { unsigned int step; - if (i < s_minimise_one_lab) { + if (i < SyncRes::s_minimize_one_lab) { step = 1; } - else if (i < s_max_minimise_count) { - step = std::max(1U, (qnamelen - labels) / (10 - i)); + else if (i < SyncRes::s_max_minimize_count) { + step = std::max(1U, (qnamelen - labels) / (SyncRes::s_max_minimize_count - i)); } else { step = qnamelen - labels; @@ -1788,6 +1788,7 @@ int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector Date: Mon, 25 Sep 2023 14:59:47 +0200 Subject: [PATCH 867/909] Typo Co-authored-by: Remi Gacogne --- pdns/recursordist/settings/table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index 2a54dc147836..826d843c7b6d 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -1967,7 +1967,7 @@ 'help' : 'RFC9156 max minimize count', 'doc' : ''' ``Max minimize count`` parameter, described in :rfc:`9156`. This is the maximum number of iterations -of the Quqey Name Minimization Algorithm. +of the Query Name Minimization Algorithm. ''', 'versionadded': '5.0.0' }, From 831baae77e9d6e29dd6de5919df275083aa797a9 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 25 Sep 2023 16:08:18 +0200 Subject: [PATCH 868/909] Init default values for new settings --- pdns/recursordist/test-syncres_cc.cc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index 044af5533229..b544195ceb00 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -183,6 +183,8 @@ void initSR(bool debug) SyncRes::s_save_parent_ns_set = true; SyncRes::s_maxnsperresolve = 13; SyncRes::s_locked_ttlperc = 0; + SyncRes::s_minimize_one_lab = 4; + SyncRes::s_max_minimize_count = 10; SyncRes::clearNSSpeeds(); BOOST_CHECK_EQUAL(SyncRes::getNSSpeedsSize(), 0U); From 3f15edc89322468d96125844d29f79ad9e92c002 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 9 Oct 2023 12:02:24 +0200 Subject: [PATCH 869/909] Apply suggestion from review by @rgacogne, thanks! --- pdns/recursordist/rec-main.cc | 2 +- pdns/recursordist/settings/table.py | 1 + pdns/recursordist/syncres.cc | 9 ++++----- pdns/recursordist/syncres.hh | 2 +- pdns/recursordist/test-syncres_cc.cc | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index fd713a11fd1e..aa964c82a3d2 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1687,7 +1687,7 @@ static int initSyncRes(Logr::log_t log) SyncRes::s_ecscachelimitttl = ::arg().asNum("ecs-cache-limit-ttl"); SyncRes::s_qnameminimization = ::arg().mustDo("qname-minimization"); - SyncRes::s_minimize_one_lab = ::arg().asNum("qname-minimize-one-label"); + SyncRes::s_minimize_one_label = ::arg().asNum("qname-minimize-one-label"); SyncRes::s_max_minimize_count = ::arg().asNum("qname-max-minimize-count"); SyncRes::s_hardenNXD = SyncRes::HardenNXD::DNSSEC; diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index 826d843c7b6d..31d24af82826 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -1980,6 +1980,7 @@ 'doc' : ''' ``Minimize one label`` parameter, described in :rfc:`9156`. The value for the number of iterations of the Query Name Minimization Algorithm that should only have one label appended. +This value has precedence over :ref:`setting-qname-max-minimize-count`. ''', 'versionadded': '5.0.0' }, diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 2c779dddcffe..53e6327fca1a 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -1599,13 +1599,13 @@ LWResult::Result SyncRes::asyncresolveWrapper(const ComboAddress& address, bool /* maximum number of QNAME minimization iterations */ unsigned int SyncRes::s_max_minimize_count; // default is 10 /* number of iterations that should only have one label appended */ -unsigned int SyncRes::s_minimize_one_lab; // default is 4 +unsigned int SyncRes::s_minimize_one_label; // default is 4 static unsigned int qmStepLen(unsigned int labels, unsigned int qnamelen, unsigned int i) { unsigned int step; - if (i < SyncRes::s_minimize_one_lab) { + if (i < SyncRes::s_minimize_one_label) { step = 1; } else if (i < SyncRes::s_max_minimize_count) { @@ -1695,7 +1695,7 @@ int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector bestns; @@ -1714,7 +1714,7 @@ int SyncRes::doResolve(const DNSName& qname, const QType qtype, vector Date: Wed, 11 Oct 2023 15:39:46 +0200 Subject: [PATCH 870/909] Tidy --- pdns/recursordist/syncres.cc | 2 +- pdns/recursordist/test-syncres_cc10.cc | 29 ++++++++++++-------------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 0f7bb2646de8..49ad614436c1 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -4747,7 +4747,7 @@ dState SyncRes::getDenialValidationState(const NegCache::NegCacheEntry& ne, cons return getDenial(csp, ne.d_name, ne.d_qtype.getCode(), referralToUnsigned, expectedState == dState::NXQTYPE, LogObject(prefix)); } -bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, const QType qtype, const DNSName& auth, LWResult& lwr, const bool sendRDQuery, vector& ret, set& nsset, DNSName& newtarget, DNSName& newauth, bool& realreferral, bool& negindic, vState& state, const bool needWildcardProof, const bool gatherWildcardProof, const unsigned int wildcardLabelsCount, int& rcode, bool& negIndicHasSignatures, unsigned int depth) +bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, const QType qtype, const DNSName& auth, LWResult& lwr, const bool sendRDQuery, vector& ret, set& nsset, DNSName& newtarget, DNSName& newauth, bool& realreferral, bool& negindic, vState& state, const bool needWildcardProof, const bool gatherWildcardProof, const unsigned int wildcardLabelsCount, int& rcode, bool& negIndicHasSignatures, unsigned int depth) // NOLINT(readability-function-cognitive-complexity) { bool done = false; DNSName dnameTarget, dnameOwner; diff --git a/pdns/recursordist/test-syncres_cc10.cc b/pdns/recursordist/test-syncres_cc10.cc index 1f8abffba9a5..cefe3fd49ddb 100644 --- a/pdns/recursordist/test-syncres_cc10.cc +++ b/pdns/recursordist/test-syncres_cc10.cc @@ -1643,24 +1643,24 @@ BOOST_AUTO_TEST_CASE(test_servestale_cname_to_nodata) size_t lookupCount = 0; bool cnameOK = true; - const int theTTL = 5; - const int negTTL = 60; + const time_t theTTL = 5; + const time_t negTTL = 60; - sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &cnameOK, target, auth](const ComboAddress& ip, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, boost::optional /* context */, LWResult* res, bool* /* chained */) { + sr->setAsyncCallback([&downServers, &downCount, &lookupCount, &cnameOK, target, auth](const ComboAddress& ipAddress, const DNSName& /* domain */, int /* type */, bool /* doTCP */, bool /* sendRDQuery */, int /* EDNS0Level */, struct timeval* /* now */, boost::optional& /* srcmask */, const boost::optional& /* context */, LWResult* res, bool* /* chained */) { /* this will cause issue with qname minimization if we ever implement it */ - if (downServers.find(ip) != downServers.end()) { + if (downServers.find(ipAddress) != downServers.end()) { downCount++; return LWResult::Result::Timeout; } - if (isRootServer(ip)) { + if (isRootServer(ipAddress)) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "com.", QType::NS, "a.gtld-servers.net.", DNSResourceRecord::AUTHORITY); addRecordToLW(res, "a.gtld-servers.net.", QType::A, "192.0.2.1", DNSResourceRecord::ADDITIONAL); addRecordToLW(res, "a.gtld-servers.net.", QType::AAAA, "2001:DB8::1", DNSResourceRecord::ADDITIONAL); return LWResult::Result::Success; } - else if (ip == ComboAddress("192.0.2.1:53") || ip == ComboAddress("[2001:DB8::1]:53")) { + if (ipAddress == ComboAddress("192.0.2.1:53") || ipAddress == ComboAddress("[2001:DB8::1]:53")) { setLWResult(res, 0, false, false, true); addRecordToLW(res, "powerdns.com.", QType::NS, "pdns-public-ns1.powerdns.com.", DNSResourceRecord::AUTHORITY, theTTL); addRecordToLW(res, "powerdns.com.", QType::NS, "pdns-public-ns2.powerdns.com.", DNSResourceRecord::AUTHORITY, theTTL); @@ -1670,7 +1670,7 @@ BOOST_AUTO_TEST_CASE(test_servestale_cname_to_nodata) addRecordToLW(res, "pdns-public-ns2.powerdns.com.", QType::AAAA, "2001:DB8::3", DNSResourceRecord::ADDITIONAL, theTTL); return LWResult::Result::Success; } - else if (ip == ComboAddress("192.0.2.2:53") || ip == ComboAddress("192.0.2.3:53") || ip == ComboAddress("[2001:DB8::2]:53") || ip == ComboAddress("[2001:DB8::3]:53")) { + if (ipAddress == ComboAddress("192.0.2.2:53") || ipAddress == ComboAddress("192.0.2.3:53") || ipAddress == ComboAddress("[2001:DB8::2]:53") || ipAddress == ComboAddress("[2001:DB8::3]:53")) { if (cnameOK) { setLWResult(res, 0, true, false, true); addRecordToLW(res, target, QType::CNAME, "cname.powerdns.com.", DNSResourceRecord::ANSWER, 5); @@ -1678,22 +1678,19 @@ BOOST_AUTO_TEST_CASE(test_servestale_cname_to_nodata) lookupCount++; return LWResult::Result::Success; } - else { - setLWResult(res, RCode::NoError, true, false, true); - addRecordToLW(res, auth, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 60", DNSResourceRecord::AUTHORITY, negTTL); - lookupCount++; - return LWResult::Result::Success; - } - } - else { - return LWResult::Result::Timeout; + setLWResult(res, RCode::NoError, true, false, true); + addRecordToLW(res, auth, QType::SOA, "pdns-public-ns1.powerdns.com. pieter\\.lexis.powerdns.com. 2017032301 10800 3600 604800 60", DNSResourceRecord::AUTHORITY, negTTL); + lookupCount++; + return LWResult::Result::Success; } + return LWResult::Result::Timeout; }); time_t now = time(nullptr); vector ret; int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret); + BOOST_CHECK_EQUAL(res, RCode::NoError); BOOST_REQUIRE_EQUAL(ret.size(), 2U); BOOST_CHECK(ret[0].d_type == QType::CNAME); BOOST_CHECK(ret[1].d_type == QType::A); From de02bfc15ca0b17bb082bcffd0882ec03257ce57 Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Wed, 11 Oct 2023 17:12:56 +0200 Subject: [PATCH 871/909] dnsdist Docker: enable h2o again, using our fork --- Dockerfile-dnsdist | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/Dockerfile-dnsdist b/Dockerfile-dnsdist index d9ad05a1a782..e89215d40b8d 100644 --- a/Dockerfile-dnsdist +++ b/Dockerfile-dnsdist @@ -40,6 +40,13 @@ RUN if [ "${DOCKER_FAKE_RELEASE}" = "YES" ]; then \ fi && \ BUILDER_MODULES=dnsdist autoreconf -vfi + +RUN mkdir /libh2o && cd /libh2o && \ + apt-get update && apt-get install -y cmake curl libssl-dev zlib1g-dev && \ + curl -f -L https://github.com/PowerDNS/h2o/archive/refs/tags/v2.2.6+pdns2.tar.gz | tar xz && \ + CFLAGS='-fPIC' cmake -DWITH_PICOTLS=off -DWITH_BUNDLED_SSL=off -DWITH_MRUBY=off -DCMAKE_INSTALL_PREFIX=/opt ./h2o-2.2.6-pdns2 && \ + make install + RUN mkdir /build && \ LUAVER=$([ -z "${NO_LUA_JIT##*$(dpkg --print-architecture)*}" ] && echo 'lua5.3' || echo 'luajit') && \ ./configure \ @@ -50,7 +57,9 @@ RUN mkdir /build && \ --enable-dnscrypt \ --enable-dns-over-tls \ --enable-dns-over-https \ - --with-re2 && \ + --with-re2 \ + --with-h2o \ + PKG_CONFIG_PATH=/opt/lib/pkgconfig && \ make clean && \ make $MAKEFLAGS install DESTDIR=/build && make clean && \ strip /build/usr/local/bin/* From 93522cd208e125ab5f13fa2487c55ded59d186ee Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Wed, 27 Sep 2023 14:56:14 +0200 Subject: [PATCH 872/909] First stab at converting api managed files --- pdns/recursordist/rec-main.cc | 2 + pdns/recursordist/settings/cxxsettings.hh | 1 + pdns/recursordist/settings/cxxsupport.cc | 119 ++++++++++++++++++++++ 3 files changed, 122 insertions(+) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index 25e6d7d74c7c..f61c81968396 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -1288,6 +1288,7 @@ void parseACLs() throw runtime_error("Error processing '" + configName + "': " + msg); break; case pdns::settings::rec::YamlSettingsStatus::OK: + pdns::settings::rec::processAPIDir(arg()["include-dir"], settings, log); // Does *not* set include-dir pdns::settings::rec::setArgsForACLRelatedSettings(settings); break; @@ -3384,6 +3385,7 @@ int main(int argc, char** argv) g_yamlSettings = true; SLOG(g_log << Logger::Notice << "YAML config found and processed for configname '" << yamlconfigname << "'" << endl, startupLog->info(Logr::Notice, "YAML config found and processed", "configname", Logging::Loggable(yamlconfigname))); + pdns::settings::rec::processAPIDir(arg()["include-dir"], settings, startupLog); pdns::settings::rec::bridgeStructToOldStyleSettings(settings); break; } diff --git a/pdns/recursordist/settings/cxxsettings.hh b/pdns/recursordist/settings/cxxsettings.hh index 7577e86d320f..ad21578da1ee 100644 --- a/pdns/recursordist/settings/cxxsettings.hh +++ b/pdns/recursordist/settings/cxxsettings.hh @@ -43,6 +43,7 @@ bool oldKVToBridgeStruct(string& key, const string& value, ::rust::String& secti std::string oldStyleSettingsFileToYaml(const string& fname, bool mainFile); std::string defaultsToYaml(); YamlSettingsStatus readYamlSettings(const std::string& configname, const std::string& includeDirOnCommandLine, rust::settings::rec::Recursorsettings& settings, std::string& msg, Logr::log_t log); +void processAPIDir(const string& includeDirOnCommandLine, pdns::rust::settings::rec::Recursorsettings& settings, Logr::log_t log); void bridgeStructToOldStyleSettings(const pdns::rust::settings::rec::Recursorsettings& settings); void readYamlForwardZonesFile(const std::string& filename, ::rust::Vec& vec, Logr::log_t log); void readYamlAllowFromFile(const std::string& filename, ::rust::Vec<::rust::String>& vec, Logr::log_t log); diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index bde1a244a3ae..b6db21383cc8 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -22,6 +22,9 @@ #include #include +#include +#include +#include #include "namespaces.hh" #include "arguments.hh" @@ -131,6 +134,122 @@ static void mergeYamlSubFile(const std::string& configname, Recursorsettings& se pdns::rust::settings::rec::merge(settings, data); } +static void convertACLFile(const string& includeDir, const string& apiDir, const std::string& filename) +{ + auto path = includeDir; + path.append("/").append(filename).append(".conf"); + auto file = ifstream(path); + if (!file.is_open()) { + cerr << "Cannot open " << path << endl; + return; + } + rust::vec result; + std::string line; + while (getline(file, line)) { + auto pos = line.find('#'); + if (pos != string::npos) { + line.resize(pos); + } + boost::trim(line); + if (line.empty()) { + continue; + } + auto plusis = line.find("+="); + if (plusis != string::npos) { + auto val = line.substr(plusis + 2); + boost::trim(val); + result.emplace_back(val); + } + } + rust::string yaml; + if (filename == "allow-from") { + yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_from", "allow_from_file", result); + } + else { + yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_notify_from", "allow_notify_from_file", result); + } + string yamlfilename = apiDir; + yamlfilename.append("/").append(filename).append(".yml"); + ofstream ofconf(yamlfilename + ".tmp"); + if (!ofconf) { + throw runtime_error("Could not open config file '" + yamlfilename + "' for writing: " + stringerror()); + } + ofconf << "# Generated by pdns-recursor REST API, DO NOT EDIT" << endl; + ofconf << yaml << endl; + ofconf.close(); + cerr << "Converted " << path << " to " << yamlfilename < forwardFiles; + ::arg().gatherIncludes(includeDir, "..conf", forwardFiles); + pdns::rust::settings::rec::Recursorsettings settings; + for (const auto& file : forwardFiles) { + auto yaml = pdns::settings::rec::oldStyleSettingsFileToYaml(file, false); + cerr << "Converted YAML for " << file << endl; + cerr << yaml << endl; + pdns::rust::settings::rec::merge(settings, yaml); + } + const string yamlAPiZonesFile = apiDir + "/apizones"; + + for (auto& zone : settings.recursor.auth_zones) { + const std::string origName(zone.file); + std::string newName(zone.file); + newName.replace(0, includeDir.length(), apiDir); + cerr << "Rename " << origName << ' ' << newName << ' '; + auto ret = rename(origName.c_str(), newName.c_str()); + cerr << ret << ' ' << stringerror() << endl; + zone.file = ::rust::String(newName); + api_add_auth_zone(yamlAPiZonesFile, zone); + } + for (const auto& zone : settings.recursor.forward_zones) { + api_add_forward_zone(yamlAPiZonesFile, zone); + } + for (const auto& zone : settings.recursor.forward_zones_recurse) { + api_add_forward_zone(yamlAPiZonesFile, zone); + } + for (const auto& file : forwardFiles) { + rename(file.c_str(), (file + ".converted").c_str()); + } +} + +void pdns::settings::rec::processAPIDir(const string& includeDirOnCommandLine, pdns::rust::settings::rec::Recursorsettings& settings, Logr::log_t log) +{ + auto apiDir = std::string(settings.webservice.api_dir); + if (apiDir.empty()) { + return; + } + auto includeDir = std::string(settings.recursor.include_dir); + if (!includeDirOnCommandLine.empty()) { + includeDir = includeDirOnCommandLine; + } + if (includeDir == apiDir) { + throw runtime_error("Active YAML settings do not allow include_dir to be equal to api_dir"); + } + const std::array aclFiles = { + "allow-from", + "allow-notify-from" + }; + for (const auto& file : aclFiles) { + convertACLFile(includeDir, apiDir, file); + auto path = apiDir; + path.append("/").append(file).append(".yml"); + try { + mergeYamlSubFile(path, settings, log); + } + catch (const runtime_error& err) { + } + } + convertForwardsandAuths(includeDir, apiDir, log); +} + pdns::settings::rec::YamlSettingsStatus pdns::settings::rec::readYamlSettings(const std::string& configname, const std::string& includeDirOnCommandLine, Recursorsettings& settings, std::string& msg, Logr::log_t log) { auto file = ifstream(configname); From d6ee98b05977c270fb7d9d9c8d758e8799b94555 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 12 Oct 2023 11:02:17 +0200 Subject: [PATCH 873/909] Error handling and bulk update of forwards --- pdns/recursordist/settings/cxxsupport.cc | 94 +++++++++++++------ pdns/recursordist/settings/rust-bridge-in.rs | 1 + pdns/recursordist/settings/rust/src/bridge.rs | 9 ++ 3 files changed, 76 insertions(+), 28 deletions(-) diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index b6db21383cc8..37ccfc35d426 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -134,13 +134,13 @@ static void mergeYamlSubFile(const std::string& configname, Recursorsettings& se pdns::rust::settings::rec::merge(settings, data); } -static void convertACLFile(const string& includeDir, const string& apiDir, const std::string& filename) +static void possiblyConvertACLFile(const string& includeDir, const string& apiDir, const std::string& filename, Logr::log_t log) { auto path = includeDir; path.append("/").append(filename).append(".conf"); auto file = ifstream(path); if (!file.is_open()) { - cerr << "Cannot open " << path << endl; + // Not an error, file just is not there return; } rust::vec result; @@ -170,31 +170,71 @@ static void convertACLFile(const string& includeDir, const string& apiDir, const } string yamlfilename = apiDir; yamlfilename.append("/").append(filename).append(".yml"); - ofstream ofconf(yamlfilename + ".tmp"); + string tmpfilename = yamlfilename + ".tmp"; + ofstream ofconf(tmpfilename); if (!ofconf) { - throw runtime_error("Could not open config file '" + yamlfilename + "' for writing: " + stringerror()); + int err = errno; + log->error(Logr::Error, err, "Cannot open for file for writing YAML", "to", Logging::Loggable(tmpfilename)); + throw runtime_error("YAML Conversion"); } ofconf << "# Generated by pdns-recursor REST API, DO NOT EDIT" << endl; ofconf << yaml << endl; ofconf.close(); - cerr << "Converted " << path << " to " << yamlfilename <error(Logr::Error, err, "Rename failed", "file", Logging::Loggable(path), "to", Logging::Loggable(path + ".converted")); + unlink(tmpfilename.c_str()); + throw runtime_error("YAML Conversion"); + } + + if (rename(tmpfilename.c_str(), yamlfilename.c_str()) != 0) { + int err = errno; + log->error(Logr::Error, err, "Rename failed", "file", Logging::Loggable(tmpfilename), "to", Logging::Loggable(yamlfilename)); + rename((path + ".converted").c_str(), path.c_str()); + throw runtime_error("YAML Conversion"); } - // ERROR CHECKS AND LOG - rename((yamlfilename + ".tmp").c_str(), yamlfilename.c_str()); + log->info(Logr::Notice, "Converted to YAML", "file", Logging::Loggable(path), "to", Logging::Loggable(yamlfilename)); } -static void convertForwardsandAuths(const std::string& includeDir, const std::string& apiDir, Logr::log_t log) +static void fileCopy(const string& src, const string& dst, Logr::log_t log) { - std::vector forwardFiles; - ::arg().gatherIncludes(includeDir, "..conf", forwardFiles); + ifstream ifconf(src); + if (!ifconf) { + log->info(Logr::Error, "Cannot open for file for reading", "file", Logging::Loggable(src)); + throw runtime_error("YAML Conversion"); + } + ofstream ofconf(dst); + if (!ofconf) { + log->info(Logr::Error, "Cannot open for file for writing YAML", "to", Logging::Loggable(dst)); + throw runtime_error("YAML Conversion"); + } + for (;;) { + auto character = ifconf.get(); + if (ifconf.eof()) { + break; + } + if (ifconf.bad()) { + int err = errno; + log->error(Logr::Error, err, "Error reading", "to", Logging::Loggable(src)); + throw runtime_error("YAML Conversion"); + } + ofconf.put(character); + if (ofconf.bad()) { + int err = errno; + log->error(Logr::Error, err, "Error writing YAML", "to", Logging::Loggable(dst)); + throw runtime_error("YAML Conversion"); + } + } + ofconf.close(); + ifconf.close(); +} +static void possiblyConvertForwardsandAuths(const std::string& includeDir, const std::string& apiDir, Logr::log_t log) +{ + std::vector forwAndAuthFiles; + ::arg().gatherIncludes(includeDir, "..conf", forwAndAuthFiles); pdns::rust::settings::rec::Recursorsettings settings; - for (const auto& file : forwardFiles) { + for (const auto& file : forwAndAuthFiles) { auto yaml = pdns::settings::rec::oldStyleSettingsFileToYaml(file, false); - cerr << "Converted YAML for " << file << endl; - cerr << yaml << endl; pdns::rust::settings::rec::merge(settings, yaml); } const string yamlAPiZonesFile = apiDir + "/apizones"; @@ -203,20 +243,18 @@ static void convertForwardsandAuths(const std::string& includeDir, const std::st const std::string origName(zone.file); std::string newName(zone.file); newName.replace(0, includeDir.length(), apiDir); - cerr << "Rename " << origName << ' ' << newName << ' '; - auto ret = rename(origName.c_str(), newName.c_str()); - cerr << ret << ' ' << stringerror() << endl; + log->info(Logr::Notice, "Copying auth zone file", "file", Logging::Loggable(origName), "to", Logging::Loggable(newName)); + fileCopy(origName, newName, log); zone.file = ::rust::String(newName); api_add_auth_zone(yamlAPiZonesFile, zone); } - for (const auto& zone : settings.recursor.forward_zones) { - api_add_forward_zone(yamlAPiZonesFile, zone); - } - for (const auto& zone : settings.recursor.forward_zones_recurse) { - api_add_forward_zone(yamlAPiZonesFile, zone); - } - for (const auto& file : forwardFiles) { - rename(file.c_str(), (file + ".converted").c_str()); + api_add_forward_zones(yamlAPiZonesFile, settings.recursor.forward_zones); + api_add_forward_zones(yamlAPiZonesFile, settings.recursor.forward_zones_recurse); + for (const auto& file : forwAndAuthFiles) { + if (rename(file.c_str(), (file + ".converted").c_str()) != 0) { + int err = errno; + log->error(Logr::Error, err, "Rename failed", "file", Logging::Loggable(file), "to", Logging::Loggable(file + ".converted")); + } } } @@ -238,7 +276,7 @@ void pdns::settings::rec::processAPIDir(const string& includeDirOnCommandLine, p "allow-notify-from" }; for (const auto& file : aclFiles) { - convertACLFile(includeDir, apiDir, file); + possiblyConvertACLFile(includeDir, apiDir, file, log); auto path = apiDir; path.append("/").append(file).append(".yml"); try { @@ -247,7 +285,7 @@ void pdns::settings::rec::processAPIDir(const string& includeDirOnCommandLine, p catch (const runtime_error& err) { } } - convertForwardsandAuths(includeDir, apiDir, log); + possiblyConvertForwardsandAuths(includeDir, apiDir, log); } pdns::settings::rec::YamlSettingsStatus pdns::settings::rec::readYamlSettings(const std::string& configname, const std::string& includeDirOnCommandLine, Recursorsettings& settings, std::string& msg, Logr::log_t log) diff --git a/pdns/recursordist/settings/rust-bridge-in.rs b/pdns/recursordist/settings/rust-bridge-in.rs index 1ee664c173cf..40e53b144f0c 100644 --- a/pdns/recursordist/settings/rust-bridge-in.rs +++ b/pdns/recursordist/settings/rust-bridge-in.rs @@ -105,5 +105,6 @@ extern "Rust" { fn api_read_zones(path: &str) -> Result>; fn api_add_auth_zone(file: &str, authzone: AuthZone) -> Result<()>; fn api_add_forward_zone(file: &str, forwardzone: ForwardZone) -> Result<()>; + fn api_add_forward_zones(file: &str, forwardzones: &mut Vec) -> Result<()>; fn api_delete_zone(file: &str, zone: &str) -> Result<()>; } diff --git a/pdns/recursordist/settings/rust/src/bridge.rs b/pdns/recursordist/settings/rust/src/bridge.rs index 370a881074f8..181e23424247 100644 --- a/pdns/recursordist/settings/rust/src/bridge.rs +++ b/pdns/recursordist/settings/rust/src/bridge.rs @@ -465,6 +465,15 @@ pub fn api_add_forward_zone(path: &str, forwardzone: ForwardZone) -> Result<(), zones.forward_zones.push(forwardzone); api_write_zones(path, &zones) } + +// This function is called from C++, it needs to acquire the lock +pub fn api_add_forward_zones(path: &str, forwardzones: &mut Vec) -> Result<(), std::io::Error> { + let _lock = LOCK.lock().unwrap(); + let mut zones = api_read_zones_locked(path, true)?; + zones.forward_zones.append(forwardzones); + api_write_zones(path, &zones) +} + // This function is called from C++, it needs to acquire the lock pub fn api_delete_zone(path: &str, zone: &str) -> Result<(), std::io::Error> { let _lock = LOCK.lock().unwrap(); From 8a91c7b5c3eaee73b275643f7901ebe22d7367b4 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 12 Oct 2023 14:42:55 +0200 Subject: [PATCH 874/909] Regression test for YAML conversino of API maintained config files --- .../YAMLConversion/allow-from.yml.expected | 6 + .../allow-notify-from.yml.expected | 6 + .../YAMLConversion/apiconfig.tar.gz | Bin 0 -> 27519 bytes .../YAMLConversion/apizones.expected | 5446 +++++++++++++++++ .../YAMLConversion/command | 26 + .../YAMLConversion/description | 1 + .../YAMLConversion/expected_result | 1 + 7 files changed, 5486 insertions(+) create mode 100644 regression-tests.recursor/YAMLConversion/allow-from.yml.expected create mode 100644 regression-tests.recursor/YAMLConversion/allow-notify-from.yml.expected create mode 100644 regression-tests.recursor/YAMLConversion/apiconfig.tar.gz create mode 100644 regression-tests.recursor/YAMLConversion/apizones.expected create mode 100755 regression-tests.recursor/YAMLConversion/command create mode 100644 regression-tests.recursor/YAMLConversion/description create mode 100644 regression-tests.recursor/YAMLConversion/expected_result diff --git a/regression-tests.recursor/YAMLConversion/allow-from.yml.expected b/regression-tests.recursor/YAMLConversion/allow-from.yml.expected new file mode 100644 index 000000000000..7dbc41463256 --- /dev/null +++ b/regression-tests.recursor/YAMLConversion/allow-from.yml.expected @@ -0,0 +1,6 @@ +# Generated by pdns-recursor REST API, DO NOT EDIT +incoming: + allow_from_file: '' + allow_from: !override + - 1.2.3.4/32, 127.0.0.0/24 + diff --git a/regression-tests.recursor/YAMLConversion/allow-notify-from.yml.expected b/regression-tests.recursor/YAMLConversion/allow-notify-from.yml.expected new file mode 100644 index 000000000000..0e17dcd0303e --- /dev/null +++ b/regression-tests.recursor/YAMLConversion/allow-notify-from.yml.expected @@ -0,0 +1,6 @@ +# Generated by pdns-recursor REST API, DO NOT EDIT +incoming: + allow_notify_from_file: '' + allow_notify_from: !override + - 127.0.0.0/24 + diff --git a/regression-tests.recursor/YAMLConversion/apiconfig.tar.gz b/regression-tests.recursor/YAMLConversion/apiconfig.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..c09d5a965c0cc6614f035994b3329d08b17c772b GIT binary patch literal 27519 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[$Y+qMK6z= Xk>_ju-@oNa`?|)*Zb recursor.yml << EOF +incoming: + port: 9999 +recursor: + include_dir: $d + socket_dir: . +webservice: + api_dir: $d2 +EOF +${PDNSRECURSOR} --config-dir=. & + +sleep 1 +${RECCONTROL} --config-dir=. quit-nicely +diff -u apizones.expected $d2/apizones +diff -u allow-from.yml.expected $d2/allow-from.yml +diff -u allow-notify-from.yml.expected $d2/allow-notify-from.yml +rm -rf $d $d2 recursor.yml diff --git a/regression-tests.recursor/YAMLConversion/description b/regression-tests.recursor/YAMLConversion/description new file mode 100644 index 000000000000..973b0be2d7b1 --- /dev/null +++ b/regression-tests.recursor/YAMLConversion/description @@ -0,0 +1 @@ +Test the conversion of the recursor's API-maintaned config files to YAML diff --git a/regression-tests.recursor/YAMLConversion/expected_result b/regression-tests.recursor/YAMLConversion/expected_result new file mode 100644 index 000000000000..b0452016387f --- /dev/null +++ b/regression-tests.recursor/YAMLConversion/expected_result @@ -0,0 +1 @@ +bye nicely From aa171aa0ff67166e55e5c69b6ca66bb4a28a4b47 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 12 Oct 2023 15:06:55 +0200 Subject: [PATCH 875/909] Formatting --- pdns/recursordist/settings/cxxsupport.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index 37ccfc35d426..051ca54b5f81 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -168,7 +168,7 @@ static void possiblyConvertACLFile(const string& includeDir, const string& apiDi else { yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_notify_from", "allow_notify_from_file", result); } - string yamlfilename = apiDir; + string yamlfilename = apiDir; yamlfilename.append("/").append(filename).append(".yml"); string tmpfilename = yamlfilename + ".tmp"; ofstream ofconf(tmpfilename); @@ -273,8 +273,7 @@ void pdns::settings::rec::processAPIDir(const string& includeDirOnCommandLine, p } const std::array aclFiles = { "allow-from", - "allow-notify-from" - }; + "allow-notify-from"}; for (const auto& file : aclFiles) { possiblyConvertACLFile(includeDir, apiDir, file, log); auto path = apiDir; From fb355c474f0601670c8d41dcf3aa6b9e9365bb98 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 12 Oct 2023 15:07:07 +0200 Subject: [PATCH 876/909] include_dir must be != api_dir for YAML mode --- regression-tests.api/runtests.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/regression-tests.api/runtests.py b/regression-tests.api/runtests.py index 51e603e4b351..ea2b230b6eaa 100755 --- a/regression-tests.api/runtests.py +++ b/regression-tests.api/runtests.py @@ -110,7 +110,7 @@ allow_from_file: acl.list.yml allow_notify_from_file: acl-notify.list.yml webservice: - api_dir: %(conf_dir)s + api_dir: %(api_dir)s recursor: include_dir: %(conf_dir)s devonly_regression_test_mode: true @@ -226,6 +226,8 @@ def run_check_call(cmd, *args, **kwargs): else: conf_dir = 'rec-conf.d' ensure_empty_dir(conf_dir) + api_dir = 'rec-api.d' + ensure_empty_dir(api_dir) with open('acl.list.yml', 'w') as acl_list: acl_list.write(ACL_LIST_TPL) with open('acl-notify.list.yml', 'w') as acl_notify_list: From e78af61d87b800e5bff04038aae7a73cc9d7314b Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Thu, 12 Oct 2023 15:20:40 +0200 Subject: [PATCH 877/909] Try a couple of times asking rec to quit --- regression-tests.recursor/YAMLConversion/command | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/regression-tests.recursor/YAMLConversion/command b/regression-tests.recursor/YAMLConversion/command index 1c759206c11b..330dd0fe96f5 100755 --- a/regression-tests.recursor/YAMLConversion/command +++ b/regression-tests.recursor/YAMLConversion/command @@ -18,8 +18,16 @@ webservice: EOF ${PDNSRECURSOR} --config-dir=. & +set +e +for in in 0 1 2 3 4 5 6 7 8 9; do sleep 1 ${RECCONTROL} --config-dir=. quit-nicely +if [ $? = 0 ]; then + break +fi +done +set -e + diff -u apizones.expected $d2/apizones diff -u allow-from.yml.expected $d2/allow-from.yml diff -u allow-notify-from.yml.expected $d2/allow-notify-from.yml From 0706da10180221cdba56c0f30c7513389b9f8670 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 28 Sep 2023 22:37:56 +0200 Subject: [PATCH 878/909] Minor cleanups to geoip and lmdb --- ext/lmdb-safe/lmdb-typed.hh | 2 - modules/geoipbackend/geoipbackend.cc | 113 +++++++++++++++------------ modules/geoipbackend/geoipbackend.hh | 4 +- modules/lmdbbackend/lmdbbackend.cc | 8 +- 4 files changed, 70 insertions(+), 57 deletions(-) diff --git a/ext/lmdb-safe/lmdb-typed.hh b/ext/lmdb-safe/lmdb-typed.hh index 790fead2910b..ae32d78fd67b 100644 --- a/ext/lmdb-safe/lmdb-typed.hh +++ b/ext/lmdb-safe/lmdb-typed.hh @@ -162,8 +162,6 @@ struct LMDBIndexOps auto scombined = makeCombinedKey(keyConv(d_parent->getMember(t)), id); MDBInVal combined(scombined); - MDBOutVal currentvalue; - // if the entry existed already, this will just update the timestamp/txid in the LS header. This is intentional, so objects and their indexes always get synced together. txn->put(d_idx, combined, empty, flags); } diff --git a/modules/geoipbackend/geoipbackend.cc b/modules/geoipbackend/geoipbackend.cc index ada8093b41a7..497d80c860cf 100644 --- a/modules/geoipbackend/geoipbackend.cc +++ b/modules/geoipbackend/geoipbackend.cc @@ -38,8 +38,8 @@ ReadWriteLock GeoIPBackend::s_state_lock; struct GeoIPDNSResourceRecord : DNSResourceRecord { - int weight; - bool has_weight; + int weight{}; + bool has_weight{}; }; struct GeoIPService @@ -53,7 +53,7 @@ struct GeoIPDomain { int id; DNSName domain; - int ttl; + int ttl{}; map services; map> records; vector mapping_lookup_formats; @@ -77,16 +77,15 @@ const static std::array GeoIP_MONTHS = {"jan", "feb", "mar", "apr", GeoIPBackend::GeoIPBackend(const string& suffix) { - WriteLock wl(&s_state_lock); - d_dnssec = false; + WriteLock writeLock(&s_state_lock); setArgPrefix("geoip" + suffix); - if (getArg("dnssec-keydir").empty() == false) { - DIR* d = opendir(getArg("dnssec-keydir").c_str()); - if (d == nullptr) { + if (!getArg("dnssec-keydir").empty()) { + DIR* dir = opendir(getArg("dnssec-keydir").c_str()); + if (dir == nullptr) { throw PDNSException("dnssec-keydir " + getArg("dnssec-keydir") + " does not exist"); } d_dnssec = true; - closedir(d); + closedir(dir); } if (s_rc == 0) { // first instance gets to open everything initialize(); @@ -104,14 +103,17 @@ static string queryGeoIP(const Netmask& addr, GeoIPInterface::GeoIPQueryAttribut // infinite recursion. static bool validateMappingLookupFormats(const vector& formats) { - string::size_type cur, last; + string::size_type cur = 0; + string::size_type last = 0; + for (const auto& lookupFormat : formats) { last = 0; while ((cur = lookupFormat.find("%", last)) != string::npos) { - if (!lookupFormat.compare(cur, 3, "%mp")) { + if (lookupFormat.compare(cur, 3, "%mp") == 0) { return false; } - else if (!lookupFormat.compare(cur, 2, "%%")) { // Ensure escaped % is also accepted + + if (lookupFormat.compare(cur, 2, "%%") == 0) { // Ensure escaped % is also accepted last = cur + 2; continue; } @@ -127,12 +129,12 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo dom.domain = DNSName(domain["domain"].as()); dom.ttl = domain["ttl"].as(); - for (YAML::const_iterator recs = domain["records"].begin(); recs != domain["records"].end(); recs++) { + for (auto recs = domain["records"].begin(); recs != domain["records"].end(); recs++) { DNSName qname = DNSName(recs->first.as()); vector rrs; - for (YAML::const_iterator item = recs->second.begin(); item != recs->second.end(); item++) { - YAML::const_iterator rec = item->begin(); + for (auto item = recs->second.begin(); item != recs->second.end(); item++) { + auto rec = item->begin(); GeoIPDNSResourceRecord rr; rr.domain_id = dom.id; rr.ttl = dom.ttl; @@ -151,9 +153,9 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo } else if (rec->second.IsMap()) { for (YAML::const_iterator iter = rec->second.begin(); iter != rec->second.end(); iter++) { - string attr = iter->first.as(); + auto attr = iter->first.as(); if (attr == "content") { - string content = iter->second.as(); + auto content = iter->second.as(); rr.content = std::move(content); } else if (attr == "weight") { @@ -174,24 +176,25 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo } } else { - string content = rec->second.as(); + auto content = rec->second.as(); rr.content = std::move(content); rr.weight = 100; } - rr.auth = 1; + rr.auth = true; rrs.push_back(rr); } std::swap(dom.records[qname], rrs); } - for (YAML::const_iterator service = domain["services"].begin(); service != domain["services"].end(); service++) { - unsigned int netmask4 = 0, netmask6 = 0; + for (auto service = domain["services"].begin(); service != domain["services"].end(); service++) { + unsigned int netmask4 = 0; + unsigned int netmask6 = 0; DNSName srvName{service->first.as()}; NetmaskTree> nmt; // if it's an another map, we need to iterate it again, otherwise we just add two root entries. if (service->second.IsMap()) { - for (YAML::const_iterator net = service->second.begin(); net != service->second.end(); net++) { + for (auto net = service->second.begin(); net != service->second.end(); net++) { vector value; if (net->second.IsSequence()) { value = net->second.as>(); @@ -204,12 +207,14 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo nmt.insert(Netmask("::/0")).second.swap(value); } else { - Netmask nm{net->first.as()}; - nmt.insert(nm).second.swap(value); - if (nm.isIPv6() == true && netmask6 < nm.getBits()) - netmask6 = nm.getBits(); - if (nm.isIPv6() == false && netmask4 < nm.getBits()) - netmask4 = nm.getBits(); + Netmask netmask{net->first.as()}; + nmt.insert(netmask).second.swap(value); + if (netmask.isIPv6() && netmask6 < netmask.getBits()) { + netmask6 = netmask.getBits(); + } + if (!netmask.isIPv6() && netmask4 < netmask.getBits()) { + netmask4 = netmask.getBits(); + } } } } @@ -228,9 +233,10 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo // Allow per domain override of mapping_lookup_formats and custom_mapping. // If not defined, the global values will be used. if (YAML::Node formats = domain["mapping_lookup_formats"]) { - vector mapping_lookup_formats = formats.as>(); - if (!validateMappingLookupFormats(mapping_lookup_formats)) + auto mapping_lookup_formats = formats.as>(); + if (!validateMappingLookupFormats(mapping_lookup_formats)) { throw PDNSException(string("%mp is not allowed in mapping lookup formats of domain ") + dom.domain.toLogString()); + } dom.mapping_lookup_formats = mapping_lookup_formats; } @@ -254,8 +260,8 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo // ensure we have parent in records DNSName name = item.first; while (name.chopOff() && name.isPartOf(dom.domain)) { - if (dom.records.find(name) == dom.records.end() && !dom.services.count(name)) { // don't ENT out a service! GeoIPDNSResourceRecord rr; + if (dom.records.find(name) == dom.records.end() && (dom.services.count(name) == 0U)) { // don't ENT out a service! vector rrs; rr.domain_id = dom.id; rr.ttl = dom.ttl; @@ -300,25 +306,27 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo map lasts; bool has_weight = false; // first we look for used weight - for (const auto& rr : item.second) { - weights[rr.qtype.getCode()] += rr.weight; - if (rr.has_weight) + for (const auto& resourceRecord : item.second) { + weights[resourceRecord.qtype.getCode()] += static_cast(resourceRecord.weight); + if (resourceRecord.has_weight) { has_weight = true; + } } if (has_weight) { // put them back as probabilities and values.. - for (auto& rr : item.second) { - uint16_t rr_type = rr.qtype.getCode(); - rr.weight = static_cast((static_cast(rr.weight) / weights[rr_type]) * 1000.0); - sums[rr_type] += rr.weight; - rr.has_weight = has_weight; - lasts[rr_type] = &rr; + for (auto& resourceRecord : item.second) { + uint16_t rr_type = resourceRecord.qtype.getCode(); + resourceRecord.weight = static_cast((static_cast(resourceRecord.weight) / weights[rr_type]) * 1000.0); + sums[rr_type] += static_cast(resourceRecord.weight); + resourceRecord.has_weight = has_weight; + lasts[rr_type] = &resourceRecord; } // remove rounding gap for (auto& x : lasts) { float sum = sums[x.first]; - if (sum < 1000) + if (sum < 1000) { x.second->weight += (1000 - sum); + } } } } @@ -337,9 +345,11 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo void GeoIPBackend::loadDomainsFromDirectory(const std::string& dir, vector& domains) { vector paths; - for (const std::filesystem::path& p : std::filesystem::directory_iterator(std::filesystem::path(dir))) - if (std::filesystem::is_regular_file(p) && p.has_extension() && (p.extension() == ".yaml" || p.extension() == ".yml")) + for (const std::filesystem::path& p : std::filesystem::directory_iterator(std::filesystem::path(dir))) { + if (std::filesystem::is_regular_file(p) && p.has_extension() && (p.extension() == ".yaml" || p.extension() == ".yml")) { paths.push_back(p); + } + } std::sort(paths.begin(), paths.end()); for (const auto& p : paths) { try { @@ -347,8 +357,9 @@ void GeoIPBackend::loadDomainsFromDirectory(const std::string& dir, vector>(); - if (!validateMappingLookupFormats(d_global_mapping_lookup_formats)) + if (!validateMappingLookupFormats(d_global_mapping_lookup_formats)) { throw PDNSException(string("%mp is not allowed in mapping lookup")); + } } if (YAML::Node mapping = config["custom_mapping"]) { d_global_custom_mapping = mapping.as>(); @@ -397,12 +410,14 @@ void GeoIPBackend::initialize() for (YAML::const_iterator _domain = config["domains"].begin(); _domain != config["domains"].end(); _domain++) { GeoIPDomain dom; auto id = tmp_domains.size(); - if (loadDomain(*_domain, id, dom)) + if (loadDomain(*_domain, id, dom)) { tmp_domains.push_back(std::move(dom)); + } } - if (YAML::Node domain_dir = config["zones_dir"]) + if (YAML::Node domain_dir = config["zones_dir"]) { loadDomainsFromDirectory(domain_dir.as(), tmp_domains); + } s_domains.clear(); std::swap(s_domains, tmp_domains); @@ -414,7 +429,7 @@ void GeoIPBackend::initialize() GeoIPBackend::~GeoIPBackend() { try { - WriteLock wl(&s_state_lock); + WriteLock writeLock(&s_state_lock); s_rc--; if (s_rc == 0) { // last instance gets to cleanup s_geoip_files.clear(); diff --git a/modules/geoipbackend/geoipbackend.hh b/modules/geoipbackend/geoipbackend.hh index c7e988a2f8ec..851927628d1f 100644 --- a/modules/geoipbackend/geoipbackend.hh +++ b/modules/geoipbackend/geoipbackend.hh @@ -79,10 +79,10 @@ private: void initialize(); string format2str(string format, const Netmask& addr, GeoIPNetmask& gl, const GeoIPDomain& dom); - bool d_dnssec; + bool d_dnssec{}; bool hasDNSSECkey(const DNSName& name); bool lookup_static(const GeoIPDomain& dom, const DNSName& search, const QType& qtype, const DNSName& qdomain, const Netmask& addr, GeoIPNetmask& gl); - bool loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDomain& dom); + bool loadDomain(const YAML::Node& domain, unsigned int /* id */, GeoIPDomain& dom); void loadDomainsFromDirectory(const std::string& dir, vector& domains); vector d_result; vector d_files; diff --git a/modules/lmdbbackend/lmdbbackend.cc b/modules/lmdbbackend/lmdbbackend.cc index 9b600f137064..60a05cac1d09 100644 --- a/modules/lmdbbackend/lmdbbackend.cc +++ b/modules/lmdbbackend/lmdbbackend.cc @@ -464,7 +464,7 @@ bool LMDBBackend::upgradeToSchemav5(std::string& filename) int index = 0; - for (const std::string& dbname : {"domains", "keydata", "tsig", "metadata"}) { + for (const std::string dbname : {"domains", "keydata", "tsig", "metadata"}) { std::cerr << "migrating " << dbname << std::endl; std::string tdbname = dbname + "_v5"; @@ -504,7 +504,7 @@ bool LMDBBackend::upgradeToSchemav5(std::string& filename) index = 0; - for (const std::string& dbname : {"domains", "keydata", "tsig", "metadata"}) { + for (const std::string dbname : {"domains", "keydata", "tsig", "metadata"}) { std::string fdbname = dbname + "_0"; std::cerr << "migrating " << dbname << std::endl; std::string tdbname = dbname + "_v5_0"; @@ -553,7 +553,7 @@ bool LMDBBackend::upgradeToSchemav5(std::string& filename) std::string header(LMDBLS::LS_MIN_HEADER_SIZE, '\0'); - for (const std::string& keyname : {"schemaversion", "shards"}) { + for (const std::string keyname : {"schemaversion", "shards"}) { cerr << "migrating pdns." << keyname << endl; key.mv_data = (char*)keyname.c_str(); @@ -591,7 +591,7 @@ bool LMDBBackend::upgradeToSchemav5(std::string& filename) } } - for (const std::string& keyname : {"uuid"}) { + for (const std::string keyname : {"uuid"}) { cerr << "migrating pdns." << keyname << endl; key.mv_data = (char*)keyname.c_str(); From 9ef17e137418086dc913f10bb7d31602ad2a54c5 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Mon, 9 Oct 2023 15:02:51 +0200 Subject: [PATCH 879/909] Set the domain ID --- modules/geoipbackend/geoipbackend.cc | 51 ++++++++++++++-------------- modules/geoipbackend/geoipbackend.hh | 3 +- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/modules/geoipbackend/geoipbackend.cc b/modules/geoipbackend/geoipbackend.cc index 497d80c860cf..5341e1d8549a 100644 --- a/modules/geoipbackend/geoipbackend.cc +++ b/modules/geoipbackend/geoipbackend.cc @@ -19,6 +19,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -51,7 +52,7 @@ struct GeoIPService struct GeoIPDomain { - int id; + std::uint32_t id{}; DNSName domain; int ttl{}; map services; @@ -123,9 +124,10 @@ static bool validateMappingLookupFormats(const vector& formats) return true; } -bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDomain& dom) +bool GeoIPBackend::loadDomain(const YAML::Node& domain, std::uint32_t domainID, GeoIPDomain& dom) { try { + dom.id = domainID; dom.domain = DNSName(domain["domain"].as()); dom.ttl = domain["ttl"].as(); @@ -136,7 +138,7 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo for (auto item = recs->second.begin(); item != recs->second.end(); item++) { auto rec = item->begin(); GeoIPDNSResourceRecord rr; - rr.domain_id = dom.id; + rr.domain_id = static_cast(dom.id); rr.ttl = dom.ttl; rr.qname = qname; if (rec->first.IsNull()) { @@ -260,18 +262,18 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo // ensure we have parent in records DNSName name = item.first; while (name.chopOff() && name.isPartOf(dom.domain)) { - GeoIPDNSResourceRecord rr; if (dom.records.find(name) == dom.records.end() && (dom.services.count(name) == 0U)) { // don't ENT out a service! + GeoIPDNSResourceRecord resourceRecord; vector rrs; - rr.domain_id = dom.id; - rr.ttl = dom.ttl; - rr.qname = name; - rr.qtype = QType(0); // empty non terminal - rr.content = ""; - rr.auth = 1; - rr.weight = 100; - rr.has_weight = false; - rrs.push_back(rr); + resourceRecord.domain_id = static_cast(dom.id); + resourceRecord.ttl = dom.ttl; + resourceRecord.qname = name; + resourceRecord.qtype = QType(0); // empty non terminal + resourceRecord.content = ""; + resourceRecord.auth = true; + resourceRecord.weight = 100; + resourceRecord.has_weight = false; + rrs.push_back(resourceRecord); std::swap(dom.records[name], rrs); } } @@ -283,17 +285,17 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, unsigned int id, GeoIPDo DNSName name = item.first; while (name.chopOff() && name.isPartOf(dom.domain)) { if (dom.records.find(name) == dom.records.end()) { - GeoIPDNSResourceRecord rr; + GeoIPDNSResourceRecord resourceRecord; vector rrs; - rr.domain_id = dom.id; - rr.ttl = dom.ttl; - rr.qname = name; - rr.qtype = QType(0); - rr.content = ""; - rr.auth = 1; - rr.weight = 100; - rr.has_weight = false; - rrs.push_back(rr); + resourceRecord.domain_id = static_cast(dom.id); + resourceRecord.ttl = dom.ttl; + resourceRecord.qname = name; + resourceRecord.qtype = QType(0); + resourceRecord.content = ""; + resourceRecord.auth = true; + resourceRecord.weight = 100; + resourceRecord.has_weight = false; + rrs.push_back(resourceRecord); std::swap(dom.records[name], rrs); } } @@ -409,8 +411,7 @@ void GeoIPBackend::initialize() for (YAML::const_iterator _domain = config["domains"].begin(); _domain != config["domains"].end(); _domain++) { GeoIPDomain dom; - auto id = tmp_domains.size(); - if (loadDomain(*_domain, id, dom)) { + if (loadDomain(*_domain, tmp_domains.size(), dom)) { tmp_domains.push_back(std::move(dom)); } } diff --git a/modules/geoipbackend/geoipbackend.hh b/modules/geoipbackend/geoipbackend.hh index 851927628d1f..a2d3c7b994ad 100644 --- a/modules/geoipbackend/geoipbackend.hh +++ b/modules/geoipbackend/geoipbackend.hh @@ -22,6 +22,7 @@ #pragma once #include "pdns/namespaces.hh" +#include #include #include #include @@ -82,7 +83,7 @@ private: bool d_dnssec{}; bool hasDNSSECkey(const DNSName& name); bool lookup_static(const GeoIPDomain& dom, const DNSName& search, const QType& qtype, const DNSName& qdomain, const Netmask& addr, GeoIPNetmask& gl); - bool loadDomain(const YAML::Node& domain, unsigned int /* id */, GeoIPDomain& dom); + bool loadDomain(const YAML::Node& domain, std::uint32_t domainID, GeoIPDomain& dom); void loadDomainsFromDirectory(const std::string& dir, vector& domains); vector d_result; vector d_files; From 195e117563293375e52616fc3a3aeae316def566 Mon Sep 17 00:00:00 2001 From: Fred Morcos Date: Thu, 12 Oct 2023 16:32:24 +0200 Subject: [PATCH 880/909] Small refactoring of GeoIPBackend::loadDomain --- modules/geoipbackend/geoipbackend.cc | 182 ++++++++++++++------------- modules/geoipbackend/geoipbackend.hh | 1 + 2 files changed, 93 insertions(+), 90 deletions(-) diff --git a/modules/geoipbackend/geoipbackend.cc b/modules/geoipbackend/geoipbackend.cc index 5341e1d8549a..2d0523158b38 100644 --- a/modules/geoipbackend/geoipbackend.cc +++ b/modules/geoipbackend/geoipbackend.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include ReadWriteLock GeoIPBackend::s_state_lock; @@ -124,6 +125,94 @@ static bool validateMappingLookupFormats(const vector& formats) return true; } +static vector makeDNSResourceRecord(GeoIPDomain& dom, DNSName name) +{ + GeoIPDNSResourceRecord resourceRecord; + resourceRecord.domain_id = static_cast(dom.id); + resourceRecord.ttl = dom.ttl; + resourceRecord.qname = std::move(name); + resourceRecord.qtype = QType(0); // empty non terminal + resourceRecord.content = ""; + resourceRecord.auth = true; + resourceRecord.weight = 100; + resourceRecord.has_weight = false; + vector rrs; + rrs.push_back(resourceRecord); + return rrs; +} + +void GeoIPBackend::setupNetmasks(const YAML::Node& domain, GeoIPDomain& dom) +{ + for (auto service = domain["services"].begin(); service != domain["services"].end(); service++) { + unsigned int netmask4 = 0; + unsigned int netmask6 = 0; + DNSName serviceName{service->first.as()}; + NetmaskTree> netmaskTree; + + // if it's an another map, we need to iterate it again, otherwise we just add two root entries. + if (service->second.IsMap()) { + for (auto net = service->second.begin(); net != service->second.end(); net++) { + vector value; + if (net->second.IsSequence()) { + value = net->second.as>(); + } + else { + value.push_back(net->second.as()); + } + if (net->first.as() == "default") { + netmaskTree.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(), value.end()); + netmaskTree.insert(Netmask("::/0")).second.swap(value); + } + else { + Netmask netmask{net->first.as()}; + netmaskTree.insert(netmask).second.swap(value); + if (netmask.isIPv6() && netmask6 < netmask.getBits()) { + netmask6 = netmask.getBits(); + } + if (!netmask.isIPv6() && netmask4 < netmask.getBits()) { + netmask4 = netmask.getBits(); + } + } + } + } + else { + vector value; + if (service->second.IsSequence()) { + value = service->second.as>(); + } + else { + value.push_back(service->second.as()); + } + netmaskTree.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(), value.end()); + netmaskTree.insert(Netmask("::/0")).second.swap(value); + } + + // Allow per domain override of mapping_lookup_formats and custom_mapping. + // If not defined, the global values will be used. + if (YAML::Node formats = domain["mapping_lookup_formats"]) { + auto mapping_lookup_formats = formats.as>(); + if (!validateMappingLookupFormats(mapping_lookup_formats)) { + throw PDNSException(string("%mp is not allowed in mapping lookup formats of domain ") + dom.domain.toLogString()); + } + + dom.mapping_lookup_formats = mapping_lookup_formats; + } + else { + dom.mapping_lookup_formats = d_global_mapping_lookup_formats; + } + if (YAML::Node mapping = domain["custom_mapping"]) { + dom.custom_mapping = mapping.as>(); + } + else { + dom.custom_mapping = d_global_custom_mapping; + } + + dom.services[serviceName].netmask4 = netmask4; + dom.services[serviceName].netmask6 = netmask6; + dom.services[serviceName].masks.swap(netmaskTree); + } +} + bool GeoIPBackend::loadDomain(const YAML::Node& domain, std::uint32_t domainID, GeoIPDomain& dom) { try { @@ -188,74 +277,7 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, std::uint32_t domainID, std::swap(dom.records[qname], rrs); } - for (auto service = domain["services"].begin(); service != domain["services"].end(); service++) { - unsigned int netmask4 = 0; - unsigned int netmask6 = 0; - DNSName srvName{service->first.as()}; - NetmaskTree> nmt; - - // if it's an another map, we need to iterate it again, otherwise we just add two root entries. - if (service->second.IsMap()) { - for (auto net = service->second.begin(); net != service->second.end(); net++) { - vector value; - if (net->second.IsSequence()) { - value = net->second.as>(); - } - else { - value.push_back(net->second.as()); - } - if (net->first.as() == "default") { - nmt.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(), value.end()); - nmt.insert(Netmask("::/0")).second.swap(value); - } - else { - Netmask netmask{net->first.as()}; - nmt.insert(netmask).second.swap(value); - if (netmask.isIPv6() && netmask6 < netmask.getBits()) { - netmask6 = netmask.getBits(); - } - if (!netmask.isIPv6() && netmask4 < netmask.getBits()) { - netmask4 = netmask.getBits(); - } - } - } - } - else { - vector value; - if (service->second.IsSequence()) { - value = service->second.as>(); - } - else { - value.push_back(service->second.as()); - } - nmt.insert(Netmask("0.0.0.0/0")).second.assign(value.begin(), value.end()); - nmt.insert(Netmask("::/0")).second.swap(value); - } - - // Allow per domain override of mapping_lookup_formats and custom_mapping. - // If not defined, the global values will be used. - if (YAML::Node formats = domain["mapping_lookup_formats"]) { - auto mapping_lookup_formats = formats.as>(); - if (!validateMappingLookupFormats(mapping_lookup_formats)) { - throw PDNSException(string("%mp is not allowed in mapping lookup formats of domain ") + dom.domain.toLogString()); - } - - dom.mapping_lookup_formats = mapping_lookup_formats; - } - else { - dom.mapping_lookup_formats = d_global_mapping_lookup_formats; - } - if (YAML::Node mapping = domain["custom_mapping"]) { - dom.custom_mapping = mapping.as>(); - } - else { - dom.custom_mapping = d_global_custom_mapping; - } - - dom.services[srvName].netmask4 = netmask4; - dom.services[srvName].netmask6 = netmask6; - dom.services[srvName].masks.swap(nmt); - } + setupNetmasks(domain, dom); // rectify the zone, first static records for (auto& item : dom.records) { @@ -263,17 +285,7 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, std::uint32_t domainID, DNSName name = item.first; while (name.chopOff() && name.isPartOf(dom.domain)) { if (dom.records.find(name) == dom.records.end() && (dom.services.count(name) == 0U)) { // don't ENT out a service! - GeoIPDNSResourceRecord resourceRecord; - vector rrs; - resourceRecord.domain_id = static_cast(dom.id); - resourceRecord.ttl = dom.ttl; - resourceRecord.qname = name; - resourceRecord.qtype = QType(0); // empty non terminal - resourceRecord.content = ""; - resourceRecord.auth = true; - resourceRecord.weight = 100; - resourceRecord.has_weight = false; - rrs.push_back(resourceRecord); + auto rrs = makeDNSResourceRecord(dom, name); std::swap(dom.records[name], rrs); } } @@ -285,17 +297,7 @@ bool GeoIPBackend::loadDomain(const YAML::Node& domain, std::uint32_t domainID, DNSName name = item.first; while (name.chopOff() && name.isPartOf(dom.domain)) { if (dom.records.find(name) == dom.records.end()) { - GeoIPDNSResourceRecord resourceRecord; - vector rrs; - resourceRecord.domain_id = static_cast(dom.id); - resourceRecord.ttl = dom.ttl; - resourceRecord.qname = name; - resourceRecord.qtype = QType(0); - resourceRecord.content = ""; - resourceRecord.auth = true; - resourceRecord.weight = 100; - resourceRecord.has_weight = false; - rrs.push_back(resourceRecord); + auto rrs = makeDNSResourceRecord(dom, name); std::swap(dom.records[name], rrs); } } diff --git a/modules/geoipbackend/geoipbackend.hh b/modules/geoipbackend/geoipbackend.hh index a2d3c7b994ad..6185b2d9bd80 100644 --- a/modules/geoipbackend/geoipbackend.hh +++ b/modules/geoipbackend/geoipbackend.hh @@ -83,6 +83,7 @@ private: bool d_dnssec{}; bool hasDNSSECkey(const DNSName& name); bool lookup_static(const GeoIPDomain& dom, const DNSName& search, const QType& qtype, const DNSName& qdomain, const Netmask& addr, GeoIPNetmask& gl); + void setupNetmasks(const YAML::Node& domain, GeoIPDomain& dom); bool loadDomain(const YAML::Node& domain, std::uint32_t domainID, GeoIPDomain& dom); void loadDomainsFromDirectory(const std::string& dir, vector& domains); vector d_result; From 607be52e43821afdfc885d984a059295d5bf15be Mon Sep 17 00:00:00 2001 From: phonedph1 <20867105+phonedph1@users.noreply.github.com> Date: Thu, 12 Oct 2023 09:29:09 -0600 Subject: [PATCH 881/909] Update dq.rst --- pdns/dnsdistdist/docs/reference/dq.rst | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/reference/dq.rst b/pdns/dnsdistdist/docs/reference/dq.rst index 08bb84cde74d..33e209e5539d 100644 --- a/pdns/dnsdistdist/docs/reference/dq.rst +++ b/pdns/dnsdistdist/docs/reference/dq.rst @@ -463,7 +463,8 @@ DNSResponse object return DNSAction.None end function restartOnServFail(dr) - if dr.rcode == DNSRCode.SERVFAIL then + -- if the query was SERVFAIL and not already tried on the restarted pool + if dr.rcode == DNSRCode.SERVFAIL and dr.pool ~= 'restarted' then -- assign this query to a new pool dr.pool = 'restarted' -- discard the received response and From dc17048bce3ee6bd1515cedf61cccdcdc57af96d Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 13 Oct 2023 09:40:09 +0200 Subject: [PATCH 882/909] Docs --- pdns/recursordist/docs/appendices/yamlconversion.rst | 6 ++++-- pdns/recursordist/docs/http-api/endpoint-servers-config.rst | 3 ++- pdns/recursordist/docs/http-api/zone.rst | 5 +++-- pdns/recursordist/settings/table.py | 5 +++-- 4 files changed, 12 insertions(+), 7 deletions(-) diff --git a/pdns/recursordist/docs/appendices/yamlconversion.rst b/pdns/recursordist/docs/appendices/yamlconversion.rst index d3c263cf7c35..ed2f83dbdb8e 100644 --- a/pdns/recursordist/docs/appendices/yamlconversion.rst +++ b/pdns/recursordist/docs/appendices/yamlconversion.rst @@ -59,5 +59,7 @@ API Managed Files The format of API managed files was also changed to use YAML format. Specifically, the list of API managed zones is now a single file containing a sequence of ``auth_zones`` and a sequence of ``forward_zones`` instead of a settings file per zone. The list of ACLs is a YAML sequence of subnets or IP addresses. -There is no conversion of API managed files from old-style to YAML yet. -The intention is to add automatic conversion code before the final release of a YAML enabled :program:`Recursor`, +When using YAML settings :ref:`setting-yaml-recursor.include-dir` and :ref:`setting-yaml-webservice.api-config-dir` must have a different value. +When YAML settings are active the :program:`Recursor` will read old-style API managed files from the include directory on startup, convert them to the new format and write them into the API config directory. +After conversion, it will inactivate the old-style API managed config files in the include directory by renaming them. + diff --git a/pdns/recursordist/docs/http-api/endpoint-servers-config.rst b/pdns/recursordist/docs/http-api/endpoint-servers-config.rst index 0d96dbd9e83c..0d8f24c6b89b 100644 --- a/pdns/recursordist/docs/http-api/endpoint-servers-config.rst +++ b/pdns/recursordist/docs/http-api/endpoint-servers-config.rst @@ -8,7 +8,8 @@ Only :ref:`setting-allow-from` and :ref:`setting-allow-notify-from` can be set. .. note:: - For configuration changes to work :ref:`setting-include-dir` and :ref:`setting-api-config-dir` should have the same value. + For configuration changes to work :ref:`setting-include-dir` and :ref:`setting-api-config-dir` should have the same value for old-style settings. + When using YAML settings :ref:`setting-yaml-recursor.include_dir` and :ref:`setting-yaml-webservice.api_dir` must have a different value. :param server_id: The name of the server :param config_setting_name: The name of the setting to change diff --git a/pdns/recursordist/docs/http-api/zone.rst b/pdns/recursordist/docs/http-api/zone.rst index bece530b2829..35e69ed4c3eb 100644 --- a/pdns/recursordist/docs/http-api/zone.rst +++ b/pdns/recursordist/docs/http-api/zone.rst @@ -32,7 +32,8 @@ be true: command line. Setting these options on the command line will override what has been set in the dynamically generated configuration files. -* ``include-dir`` must refer to the same directory as - ``api-config-dir`` for the dynamic reloading to work. + +* For configuration changes to work :ref:`setting-include-dir` and :ref:`setting-api-config-dir` should have the same value for old-style settings. + When using YAML settings :ref:`setting-yaml-recursor.include_dir` and :ref:`setting-yaml-webservice.api_dir` must have a different value. .. include:: ../common/api/zone.rst diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index e833fb656406..d521ea82382a 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -225,7 +225,8 @@ 'help' : 'Directory where REST API stores config and zones', 'doc' : ''' Directory where the REST API stores its configuration and zones. -For configuration updates to work, :ref:`setting-include-dir` should have the same value. +For configuration updates to work, :ref:`setting-include-dir` should have the same value when using old-style settings. +When using YAML settings :ref:`setting-yaml-recursor.include_dir` and :ref:`setting-yaml-webservice.api_dir` must have a different value. ''', 'versionadded': '4.0.0' }, @@ -2119,7 +2120,7 @@ }, { 'name' : 'serve_stale_extensions', - 'section' : 'recursor', + 'section' : 'recordcache', 'type' : LType.Uint64, 'default' : '0', 'help' : 'Number of times a record\'s ttl is extended by 30s to be served stale', From 3056b38256a084d4377a89aecccb7948f07e9b9e Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 13 Oct 2023 09:53:43 +0200 Subject: [PATCH 883/909] Print version earlier, logging tweak --- pdns/recursordist/rec-main.cc | 3 +-- pdns/recursordist/settings/cxxsupport.cc | 4 ++-- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pdns/recursordist/rec-main.cc b/pdns/recursordist/rec-main.cc index f61c81968396..51f3bdabd360 100644 --- a/pdns/recursordist/rec-main.cc +++ b/pdns/recursordist/rec-main.cc @@ -2028,8 +2028,6 @@ static int serviceMain(Logr::log_t log) } } - showProductVersion(); - g_disthashseed = dns_random_uint32(); int ret = initNet(log); @@ -3314,6 +3312,7 @@ int main(int argc, char** argv) } g_log.setLoglevel(s_logUrgency); g_log.toConsole(s_logUrgency); + showProductVersion(); g_yamlSettings = false; string configname = ::arg()["config-dir"] + "/recursor"; diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index 051ca54b5f81..0251fbae7b71 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -124,12 +124,12 @@ void pdns::settings::rec::oldStyleAllowFileToBridgeStruct(const std::string& fil static void mergeYamlSubFile(const std::string& configname, Recursorsettings& settings, Logr::log_t log) { - SLOG(g_log << Logger::Notice << "Processing YAML settings from " << configname << endl, - log->info(Logr::Notice, "Processing YAML settings", "path", Logging::Loggable(configname))); auto file = ifstream(configname); if (!file.is_open()) { throw runtime_error("Cannot open " + configname); } + SLOG(g_log << Logger::Notice << "Processing YAML settings from " << configname << endl, + log->info(Logr::Notice, "Processing YAML settings", "path", Logging::Loggable(configname))); auto data = string(std::istreambuf_iterator(file), std::istreambuf_iterator()); pdns::rust::settings::rec::merge(settings, data); } From 951479eb0baa2a86d75fa35c4bfdbf609a1c1388 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 13 Oct 2023 10:10:42 +0200 Subject: [PATCH 884/909] rec: Fix Coverity 1522436 Dereference null return value --- pdns/recursordist/rec-zonetocache.cc | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pdns/recursordist/rec-zonetocache.cc b/pdns/recursordist/rec-zonetocache.cc index 10936401c0fd..32bae21b5a0f 100644 --- a/pdns/recursordist/rec-zonetocache.cc +++ b/pdns/recursordist/rec-zonetocache.cc @@ -100,6 +100,9 @@ void ZoneData::parseDRForCache(DNSRecord& dnsRecord) break; case QType::RRSIG: { const auto rrsig = getRR(dnsRecord); + if (rrsig == nullptr) { + break; + } const auto sigkey = pair(key.first, rrsig->d_type); auto found = d_sigs.find(sigkey); if (found != d_sigs.end()) { From 07bee03a69e58c27ef70c7c30cf28dc484b62499 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 13 Oct 2023 11:55:33 +0200 Subject: [PATCH 885/909] Tidy --- pdns/recursordist/settings/cxxsupport.cc | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index 0251fbae7b71..3be355ba1adf 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -161,13 +161,15 @@ static void possiblyConvertACLFile(const string& includeDir, const string& apiDi result.emplace_back(val); } } - rust::string yaml; + + rust::string key = "allow_from"; + rust::string filekey = "allow_from_file"; if (filename == "allow-from") { - yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_from", "allow_from_file", result); - } - else { - yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming("allow_notify_from", "allow_notify_from_file", result); + key = "allow_notify_from"; + filekey = "allow_notify_from_file"; } + const auto yaml = pdns::rust::settings::rec::allow_from_to_yaml_string_incoming(key, filekey, result); + string yamlfilename = apiDir; yamlfilename.append("/").append(filename).append(".yml"); string tmpfilename = yamlfilename + ".tmp"; @@ -218,7 +220,7 @@ static void fileCopy(const string& src, const string& dst, Logr::log_t log) log->error(Logr::Error, err, "Error reading", "to", Logging::Loggable(src)); throw runtime_error("YAML Conversion"); } - ofconf.put(character); + ofconf.put(static_cast(character)); if (ofconf.bad()) { int err = errno; log->error(Logr::Error, err, "Error writing YAML", "to", Logging::Loggable(dst)); @@ -230,9 +232,9 @@ static void fileCopy(const string& src, const string& dst, Logr::log_t log) } static void possiblyConvertForwardsandAuths(const std::string& includeDir, const std::string& apiDir, Logr::log_t log) { - std::vector forwAndAuthFiles; + std::vector forwAndAuthFiles{}; ::arg().gatherIncludes(includeDir, "..conf", forwAndAuthFiles); - pdns::rust::settings::rec::Recursorsettings settings; + pdns::rust::settings::rec::Recursorsettings settings{}; for (const auto& file : forwAndAuthFiles) { auto yaml = pdns::settings::rec::oldStyleSettingsFileToYaml(file, false); pdns::rust::settings::rec::merge(settings, yaml); From 5c2a022154022e2872dfa5dbe27c81208c6a7647 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 9 Oct 2023 17:00:51 +0200 Subject: [PATCH 886/909] If we miss glue, but not for all NS records, we can try to resolve the missing glue, so push tasks for that. --- pdns/recursordist/syncres.cc | 44 ++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 15 deletions(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 129091b5db3a..229db97412f3 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -497,6 +497,19 @@ OptLog SyncRes::LogObject(const string& prefix) return ret; } +static bool pushResolveIfNotInNegCache(const DNSName& qname, QType qtype, const struct timeval& now) +{ + NegCache::NegCacheEntry negEntry; + bool inNegCache = g_negCache->get(qname, qtype, now, negEntry, false); + if (!inNegCache) { + // There are a few cases where an answer is neither stored in the record cache nor in the neg cache. + // An example is a SOA-less NODATA response. Rate limiting will kick in if those tasks are pushed too often. + // We might want to fix these cases (and always either store positive or negative) some day. + pushResolveTask(qname, qtype, now.tv_sec, now.tv_sec + 60, false); + } + return !inNegCache; +} + // A helper function to print a double with specific printf format. // Not using boost::format since it is not thread safe while calling // into locale handling code according to tsan. @@ -607,15 +620,7 @@ void SyncRes::resolveAdditionals(const DNSName& qname, QType qtype, AdditionalMo } } // Not found in cache, check negcache and push task if also not in negcache - NegCache::NegCacheEntry ne; - bool inNegCache = g_negCache->get(qname, qtype, d_now, ne, false); - if (!inNegCache) { - // There are a few cases where an answer is neither stored in the record cache nor in the neg cache. - // An example is a SOA-less NODATA response. Rate limiting will kick in if those tasks are pushed too often. - // We might want to fix these cases (and always either store positive or negative) some day. - pushResolveTask(qname, qtype, d_now.tv_sec, d_now.tv_sec + 60, false); - additionalsNotInCache = true; - } + additionalsNotInCache = pushResolveIfNotInNegCache(qname, qtype, d_now); break; } case AdditionalMode::Ignore: @@ -2167,11 +2172,7 @@ vector SyncRes::getAddrs(const DNSName& qname, unsigned int depth, if (s_doIPv6 && !seenV6 && !cacheOnly) { // No IPv6 records in cache, check negcache and submit async task if negache does not have the data // so that the next time the cache or the negcache will have data - NegCache::NegCacheEntry ne; - bool inNegCache = g_negCache->get(qname, QType::AAAA, d_now, ne, false); - if (!inNegCache) { - pushResolveTask(qname, QType::AAAA, d_now.tv_sec, d_now.tv_sec + 60, true); - } + pushResolveIfNotInNegCache(qname, QType::AAAA, d_now); } } catch (const PolicyHitException&) { @@ -2234,7 +2235,7 @@ vector SyncRes::getAddrs(const DNSName& qname, unsigned int depth, return ret; } -void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector& bestns, bool* flawedNSSet, unsigned int depth, const string& prefix, set& beenthere, const boost::optional& cutOffDomain) +void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector& bestns, bool* flawedNSSet, unsigned int depth, const string& prefix, set& beenthere, const boost::optional& cutOffDomain) // NOLINT(readability-function-cognitive-complexity) { DNSName subdomain(qname); bestns.clear(); @@ -2261,6 +2262,7 @@ void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector } bestns.reserve(ns.size()); + vector missing; for (auto k = ns.cbegin(); k != ns.cend(); ++k) { if (k->d_ttl > (unsigned int)d_now.tv_sec) { vector aset; @@ -2288,6 +2290,7 @@ void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector else { *flawedNSSet = true; LOG(prefix << qname << ": NS in cache for '" << subdomain << "', but needs glue (" << nrr->getNS() << ") which we miss or is expired" << endl); + missing.emplace_back(nrr->getNS()); } } } @@ -2297,6 +2300,17 @@ void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector LOG(prefix << qname << ": Wiping flawed authoritative NS records for " << subdomain << endl); g_recCache->doWipeCache(subdomain, false, QType::NS); } + if (!missing.empty() && missing.size() < ns.size()) { + // We miss glue, but we have a chance to resolve it, since we do have address(es) for at least one NS + for (const auto& name : missing) { + if (s_doIPv4 && pushResolveIfNotInNegCache(name, QType::A, d_now)) { + LOG(prefix << qname << ": A glue for " << subdomain << " NS " << name << " missing, pushed task to resolve" << endl); + } + if (s_doIPv6 && pushResolveIfNotInNegCache(name, QType::AAAA, d_now)) { + LOG(prefix << qname << ": AAAA glue for " << subdomain << " NS " << name << " missing, pushed task to resolve" << endl); + } + } + } if (!bestns.empty()) { GetBestNSAnswer answer; From 5eec1d2a52421f5e2aec4a6cc2644c05a42cae6d Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 13 Oct 2023 14:31:42 +0200 Subject: [PATCH 887/909] dnsdist: Better clang-tidy suppressions --- pdns/dnsdistdist/dnsdist-nghttp2-in.cc | 4 ++-- pdns/dnsdistdist/doh.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc index 432e9f22c94d..7c7864466f1c 100644 --- a/pdns/dnsdistdist/dnsdist-nghttp2-in.cc +++ b/pdns/dnsdistdist/dnsdist-nghttp2-in.cc @@ -495,13 +495,13 @@ void NGHTTP2Headers::addStaticHeader(std::vector& headers, NGHTTP2He const auto& name = s_headerConstants.at(static_cast(nameKey)); const auto& value = s_headerConstants.at(static_cast(valueKey)); - // NOLINTNEXTLINE nghttp2 API + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast,cppcoreguidelines-pro-type-reinterpret-cast): nghttp2 API headers.push_back({const_cast(reinterpret_cast(name.c_str())), const_cast(reinterpret_cast(value.c_str())), name.size(), value.size(), NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE}); } void NGHTTP2Headers::addCustomDynamicHeader(std::vector& headers, const std::string& name, const std::string_view& value) { - // NOLINTNEXTLINE nghttp2 API + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-const-cast,cppcoreguidelines-pro-type-reinterpret-cast): nghttp2 API headers.push_back({const_cast(reinterpret_cast(name.data())), const_cast(reinterpret_cast(value.data())), name.size(), value.size(), NGHTTP2_NV_FLAG_NO_COPY_NAME | NGHTTP2_NV_FLAG_NO_COPY_VALUE}); } diff --git a/pdns/dnsdistdist/doh.cc b/pdns/dnsdistdist/doh.cc index 128bee4126d5..55555292a186 100644 --- a/pdns/dnsdistdist/doh.cc +++ b/pdns/dnsdistdist/doh.cc @@ -1576,7 +1576,7 @@ void dohThread(ClientState* clientState) // in this complicated way we insert the DOHServerConfig pointer in there h2o_vector_reserve(nullptr, &dsc->h2o_ctx.storage, 1); - // NOLINTNEXTLINE: h2o API + // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic): h2o API dsc->h2o_ctx.storage.entries[0].data = dsc.get(); ++dsc->h2o_ctx.storage.size; From 7ae3a637344b7e493d90e913f1dbd5159afc5754 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 13 Oct 2023 14:46:07 +0200 Subject: [PATCH 888/909] dnsdist: Remove now unneeded clang-tidy suppression Co-authored-by: Otto Moerbeek --- pdns/dnsdistdist/doq.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 093eebe35e32..7ff7c0b6c8db 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -637,7 +637,6 @@ static void processDOQQuery(DOQUnitUniquePtr&& doqUnit) { /* don't keep that pointer around, it will be invalidated if the buffer is ever resized */ - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) dnsheader_aligned dnsHeader(unit->query.data()); if (!checkQueryHeaders(dnsHeader.get(), clientState)) { From 7450fc0865f62014a86feefd9f7992bbcdc4c692 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 13 Oct 2023 14:46:33 +0200 Subject: [PATCH 889/909] dnsdist: Use the QuicheConnection type, as suggested by Otto Co-authored-by: Otto Moerbeek --- pdns/dnsdistdist/doq.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/doq.cc b/pdns/dnsdistdist/doq.cc index 7ff7c0b6c8db..9489120191bd 100644 --- a/pdns/dnsdistdist/doq.cc +++ b/pdns/dnsdistdist/doq.cc @@ -53,7 +53,7 @@ using QuicheConfig = std::unique_ptr&& conn) : + Connection(const ComboAddress& peer, QuicheConnection&& conn) : d_peer(peer), d_conn(std::move(conn)) { } From 092247fff196366e82de794fe10e8847f73a4133 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 13 Oct 2023 14:48:30 +0200 Subject: [PATCH 890/909] Quiche: Fix the installation of library on macOS --- builder-support/helpers/install_quiche.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/builder-support/helpers/install_quiche.sh b/builder-support/helpers/install_quiche.sh index 908e949f50ed..82f2501fbaa8 100755 --- a/builder-support/helpers/install_quiche.sh +++ b/builder-support/helpers/install_quiche.sh @@ -29,6 +29,11 @@ RUST_BACKTRACE=1 cargo build --release --no-default-features --features ffi,bori install -m644 quiche/include/quiche.h "${INSTALL_PREFIX}"/include install -m644 target/release/libquiche.${SOEXT} "${INSTALL_PREFIX}"/lib/libdnsdist-quiche.${SOEXT} + +if [ $(uname) = Darwin ]; then + install_name_tool -id "${INSTALL_PREFIX}"/lib/libdnsdist-quiche.${SOEXT} "${INSTALL_PREFIX}"/lib/libdnsdist-quiche.${SOEXT} +fi + if [ ! -d "${INSTALL_PREFIX}"/lib/pkgconfig/ ]; then mkdir "${INSTALL_PREFIX}"/lib/pkgconfig/ fi From 5fd8b32b553c0358f613b00fce01bdc82393e1a5 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Fri, 13 Oct 2023 15:39:05 +0200 Subject: [PATCH 891/909] Only set additionalsNotInCache in the true case --- pdns/logging.hh | 4 ++-- pdns/recursordist/syncres.cc | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/pdns/logging.hh b/pdns/logging.hh index 0ddf6beae112..637e97d67ee6 100644 --- a/pdns/logging.hh +++ b/pdns/logging.hh @@ -203,14 +203,14 @@ extern bool g_slogStructured; // startupLog->error("No such file", "Unable to parse configuration file", "config_file", Logging::Loggable(configname)); // #define SLOG(oldStyle, slogCall) \ - do { \ + if (true) { \ if (g_slogStructured) { \ slogCall; \ } \ else { \ oldStyle; \ } \ - } while (0); + } #else // No structured logging (e.g. auth) #define SLOG(oldStyle, slogCall) \ diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index 229db97412f3..f7c56a4e21e5 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -620,7 +620,9 @@ void SyncRes::resolveAdditionals(const DNSName& qname, QType qtype, AdditionalMo } } // Not found in cache, check negcache and push task if also not in negcache - additionalsNotInCache = pushResolveIfNotInNegCache(qname, qtype, d_now); + if (pushResolveIfNotInNegCache(qname, qtype, d_now)) { + additionalsNotInCache = true; + } break; } case AdditionalMode::Ignore: From a7643425a12d273461c5e20bed1b4d37d56ef7c2 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 13 Oct 2023 17:04:25 +0200 Subject: [PATCH 892/909] dnsdist: Fix clang-tidy warnings --- pdns/dnsdist-lua.cc | 5 +- pdns/dnsdist.cc | 781 ++++++++++++++------------ pdns/dnsdistdist/dnsdist-dnsparser.cc | 6 +- pdns/dnsdistdist/dnsdist-dnsparser.hh | 4 +- 4 files changed, 417 insertions(+), 379 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index de7284c5411f..d75d85017a43 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -293,6 +293,7 @@ static bool checkConfigurationTime(const std::string& name) return false; } +// NOLINTNEXTLINE(readability-function-cognitive-complexity): this function declares Lua bindings, even with a good refactoring it will likely blow up the threshold static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) { typedef LuaAssociativeTable, DownstreamState::checkfunc_t>> newserver_t; @@ -2483,7 +2484,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) #endif /* HAVE_DNS_OVER_HTTPS */ }); - luaCtx.writeFunction("addDOQLocal", [client](const std::string& addr, boost::variant, LuaArray, LuaArray>> certFiles, boost::variant> keyFiles, boost::optional vars) { + luaCtx.writeFunction("addDOQLocal", [client](const std::string& addr, const boost::variant, LuaArray, LuaArray>>& certFiles, const boost::variant>& keyFiles, boost::optional vars) { if (client) { return; } @@ -2519,7 +2520,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) { std::string valueStr; if (getOptionalValue(vars, "congestionControlAlgo", valueStr) > 0) { - if (DOQFrontend::s_available_cc_algorithms.count(valueStr)) { + if (DOQFrontend::s_available_cc_algorithms.count(valueStr) > 0) { frontend->d_ccAlgo = valueStr; } else { diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index 1276f09df4cb..a54aed88f6db 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -227,7 +227,7 @@ struct DelayedPacket } }; -static DelayPipe* g_delay = nullptr; +static std::unique_ptr> g_delay{nullptr}; #endif /* DISABLE_DELAY_PIPE */ std::string DNSQuestion::getTrailingData() const @@ -607,7 +607,7 @@ static size_t getMaximumIncomingPacketSize(const ClientState& cs) bool sendUDPResponse(int origFD, const PacketBuffer& response, const int delayMsec, const ComboAddress& origDest, const ComboAddress& origRemote) { #ifndef DISABLE_DELAY_PIPE - if (delayMsec && g_delay) { + if (delayMsec && g_delay != nullptr) { DelayedPacket dp{origFD, response, origRemote, origDest}; g_delay->submit(dp, delayMsec); return true; @@ -1978,7 +1978,7 @@ static void maintThread() if something prevents us from cleaning the expired entries */ auto localPools = g_pools.getLocal(); for (const auto& entry : *localPools) { - auto& pool = entry.second; + const auto& pool = entry.second; auto packetCache = pool->packetCache; if (!packetCache) { @@ -1990,7 +1990,7 @@ static void maintThread() /* if we need to keep stale data for this cache (ie, not clear expired entries when at least one pool using this cache has all its backends down) */ - if (packetCache->keepStaleData() && iter->second == false) { + if (packetCache->keepStaleData() && !iter->second) { /* so far all pools had at least one backend up */ if (pool->countServers(true) == 0) { iter->second = true; @@ -2001,10 +2001,10 @@ static void maintThread() const time_t now = time(nullptr); for (const auto& pair : caches) { /* shall we keep expired entries ? */ - if (pair.second == true) { + if (pair.second) { continue; } - auto& packetCache = pair.first; + const auto& packetCache = pair.first; size_t upTo = (packetCache->getMaxEntries()* (100 - g_cacheCleaningPercentage)) / 100; packetCache->purgeExpired(upTo, now); } @@ -2118,9 +2118,9 @@ static void bindAny(int af, int sock) static void dropGroupPrivs(gid_t gid) { - if (gid) { + if (gid != 0) { if (setgid(gid) == 0) { - if (setgroups(0, NULL) < 0) { + if (setgroups(0, nullptr) < 0) { warnlog("Warning: Unable to drop supplementary gids: %s", stringerror()); } } @@ -2132,8 +2132,8 @@ static void dropGroupPrivs(gid_t gid) static void dropUserPrivs(uid_t uid) { - if(uid) { - if(setuid(uid) < 0) { + if (uid != 0) { + if (setuid(uid) < 0) { warnlog("Warning: Unable to set user ID to %d: %s", uid, stringerror()); } } @@ -2191,149 +2191,150 @@ static void checkFileDescriptorsLimits(size_t udpBindsCount, size_t tcpBindsCoun static bool g_warned_ipv6_recvpktinfo = false; -static void setUpLocalBind(std::unique_ptr& cstate) +static void setupLocalSocket(ClientState& clientState, const ComboAddress& addr, int& socket, bool tcp, bool warn) { - auto setupSocket = [](ClientState& cs, const ComboAddress& addr, int& socket, bool tcp, bool warn) { - (void) warn; - socket = SSocket(addr.sin4.sin_family, tcp == false ? SOCK_DGRAM : SOCK_STREAM, 0); + (void) warn; + socket = SSocket(addr.sin4.sin_family, !tcp ? SOCK_DGRAM : SOCK_STREAM, 0); - if (tcp) { - SSetsockopt(socket, SOL_SOCKET, SO_REUSEADDR, 1); + if (tcp) { + SSetsockopt(socket, SOL_SOCKET, SO_REUSEADDR, 1); #ifdef TCP_DEFER_ACCEPT - SSetsockopt(socket, IPPROTO_TCP, TCP_DEFER_ACCEPT, 1); + SSetsockopt(socket, IPPROTO_TCP, TCP_DEFER_ACCEPT, 1); #endif - if (cs.fastOpenQueueSize > 0) { + if (clientState.fastOpenQueueSize > 0) { #ifdef TCP_FASTOPEN - SSetsockopt(socket, IPPROTO_TCP, TCP_FASTOPEN, cs.fastOpenQueueSize); + SSetsockopt(socket, IPPROTO_TCP, TCP_FASTOPEN, clientState.fastOpenQueueSize); #ifdef TCP_FASTOPEN_KEY - if (!g_TCPFastOpenKey.empty()) { - auto res = setsockopt(socket, IPPROTO_IP, TCP_FASTOPEN_KEY, g_TCPFastOpenKey.data(), g_TCPFastOpenKey.size() * sizeof(g_TCPFastOpenKey[0])); - if (res == -1) { - throw runtime_error("setsockopt for level IPPROTO_TCP and opname TCP_FASTOPEN_KEY failed: " + stringerror()); - } + if (!g_TCPFastOpenKey.empty()) { + auto res = setsockopt(socket, IPPROTO_IP, TCP_FASTOPEN_KEY, g_TCPFastOpenKey.data(), g_TCPFastOpenKey.size() * sizeof(g_TCPFastOpenKey[0])); + if (res == -1) { + throw runtime_error("setsockopt for level IPPROTO_TCP and opname TCP_FASTOPEN_KEY failed: " + stringerror()); } + } #endif /* TCP_FASTOPEN_KEY */ #else /* TCP_FASTOPEN */ - if (warn) { - warnlog("TCP Fast Open has been configured on local address '%s' but is not supported", addr.toStringWithPort()); - } -#endif /* TCP_FASTOPEN */ + if (warn) { + warnlog("TCP Fast Open has been configured on local address '%s' but is not supported", addr.toStringWithPort()); } +#endif /* TCP_FASTOPEN */ } + } - if (addr.sin4.sin_family == AF_INET6) { - SSetsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, 1); - } + if (addr.sin4.sin_family == AF_INET6) { + SSetsockopt(socket, IPPROTO_IPV6, IPV6_V6ONLY, 1); + } - bindAny(addr.sin4.sin_family, socket); + bindAny(addr.sin4.sin_family, socket); - if (!tcp && IsAnyAddress(addr)) { - int one = 1; - (void) setsockopt(socket, IPPROTO_IP, GEN_IP_PKTINFO, &one, sizeof(one)); // linux supports this, so why not - might fail on other systems + if (!tcp && IsAnyAddress(addr)) { + int one = 1; + (void) setsockopt(socket, IPPROTO_IP, GEN_IP_PKTINFO, &one, sizeof(one)); // linux supports this, so why not - might fail on other systems #ifdef IPV6_RECVPKTINFO - if (addr.isIPv6() && setsockopt(socket, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)) < 0 && - !g_warned_ipv6_recvpktinfo) { - warnlog("Warning: IPV6_RECVPKTINFO setsockopt failed: %s", stringerror()); - g_warned_ipv6_recvpktinfo = true; - } -#endif + if (addr.isIPv6() && setsockopt(socket, IPPROTO_IPV6, IPV6_RECVPKTINFO, &one, sizeof(one)) < 0 && + !g_warned_ipv6_recvpktinfo) { + warnlog("Warning: IPV6_RECVPKTINFO setsockopt failed: %s", stringerror()); + g_warned_ipv6_recvpktinfo = true; } +#endif + } - if (cs.reuseport) { - if (!setReusePort(socket)) { - if (warn) { - /* no need to warn again if configured but support is not available, we already did for UDP */ - warnlog("SO_REUSEPORT has been configured on local address '%s' but is not supported", addr.toStringWithPort()); - } + if (clientState.reuseport) { + if (!setReusePort(socket)) { + if (warn) { + /* no need to warn again if configured but support is not available, we already did for UDP */ + warnlog("SO_REUSEPORT has been configured on local address '%s' but is not supported", addr.toStringWithPort()); } } + } + + /* Only set this on IPv4 UDP sockets. + Don't set it for DNSCrypt binds. DNSCrypt pads queries for privacy + purposes, so we do receive large, sometimes fragmented datagrams. */ + if (!tcp && !clientState.dnscryptCtx) { + try { + setSocketIgnorePMTU(socket, addr.sin4.sin_family); + } + catch (const std::exception& e) { + warnlog("Failed to set IP_MTU_DISCOVER on UDP server socket for local address '%s': %s", addr.toStringWithPort(), e.what()); + } + } - /* Only set this on IPv4 UDP sockets. - Don't set it for DNSCrypt binds. DNSCrypt pads queries for privacy - purposes, so we do receive large, sometimes fragmented datagrams. */ - if (!tcp && !cs.dnscryptCtx) { + if (!tcp) { + if (g_socketUDPSendBuffer > 0) { try { - setSocketIgnorePMTU(socket, addr.sin4.sin_family); + setSocketSendBuffer(socket, g_socketUDPSendBuffer); } catch (const std::exception& e) { - warnlog("Failed to set IP_MTU_DISCOVER on UDP server socket for local address '%s': %s", addr.toStringWithPort(), e.what()); + warnlog(e.what()); } } - if (!tcp) { - if (g_socketUDPSendBuffer > 0) { - try { - setSocketSendBuffer(socket, g_socketUDPSendBuffer); - } - catch (const std::exception& e) { - warnlog(e.what()); - } + if (g_socketUDPRecvBuffer > 0) { + try { + setSocketReceiveBuffer(socket, g_socketUDPRecvBuffer); } - - if (g_socketUDPRecvBuffer > 0) { - try { - setSocketReceiveBuffer(socket, g_socketUDPRecvBuffer); - } - catch (const std::exception& e) { - warnlog(e.what()); - } + catch (const std::exception& e) { + warnlog(e.what()); } } + } - const std::string& itf = cs.interface; - if (!itf.empty()) { + const std::string& itf = clientState.interface; + if (!itf.empty()) { #ifdef SO_BINDTODEVICE - int res = setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, itf.c_str(), itf.length()); - if (res != 0) { - warnlog("Error setting up the interface on local address '%s': %s", addr.toStringWithPort(), stringerror()); - } + int res = setsockopt(socket, SOL_SOCKET, SO_BINDTODEVICE, itf.c_str(), itf.length()); + if (res != 0) { + warnlog("Error setting up the interface on local address '%s': %s", addr.toStringWithPort(), stringerror()); + } #else - if (warn) { - warnlog("An interface has been configured on local address '%s' but SO_BINDTODEVICE is not supported", addr.toStringWithPort()); - } -#endif + if (warn) { + warnlog("An interface has been configured on local address '%s' but SO_BINDTODEVICE is not supported", addr.toStringWithPort()); } +#endif + } #ifdef HAVE_EBPF - if (g_defaultBPFFilter && !g_defaultBPFFilter->isExternal()) { - cs.attachFilter(g_defaultBPFFilter, socket); - vinfolog("Attaching default BPF Filter to %s frontend %s", (!tcp ? "UDP" : "TCP"), addr.toStringWithPort()); - } + if (g_defaultBPFFilter && !g_defaultBPFFilter->isExternal()) { + clientState.attachFilter(g_defaultBPFFilter, socket); + vinfolog("Attaching default BPF Filter to %s frontend %s", (!tcp ? "UDP" : "TCP"), addr.toStringWithPort()); + } #endif /* HAVE_EBPF */ - SBind(socket, addr); + SBind(socket, addr); - if (tcp) { - SListen(socket, cs.tcpListenQueueSize); + if (tcp) { + SListen(socket, clientState.tcpListenQueueSize); - if (cs.tlsFrontend != nullptr) { - infolog("Listening on %s for TLS", addr.toStringWithPort()); - } - else if (cs.dohFrontend != nullptr) { - infolog("Listening on %s for DoH", addr.toStringWithPort()); - } - else if (cs.dnscryptCtx != nullptr) { - infolog("Listening on %s for DNSCrypt", addr.toStringWithPort()); - } - else { - infolog("Listening on %s", addr.toStringWithPort()); - } - } else { - if (cs.doqFrontend != nullptr) { - infolog("Listening on %s for DoQ", addr.toStringWithPort()); - } + if (clientState.tlsFrontend != nullptr) { + infolog("Listening on %s for TLS", addr.toStringWithPort()); } - }; + else if (clientState.dohFrontend != nullptr) { + infolog("Listening on %s for DoH", addr.toStringWithPort()); + } + else if (clientState.dnscryptCtx != nullptr) { + infolog("Listening on %s for DNSCrypt", addr.toStringWithPort()); + } + else { + infolog("Listening on %s", addr.toStringWithPort()); + } + } else { + if (clientState.doqFrontend != nullptr) { + infolog("Listening on %s for DoQ", addr.toStringWithPort()); + } + } +} +static void setUpLocalBind(std::unique_ptr& cstate) +{ /* skip some warnings if there is an identical UDP context */ - bool warn = cstate->tcp == false || cstate->tlsFrontend != nullptr || cstate->dohFrontend != nullptr; - int& fd = cstate->tcp == false ? cstate->udpFD : cstate->tcpFD; + bool warn = !cstate->tcp || cstate->tlsFrontend != nullptr || cstate->dohFrontend != nullptr; + int& descriptor = !cstate->tcp ? cstate->udpFD : cstate->tcpFD; (void) warn; - setupSocket(*cstate, cstate->local, fd, cstate->tcp, warn); + setupLocalSocket(*cstate, cstate->local, descriptor, cstate->tcp, warn); for (auto& [addr, socket] : cstate->d_additionalAddresses) { - setupSocket(*cstate, addr, socket, true, false); + setupLocalSocket(*cstate, addr, socket, true, false); } if (cstate->tlsFrontend != nullptr) { @@ -2454,221 +2455,352 @@ static void sigTermHandler(int) } #endif /* COVERAGE */ -int main(int argc, char** argv) +static void reportFeatures() { - try { - size_t udpBindsCount = 0; - size_t tcpBindsCount = 0; -#ifdef HAVE_LIBEDIT -#ifndef DISABLE_COMPLETION - rl_attempted_completion_function = my_completion; - rl_completion_append_character = 0; -#endif /* DISABLE_COMPLETION */ -#endif /* HAVE_LIBEDIT */ - - signal(SIGPIPE, SIG_IGN); - signal(SIGCHLD, SIG_IGN); - signal(SIGTERM, sigTermHandler); - - openlog("dnsdist", LOG_PID|LOG_NDELAY, LOG_DAEMON); - -#ifdef HAVE_LIBSODIUM - if (sodium_init() == -1) { - cerr<<"Unable to initialize crypto library"< longopts{{ + {"acl", required_argument, nullptr, 'a'}, + {"check-config", no_argument, nullptr, 1}, + {"client", no_argument, nullptr, 'c'}, + {"config", required_argument, nullptr, 'C'}, + {"disable-syslog", no_argument, nullptr, 2}, + {"execute", required_argument, nullptr, 'e'}, + {"gid", required_argument, nullptr, 'g'}, + {"help", no_argument, nullptr, 'h'}, + {"local", required_argument, nullptr, 'l'}, + {"log-timestamps", no_argument, nullptr, 4}, + {"setkey", required_argument, nullptr, 'k'}, + {"supervised", no_argument, nullptr, 3}, + {"uid", required_argument, nullptr, 'u'}, + {"verbose", no_argument, nullptr, 'v'}, + {"version", no_argument, nullptr, 'V'}, + {nullptr, 0, nullptr, 0} + }}; + int longindex = 0; + string optstring; + while (true) { + // NOLINTNEXTLINE(concurrency-mt-unsafe): only one thread at this point + int gotChar = getopt_long(argc, argv, "a:cC:e:g:hk:l:u:vV", longopts.data(), &longindex); + if (gotChar == -1) { + break; + } + switch (gotChar) { + case 1: + g_cmdLine.checkConfig = true; + break; + case 2: + g_syslog = false; + break; + case 3: + g_cmdLine.beSupervised = true; + break; + case 4: + g_logtimestamps = true; + break; + case 'C': + g_cmdLine.config = optarg; + break; + case 'c': + g_cmdLine.beClient = true; + break; + case 'e': + g_cmdLine.command = optarg; + break; + case 'g': + g_cmdLine.gid = optarg; + break; + case 'h': + cout<<"dnsdist "<getName() == "chashed") { + precompute = true; + } else { + for (const auto& entry: pools) { + if (entry.second->policy != nullptr && entry.second->policy->getName() == "chashed") { + precompute = true; + break ; + } + } + } + if (precompute) { + vinfolog("Pre-computing hashes for consistent hash load-balancing policy"); + // pre compute hashes + auto backends = g_dstates.getLocal(); + for (const auto& backend: *backends) { + if (backend->d_config.d_weight < 100) { + vinfolog("Warning, the backend '%s' has a very low weight (%d), which will not yield a good distribution of queries with the 'chashed' policy. Please consider raising it to at least '100'.", backend->getName(), backend->d_config.d_weight); + } + + backend->hash(); + } + } + } +} + +static void dropPrivileges() +{ + uid_t newgid = getegid(); + gid_t newuid = geteuid(); + + if (!g_cmdLine.gid.empty()) { + newgid = strToGID(g_cmdLine.gid); + } + + if (!g_cmdLine.uid.empty()) { + newuid = strToUID(g_cmdLine.uid); + } + + bool retainedCapabilities = true; + if (!g_capabilitiesToRetain.empty() && + (getegid() != newgid || geteuid() != newuid)) { + retainedCapabilities = keepCapabilitiesAfterSwitchingIDs(); + } + + if (getegid() != newgid) { + if (running_in_service_mgr()) { + errlog("--gid/-g set on command-line, but dnsdist was started as a systemd service. Use the 'Group' setting in the systemd unit file to set the group to run as"); + _exit(EXIT_FAILURE); + } + dropGroupPrivs(newgid); + } + + if (geteuid() != newuid) { + if (running_in_service_mgr()) { + errlog("--uid/-u set on command-line, but dnsdist was started as a systemd service. Use the 'User' setting in the systemd unit file to set the user to run as"); + _exit(EXIT_FAILURE); } + dropUserPrivs(newuid); + } + + if (retainedCapabilities) { + dropCapabilitiesAfterSwitchingIDs(); + } - argc -= optind; - argv += optind; - (void) argc; + try { + /* we might still have capabilities remaining, + for example if we have been started as root + without --uid or --gid (please don't do that) + or as an unprivileged user with ambient + capabilities like CAP_NET_BIND_SERVICE. + */ + dropCapabilities(g_capabilitiesToRetain); + } + catch (const std::exception& e) { + warnlog("%s", e.what()); + } +} - for (auto p = argv; *p; ++p) { - if(g_cmdLine.beClient) { - clientAddress = ComboAddress(*p, 5199); - } else { - g_cmdLine.remotes.push_back(*p); +static void initFrontends() +{ + if (!g_cmdLine.locals.empty()) { + for (auto it = g_frontends.begin(); it != g_frontends.end(); ) { + /* DoH, DoT and DNSCrypt frontends are separate */ + if ((*it)->dohFrontend == nullptr && (*it)->tlsFrontend == nullptr && (*it)->dnscryptCtx == nullptr && (*it)->doqFrontend == nullptr) { + it = g_frontends.erase(it); } + else { + ++it; + } + } + + for (const auto& loc : g_cmdLine.locals) { + /* UDP */ + g_frontends.emplace_back(std::make_unique(ComboAddress(loc, 53), false, false, 0, "", std::set{})); + /* TCP */ + g_frontends.emplace_back(std::make_unique(ComboAddress(loc, 53), true, false, 0, "", std::set{})); } + } + + if (g_frontends.empty()) { + /* UDP */ + g_frontends.emplace_back(std::make_unique(ComboAddress("127.0.0.1", 53), false, false, 0, "", std::set{})); + /* TCP */ + g_frontends.emplace_back(std::make_unique(ComboAddress("127.0.0.1", 53), true, false, 0, "", std::set{})); + } +} + +int main(int argc, char** argv) +{ + try { + size_t udpBindsCount = 0; + size_t tcpBindsCount = 0; +#ifdef HAVE_LIBEDIT +#ifndef DISABLE_COMPLETION + rl_attempted_completion_function = my_completion; + rl_completion_append_character = 0; +#endif /* DISABLE_COMPLETION */ +#endif /* HAVE_LIBEDIT */ + + signal(SIGPIPE, SIG_IGN); + signal(SIGCHLD, SIG_IGN); + signal(SIGTERM, sigTermHandler); + + openlog("dnsdist", LOG_PID|LOG_NDELAY, LOG_DAEMON); + +#ifdef HAVE_LIBSODIUM + if (sodium_init() == -1) { + cerr<<"Unable to initialize crypto library"<getName() == "chashed") { - precompute = true; - } else { - for (const auto& entry: localPools) { - if (entry.second->policy != nullptr && entry.second->policy->getName() == "chashed") { - precompute = true; - break ; - } - } - } - if (precompute) { - vinfolog("Pre-computing hashes for consistent hash load-balancing policy"); - // pre compute hashes - auto backends = g_dstates.getLocal(); - for (auto& backend: *backends) { - if (backend->d_config.d_weight < 100) { - vinfolog("Warning, the backend '%s' has a very low weight (%d), which will not yield a good distribution of queries with the 'chashed' policy. Please consider raising it to at least '100'.", backend->getName(), backend->d_config.d_weight); - } + setupPools(); - backend->hash(); - } - } - } - - if (!g_cmdLine.locals.empty()) { - for (auto it = g_frontends.begin(); it != g_frontends.end(); ) { - /* DoH, DoT and DNSCrypt frontends are separate */ - if ((*it)->dohFrontend == nullptr && (*it)->tlsFrontend == nullptr && (*it)->dnscryptCtx == nullptr && (*it)->doqFrontend == nullptr) { - it = g_frontends.erase(it); - } - else { - ++it; - } - } - - for (const auto& loc : g_cmdLine.locals) { - /* UDP */ - g_frontends.push_back(std::unique_ptr(new ClientState(ComboAddress(loc, 53), false, false, 0, "", {}))); - /* TCP */ - g_frontends.push_back(std::unique_ptr(new ClientState(ComboAddress(loc, 53), true, false, 0, "", {}))); - } - } - - if (g_frontends.empty()) { - /* UDP */ - g_frontends.push_back(std::unique_ptr(new ClientState(ComboAddress("127.0.0.1", 53), false, false, 0, "", {}))); - /* TCP */ - g_frontends.push_back(std::unique_ptr(new ClientState(ComboAddress("127.0.0.1", 53), true, false, 0, "", {}))); - } + initFrontends(); g_configurationDone = true; g_rings.init(); - for(auto& frontend : g_frontends) { + for (auto& frontend : g_frontends) { setUpLocalBind(frontend); - if (frontend->tcp == false) { + if (!frontend->tcp) { ++udpBindsCount; } else { @@ -2780,12 +2864,13 @@ int main(int argc, char** argv) vector vec; std::string acls; g_ACL.getLocal()->toStringVector(&vec); - for(const auto& s : vec) { - if (!acls.empty()) + for (const auto& aclEntry : vec) { + if (!acls.empty()) { acls += ", "; - acls += s; + } + acls += aclEntry; } - infolog("ACL allowing queries from: %s", acls.c_str()); + infolog("ACL allowing queries from: %s", acls); vec.clear(); acls.clear(); g_consoleACL.getLocal()->toStringVector(&vec); @@ -2803,62 +2888,14 @@ int main(int argc, char** argv) } #endif - uid_t newgid=getegid(); - gid_t newuid=geteuid(); - - if (!g_cmdLine.gid.empty()) { - newgid = strToGID(g_cmdLine.gid); - } - - if (!g_cmdLine.uid.empty()) { - newuid = strToUID(g_cmdLine.uid); - } - - bool retainedCapabilities = true; - if (!g_capabilitiesToRetain.empty() && - (getegid() != newgid || geteuid() != newuid)) { - retainedCapabilities = keepCapabilitiesAfterSwitchingIDs(); - } - - if (getegid() != newgid) { - if (running_in_service_mgr()) { - errlog("--gid/-g set on command-line, but dnsdist was started as a systemd service. Use the 'Group' setting in the systemd unit file to set the group to run as"); - _exit(EXIT_FAILURE); - } - dropGroupPrivs(newgid); - } - - if (geteuid() != newuid) { - if (running_in_service_mgr()) { - errlog("--uid/-u set on command-line, but dnsdist was started as a systemd service. Use the 'User' setting in the systemd unit file to set the user to run as"); - _exit(EXIT_FAILURE); - } - dropUserPrivs(newuid); - } - - if (retainedCapabilities) { - dropCapabilitiesAfterSwitchingIDs(); - } - - try { - /* we might still have capabilities remaining, - for example if we have been started as root - without --uid or --gid (please don't do that) - or as an unprivileged user with ambient - capabilities like CAP_NET_BIND_SERVICE. - */ - dropCapabilities(g_capabilitiesToRetain); - } - catch (const std::exception& e) { - warnlog("%s", e.what()); - } + dropPrivileges(); /* this need to be done _after_ dropping privileges */ #ifndef DISABLE_DELAY_PIPE - g_delay = new DelayPipe(); + g_delay = std::make_unique>(); #endif /* DISABLE_DELAY_PIPE */ - if (g_snmpAgent) { + if (g_snmpAgent != nullptr) { g_snmpAgent->run(); } @@ -2879,14 +2916,14 @@ int main(int argc, char** argv) initDoHWorkers(); - for (auto& t : todo) { - t(); + for (auto& todoItem : todo) { + todoItem(); } - localPools = g_pools.getCopy(); + auto localPools = g_pools.getCopy(); /* create the default pool no matter what */ createPoolIfNotExists(localPools, ""); - if (g_cmdLine.remotes.size()) { + if (!g_cmdLine.remotes.empty()) { for (const auto& address : g_cmdLine.remotes) { DownstreamState::Config config; config.remote = ComboAddress(address, 53); diff --git a/pdns/dnsdistdist/dnsdist-dnsparser.cc b/pdns/dnsdistdist/dnsdist-dnsparser.cc index 49f2942b03d4..a15f2d5e9f54 100644 --- a/pdns/dnsdistdist/dnsdist-dnsparser.cc +++ b/pdns/dnsdistdist/dnsdist-dnsparser.cc @@ -188,7 +188,7 @@ bool changeNameInDNSPacket(PacketBuffer& initialPacket, const DNSName& from, con namespace PacketMangling { - bool editDNSHeaderFromPacket(PacketBuffer& packet, std::function editFunction) + bool editDNSHeaderFromPacket(PacketBuffer& packet, const std::function& editFunction) { if (packet.size() < sizeof(dnsheader)) { throw std::runtime_error("Trying to edit the DNS header of a too small packet"); @@ -197,7 +197,7 @@ namespace PacketMangling return editDNSHeaderFromRawPacket(packet.data(), editFunction); } - bool editDNSHeaderFromRawPacket(void* packet, std::function editFunction) + bool editDNSHeaderFromRawPacket(void* packet, const std::function& editFunction) { if (dnsheader_aligned::isMemoryAligned(packet)) { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) @@ -205,7 +205,7 @@ namespace PacketMangling return editFunction(*header); } - dnsheader header; + dnsheader header{}; memcpy(&header, packet, sizeof(header)); if (!editFunction(header)) { return false; diff --git a/pdns/dnsdistdist/dnsdist-dnsparser.hh b/pdns/dnsdistdist/dnsdist-dnsparser.hh index 839f6cd396fe..4f7cdaded409 100644 --- a/pdns/dnsdistdist/dnsdist-dnsparser.hh +++ b/pdns/dnsdistdist/dnsdist-dnsparser.hh @@ -57,7 +57,7 @@ bool changeNameInDNSPacket(PacketBuffer& initialPacket, const DNSName& from, con namespace PacketMangling { - bool editDNSHeaderFromPacket(PacketBuffer& packet, std::function editFunction); - bool editDNSHeaderFromRawPacket(void* packet, std::function editFunction); + bool editDNSHeaderFromPacket(PacketBuffer& packet, const std::function& editFunction); + bool editDNSHeaderFromRawPacket(void* packet, const std::function& editFunction); } } From 61e8b855282c08fcc9e983ad7943f1855c089cdd Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Fri, 13 Oct 2023 17:44:13 +0200 Subject: [PATCH 893/909] dnsdist: More clang-tidy delinting --- pdns/dnsdist-lua.cc | 1 + pdns/dnsdist.cc | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index d75d85017a43..e39748e8c2ad 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -2484,6 +2484,7 @@ static void setupLuaConfig(LuaContext& luaCtx, bool client, bool configCheck) #endif /* HAVE_DNS_OVER_HTTPS */ }); + // NOLINTNEXTLINE(performance-unnecessary-value-param): somehow clang-tidy gets confused about the fact vars could be const while it cannot luaCtx.writeFunction("addDOQLocal", [client](const std::string& addr, const boost::variant, LuaArray, LuaArray>>& certFiles, const boost::variant>& keyFiles, boost::optional vars) { if (client) { return; diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index a54aed88f6db..cf2bf9c5315d 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -607,7 +607,7 @@ static size_t getMaximumIncomingPacketSize(const ClientState& cs) bool sendUDPResponse(int origFD, const PacketBuffer& response, const int delayMsec, const ComboAddress& origDest, const ComboAddress& origRemote) { #ifndef DISABLE_DELAY_PIPE - if (delayMsec && g_delay != nullptr) { + if (delayMsec > 0 && g_delay != nullptr) { DelayedPacket dp{origFD, response, origRemote, origDest}; g_delay->submit(dp, delayMsec); return true; @@ -2296,7 +2296,7 @@ static void setupLocalSocket(ClientState& clientState, const ComboAddress& addr, #ifdef HAVE_EBPF if (g_defaultBPFFilter && !g_defaultBPFFilter->isExternal()) { clientState.attachFilter(g_defaultBPFFilter, socket); - vinfolog("Attaching default BPF Filter to %s frontend %s", (!tcp ? "UDP" : "TCP"), addr.toStringWithPort()); + vinfolog("Attaching default BPF Filter to %s frontend %s", std::string(!tcp ? "UDP" : "TCP"), addr.toStringWithPort()); } #endif /* HAVE_EBPF */ @@ -2772,7 +2772,9 @@ int main(int argc, char** argv) #endif /* DISABLE_COMPLETION */ #endif /* HAVE_LIBEDIT */ + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast): SIG_IGN macro signal(SIGPIPE, SIG_IGN); + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-cstyle-cast): SIG_IGN macro signal(SIGCHLD, SIG_IGN); signal(SIGTERM, sigTermHandler); @@ -2781,7 +2783,7 @@ int main(int argc, char** argv) #ifdef HAVE_LIBSODIUM if (sodium_init() == -1) { cerr<<"Unable to initialize crypto library"< Date: Mon, 16 Oct 2023 10:02:25 +0200 Subject: [PATCH 894/909] fix: added missing closed bracket --- pdns/dnsdistdist/docs/guides/dns-over-https.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdistdist/docs/guides/dns-over-https.rst b/pdns/dnsdistdist/docs/guides/dns-over-https.rst index 6f4e5d16b682..eefd78864ccd 100644 --- a/pdns/dnsdistdist/docs/guides/dns-over-https.rst +++ b/pdns/dnsdistdist/docs/guides/dns-over-https.rst @@ -25,7 +25,7 @@ the call to :func:`addDOHLocal`. It is optional and defaults to ``/`` in 1.4.0, The fifth parameter, if present, indicates various options. For instance, you use it to indicate custom HTTP headers. An example is:: - addDOHLocal('2001:db8:1:f00::1', '/etc/ssl/certs/example.com.pem', '/etc/ssl/private/example.com.key', "/dns", {customResponseHeaders={["x-foo"]="bar"}} + addDOHLocal('2001:db8:1:f00::1', '/etc/ssl/certs/example.com.pem', '/etc/ssl/private/example.com.key', "/dns", {customResponseHeaders={["x-foo"]="bar"}}) A more complicated (and more realistic) example is when you want to indicate metainformation about the server, such as the stated policy (privacy statement and so on). We use the link types of RFC 8631:: From e76816cf473a66f845f8685a7b905648a7a35e23 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 16 Oct 2023 10:53:34 +0200 Subject: [PATCH 895/909] dnsdist: More clang-tidy delinting --- pdns/dnsdist.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/dnsdist.cc b/pdns/dnsdist.cc index cf2bf9c5315d..71955161dc38 100644 --- a/pdns/dnsdist.cc +++ b/pdns/dnsdist.cc @@ -2296,7 +2296,7 @@ static void setupLocalSocket(ClientState& clientState, const ComboAddress& addr, #ifdef HAVE_EBPF if (g_defaultBPFFilter && !g_defaultBPFFilter->isExternal()) { clientState.attachFilter(g_defaultBPFFilter, socket); - vinfolog("Attaching default BPF Filter to %s frontend %s", std::string(!tcp ? "UDP" : "TCP"), addr.toStringWithPort()); + vinfolog("Attaching default BPF Filter to %s frontend %s", (!tcp ? std::string("UDP") : std::string("TCP")), addr.toStringWithPort()); } #endif /* HAVE_EBPF */ From bcb4b8080c496517dd9495c9061f50887cf440bf Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 16 Oct 2023 11:06:20 +0200 Subject: [PATCH 896/909] Check if nrr pointer is valid before using Co-authored-by: Remi Gacogne --- pdns/recursordist/syncres.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index f7c56a4e21e5..79eed8d6afd2 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -2289,7 +2289,7 @@ void SyncRes::getBestNSFromCache(const DNSName& qname, const QType qtype, vector LOG(", not in cache / did not look at cache" << endl); } } - else { + else if (nrr != nullptr) { *flawedNSSet = true; LOG(prefix << qname << ": NS in cache for '" << subdomain << "', but needs glue (" << nrr->getNS() << ") which we miss or is expired" << endl); missing.emplace_back(nrr->getNS()); From d408178740515b15aea5b269a2731716a4d93473 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 16 Oct 2023 12:09:39 +0200 Subject: [PATCH 897/909] Better handling of potential absent file --- pdns/recursordist/settings/cxxsupport.cc | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index 3be355ba1adf..6a8870068a7f 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -122,10 +122,13 @@ void pdns::settings::rec::oldStyleAllowFileToBridgeStruct(const std::string& fil } } -static void mergeYamlSubFile(const std::string& configname, Recursorsettings& settings, Logr::log_t log) +static void mergeYamlSubFile(const std::string& configname, Recursorsettings& settings, bool allowabsent, Logr::log_t log) { auto file = ifstream(configname); if (!file.is_open()) { + if (allowabsent) { + return; + } throw runtime_error("Cannot open " + configname); } SLOG(g_log << Logger::Notice << "Processing YAML settings from " << configname << endl, @@ -164,7 +167,7 @@ static void possiblyConvertACLFile(const string& includeDir, const string& apiDi rust::string key = "allow_from"; rust::string filekey = "allow_from_file"; - if (filename == "allow-from") { + if (filename == "allow-notify-from") { key = "allow_notify_from"; filekey = "allow_notify_from_file"; } @@ -280,11 +283,7 @@ void pdns::settings::rec::processAPIDir(const string& includeDirOnCommandLine, p possiblyConvertACLFile(includeDir, apiDir, file, log); auto path = apiDir; path.append("/").append(file).append(".yml"); - try { - mergeYamlSubFile(path, settings, log); - } - catch (const runtime_error& err) { - } + mergeYamlSubFile(path, settings, true, log); } possiblyConvertForwardsandAuths(includeDir, apiDir, log); } @@ -305,7 +304,7 @@ pdns::settings::rec::YamlSettingsStatus pdns::settings::rec::readYamlSettings(co ::arg().gatherIncludes(!includeDirOnCommandLine.empty() ? includeDirOnCommandLine : string(yamlstruct.recursor.include_dir), ".yml", yamlFiles); for (const auto& yamlfile : yamlFiles) { - mergeYamlSubFile(yamlfile, yamlstruct, log); + mergeYamlSubFile(yamlfile, yamlstruct, false, log); } yamlstruct.validate(); settings = yamlstruct; From 49708be4278c1ed7430f952de395261228a7d0c6 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 16 Oct 2023 13:32:13 +0200 Subject: [PATCH 898/909] Update boost.m4, clang 17 is out Will upstream as well I wish the boost script would not need this... --- m4/boost.m4 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/m4/boost.m4 b/m4/boost.m4 index d1b6e2c0cac2..30a4d917b276 100644 --- a/m4/boost.m4 +++ b/m4/boost.m4 @@ -1615,6 +1615,9 @@ if test x$boost_cv_inc_path != xno; then # I'm not sure about my test for `il' (be careful: Intel's ICC pre-defines # the same defines as GCC's). for i in \ + "defined __clang__ && __clang_major__ == 17 && __clang_minor__ == 0 @ clang170" \ + "defined __clang__ && __clang_major__ == 16 && __clang_minor__ == 0 @ clang160" \ + "defined __clang__ && __clang_major__ == 15 && __clang_minor__ == 0 @ clang150" \ "defined __clang__ && __clang_major__ == 14 && __clang_minor__ == 0 @ clang140" \ "defined __clang__ && __clang_major__ == 13 && __clang_minor__ == 0 @ clang130" \ "defined __clang__ && __clang_major__ == 12 && __clang_minor__ == 0 @ clang120" \ From 5a3e2bc9da9f5076eb5a31c922ae6c8352aa2b2c Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 16 Oct 2023 14:49:47 +0200 Subject: [PATCH 899/909] Only explictly dump coverage data if we're heading for _exit() --- pdns/recursordist/rec_channel_rec.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pdns/recursordist/rec_channel_rec.cc b/pdns/recursordist/rec_channel_rec.cc index bbff8289a24d..3d6dfc1901fc 100644 --- a/pdns/recursordist/rec_channel_rec.cc +++ b/pdns/recursordist/rec_channel_rec.cc @@ -1591,12 +1591,11 @@ void doExitGeneric(bool nicely) unlink(g_pidfname.c_str()); // we can at least try.. } - pdns::coverage::dumpCoverageData(); - if (nicely) { RecursorControlChannel::stop = true; } else { + pdns::coverage::dumpCoverageData(); _exit(1); } } From ba274b76ae2aef0347172a1fdd1df26594585fe0 Mon Sep 17 00:00:00 2001 From: Remi Gacogne Date: Mon, 16 Oct 2023 16:13:47 +0200 Subject: [PATCH 900/909] tasks: Enable LTO back for dnsdist --- tasks.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tasks.py b/tasks.py index 5e07f0b3f688..e647349c1f29 100644 --- a/tasks.py +++ b/tasks.py @@ -565,6 +565,7 @@ def ci_dnsdist_configure(c, features): --enable-option-checking=fatal \ --enable-fortify-source=auto \ --enable-auto-var-init=pattern \ + --enable-lto=thin \ --prefix=/opt/dnsdist %s %s %s %s %s''' % (cflags, cxxflags, features_set, sanitizers, unittests, fuzztargets, coverage), warn=True) if res.exited != 0: c.run('cat config.log') From 863d702c566db788370a1ae998eeaf7b9d61d511 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 16 Oct 2023 16:16:53 +0200 Subject: [PATCH 901/909] ws fix Co-authored-by: Remi Gacogne --- pdns/recursordist/docs/http-api/zone.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdns/recursordist/docs/http-api/zone.rst b/pdns/recursordist/docs/http-api/zone.rst index 35e69ed4c3eb..4ff312afa3d1 100644 --- a/pdns/recursordist/docs/http-api/zone.rst +++ b/pdns/recursordist/docs/http-api/zone.rst @@ -33,7 +33,7 @@ be true: override what has been set in the dynamically generated configuration files. -* For configuration changes to work :ref:`setting-include-dir` and :ref:`setting-api-config-dir` should have the same value for old-style settings. +* For configuration changes to work :ref:`setting-include-dir` and :ref:`setting-api-config-dir` should have the same value for old-style settings. When using YAML settings :ref:`setting-yaml-recursor.include_dir` and :ref:`setting-yaml-webservice.api_dir` must have a different value. .. include:: ../common/api/zone.rst From a778d82ba58634c1ec3dd3f80b936bb6c9654b4d Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Mon, 16 Oct 2023 16:25:37 +0200 Subject: [PATCH 902/909] Check stream status in more cases as suggested by @rgacogne --- pdns/recursordist/settings/cxxsupport.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/settings/cxxsupport.cc b/pdns/recursordist/settings/cxxsupport.cc index 6a8870068a7f..511305930a28 100644 --- a/pdns/recursordist/settings/cxxsupport.cc +++ b/pdns/recursordist/settings/cxxsupport.cc @@ -185,6 +185,11 @@ static void possiblyConvertACLFile(const string& includeDir, const string& apiDi ofconf << "# Generated by pdns-recursor REST API, DO NOT EDIT" << endl; ofconf << yaml << endl; ofconf.close(); + if (ofconf.bad()) { + log->error(Logr::Error, "Error writing YAML", "to", Logging::Loggable(tmpfilename)); + unlink(tmpfilename.c_str()); + throw runtime_error("YAML Conversion"); + } if (rename(path.c_str(), (path + ".converted").c_str()) != 0) { int err = errno; log->error(Logr::Error, err, "Rename failed", "file", Logging::Loggable(path), "to", Logging::Loggable(path + ".converted")); @@ -230,9 +235,14 @@ static void fileCopy(const string& src, const string& dst, Logr::log_t log) throw runtime_error("YAML Conversion"); } } - ofconf.close(); ifconf.close(); + ofconf.close(); + if (ofconf.bad()) { + log->error(Logr::Error, "Error writing YAML", "to", Logging::Loggable(dst)); + throw runtime_error("YAML Conversion"); + } } + static void possiblyConvertForwardsandAuths(const std::string& includeDir, const std::string& apiDir, Logr::log_t log) { std::vector forwAndAuthFiles{}; From a13849bcb38186ff82e3086d5a1c8962f669f2b7 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:37:49 -0400 Subject: [PATCH 903/909] spelling: cannot Signed-off-by: Josh Soref <2119212+jsoref@users.noreply.github.com> --- docs/backends/ldap.rst | 2 +- docs/common/secpoll.rst | 2 +- docs/domainmetadata.rst | 2 +- docs/guides/recursion.rst | 4 ++-- docs/guides/svcb.rst | 2 +- docs/lua-records/index.rst | 2 +- docs/modes-of-operation.rst | 2 +- docs/settings.rst | 2 +- pdns/recursordist/docs/changelog/4.1.rst | 2 +- pdns/recursordist/settings/table.py | 2 +- 10 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/backends/ldap.rst b/docs/backends/ldap.rst index 4a5b29735c4a..9779f32491a3 100644 --- a/docs/backends/ldap.rst +++ b/docs/backends/ldap.rst @@ -431,7 +431,7 @@ Tree mode requires each component to be a dc element of its own: To use this kind of record, add the dnsdomain2 schema to the configuration of the LDAP server. -**CAUTION:** ``ldap-method=strict`` can not be used if zone transfers +**CAUTION:** ``ldap-method=strict`` cannot be used if zone transfers (AXFR) are needed to other name servers. Distributing zones can only be done directly via LDAP replication in this case, because for a full zone transfer the reverse records are missing. diff --git a/docs/common/secpoll.rst b/docs/common/secpoll.rst index 051b7ffa3edc..d181f1ffaf09 100644 --- a/docs/common/secpoll.rst +++ b/docs/common/secpoll.rst @@ -46,7 +46,7 @@ It could be lowered however if we discover the security status is less urgent th If resolution fails, and the previous security-status was 1, the new security-status becomes 0 ('no data'). If the security-status was higher than 1, it will remain that way, and not get set to 0. -In this way, security-status of 0 really means 'no data', and can not mask a known problem. +In this way, security-status of 0 really means 'no data', and cannot mask a known problem. Distributions ~~~~~~~~~~~~~ diff --git a/docs/domainmetadata.rst b/docs/domainmetadata.rst index 16ca81d9f9a7..5f399037822b 100644 --- a/docs/domainmetadata.rst +++ b/docs/domainmetadata.rst @@ -27,7 +27,7 @@ The following options can only be read (not written to) via the HTTP API metadat * PRESIGNED * TSIG-ALLOW-AXFR -The option SOA-EDIT-API can not be written or read via the HTTP API metadata endpoint. +The option SOA-EDIT-API cannot be written or read via the HTTP API metadata endpoint. .. _metadata-allow-axfr-from: diff --git a/docs/guides/recursion.rst b/docs/guides/recursion.rst index a1756ed976cd..a12fc958f174 100644 --- a/docs/guides/recursion.rst +++ b/docs/guides/recursion.rst @@ -61,7 +61,7 @@ and port 5300 change the following in ``pdns.conf``: This is most likely an ``apt-get`` or ``yum install`` away, see the `Recursor documentation `__ for more information. -It might be possible that the Recursor can not start as the listen +It might be possible that the Recursor cannot start as the listen address is in use by the Authoritative Server, this is fine for now. Now configure the listen addresses and ACL for the Recursor to be the @@ -144,7 +144,7 @@ This is most likely an ``apt-get`` or ``yum install`` away, see the `Recursor's Install Guide `__ for more information. -It might be possible that the Recursor can not start as the listen +It might be possible that the Recursor cannot start as the listen address is in use by the Authoritative Server, this is fine for now. Configure the recursor to listen on the local loopback interface on a diff --git a/docs/guides/svcb.rst b/docs/guides/svcb.rst index 8c5c2d4a2366..b0ca7e0da067 100644 --- a/docs/guides/svcb.rst +++ b/docs/guides/svcb.rst @@ -66,7 +66,7 @@ Consider the following zone content:: no-ipv6.example.org IN HTTPS 1 . ipv4hint=auto ipv6hint=auto no-ipv6.example.org IN A 192.0.2.2 -Here, no AAAA record exists for www.example.org, so PowerDNS can not put any data in the ipv6hint. +Here, no AAAA record exists for www.example.org, so PowerDNS cannot put any data in the ipv6hint. In this case, the ipv6hint parameter is dropped when answering the query (and on AXFR):: ;; QUESTION SECTION: diff --git a/docs/lua-records/index.rst b/docs/lua-records/index.rst index 66d0b82876ca..109954ac6124 100644 --- a/docs/lua-records/index.rst +++ b/docs/lua-records/index.rst @@ -198,7 +198,7 @@ Details & Security LUA records are synthesized on query. They can also be transferred via AXFR to other PowerDNS servers. -LUA records themselves can not be queried however, as this would allow third parties to see load balancing internals +LUA records themselves cannot be queried however, as this would allow third parties to see load balancing internals they do not need to see. A non-supporting DNS server will also serve a zone with LUA records, but diff --git a/docs/modes-of-operation.rst b/docs/modes-of-operation.rst index 3ba094f9b0d9..2406a0b90b93 100644 --- a/docs/modes-of-operation.rst +++ b/docs/modes-of-operation.rst @@ -200,7 +200,7 @@ Finally, IXFR updates that "plug" Empty Non-Terminals do not yet remove ENT records. A 'pdnsutil rectify-zone' may be required. PowerDNS itself is currently only able to retrieve updates via IXFR. It -can not serve IXFR updates. +cannot serve IXFR updates. .. _supermaster-operation: .. _autoprimary-operation: diff --git a/docs/settings.rst b/docs/settings.rst index d8bed0d47ce1..ef487677f2d4 100644 --- a/docs/settings.rst +++ b/docs/settings.rst @@ -1304,7 +1304,7 @@ If this is disabled (the default), ALIAS records are sent verbatim during outgoing AXFR. Note that if your slaves do not support ALIAS, they will return NODATA for A/AAAA queries for such names. -If the ALIAS target can not be resolved during AXFR the AXFR will fail. +If the ALIAS target cannot be resolved during AXFR the AXFR will fail. To allow outgoing AXFR also if the ALIAS targets are broken set this setting to `ignore-errors`. Be warned, this will lead to inconsistent zones between Primary and diff --git a/pdns/recursordist/docs/changelog/4.1.rst b/pdns/recursordist/docs/changelog/4.1.rst index 92d1b6a6f706..86e61c0145ac 100644 --- a/pdns/recursordist/docs/changelog/4.1.rst +++ b/pdns/recursordist/docs/changelog/4.1.rst @@ -1341,7 +1341,7 @@ See :doc:`EOL Statements <../appendices/EOL>`. :tags: Bug Fixes :pullreq: 5209 - Ensure locks can not be copied. + Ensure locks cannot be copied. .. change:: :tags: Improvements, RPZ diff --git a/pdns/recursordist/settings/table.py b/pdns/recursordist/settings/table.py index e833fb656406..99b7e39ba6b1 100644 --- a/pdns/recursordist/settings/table.py +++ b/pdns/recursordist/settings/table.py @@ -502,7 +502,7 @@ 'default' : 'false', 'help' : 'Disable packetcache', 'doc' : ''' -Turn off the packet cache. Useful when running with Lua scripts that can not be cached, though individual query caching can be controlled from Lua as well. +Turn off the packet cache. Useful when running with Lua scripts that cannot be cached, though individual query caching can be controlled from Lua as well. ''', }, { From c16860d87398ab1fb7c37dedf89c2a22b6c4a825 Mon Sep 17 00:00:00 2001 From: Josh Soref <2119212+jsoref@users.noreply.github.com> Date: Mon, 16 Oct 2023 15:32:58 -0400 Subject: [PATCH 904/909] Small refresh to workflow --- .../actions/spell-check/candidate.patterns | 16 +++++++++---- .github/actions/spell-check/excludes.txt | 23 ++++++++++++++----- .../spell-check/line_forbidden.patterns | 3 +++ .github/actions/spell-check/patterns.txt | 19 ++++++++++----- .github/workflows/spelling3.yml | 6 ++--- 5 files changed, 47 insertions(+), 20 deletions(-) diff --git a/.github/actions/spell-check/candidate.patterns b/.github/actions/spell-check/candidate.patterns index bf9dce0b1220..7325ad600758 100644 --- a/.github/actions/spell-check/candidate.patterns +++ b/.github/actions/spell-check/candidate.patterns @@ -396,7 +396,7 @@ Joaqu[^[:ascii:]]n (?:\\(?:u00|x)1[Bb]|\x1b|\\u\{1[Bb]\})\[\d+(?:;\d+|)m # URL escaped characters -\%[0-9A-F][A-F] +\%[0-9A-F][A-F](?=[A-Za-z]) # lower URL escaped characters \%[0-9a-f][a-f](?=[a-z]{2,}) # IPv6 @@ -496,6 +496,9 @@ content: (['"])[-a-zA-Z=;:/0-9+]*=\g{-1} # perl qr regex (?|\(.*?\)|([|!/@#,;']).*?\g{-1}) +# perl run +perl(?:\s+-[a-zA-Z]\w*)+ + # Go regular expressions regexp?\.MustCompile\(`[^`]*`\) @@ -514,6 +517,9 @@ sed 's/(?:[^/]*?[a-zA-Z]{3,}[^/]*?/){2} # go install go install(?:\s+[a-z]+\.[-@\w/.]+)+ +# jetbrains schema https://youtrack.jetbrains.com/issue/RSRP-489571 +urn:shemas-jetbrains-com + # kubernetes pod status lists # https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase \w+(?:-\w+)+\s+\d+/\d+\s+(?:Running|Pending|Succeeded|Failed|Unknown)\s+ @@ -578,13 +584,13 @@ systemd.*?running in system mode \([-+].*\)$ # Non-English [a-zA-Z]*[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3}[a-zA-ZÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]*|[a-zA-Z]{3,}[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź]|[ÀÁÂÃÄÅÆČÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæčçèéêëìíîïðñòóôõöøùúûüýÿĀāŁłŃńŅņŒœŚśŠšŜŝŸŽžź][a-zA-Z]{3,} +# highlighted letters +\[[A-Z]\][a-z]+ + # French # This corpus only had capital letters, but you probably want lowercase ones as well. \b[LN]'+[a-z]{2,}\b -# latex (check-spelling <= 0.0.21) -#\\(?:n(?:ew|ormal|osub)|r(?:enew)|t(?:able(?:of|)|he|itle))(?=[a-z]+) - # latex (check-spelling >= 0.0.22) \\\w{2,}\{ @@ -594,7 +600,7 @@ systemd.*?running in system mode \([-+].*\)$ # Windows short paths [/\\][^/\\]{5,6}~\d{1,2}[/\\] -# in a version of check-spelling after @0.0.21 printf markers won't be automatically consumed +# in check-spelling@v0.0.22+, printf markers aren't automatically consumed # printf markers (?]*>|[^<]*)\s*$ diff --git a/.github/workflows/spelling3.yml b/.github/workflows/spelling3.yml index f09a7ffc1980..9df9009ca478 100644 --- a/.github/workflows/spelling3.yml +++ b/.github/workflows/spelling3.yml @@ -11,8 +11,6 @@ on: pull_request: branches: - "**" - tags-ignore: - - "**" types: - 'opened' - 'reopened' @@ -34,7 +32,7 @@ jobs: outputs: followup: ${{ steps.spelling.outputs.followup }} runs-on: ubuntu-latest - if: "contains(github.event_name, 'pull_request') || github.event_name == 'push'" + if: ${{ contains(github.event_name, 'pull_request') || github.event_name == 'push' }} concurrency: group: spelling-${{ github.event.pull_request.number || github.ref }} # note: If you use only_check_changed_files, you do not want cancel-in-progress @@ -45,9 +43,11 @@ jobs: uses: check-spelling/check-spelling@v0.0.22 with: config: .github/actions/spell-check + suppress_push_for_open_pull_request: ${{ github.actor != 'dependabot[bot]' && 1 }} checkout: true spell_check_this: powerdns/pdns@master post_comment: 0 + warnings: bad-regex,binary-file,deprecated-feature,ignored-expect-variant,large-file,limited-references,no-newline-at-eof,noisy-file,non-alpha-in-dictionary,token-is-substring,unexpected-line-ending,whitespace-in-dictionary,minified-file,unsupported-configuration,no-files-to-check use_sarif: ${{ (!github.event.pull_request || (github.event.pull_request.head.repo.full_name == github.repository)) && 1 }} extra_dictionaries: cspell:software-terms/dict/softwareTerms.txt From e63e16c148664927864127b9ef48fb8293a7a6bd Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Wed, 12 Jul 2023 20:06:27 +0200 Subject: [PATCH 905/909] auth: add bind primary, secondary and primaries keywords --- docs/backends/bind.rst | 3 ++ modules/bindbackend/bindbackend2.cc | 10 +++--- pdns/bindlexer.l | 3 +- pdns/bindparser.yy | 12 +++---- pdns/named.conf.parsertest | 17 +++++----- pdns/test-bindparser_cc.cc | 17 +++++----- pdns/zone2json.cc | 8 ++--- pdns/zone2ldap.cc | 8 ++--- pdns/zone2sql.cc | 8 ++--- regression-tests.auth-py/authtests.py | 2 +- .../test_ProxyProtocol.py | 2 +- .../counters/named.conf | 2 +- .../default-publish-cds/named.conf | 2 +- .../edns-packet-cache/named.conf | 2 +- .../negcache-tests-dotted-cname/named.conf | 2 +- .../rectify-axfr/command | 2 +- .../soa-edit/named.conf | 2 +- .../supermaster-signed/command | 4 +-- .../supermaster-unsigned/command | 4 +-- .../recursortests.py | 2 +- regression-tests.recursor/config.sh | 2 +- regression-tests.rootzone/named.conf | 2 +- regression-tests/backends/bind-slave | 2 +- regression-tests/ext/bind-master | 2 +- regression-tests/ext/bind-slave | 2 +- regression-tests/named.conf | 34 +++++++++---------- 26 files changed, 81 insertions(+), 75 deletions(-) diff --git a/docs/backends/bind.rst b/docs/backends/bind.rst index 7b3da21e39ab..19d7021606f2 100644 --- a/docs/backends/bind.rst +++ b/docs/backends/bind.rst @@ -53,8 +53,11 @@ It supports the following blocks and directives: * ``file`` * ``type`` * ``masters`` + * ``primaries`` (added in version 4.9.0) * ``also-notify`` +Unknown directives will be ignored. + .. _setting-bind-check-interval: ``bind-check-interval`` diff --git a/modules/bindbackend/bindbackend2.cc b/modules/bindbackend/bindbackend2.cc index 1a0b01a57886..c90ae0124509 100644 --- a/modules/bindbackend/bindbackend2.cc +++ b/modules/bindbackend/bindbackend2.cc @@ -935,7 +935,7 @@ void Bind2Backend::loadConfig(string* status) if (domain.type.empty()) { g_log << Logger::Notice << d_logprefix << " Zone '" << domain.name << "' has no type specified, assuming 'native'" << endl; } - if (domain.type != "master" && domain.type != "slave" && domain.type != "native" && !domain.type.empty()) { + if (domain.type != "primary" && domain.type != "secondary" && domain.type != "native" && !domain.type.empty() && domain.type != "master" && domain.type != "slave") { g_log << Logger::Warning << d_logprefix << " Warning! Skipping zone '" << domain.name << "' because type '" << domain.type << "' is invalid" << endl; rejected++; continue; @@ -961,9 +961,9 @@ void Bind2Backend::loadConfig(string* status) bbd.d_also_notify = domain.alsoNotify; DomainInfo::DomainKind kind = DomainInfo::Native; - if (domain.type == "master") + if (domain.type == "primary" || domain.type == "master") kind = DomainInfo::Master; - if (domain.type == "slave") + if (domain.type == "secondary" || domain.type == "slave") kind = DomainInfo::Slave; bool kindChanged = (bbd.d_kind != kind); @@ -1431,9 +1431,9 @@ bool Bind2Backend::createSlaveDomain(const string& ip, const DNSName& domain, co c_of << endl; c_of << "# Superslave zone '" << domain.toString() << "' (added: " << nowTime() << ") (account: " << account << ')' << endl; c_of << "zone \"" << domain.toStringNoDot() << "\" {" << endl; - c_of << "\ttype slave;" << endl; + c_of << "\ttype secondary;" << endl; c_of << "\tfile \"" << filename << "\";" << endl; - c_of << "\tmasters { " << ip << "; };" << endl; + c_of << "\tprimaries { " << ip << "; };" << endl; c_of << "};" << endl; c_of.close(); } diff --git a/pdns/bindlexer.l b/pdns/bindlexer.l index 65dfc4da02ca..481e3b9f9345 100644 --- a/pdns/bindlexer.l +++ b/pdns/bindlexer.l @@ -114,7 +114,8 @@ also-notify return ALSONOTIFYTOK; acl return ACLTOK; logging return LOGGINGTOK; directory return DIRECTORYTOK; -masters return MASTERTOK; +masters return PRIMARYTOK; +primaries return PRIMARYTOK; type return TYPETOK; \" yy_push_state(quoted); [^\"]* yylval=strdup(yytext); return QUOTEDWORD; diff --git a/pdns/bindparser.yy b/pdns/bindparser.yy index 0b1056f2db6e..9f6ba81fe61b 100644 --- a/pdns/bindparser.yy +++ b/pdns/bindparser.yy @@ -108,7 +108,7 @@ void BindParser::commit(BindDomainInfo DI) %} %token AWORD QUOTEDWORD OBRACE EBRACE SEMICOLON ZONETOK FILETOK OPTIONSTOK -%token DIRECTORYTOK ACLTOK LOGGINGTOK CLASSTOK TYPETOK MASTERTOK ALSONOTIFYTOK +%token DIRECTORYTOK ACLTOK LOGGINGTOK CLASSTOK TYPETOK PRIMARYTOK ALSONOTIFYTOK %% @@ -230,10 +230,10 @@ zone_command: command | global_zone_command | zone_also_notify_command ; /* zone commands that also are available at global scope */ -global_zone_command: zone_file_command | zone_type_command | zone_masters_command +global_zone_command: zone_file_command | zone_type_command | zone_primaries_command ; -zone_masters_command: MASTERTOK OBRACE masters EBRACE +zone_primaries_command: PRIMARYTOK OBRACE primaries EBRACE ; zone_also_notify_command: ALSONOTIFYTOK OBRACE zone_also_notify_list EBRACE @@ -251,12 +251,12 @@ zone_also_notify: AWORD } ; -masters: /* empty */ +primaries: /* empty */ | - masters master SEMICOLON + primaries primary SEMICOLON ; -master: AWORD +primary: AWORD { s_di.masters.push_back(ComboAddress($1, 53)); free($1); diff --git a/pdns/named.conf.parsertest b/pdns/named.conf.parsertest index 4d38d223f7ec..b8b0e3599358 100644 --- a/pdns/named.conf.parsertest +++ b/pdns/named.conf.parsertest @@ -30,41 +30,42 @@ zone "test.dyndns" { }; zone "wtest.com"{ - type master; + type primary; file "wtest.com"; }; zone "nztest.com"{ - type master; + type secondary; file "nztest.com"; + primaries { 1.2.3.4:5678; }; }; zone "dnssec-parent.com"{ - type master; + type primary; file "dnssec-parent.com"; }; zone "delegated.dnssec-parent.com"{ - type master; + type primary; file "delegated.dnssec-parent.com"; }; zone "secure-delegated.dnssec-parent.com"{ - type master; + type primary; file "secure-delegated.dnssec-parent.com"; }; zone "minimal.com"{ - type master; + type primary; file "minimal.com"; }; zone "tsig.com"{ - type master; + type primary; file "tsig.com"; }; zone "stest.com"{ - type master; + type primary; file "stest.com"; }; diff --git a/pdns/test-bindparser_cc.cc b/pdns/test-bindparser_cc.cc index cd8fda27183c..bff31f21fc51 100644 --- a/pdns/test-bindparser_cc.cc +++ b/pdns/test-bindparser_cc.cc @@ -48,14 +48,15 @@ BOOST_AUTO_TEST_CASE(test_parser) checkzone(1, "test.com", "./zones/test.com", slave, 1U); BOOST_CHECK_EQUAL(domains[1].masters[0].toString(), ComboAddress("1.2.3.4", 5678).toString()); checkzone(2, "test.dyndns", "./zones/test.dyndns", garblewarble, 0U); - checkzone(3, "wtest.com", "./zones/wtest.com", master, 0U); - checkzone(4, "nztest.com", "./zones/nztest.com", master, 0U); - checkzone(5, "dnssec-parent.com", "./zones/dnssec-parent.com", master, 0U); - checkzone(6, "delegated.dnssec-parent.com", "./zones/delegated.dnssec-parent.com", master, 0U); - checkzone(7, "secure-delegated.dnssec-parent.com", "./zones/secure-delegated.dnssec-parent.com", master, 0U); - checkzone(8, "minimal.com", "./zones/minimal.com", master, 0U); - checkzone(9, "tsig.com", "./zones/tsig.com", master, 0U); - checkzone(10, "stest.com", "./zones/stest.com", master, 0U); + checkzone(3, "wtest.com", "./zones/wtest.com", primary, 0U); + checkzone(4, "nztest.com", "./zones/nztest.com", secondary, 1U); + BOOST_CHECK_EQUAL(domains[1].masters[0].toString(), ComboAddress("1.2.3.4", 5678).toString()); + checkzone(5, "dnssec-parent.com", "./zones/dnssec-parent.com", primary, 0U); + checkzone(6, "delegated.dnssec-parent.com", "./zones/delegated.dnssec-parent.com", primary, 0U); + checkzone(7, "secure-delegated.dnssec-parent.com", "./zones/secure-delegated.dnssec-parent.com", primary, 0U); + checkzone(8, "minimal.com", "./zones/minimal.com", primary, 0U); + checkzone(9, "tsig.com", "./zones/tsig.com", primary, 0U); + checkzone(10, "stest.com", "./zones/stest.com", primary, 0U); } BOOST_AUTO_TEST_SUITE_END() diff --git a/pdns/zone2json.cc b/pdns/zone2json.cc index 9ef9fadb1896..51e76fa03b42 100644 --- a/pdns/zone2json.cc +++ b/pdns/zone2json.cc @@ -162,10 +162,10 @@ try i!=domains.end(); ++i) { - if(i->type!="master" && i->type!="slave") { - cerr<<" Warning! Skipping '"<type<<"' zone '"<name<<"'"<type != "primary" && i->type != "secondary" && !i->type.empty() && i->type != "master" && i->type != "slave") { + cerr << " Warning! Skipping '" << i->type << "' zone '" << i->name << "'" << endl; + continue; + } lines.clear(); try { Json::object obj; diff --git a/pdns/zone2ldap.cc b/pdns/zone2ldap.cc index f0c905977824..5752350e0df4 100644 --- a/pdns/zone2ldap.cc +++ b/pdns/zone2ldap.cc @@ -306,10 +306,10 @@ int main( int argc, char* argv[] ) for(const auto& i: domains) { - if(i.type!="master" && i.type!="slave") { - cerr<<" Warning! Skipping '"<> ./named.conf << __EOF__ zone "."{ - type master; + type primary; file "../../regression-tests.rootzone/zones/ROOT"; }; __EOF__ diff --git a/regression-tests.nobackend/soa-edit/named.conf b/regression-tests.nobackend/soa-edit/named.conf index e94fe49cf821..15e634623d7c 100644 --- a/regression-tests.nobackend/soa-edit/named.conf +++ b/regression-tests.nobackend/soa-edit/named.conf @@ -9,6 +9,6 @@ options { }; zone "minimal.com"{ - type master; + type primary; file "./minimal.com"; }; diff --git a/regression-tests.nobackend/supermaster-signed/command b/regression-tests.nobackend/supermaster-signed/command index 30be471ef1f3..9829dbc8cf99 100755 --- a/regression-tests.nobackend/supermaster-signed/command +++ b/regression-tests.nobackend/supermaster-signed/command @@ -35,12 +35,12 @@ options { minimal-responses yes; }; zone "example.com"{ - type master; + type primary; file "example.com"; }; zone "test.com"{ - type master; + type primary; file "test.com"; }; EOF diff --git a/regression-tests.nobackend/supermaster-unsigned/command b/regression-tests.nobackend/supermaster-unsigned/command index 22935a93f6f0..53b6881c07b0 100755 --- a/regression-tests.nobackend/supermaster-unsigned/command +++ b/regression-tests.nobackend/supermaster-unsigned/command @@ -30,12 +30,12 @@ options { minimal-responses yes; }; zone "example.com"{ - type master; + type primary; file "example.com"; }; zone "test.com"{ - type master; + type primary; file "test.com"; }; EOF diff --git a/regression-tests.recursor-dnssec/recursortests.py b/regression-tests.recursor-dnssec/recursortests.py index c19426965e0b..93e68cc210dd 100644 --- a/regression-tests.recursor-dnssec/recursortests.py +++ b/regression-tests.recursor-dnssec/recursortests.py @@ -474,7 +474,7 @@ def generateAuthNamedConf(cls, confdir, zones): namedconf.write(""" zone "%s" { - type master; + type primary; file "%s.zone"; };""" % (zone, zonename)) diff --git a/regression-tests.recursor/config.sh b/regression-tests.recursor/config.sh index 480f1dd9ffa8..0e40c321542e 100755 --- a/regression-tests.recursor/config.sh +++ b/regression-tests.recursor/config.sh @@ -541,7 +541,7 @@ EOF fi cat >> $dir/named.conf < named-slave.conf + perl -pe 's/type primary;/type secondary;\n\tprimaries { 127.0.0.1:'$port'; };/ ;s/file "([^"]+)/file "$1-slave/' < named.conf > named-slave.conf for zone in $(grep 'zone ' named.conf | cut -f2 -d\") do diff --git a/regression-tests/ext/bind-master b/regression-tests/ext/bind-master index bd2fa1068f29..01b677c418f9 100644 --- a/regression-tests/ext/bind-master +++ b/regression-tests/ext/bind-master @@ -75,7 +75,7 @@ __EOF__ echo "" >> bind.conf echo "zone \"${zone}\" {" >> bind.conf - echo " type master;" >> bind.conf + echo " type primary;" >> bind.conf if [ "${zone}" = "tsig.com" ] then echo " allow-transfer { key test; none; };" >> bind.conf diff --git a/regression-tests/ext/bind-slave b/regression-tests/ext/bind-slave index f0afa2198100..20e7693d8bbc 100644 --- a/regression-tests/ext/bind-slave +++ b/regression-tests/ext/bind-slave @@ -21,7 +21,7 @@ __EOF__ echo "" >> bind-slave.conf echo "zone \"${zone}\" {" >> bind-slave.conf - echo " type slave;" >> bind-slave.conf + echo " type secondary;" >> bind-slave.conf echo " file \"${zone}-slave\";" >> bind-slave.conf if [ "${zone}" = "tsig.com" ] then diff --git a/regression-tests/named.conf b/regression-tests/named.conf index c1105a0891c1..f1ba7d0b5af0 100644 --- a/regression-tests/named.conf +++ b/regression-tests/named.conf @@ -8,17 +8,17 @@ options { minimal-responses yes; }; zone "example.com"{ - type master; + type primary; file "example.com"; }; zone "test.com"{ - type master; + type primary; file "test.com"; }; zone "test.dyndns" { - type master; + type primary; file "test.dyndns"; allow-update { 127.0.0.0/8; @@ -26,7 +26,7 @@ zone "test.dyndns" { }; zone "sub.test.dyndns" { - type master; + type primary; file "sub.test.dyndns"; allow-update { 127.0.0.0/8; @@ -34,67 +34,67 @@ zone "sub.test.dyndns" { }; zone "wtest.com"{ - type master; + type primary; file "wtest.com"; }; zone "nztest.com"{ - type master; + type primary; file "nztest.com"; }; zone "dnssec-parent.com"{ - type master; + type primary; file "dnssec-parent.com"; }; zone "insecure.dnssec-parent.com"{ - type master; + type primary; file "insecure.dnssec-parent.com"; }; zone "delegated.dnssec-parent.com"{ - type master; + type primary; file "delegated.dnssec-parent.com"; }; zone "secure-delegated.dnssec-parent.com"{ - type master; + type primary; file "secure-delegated.dnssec-parent.com"; }; zone "minimal.com"{ - type master; + type primary; file "minimal.com"; }; zone "tsig.com"{ - type master; + type primary; file "tsig.com"; }; zone "stest.com"{ - type master; + type primary; file "stest.com"; }; zone "cdnskey-cds-test.com"{ - type master; + type primary; file "cdnskey-cds-test.com"; }; zone "2.0.192.in-addr.arpa"{ - type master; + type primary; file "2.0.192.in-addr.arpa"; }; zone "cryptokeys.org"{ - type master; + type primary; file "cryptokeys.org"; }; zone "hiddencryptokeys.org"{ - type master; + type primary; file "hiddencryptokeys.org"; }; From a2937344a9d753378dd53b59059ccdc8542945e9 Mon Sep 17 00:00:00 2001 From: Kees Monshouwer Date: Thu, 13 Jul 2023 12:46:17 +0200 Subject: [PATCH 906/909] revert to legacy in recursor tests, they use an old release for testing --- regression-tests.recursor-dnssec/recursortests.py | 2 +- regression-tests.recursor/config.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/regression-tests.recursor-dnssec/recursortests.py b/regression-tests.recursor-dnssec/recursortests.py index 93e68cc210dd..c19426965e0b 100644 --- a/regression-tests.recursor-dnssec/recursortests.py +++ b/regression-tests.recursor-dnssec/recursortests.py @@ -474,7 +474,7 @@ def generateAuthNamedConf(cls, confdir, zones): namedconf.write(""" zone "%s" { - type primary; + type master; file "%s.zone"; };""" % (zone, zonename)) diff --git a/regression-tests.recursor/config.sh b/regression-tests.recursor/config.sh index 0e40c321542e..480f1dd9ffa8 100755 --- a/regression-tests.recursor/config.sh +++ b/regression-tests.recursor/config.sh @@ -541,7 +541,7 @@ EOF fi cat >> $dir/named.conf < Date: Tue, 17 Oct 2023 09:09:14 +0200 Subject: [PATCH 907/909] Followup to #13353, missed the suggested change; add recursor.yml to .gitignore --- pdns/recursordist/.gitignore | 1 + pdns/recursordist/syncres.cc | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pdns/recursordist/.gitignore b/pdns/recursordist/.gitignore index bb7e771610f7..0d8c2d01c818 100644 --- a/pdns/recursordist/.gitignore +++ b/pdns/recursordist/.gitignore @@ -57,3 +57,4 @@ PowerDNS-Recursor.pdf /*.pb.h /.cache /.clang-tidy +/recursor.yml diff --git a/pdns/recursordist/syncres.cc b/pdns/recursordist/syncres.cc index c90c47c5b0dc..8300e1c19eae 100644 --- a/pdns/recursordist/syncres.cc +++ b/pdns/recursordist/syncres.cc @@ -4763,7 +4763,7 @@ dState SyncRes::getDenialValidationState(const NegCache::NegCacheEntry& ne, cons return getDenial(csp, ne.d_name, ne.d_qtype.getCode(), referralToUnsigned, expectedState == dState::NXQTYPE, LogObject(prefix)); } -bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, const QType qtype, const DNSName& auth, LWResult& lwr, const bool sendRDQuery, vector& ret, set& nsset, DNSName& newtarget, DNSName& newauth, bool& realreferral, bool& negindic, vState& state, const bool needWildcardProof, const bool gatherWildcardProof, const unsigned int wildcardLabelsCount, int& rcode, bool& negIndicHasSignatures, unsigned int depth) // NOLINT(readability-function-cognitive-complexity) +bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, const QType qtype, const DNSName& auth, LWResult& lwr, const bool sendRDQuery, vector& ret, set& nsset, DNSName& newtarget, DNSName& newauth, bool& realreferral, bool& negindic, vState& state, const bool needWildcardProof, const bool gatherWildcardProof, const unsigned int wildcardLabelsCount, int& rcode, bool& negIndicHasSignatures, unsigned int depth) { bool done = false; DNSName dnameTarget, dnameOwner; From dce1e3d6b1293e3a8430f18539cd0434aac0b34d Mon Sep 17 00:00:00 2001 From: Peter van Dijk Date: Tue, 17 Oct 2023 10:13:47 +0200 Subject: [PATCH 908/909] make clang-tidy happy --- modules/bindbackend/bindbackend2.cc | 8 +++++--- pdns/zone2sql.cc | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/bindbackend/bindbackend2.cc b/modules/bindbackend/bindbackend2.cc index c90ae0124509..f9e53a64ecf4 100644 --- a/modules/bindbackend/bindbackend2.cc +++ b/modules/bindbackend/bindbackend2.cc @@ -883,7 +883,7 @@ void Bind2Backend::doEmptyNonTerminals(std::shared_ptr& records } } -void Bind2Backend::loadConfig(string* status) +void Bind2Backend::loadConfig(string* status) // NOLINT(readability-function-cognitive-complexity) 13379 https://github.com/PowerDNS/pdns/issues/13379 Habbie: zone2sql.cc, bindbackend2.cc: reduce complexity { static int domain_id = 1; @@ -961,10 +961,12 @@ void Bind2Backend::loadConfig(string* status) bbd.d_also_notify = domain.alsoNotify; DomainInfo::DomainKind kind = DomainInfo::Native; - if (domain.type == "primary" || domain.type == "master") + if (domain.type == "primary" || domain.type == "master") { kind = DomainInfo::Master; - if (domain.type == "secondary" || domain.type == "slave") + } + if (domain.type == "secondary" || domain.type == "slave") { kind = DomainInfo::Slave; + } bool kindChanged = (bbd.d_kind != kind); bbd.d_kind = kind; diff --git a/pdns/zone2sql.cc b/pdns/zone2sql.cc index 7a12f2df5780..c309533f6fb7 100644 --- a/pdns/zone2sql.cc +++ b/pdns/zone2sql.cc @@ -193,7 +193,7 @@ ArgvMap &arg() } -int main(int argc, char **argv) +int main(int argc, char **argv) // NOLINT(readability-function-cognitive-complexity) 13379 https://github.com/PowerDNS/pdns/issues/13379 Habbie: zone2sql.cc, bindbackend2.cc: reduce complexity try { reportAllTypes(); From 0eafc57b29ad30438c04f8feeb32246f41dd6138 Mon Sep 17 00:00:00 2001 From: Otto Moerbeek Date: Tue, 17 Oct 2023 10:32:40 +0200 Subject: [PATCH 909/909] rec: prep rec-5.0.0-alpha2 --- docs/secpoll.zone | 5 +- .../docs/appendices/yamlconversion.rst | 3 +- pdns/recursordist/docs/changelog/5.0.rst | 101 ++++++++++++++++++ pdns/recursordist/docs/upgrade.rst | 23 ++-- 4 files changed, 123 insertions(+), 9 deletions(-) diff --git a/docs/secpoll.zone b/docs/secpoll.zone index a734668c98e6..b8983a8cc42f 100644 --- a/docs/secpoll.zone +++ b/docs/secpoll.zone @@ -1,4 +1,4 @@ -@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023101103 10800 3600 604800 10800 +@ 86400 IN SOA pdns-public-ns1.powerdns.com. peter\.van\.dijk.powerdns.com. 2023101701 10800 3600 604800 10800 @ 3600 IN NS pdns-public-ns1.powerdns.com. @ 3600 IN NS pdns-public-ns2.powerdns.com. @@ -359,7 +359,8 @@ recursor-4.9.0-beta1.security-status 60 IN TXT "2 Unsupported recursor-4.9.0-rc1.security-status 60 IN TXT "2 Unsupported pre-release" recursor-4.9.0.security-status 60 IN TXT "1 OK" recursor-4.9.1.security-status 60 IN TXT "1 OK" -recursor-5.0.0-alpha1.security-status 60 IN TXT "1 Unsupported pre-release" +recursor-5.0.0-alpha1.security-status 60 IN TXT "2 Unsupported pre-release" +recursor-5.0.0-alpha2.security-status 60 IN TXT "1 Unsupported pre-release" ; Recursor Debian recursor-3.6.2-2.debian.security-status 60 IN TXT "3 Upgrade now, see https://doc.powerdns.com/3/security/powerdns-advisory-2015-01/ and https://doc.powerdns.com/3/security/powerdns-advisory-2016-02/" diff --git a/pdns/recursordist/docs/appendices/yamlconversion.rst b/pdns/recursordist/docs/appendices/yamlconversion.rst index ed2f83dbdb8e..3823ae11672f 100644 --- a/pdns/recursordist/docs/appendices/yamlconversion.rst +++ b/pdns/recursordist/docs/appendices/yamlconversion.rst @@ -59,7 +59,8 @@ API Managed Files The format of API managed files was also changed to use YAML format. Specifically, the list of API managed zones is now a single file containing a sequence of ``auth_zones`` and a sequence of ``forward_zones`` instead of a settings file per zone. The list of ACLs is a YAML sequence of subnets or IP addresses. -When using YAML settings :ref:`setting-yaml-recursor.include-dir` and :ref:`setting-yaml-webservice.api-config-dir` must have a different value. + +When using YAML settings :ref:`setting-yaml-recursor.include_dir` and :ref:`setting-yaml-webservice.api_dir` must have a different value. When YAML settings are active the :program:`Recursor` will read old-style API managed files from the include directory on startup, convert them to the new format and write them into the API config directory. After conversion, it will inactivate the old-style API managed config files in the include directory by renaming them. diff --git a/pdns/recursordist/docs/changelog/5.0.rst b/pdns/recursordist/docs/changelog/5.0.rst index 3532e8b63161..c079e08a50e6 100644 --- a/pdns/recursordist/docs/changelog/5.0.rst +++ b/pdns/recursordist/docs/changelog/5.0.rst @@ -1,5 +1,106 @@ Changelogs for 5.0.X ==================== +.. changelog:: + :version: 5.0.0-alpha2 + :released: 17th of October 2023 + + .. change:: + :tags: Improvements + :pullreq: 13362 + :tickets: 13233, 12679 + + Convert API managed config from old style to YAML if YAML settings are active. + + .. change:: + :tags: Improvements + :pullreq: 13364 + + If we miss glue--but not for all NS records--try to resolve the missing address records. + + .. change:: + :tags: Bug Fixes + :pullreq: 13353 + :tickets: 12395 + + If serving stale, wipe CNAME records from cache when we get a NODATA negative response for them. + + .. change:: + :tags: Bug Fixes + :pullreq: 13363 + + Fix Coverity 1522436 potential dereference of null return value. + + .. change:: + :tags: Improvements + :pullreq: 13296 + + Make QName Minimization parameters from :rfc:`9156` settable. + + .. change:: + :tags: Improvements + :pullreq: 13312 + + Conform to :rfc:`2181` 10.3: don't allow NS records to point to aliases. + + .. change:: + :tags: Bug Fixes + :pullreq: 13303,13311 + + Fix log messages text and levels. + + .. change:: + :tags: Improvements + :pullreq: 13295 + :tickets: 8646 + + Do not use Qname Minimization for infra-queries. + + .. change:: + :tags: Improvements + :pullreq: 13289 + + Implement probabilistic un-throttle. + + .. change:: + :tags: Improvements + :pullreq: 13290 + + Put files generated by settings/generate.py into tarball so package builds do not have to run it. + + .. change:: + :tags: Improvements + :pullreq: 13278 + :tickets: 13266 + + Fix packetcache submit refresh task logic. + + .. change:: + :tags: Bug Fixes + :pullreq: 13276 + :tickets: 13259 + + Fix sysconfdir handling in new settings code. + + .. change:: + :tags: Improvements + :pullreq: 13277 + :tickets: 13264 + + Allow loglevel to be set to levels < 3. + + .. change:: + :tags: Improvements + :pullreq: 13195 + :tickets: 8394 + + Move tcp-in processing to dedicated thread(s). + + .. change:: + :tags: Bug Fixes + :pullreq: 13250 + + Fix Coverity 1519054: Using invalid iterator. + .. changelog:: :version: 5.0.0-alpha1 :released: 13th of September 2023 diff --git a/pdns/recursordist/docs/upgrade.rst b/pdns/recursordist/docs/upgrade.rst index a786699a99cb..9da78abea32e 100644 --- a/pdns/recursordist/docs/upgrade.rst +++ b/pdns/recursordist/docs/upgrade.rst @@ -7,23 +7,34 @@ When upgrading several versions, please read **all** notes applying to the upgra 4.9.0 to 5.0.0 and master -------------------------- -YAML setings ------------- +YAML settings +^^^^^^^^^^^^^ Starting with version 5.0.0-alpha1 the settings file(s) can be specified using YAML syntax. The old-style settings files are still accepted but will be unsupported in a future release. When a ``recursor.yml`` settings file is encountered it will be processed instead of a ``recursor.conf`` file. Refer to :doc:`yamlsettings` for details and the :doc:`appendices/yamlconversion` guide for how to convert old-style settings to the new YAML format. Rust ----- +^^^^ Some parts of the Recursor code are now written in Rust. This has impact if you do local builds or are third-package maintainer. According to `cargo msrv` the minimum version to compile the Rust code and its dependencies is 1.64. Some distributions ship with an older Rust compiler, see `Rustup `__ for a way to install a more recent one. For our package builds, we install a Rust compiler from the ``Standalone`` section of `Other Rust Installation Methods `__. +New settings +^^^^^^^^^^^^ +- The :ref:`setting-bypass-server-throttling-probability` setting has been introduced to try throttled servers once in a while. +- The :ref:`setting-tcp-threads` setting has been introduced to set the number of threads dedicated to processing incoming queries over TCP. + Previously either the distributor thread(s) or the general worker threads would process TCP queries. +- The :ref:`setting-qname-max-minimize-count` and :ref:`setting-qname-minimize-one-label` have been introduced to allow tuning of the parameters specified in :rfc:`9156`. + +Changed settings +^^^^^^^^^^^^^^^^ +- The :ref:`setting-loglevel` can now be set to a level below 3 (error). + 4.8.0 to 4.9.0 --------------- +-------------- Metrics ^^^^^^^ @@ -34,7 +45,7 @@ This affects the results shown by ``rec_control get-qtypelist`` and the ``respon Additionally, most ``RCodes`` and ``QTypes`` that are marked ``Unassigned``, ``Reserved`` or ``Obsolete`` by IANA are not accounted, to reduce the memory consumed by these metrics. New settings -~~~~~~~~~~~~ +^^^^^^^^^^^^ - The :ref:`setting-packetcache-negative-ttl` settings to control the TTL of negative (NxDomain or NoData) answers in the packet cache has been introduced. - The :ref:`setting-stack-cache-size` setting to control the number of allocated mthread stacks has been introduced. - The :ref:`setting-packetcache-shards` settings to control the number of shards in the packet cache has been introduced. @@ -46,7 +57,7 @@ New settings - The setting ``includeSOA`` was added to the :func:`rpzPrimary` and :func:`rpzFile` Lua functions to include the SOA of the RPZ the responses modified by the RPZ. Changed settings -~~~~~~~~~~~~~~~~ +^^^^^^^^^^^^^^^^ The first two settings below have effect on the way the recursor distributes queries over threads. In some cases, this can lead to imbalance of the number of queries process per thread. See :doc:`performance`, in particular the :ref:`worker_imbalance` section.
        #NameResponse RuleActionMatches
        "+b["id"]+""+b["rule"]+""+b["action"]+"
        "+b["id"]+""+b["name"]+""+b["rule"]+""+b["action"]+""+b["matches"]+"

        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≦#MAgDz6q2l0& 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

    2. C~5GZ6VyieYj? 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

      Lv2U^Of+U?}x8EOT*~DBGph#i);9GL_BF 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�!Uf%$gT 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≦#MAgDz6q2l0& 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

  • C~5GZ6VyieYj? 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

    Lv2U^Of+U?}x8EOT*~DBGph#i);9GL_BF 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�!Uf%$gT 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